feat: Customizable navbar and footer with Web Template

This commit is contained in:
Faris Ansari 2020-08-21 14:17:00 +05:30
parent 4889ce13ce
commit 6692211705
15 changed files with 217 additions and 79 deletions

View file

@ -43,6 +43,11 @@ app_include_css = [
"assets/css/report.min.css",
]
doctype_js = {
"Web Page": "public/js/frappe/utils/web_template.js",
"Website Settings": "public/js/frappe/utils/web_template.js"
}
web_include_js = [
"website_script.js"
]

View file

@ -307,3 +307,4 @@ frappe.patches.v13_0.rename_notification_fields
frappe.patches.v13_0.remove_duplicate_navbar_items
frappe.patches.v13_0.enable_custom_script
frappe.patches.v13_0.update_newsletter_content_type
execute:frappe.db.set_value('Website Settings', 'Website Settings', {'navbar_template': 'Standard Navbar', 'footer_template': 'Standard Footer'})

View file

@ -0,0 +1,71 @@
function open_web_template_values_editor(template, current_values = {}) {
return new Promise(resolve => {
frappe.model.with_doc("Web Template", template).then((doc) => {
let d = new frappe.ui.Dialog({
title: __("Edit Values"),
fields: get_fields(doc),
primary_action(values) {
d.hide();
resolve(values);
},
});
d.set_values(current_values);
d.show();
d.sections.forEach((sect) => {
let fields_with_value = sect.fields_list.filter(
(field) => current_values[field.df.fieldname]
);
if (fields_with_value.length) {
sect.collapse(false);
}
});
});
});
function get_fields(doc) {
let normal_fields = [];
let table_fields = [];
let current_table = null;
for (let df of doc.fields) {
if (current_table) {
current_table.fields = current_table.fields || [];
if (df.fieldtype != 'Table Break') {
current_table.fields.push(df);
} else {
table_fields.push(df);
current_table = df;
}
} else if (df.fieldtype != 'Table Break') {
normal_fields.push(df);
} else {
table_fields.push(df);
current_table = df;
}
}
let fields = [
...normal_fields,
...table_fields.map(tf => {
let data = current_values[tf.fieldname] || [];
return {
label: tf.label,
fieldname: tf.fieldname,
fieldtype: 'Table',
fields: tf.fields.map((df, i) => ({
...df,
in_list_view: i <= 1,
columns: tf.fields.length == 1 ? 10 : 5
})),
data,
get_data: () => data
};
})
];
return fields;
}
}

View file

@ -68,7 +68,13 @@
{%- endblock -%}
{%- block navbar -%}
{% include "templates/includes/navbar/navbar.html" %}
{{ web_blocks([{
'template': navbar_template or 'Standard Navbar',
'values': _context_dict,
'add_container': 0,
'add_top_padding': 0,
'add_bottom_padding': 0,
}]) }}
{%- endblock -%}
{% block content %}
@ -76,7 +82,13 @@
{% endblock %}
{%- block footer -%}
{% include "templates/includes/footer/footer.html" %}
{{ web_blocks([{
'template': footer_template or 'Standard Footer',
'values': _context_dict,
'add_container': 0,
'add_top_padding': 0,
'add_bottom_padding': 0,
}]) }}
{%- endblock -%}
{% block base_scripts %}

View file

@ -50,79 +50,10 @@ frappe.ui.form.on("Web Page Block", {
edit_values(frm, cdt, cdn) {
let row = frm.selected_doc;
let values = JSON.parse(row.web_template_values || "{}");
function get_fields(doc) {
let normal_fields = [];
let table_fields = [];
let current_table = null;
for (let df of doc.fields) {
if (current_table) {
current_table.fields = current_table.fields || [];
if (df.fieldtype != 'Table Break') {
current_table.fields.push(df);
} else {
table_fields.push(df);
current_table = df;
}
} else if (df.fieldtype != 'Table Break') {
normal_fields.push(df);
} else {
table_fields.push(df);
current_table = df;
}
}
let fields = [
...normal_fields,
...table_fields.map(tf => {
let data = values[tf.fieldname] || [];
return {
label: tf.label,
fieldname: tf.fieldname,
fieldtype: 'Table',
fields: tf.fields.map((df, i) => ({
...df,
in_list_view: i <= 1,
columns: tf.fields.length == 1 ? 10 : 5
})),
data,
get_data: () => data
};
})
];
return fields;
}
frappe.model.with_doc("Web Template", row.web_template).then((doc) => {
let d = new frappe.ui.Dialog({
title: __("Edit Values"),
fields: get_fields(doc),
primary_action(values) {
frappe.model.set_value(
cdt,
cdn,
"web_template_values",
JSON.stringify(values)
);
d.hide();
},
open_web_template_values_editor(row.web_template, values)
.then(new_values => {
frappe.model.set_value(cdt, cdn, "web_template_values", JSON.stringify(new_values));
});
d.set_values(values);
d.show();
d.sections.forEach((sect) => {
let fields_with_value = sect.fields_list.filter(
(field) => values[field.df.fieldname]
);
if (fields_with_value.length) {
sect.collapse(false);
}
});
});
},
});

View file

@ -7,6 +7,7 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"type",
"standard",
"template",
"fields"
@ -30,10 +31,16 @@
"fieldname": "standard",
"fieldtype": "Check",
"label": "Standard"
},
{
"fieldname": "type",
"fieldtype": "Select",
"label": "Type",
"options": "Section\nNavbar\nFooter"
}
],
"links": [],
"modified": "2020-08-17 13:00:11.863241",
"modified": "2020-08-19 17:50:30.948659",
"modified_by": "Administrator",
"module": "Website",
"name": "Web Template",

