BREAKING CHANGE A route is added to the sitemap if no_sitemap is not set. This PR reverses this design. Because sitemap should contain publicly accessible pages and not utility pages. Also, having lots of utility pages on sitemap does more harm than good.
267 lines
8 KiB
Python
267 lines
8 KiB
Python
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# MIT License. See license.txt
|
|
|
|
from __future__ import unicode_literals
|
|
import frappe, os, json
|
|
|
|
from frappe.website.doctype.website_settings.website_settings import get_website_settings
|
|
from frappe.website.router import get_page_context
|
|
from frappe.model.document import Document
|
|
|
|
def get_context(path, args=None):
|
|
if args and args.source:
|
|
context = args
|
|
else:
|
|
context = get_page_context(path)
|
|
if args:
|
|
context.update(args)
|
|
|
|
if hasattr(frappe.local, 'request'):
|
|
# for <body data-path=""> (remove leading slash)
|
|
# path could be overriden in render.resolve_from_map
|
|
context["path"] = frappe.local.request.path.strip('/ ')
|
|
else:
|
|
context["path"] = path
|
|
|
|
context.route = context.path
|
|
|
|
context = build_context(context)
|
|
|
|
# set using frappe.respond_as_web_page
|
|
if hasattr(frappe.local, 'response') and frappe.local.response.get('context'):
|
|
context.update(frappe.local.response.context)
|
|
|
|
return context
|
|
|
|
def update_controller_context(context, controller):
|
|
module = frappe.get_module(controller)
|
|
|
|
if module:
|
|
# get config fields
|
|
for prop in ("base_template_path", "template", "no_cache", "sitemap",
|
|
"condition_field"):
|
|
if hasattr(module, prop):
|
|
context[prop] = getattr(module, prop)
|
|
|
|
if hasattr(module, "get_context"):
|
|
try:
|
|
ret = module.get_context(context)
|
|
if ret:
|
|
context.update(ret)
|
|
except (frappe.PermissionError, frappe.DoesNotExistError, frappe.Redirect):
|
|
raise
|
|
except:
|
|
if not frappe.flags.in_migrate:
|
|
frappe.errprint(frappe.utils.get_traceback())
|
|
|
|
if hasattr(module, "get_children"):
|
|
context.children = module.get_children(context)
|
|
|
|
|
|
def build_context(context):
|
|
"""get_context method of doc or module is supposed to render
|
|
content templates and push it into context"""
|
|
context = frappe._dict(context)
|
|
|
|
if not "url_prefix" in context:
|
|
context.url_prefix = ""
|
|
|
|
if context.url_prefix and context.url_prefix[-1]!='/':
|
|
context.url_prefix += '/'
|
|
|
|
# for backward compatibility
|
|
context.docs_base_url = '/docs'
|
|
|
|
context.update(get_website_settings())
|
|
context.update(frappe.local.conf.get("website_context") or {})
|
|
|
|
# provide doc
|
|
if context.doc:
|
|
context.update(context.doc.as_dict())
|
|
context.update(context.doc.get_website_properties())
|
|
|
|
if not context.template:
|
|
context.template = context.doc.meta.get_web_template()
|
|
|
|
if hasattr(context.doc, "get_context"):
|
|
ret = context.doc.get_context(context)
|
|
|
|
if ret:
|
|
context.update(ret)
|
|
|
|
for prop in ("no_cache", "sitemap"):
|
|
if not prop in context:
|
|
context[prop] = getattr(context.doc, prop, False)
|
|
|
|
elif context.controller:
|
|
# controller based context
|
|
update_controller_context(context, context.controller)
|
|
|
|
# controller context extensions
|
|
context_controller_hooks = frappe.get_hooks("extend_website_page_controller_context") or {}
|
|
for controller, extension in context_controller_hooks.items():
|
|
if isinstance(extension, list):
|
|
for ext in extension:
|
|
if controller == context.controller:
|
|
update_controller_context(context, ext)
|
|
else:
|
|
update_controller_context(context, extension)
|
|
|
|
add_metatags(context)
|
|
add_sidebar_and_breadcrumbs(context)
|
|
|
|
# determine templates to be used
|
|
if not context.base_template_path:
|
|
app_base = frappe.get_hooks("base_template")
|
|
context.base_template_path = app_base[0] if app_base else "templates/base.html"
|
|
|
|
if context.title_prefix and context.title and not context.title.startswith(context.title_prefix):
|
|
context.title = '{0} - {1}'.format(context.title_prefix, context.title)
|
|
|
|
return context
|
|
|
|
def load_sidebar(context, sidebar_json_path):
|
|
with open(sidebar_json_path, 'r') as sidebarfile:
|
|
context.sidebar_items = json.loads(sidebarfile.read())
|
|
context.show_sidebar = 1
|
|
|
|
def get_sidebar_json_path(path, look_for=False):
|
|
'''
|
|
Get _sidebar.json path from directory path
|
|
|
|
:param path: path of the current diretory
|
|
:param look_for: if True, look for _sidebar.json going upwards from given path
|
|
|
|
:return: _sidebar.json path
|
|
'''
|
|
if os.path.split(path)[1] == 'www' or path == '/' or not path:
|
|
return ''
|
|
|
|
sidebar_json_path = os.path.join(path, '_sidebar.json')
|
|
if os.path.exists(sidebar_json_path):
|
|
return sidebar_json_path
|
|
else:
|
|
if look_for:
|
|
return get_sidebar_json_path(os.path.split(path)[0], look_for)
|
|
else:
|
|
return ''
|
|
|
|
def add_sidebar_and_breadcrumbs(context):
|
|
'''Add sidebar and breadcrumbs to context'''
|
|
from frappe.website.router import get_page_info_from_template
|
|
if context.show_sidebar:
|
|
context.no_cache = 1
|
|
add_sidebar_data(context)
|
|
else:
|
|
if context.basepath:
|
|
hooks = frappe.get_hooks('look_for_sidebar_json')
|
|
look_for_sidebar_json = hooks[0] if hooks else 0
|
|
sidebar_json_path = get_sidebar_json_path(
|
|
context.basepath,
|
|
look_for_sidebar_json
|
|
)
|
|
if sidebar_json_path:
|
|
load_sidebar(context, sidebar_json_path)
|
|
|
|
if context.add_breadcrumbs and not context.parents:
|
|
if context.basepath:
|
|
parent_path = os.path.dirname(context.path).rstrip('/')
|
|
page_info = get_page_info_from_template(parent_path)
|
|
if page_info:
|
|
context.parents = [dict(route=parent_path, title=page_info.title)]
|
|
|
|
def add_sidebar_data(context):
|
|
from frappe.utils.user import get_fullname_and_avatar
|
|
import frappe.www.list
|
|
|
|
if context.show_sidebar and context.website_sidebar:
|
|
context.sidebar_items = frappe.get_all('Website Sidebar Item',
|
|
filters=dict(parent=context.website_sidebar), fields=['title', 'route', '`group`'],
|
|
order_by='idx asc')
|
|
|
|
if not context.sidebar_items:
|
|
sidebar_items = frappe.cache().hget('portal_menu_items', frappe.session.user)
|
|
if sidebar_items == None:
|
|
sidebar_items = []
|
|
roles = frappe.get_roles()
|
|
portal_settings = frappe.get_doc('Portal Settings', 'Portal Settings')
|
|
|
|
def add_items(sidebar_items, items):
|
|
for d in items:
|
|
if d.get('enabled') and ((not d.get('role')) or d.get('role') in roles):
|
|
sidebar_items.append(d.as_dict() if isinstance(d, Document) else d)
|
|
|
|
if not portal_settings.hide_standard_menu:
|
|
add_items(sidebar_items, portal_settings.get('menu'))
|
|
|
|
if portal_settings.custom_menu:
|
|
add_items(sidebar_items, portal_settings.get('custom_menu'))
|
|
|
|
items_via_hooks = frappe.get_hooks('portal_menu_items')
|
|
if items_via_hooks:
|
|
for i in items_via_hooks: i['enabled'] = 1
|
|
add_items(sidebar_items, items_via_hooks)
|
|
|
|
frappe.cache().hset('portal_menu_items', frappe.session.user, sidebar_items)
|
|
|
|
context.sidebar_items = sidebar_items
|
|
|
|
info = get_fullname_and_avatar(frappe.session.user)
|
|
context["fullname"] = info.fullname
|
|
context["user_image"] = info.avatar
|
|
context["user"] = info.name
|
|
|
|
|
|
def add_metatags(context):
|
|
tags = context.get("metatags")
|
|
if tags:
|
|
if not "twitter:card" in tags:
|
|
tags["twitter:card"] = "summary_large_image"
|
|
|
|
if not "og:type" in tags:
|
|
tags["og:type"] = "article"
|
|
|
|
if tags.get("name"):
|
|
tags["og:title"] = tags["twitter:title"] = tags["name"]
|
|
|
|
if tags.get("title"):
|
|
tags["og:title"] = tags["twitter:title"] = tags["title"]
|
|
|
|
if tags.get("description"):
|
|
tags["og:description"] = tags["twitter:description"] = tags["description"]
|
|
|
|
image = tags.get('image', context.image or None)
|
|
if image:
|
|
tags["og:image"] = tags["twitter:image:src"] = tags["image"] = frappe.utils.get_url(image)
|
|
|
|
if context.path:
|
|
tags['og:url'] = tags['url'] = frappe.utils.get_url(context.path)
|
|
|
|
if context.published_on:
|
|
tags['datePublished'] = context.published_on
|
|
|
|
if context.author:
|
|
tags['author'] = context.author
|
|
|
|
if context.description:
|
|
tags['description'] = context.description
|
|
|
|
tags['language'] = frappe.local.lang or 'en'
|
|
|
|
# Get meta tags from Website Route meta
|
|
# they can override the defaults set above
|
|
route = context.route
|
|
if route == '':
|
|
# homepage
|
|
route = frappe.db.get_single_value('Website Settings', 'home_page')
|
|
|
|
route_exists = (route
|
|
and not route.endswith(('.js', '.css'))
|
|
and frappe.db.exists('Website Route Meta', route))
|
|
|
|
if route_exists:
|
|
context.setdefault('metatags', frappe._dict({}))
|
|
website_route_meta = frappe.get_doc('Website Route Meta', route)
|
|
for meta_tag in website_route_meta.meta_tags:
|
|
d = meta_tag.get_meta_dict()
|
|
context.metatags.update(d)
|