feat: make Web View embeddable and allow navbar and footer as Web Views
This commit is contained in:
parent
e323441c15
commit
0322ab198d
9 changed files with 176 additions and 82 deletions
|
|
@ -62,7 +62,11 @@
|
|||
{%- endblock -%}
|
||||
|
||||
{%- block navbar -%}
|
||||
{% include "templates/includes/navbar/navbar.html" %}
|
||||
{%- if navbar_content -%}
|
||||
{{ navbar_content }}
|
||||
{%- else -%}
|
||||
{% include "templates/includes/navbar/navbar.html" %}
|
||||
{%- endif -%}
|
||||
{%- endblock -%}
|
||||
|
||||
{% block content %}
|
||||
|
|
@ -70,7 +74,11 @@
|
|||
{% endblock %}
|
||||
|
||||
{%- block footer -%}
|
||||
{% include "templates/includes/footer/footer.html" %}
|
||||
{%- if footer_content -%}
|
||||
{{ footer_content }}
|
||||
{%- else -%}
|
||||
{% include "templates/includes/footer/footer.html" %}
|
||||
{%- endif -%}
|
||||
{%- endblock -%}
|
||||
|
||||
{% block base_scripts %}
|
||||
|
|
|
|||
|
|
@ -1,65 +1,7 @@
|
|||
{% extends "templates/web.html" %}
|
||||
|
||||
{% block page_content %}
|
||||
|
||||
{% if css_rules or css %}
|
||||
<style>
|
||||
{% for css_rule in css_rules %}
|
||||
{{ css_rule }}
|
||||
{% endfor %}
|
||||
{{ css }}
|
||||
</style>
|
||||
{% endif %}
|
||||
|
||||
{% macro render_element(element) %}
|
||||
{% if element.element_type=='Content' %}
|
||||
{{ element.web_content_html }}
|
||||
{% elif element.element_type=='Image' %}
|
||||
<img src='{{ element.image_url }}' {% if element.element_class %}class='{{ element.element_class }}'{% endif %}>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% for section in sections %}
|
||||
<section class='section {{ section.element_class or "" }} {{ section.hide and "hidden" or "" }}'>
|
||||
<div class='section-body container'>
|
||||
{% if section.section_intro %}
|
||||
<div class='section-intro'>{{ section.section_intro }}</div>
|
||||
{% endif %}
|
||||
{% if section.section_type == 'List' %}
|
||||
{% for element in section.elements %}
|
||||
{{ render_element(element) }}
|
||||
{% endfor %}
|
||||
{% elif section.section_type == 'Grid' %}
|
||||
<div class='row'>
|
||||
{% for element in section.elements %}
|
||||
<div class='web-content col col-md-{{ element.columns or 6 }} {{ element.element_class or "" }}'>
|
||||
{{ render_element(element) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% elif section.section_type == 'Tabbed' %}
|
||||
<ul class="nav" role="tablist">
|
||||
{% for element in section.elements %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {{ loop.index == 1 and 'active' or ''}}" href="#{{ element.element_id }}" role="tab" data-toggle="tab">
|
||||
{{ element.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
{% for element in section.elements %}
|
||||
<div class="web-content tab-pane {{ loop.index == 1 and 'show active' or ''}}" role="tabpanel" id="{{ element.element_id }}">
|
||||
{{ render_element(element) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
{% include "frappe/website/doctype/web_view/templates/web_view_content.html" %}
|
||||
{% endblock %}
|
||||
|
||||
<!-- this is a sample default web page template -->
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
{%- if css_rules or css -%}
|
||||
|
||||
<style>
|
||||
{%- for css_rule in css_rules -%}
|
||||
{{ css_rule }}
|
||||
{%- endfor -%}
|
||||
{{ css or "" }}
|
||||
</style>
|
||||
{%- endif -%}
|
||||
|
||||
{%- macro render_element(element) -%}
|
||||
{%- if element.element_type=='Content' -%}
|
||||
{{ element.web_content_html }}
|
||||
{%- elif element.element_type=='Image' -%}
|
||||
<img src='{{ element.image_url }}' {%- if element.element_class -%}class='{{ element.element_class }}'{%- endif -%}>
|
||||
{%- endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- for section in sections -%}
|
||||
<section class='section {{ section.element_class or "" }} {{ section.hide and "hidden" or "" }}'>
|
||||
<div class='section-body container'>
|
||||
{%- if section.section_intro -%}
|
||||
|
||||
<div class='section-intro'>{{ section.section_intro }}</div>
|
||||
{%- endif -%}
|
||||
|
||||
{%- if section.section_type == 'List' -%}
|
||||
{%- for element in section.elements -%}
|
||||
{{ render_element(element) }}
|
||||
{%- endfor -%}
|
||||
|
||||
{%- elif section.section_type == 'Grid' -%}
|
||||
<div class='row'>
|
||||
{%- for element in section.elements -%}
|
||||
<div class='web-content col-md-{{ element.columns or 6 }} {{ element.element_class or "" }}'>
|
||||
{{ render_element(element) }}
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
|
||||
{%- elif section.section_type == 'Tabbed' -%}
|
||||
<ul class="nav" role="tablist">
|
||||
{%- for element in section.elements -%}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {{ loop.index == 1 and 'active' or ''}}" href="#{{ element.element_id }}" role="tab" data-toggle="tab">
|
||||
{{ element.title }}
|
||||
</a>
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
{%- for element in section.elements -%}
|
||||
<div class="web-content tab-pane {{ loop.index == 1 and 'show active' or ''}}" role="tabpanel" id="{{ element.element_id }}">
|
||||
{{ render_element(element) }}
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
|
||||
{%- endif -%}
|
||||
</div>
|
||||
</section>
|
||||
{%- endfor -%}
|
||||
|
|
@ -18,29 +18,44 @@ class WebView(WebsiteGenerator):
|
|||
self.add_default_section(context)
|
||||
|
||||
if item.element_type=='Section':
|
||||
item.elements = []
|
||||
context.sections.append(item)
|
||||
|
||||
if item.section_intro:
|
||||
item.section_intro = markdown(item.section_intro)
|
||||
|
||||
self.add_section(context, item)
|
||||
else:
|
||||
if item.hide:
|
||||
continue
|
||||
self.add_item(context, item)
|
||||
|
||||
if item.web_content_type == 'Markdown':
|
||||
item.web_content_html = markdown(item.web_content_markdown)
|
||||
self.add_css_class(context, item)
|
||||
|
||||
if item.title:
|
||||
item.element_id = frappe.scrub(item.title)
|
||||
return context
|
||||
|
||||
context.sections[-1].elements.append(item)
|
||||
def add_section(self, context, item):
|
||||
item.elements = []
|
||||
context.sections.append(item)
|
||||
|
||||
if item.element_class:
|
||||
css, is_dynamic = frappe.db.get_value('CSS Class', item.element_class, ['css', 'is_dynamic'])
|
||||
if is_dynamic:
|
||||
css = frappe.render_template(css, self.get_theme())
|
||||
context.css_rules.append(css)
|
||||
if item.section_intro:
|
||||
item.section_intro = markdown(item.section_intro)
|
||||
|
||||
def add_item(self, context, item):
|
||||
if item.hide:
|
||||
return
|
||||
|
||||
if item.web_content_type == 'Markdown':
|
||||
item.web_content_html = markdown(item.web_content_markdown)
|
||||
|
||||
if item.title:
|
||||
item.element_id = frappe.scrub(item.title)
|
||||
|
||||
context.sections[-1].elements.append(item)
|
||||
|
||||
def add_css_class(self, context, item):
|
||||
# add css class definitions selected by the user
|
||||
if item.element_class and not item.hide:
|
||||
css, is_dynamic = frappe.db.get_value('CSS Class', item.element_class, ['css', 'is_dynamic'])
|
||||
if is_dynamic:
|
||||
css = frappe.render_template(css, self.get_theme())
|
||||
context.css_rules.append(css)
|
||||
|
||||
def render_content(self):
|
||||
# webview can be rendered as an object (see footer)
|
||||
return frappe.render_template("frappe/website/doctype/web_view/templates/web_view_content.html", self.get_context(self.as_dict()))
|
||||
|
||||
def get_theme(self):
|
||||
# get theme properties
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestWebsiteSettings(unittest.TestCase):
|
||||
pass
|
||||
|
|
@ -19,11 +19,15 @@
|
|||
"set_banner_from_image",
|
||||
"favicon",
|
||||
"top_bar",
|
||||
"top_bar_type",
|
||||
"top_bar_web_view",
|
||||
"navbar_search",
|
||||
"top_bar_items",
|
||||
"banner",
|
||||
"banner_html",
|
||||
"footer",
|
||||
"footer_type",
|
||||
"footer_web_view",
|
||||
"copyright",
|
||||
"address",
|
||||
"footer_items",
|
||||
|
|
@ -130,11 +134,13 @@
|
|||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.top_bar_type==='Standard'",
|
||||
"fieldname": "navbar_search",
|
||||
"fieldtype": "Check",
|
||||
"label": "Include Search in Top Bar"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.top_bar_type==='Standard'",
|
||||
"fieldname": "top_bar_items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Top Bar Items",
|
||||
|
|
@ -160,17 +166,20 @@
|
|||
"label": "Footer"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.footer_type==='Standard'",
|
||||
"fieldname": "copyright",
|
||||
"fieldtype": "Data",
|
||||
"label": "Copyright"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.footer_type==='Standard'",
|
||||
"description": "Address and other legal information you may want to put in the footer.",
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Address"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.footer_type==='Standard'",
|
||||
"fieldname": "footer_items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Footer Items",
|
||||
|
|
@ -178,6 +187,7 @@
|
|||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.footer_type==='Standard'",
|
||||
"fieldname": "hide_footer_signup",
|
||||
"fieldtype": "Check",
|
||||
"label": "Hide Footer Signup"
|
||||
|
|
@ -319,6 +329,34 @@
|
|||
"fieldname": "authorize_api_indexing_access",
|
||||
"fieldtype": "Button",
|
||||
"label": "Authorize API Indexing Access"
|
||||
},
|
||||
{
|
||||
"default": "Standard",
|
||||
"fieldname": "footer_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Footer Type",
|
||||
"options": "Standard\nWeb View"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.footer_type==='Web View'",
|
||||
"fieldname": "footer_web_view",
|
||||
"fieldtype": "Link",
|
||||
"label": "Footer Web View",
|
||||
"options": "Web View"
|
||||
},
|
||||
{
|
||||
"default": "Standard",
|
||||
"fieldname": "top_bar_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Top Bar Type",
|
||||
"options": "Standard\nWeb View"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.top_bar_type==='Web View'",
|
||||
"fieldname": "top_bar_web_view",
|
||||
"fieldtype": "Link",
|
||||
"label": "Top Bar Web View",
|
||||
"options": "Web View"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ def get_website_settings():
|
|||
context[key] = context[key][-1]
|
||||
|
||||
add_website_theme(context)
|
||||
add_webviews(context, settings)
|
||||
|
||||
if not context.get("favicon"):
|
||||
context["favicon"] = "/assets/frappe/images/favicon.png"
|
||||
|
|
@ -158,6 +159,17 @@ def get_website_settings():
|
|||
|
||||
return context
|
||||
|
||||
def add_webviews(context, settings):
|
||||
# render footer as webview, not standard view
|
||||
# see base.html for how this is handled
|
||||
if settings.footer_type=='Web View' and settings.footer_web_view:
|
||||
context.footer_content = frappe.get_doc('Web View',
|
||||
settings.footer_web_view).render_content()
|
||||
|
||||
if settings.top_bar_type=='Web View' and settings.top_bar_web_view:
|
||||
context.navbar_content = frappe.get_doc('Web View',
|
||||
settings.top_bar_web_view).render_content()
|
||||
|
||||
def get_items(parentfield):
|
||||
all_top_items = frappe.db.sql("""\
|
||||
select * from `tabTop Bar Item`
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
"configuration_section",
|
||||
"google_font",
|
||||
"font_size",
|
||||
"font_properties",
|
||||
"column_break_7",
|
||||
"primary_color",
|
||||
"text_color",
|
||||
|
|
@ -135,10 +136,16 @@
|
|||
"fieldname": "light_color",
|
||||
"fieldtype": "Color",
|
||||
"label": "Light Color"
|
||||
},
|
||||
{
|
||||
"default": "300,600",
|
||||
"fieldname": "font_properties",
|
||||
"fieldtype": "Data",
|
||||
"label": "Font Properties"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-03-17 16:52:18.541152",
|
||||
"modified": "2020-03-18 18:24:57.469492",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Website Theme",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{% if google_font %}
|
||||
@import url('https://fonts.googleapis.com/css?family={{ google_font }}:400,400italic,600&subset=latin,latin-ext');
|
||||
$font-family-sans-serif: "{{ google_font }}", '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif';
|
||||
@import url('https://fonts.googleapis.com/css?family={{ google_font }}:{{ font_properties }}&display=swap');
|
||||
$font-family-sans-serif: "{{ google_font }}", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
{% endif %}
|
||||
|
||||
{% if primary_color %}$primary: {{ primary_color }};{% endif %}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue