142 lines
4.6 KiB
Python
142 lines
4.6 KiB
Python
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# MIT License. See license.txt
|
|
|
|
from __future__ import unicode_literals
|
|
import frappe, os
|
|
|
|
from frappe.website.utils import can_cache, delete_page_cache
|
|
from frappe.model.document import get_controller
|
|
|
|
def get_route_info(path):
|
|
sitemap_options = None
|
|
cache_key = "sitemap_options:{0}:{1}".format(path, frappe.local.lang)
|
|
|
|
if can_cache():
|
|
sitemap_options_cache = frappe.cache().hget("sitemap_options", path) or {}
|
|
sitemap_options = sitemap_options_cache.get(frappe.local.lang, None)
|
|
|
|
if not sitemap_options:
|
|
sitemap_options = build_route(path)
|
|
if can_cache(sitemap_options.no_cache):
|
|
sitemap_options_cache[frappe.local.lang] = sitemap_options
|
|
frappe.cache().hset("sitemap_options", path, sitemap_options_cache)
|
|
|
|
return sitemap_options
|
|
|
|
def build_route(path):
|
|
context = resolve_route(path)
|
|
if not context:
|
|
raise frappe.DoesNotExistError
|
|
|
|
context.doctype = context.ref_doctype
|
|
context.title = context.page_title
|
|
context.pathname = frappe.local.path
|
|
|
|
return context
|
|
|
|
def resolve_route(path):
|
|
"""Returns the page route object based on searching in pages and generators.
|
|
The `www` folder is also a part of generator **Web Page**.
|
|
|
|
The only exceptions are `/about` and `/contact` these will be searched in Web Pages
|
|
first before checking the standard pages."""
|
|
if path not in ("about", "contact"):
|
|
route = get_page_route(path)
|
|
if route: return route
|
|
return get_generator_route(path)
|
|
else:
|
|
route = get_generator_route(path)
|
|
if route: return route
|
|
return get_page_route(path)
|
|
|
|
def get_page_route(path):
|
|
found = filter(lambda p: p.page_name==path, get_pages())
|
|
return found[0] if found else None
|
|
|
|
def get_generator_route(path):
|
|
generator_routes = get_generator_routes()
|
|
if path in generator_routes:
|
|
route = generator_routes[path]
|
|
return frappe.get_doc(route.get("doctype"), route.get("name")).get_route_context()
|
|
|
|
def clear_sitemap():
|
|
delete_page_cache("*")
|
|
|
|
def get_generator_routes():
|
|
routes = frappe.cache().get_value("website_generator_routes")
|
|
if not routes:
|
|
routes = {}
|
|
for app in frappe.get_installed_apps():
|
|
for doctype in frappe.get_hooks("website_generators", app_name = app):
|
|
condition = ""
|
|
route_column_name = "page_name"
|
|
controller = get_controller(doctype)
|
|
meta = frappe.get_meta(doctype)
|
|
|
|
if meta.get_field("parent_website_route"):
|
|
route_column_name = """concat(ifnull(parent_website_route, ""),
|
|
if(ifnull(parent_website_route, "")="", "", "/"), page_name)"""
|
|
|
|
if controller.website.condition_field:
|
|
condition ="where ifnull({0}, 0)=1".format(controller.website.condition_field)
|
|
|
|
for r in frappe.db.sql("""select {0} as route, name, modified from `tab{1}`
|
|
{2}""".format(route_column_name, doctype, condition), as_dict=True):
|
|
routes[r.route] = {"doctype": doctype, "name": r.name, "modified": r.modified}
|
|
|
|
frappe.cache().set_value("website_generator_routes", routes)
|
|
|
|
return routes
|
|
|
|
def get_pages():
|
|
pages = frappe.cache().get_value("_website_pages")
|
|
if not pages:
|
|
pages = []
|
|
for app in frappe.get_installed_apps():
|
|
app_path = frappe.get_app_path(app)
|
|
path = os.path.join(app_path, "templates", "pages")
|
|
if os.path.exists(path):
|
|
for fname in os.listdir(path):
|
|
fname = frappe.utils.cstr(fname)
|
|
page_name, extn = fname.rsplit(".", 1)
|
|
if extn in ("html", "xml", "js", "css"):
|
|
route_page_name = page_name if extn=="html" else fname
|
|
|
|
# add website route
|
|
route = frappe._dict()
|
|
route.page_or_generator = "Page"
|
|
route.template = os.path.relpath(os.path.join(path, fname), app_path)
|
|
route.name = route.page_name = route_page_name
|
|
controller_path = os.path.join(path, page_name.replace("-", "_") + ".py")
|
|
|
|
if os.path.exists(controller_path):
|
|
controller = app + "." + os.path.relpath(controller_path,
|
|
app_path).replace(os.path.sep, ".")[:-3]
|
|
route.controller = controller
|
|
|
|
for fieldname in ("page_title", "no_sitemap"):
|
|
try:
|
|
route[fieldname] = frappe.get_attr(controller + "." + fieldname)
|
|
except AttributeError:
|
|
pass
|
|
|
|
pages.append(route)
|
|
|
|
frappe.cache().set_value("_website_pages", pages)
|
|
return pages
|
|
|
|
def process_generators(func):
|
|
for app in frappe.get_installed_apps():
|
|
for doctype in frappe.get_hooks("website_generators", app_name = app):
|
|
order_by = "name asc"
|
|
condition_field = None
|
|
controller = get_controller(doctype)
|
|
|
|
if hasattr(controller, "condition_field"):
|
|
condition_field = controller.condition_field
|
|
if hasattr(controller, "order_by"):
|
|
order_by = controller.order_by
|
|
|
|
val = func(doctype, condition_field, order_by)
|
|
if val:
|
|
return val
|