feat: make Web View embeddable and allow navbar and footer as Web Views

This commit is contained in:
Rushabh Mehta 2020-03-18 18:51:03 +05:30
parent e323441c15
commit 0322ab198d
9 changed files with 176 additions and 82 deletions

View file

@ -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 %}

View file

@ -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 -->

View file

@ -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 -%}

View file

@ -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

View file

@ -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

View file

@ -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",

View file

@ -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`

View file

@ -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",

View file

@ -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 %}