seitime-frappe/frappe/website/router.py
2015-05-08 18:04:13 +05:30

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