View file

@ -1,4 +1,17 @@
frappe.ui.form.on('Website Settings', {
setup(frm) {
frm.set_query('navbar_template', () => ({
filters: {
type: 'Navbar'
}
}));
frm.set_query('footer_template', () => ({
filters: {
type: 'Footer'
}
}));
},
refresh: function(frm) {
frm.add_custom_button(__('View Website'), () => {
window.open('/', '_blank');
@ -80,6 +93,30 @@ frappe.ui.form.on('Website Settings', {
}
return main_items.join('\n');
},
edit_navbar_template_values(frm) {
frm.events.edit_template_values(frm, 'navbar_template');
},
edit_footer_template_values(frm) {
frm.events.edit_template_values(frm, 'footer_template');
},
edit_template_values(frm, template_field) {
let values_field = template_field + '_values';
let template = frm.doc[template_field];
if (!template) {
frappe.show_alert(__('Please select {0}', [frm.get_docfield(template_field).label]));
return;
}
let values = JSON.parse(frm.doc[values_field] || "{}");
open_web_template_values_editor(template, values)
.then(new_values => {
frm.set_value(values_field, JSON.stringify(new_values));
});
}
});
frappe.ui.form.on('Top Bar Item', {

View file

@ -28,6 +28,9 @@
"navbar_search",
"hide_login",
"top_bar_items",
"navbar_template",
"navbar_template_values",
"edit_navbar_template_values",
"call_to_action",
"call_to_action_url",
"banner",
@ -37,6 +40,9 @@
"copyright",
"address",
"footer_items",
"footer_template",
"footer_template_values",
"edit_footer_template_values",
"hide_footer_signup",
"integrations",
"enable_view_tracking",
@ -137,7 +143,7 @@
"collapsible": 1,
"fieldname": "top_bar",
"fieldtype": "Section Break",
"label": "Top Bar"
"label": "Navbar"
},
{
"default": "0",
@ -357,14 +363,53 @@
"fieldname": "hide_login",
"fieldtype": "Check",
"label": "Hide Login"
},
{
"fieldname": "navbar_template",
"fieldtype": "Link",
"label": "Navbar Template",
"options": "Web Template"
},
{
"fieldname": "navbar_template_values",
"fieldtype": "Code",
"hidden": 1,
"label": "Navbar Template Values",
"options": "JSON"
},
{
"depends_on": "eval:doc.navbar_template && doc.navbar_template !== 'Standard Navbar'",
"fieldname": "edit_navbar_template_values",
"fieldtype": "Button",
"label": "Edit Values"
},
{
"fieldname": "footer_template",
"fieldtype": "Link",
"label": "Footer Template",
"options": "Web Template"
},
{
"fieldname": "footer_template_values",
"fieldtype": "Code",
"hidden": 1,
"label": "Footer Template Values",
"options": "JSON"
},
{
"depends_on": "eval:doc.footer_template && doc.footer_template !== 'Standard Footer'",
"fieldname": "edit_footer_template_values",
"fieldtype": "Button",
"label": "Edit Values"
}
],
"icon": "fa fa-cog",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"max_attachments": 10,
"modified": "2020-08-07 13:34:19.181561",
"modified": "2020-08-21 14:02:55.168829",
"modified_by": "Administrator",
"module": "Website",
"name": "Website Settings",
@ -388,4 +433,4 @@
"sort_field": "modified",
"sort_order": "ASC",
"track_changes": 1
}
}

View file

@ -119,7 +119,8 @@ def get_website_settings(context=None):
for k in ["banner_html", "banner_image", "brand_html", "copyright", "twitter_share_via",
"facebook_share", "google_plus_one", "twitter_share", "linked_in_share",
"disable_signup", "hide_footer_signup", "head_html", "title_prefix",
"navbar_search", "enable_view_tracking", "footer_logo", "call_to_action", "call_to_action_url"]:
"navbar_template", "footer_template", "navbar_search", "enable_view_tracking",
"footer_logo", "call_to_action", "call_to_action_url"]:
if hasattr(settings, k):
context[k] = settings.get(k)

View file

@ -0,0 +1 @@
{% include "templates/includes/footer/footer.html" %}

View file

@ -0,0 +1,13 @@
{
"creation": "2020-08-21 13:55:08.557497",
"docstatus": 0,
"doctype": "Web Template",
"fields": [],
"idx": 0,
"modified": "2020-08-21 13:55:11.672764",
"modified_by": "Administrator",
"name": "Standard Footer",
"owner": "Administrator",
"standard": 1,
"type": "Footer"
}

View file

@ -0,0 +1 @@
{% include "templates/includes/navbar/navbar.html" %}

View file

@ -0,0 +1,13 @@
{
"creation": "2020-08-19 17:49:37.288380",
"docstatus": 0,
"doctype": "Web Template",
"fields": [],
"idx": 0,
"modified": "2020-08-19 17:50:44.342765",
"modified_by": "Administrator",
"name": "Standard Navbar",
"owner": "Administrator",
"standard": 1,
"type": "Navbar"
}