# ERPNext - web based ERP (http://erpnext.com) # Copyright (C) 2012 Web Notes Technologies Pvt Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from __future__ import unicode_literals import os import conf import webnotes page_map = { 'Web Page': webnotes._dict({ "template": 'html/web_page.html', "condition_field": "published" }), 'Blog': webnotes._dict({ "template": 'html/blog_page.html', "condition_field": "published", }), 'Item': webnotes._dict({ "template": 'html/product_page.html', "condition_field": "show_in_website", }), 'Item Group': webnotes._dict({ "template": "html/product_group.html", "condition_field": "show_in_website" }) } page_settings_map = { "about": "About Us Settings", "contact": "Contact Us Settings" } def render(page_name): """render html page""" try: if page_name: html = get_html(page_name) else: html = get_html('index') except Exception: html = get_html('error') from webnotes.handler import eprint, print_zip eprint("Content-Type: text/html") print_zip(html) def get_html(page_name): """get page html""" page_name = scrub_page_name(page_name) html = '' # load from cache, if auto cache clear is falsy if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0): html = webnotes.cache().get_value("page:" + page_name) from_cache = True if not html: html = load_into_cache(page_name) from_cache = False if not html: html = get_html("404") if page_name=="error": html = html.replace("%(error)s", webnotes.getTraceback()) else: comments = "\n\npage:"+page_name+\ "\nload status: " + (from_cache and "cache" or "fresh") html += """\n""" % webnotes.utils.cstr(comments) return html def scrub_page_name(page_name): if page_name.endswith('.html'): page_name = page_name[:-5] return page_name def page_name(title): """make page name from title""" import re name = title.lower() name = re.sub('[~!@#$%^&*()<>,."\']', '', name) name = re.sub('[:/]', '-', name) name = '-'.join(name.split()) # replace repeating hyphens name = re.sub(r"(-)\1+", r"\1", name) return name def update_page_name(doc, title): """set page_name and check if it is unique""" webnotes.conn.set(doc, "page_name", page_name(title)) standard_pages = get_template_pages() if doc.page_name in standard_pages: webnotes.conn.sql("""Page Name cannot be one of %s""" % ', '.join(standard_pages)) res = webnotes.conn.sql("""\ select count(*) from `tab%s` where page_name=%s and name!=%s""" % (doc.doctype, '%s', '%s'), (doc.page_name, doc.name)) if res and res[0][0] > 0: webnotes.msgprint("""A %s with the same title already exists. Please change the title of %s and save again.""" % (doc.doctype, doc.name), raise_exception=1) delete_page_cache(doc.page_name) def load_into_cache(page_name): args = prepare_args(page_name) if not args: return "" html = build_html(args) webnotes.cache().set_value("page:" + page_name, html) return html def build_html(args): from jinja2 import Environment, FileSystemLoader templates_path = os.path.join(os.path.dirname(conf.__file__), 'app', 'website', 'templates') args["len"] = len jenv = Environment(loader = FileSystemLoader(templates_path)) html = jenv.get_template(args['template']).render(args) return html def prepare_args(page_name): if page_name == 'index': page_name = get_home_page() if page_name in get_template_pages(): args = webnotes._dict({ 'template': 'pages/%s.html' % page_name, 'name': page_name, }) if page_name in page_settings_map: args.obj = webnotes.bean(page_settings_map[page_name]).obj else: args = get_doc_fields(page_name) if not args: return False get_outer_env(page_name, args) return args def get_template_pages(): pages_path = os.path.join(os.path.dirname(conf.__file__), 'app', 'website', 'templates', 'pages') page_list = [] for page in os.listdir(pages_path): page_list.append(scrub_page_name(page)) return page_list def get_doc_fields(page_name): doc_type, doc_name = get_source_doc(page_name) if not doc_type: return False obj = webnotes.get_obj(doc_type, doc_name, with_children=True) if hasattr(obj, 'prepare_template_args'): obj.prepare_template_args() args = obj.doc.fields args['template'] = page_map[doc_type].template args['obj'] = obj args['int'] = int return args def get_source_doc(page_name): """get source doc for the given page name""" for doctype in page_map: name = webnotes.conn.sql("""select name from `tab%s` where page_name=%s and ifnull(%s, 0)=1""" % (doctype, "%s", page_map[doctype].condition_field), page_name) if name: return doctype, name[0][0] return None, None def get_outer_env(page_name, args): from webnotes.utils import get_request_site_address from urllib import quote all_top_items = webnotes.conn.sql("""\ select * from `tabTop Bar Item` where parent='Website Settings' and parentfield='top_bar_items' order by idx asc""", as_dict=1) top_items = [d for d in all_top_items if not d['parent_label']] # attach child items to top bar for d in all_top_items: if d['parent_label']: for t in top_items: if t['label']==d['parent_label']: if not 'child_items' in t: t['child_items'] = [] t['child_items'].append(d) break if top_items and ("products" in [d.url.split(".")[0] for d in top_items if d.url]): # product categories products = webnotes.conn.sql("""select t1.item_group as label, t2.page_name as url, ifnull(t1.indent,0) as indent from `tabWebsite Product Category` t1, `tabItem Group` t2 where t1.item_group = t2.name and ifnull(t2.show_in_website,0)=1 order by t1.idx""", as_dict=1) products_item = filter(lambda d: d.url and d.url.split(".")[0]=="products", top_items)[0] products_item.child_items = products ret = webnotes._dict({ 'top_bar_items': top_items, 'footer_items': webnotes.conn.sql("""\ select * from `tabTop Bar Item` where parent='Website Settings' and parentfield='footer_items' order by idx asc""", as_dict=1), 'int':int }) args.update(ret) settings = webnotes.doc("Website Settings", "Website Settings") for k in ["brand_html", "copyright", "address", "top_bar_background", "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", "twitter_share_via"]: if k in settings.fields: args[k] = settings.fields.get(k) if not args.brand_html: args.brand_html = "ERPNext" if not args.top_bar_background: args.top_bar_background = "Black" args.url = quote(get_request_site_address(full_address=True), "") args.encoded_title = quote(args.title or "", "") return args def get_home_page(): doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page') if doc_name: page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name') else: page_name = 'login' return page_name def clear_cache(page_name=None): if page_name: delete_page_cache(page_name) else: cache = webnotes.cache() for p in get_all_pages(): cache.delete_value("page:" + p) def get_all_pages(): all_pages = get_template_pages() all_pages += page_settings_map.keys() for doctype in page_map: all_pages += [p[0] for p in webnotes.conn.sql("""select distinct page_name from `tab%s`""" % doctype) if p[0]] return all_pages def delete_page_cache(page_name): if page_name: webnotes.cache().delete_value("page:" + page_name) def url_for_website(url): if url and not url.lower().startswith("http"): return "files/" + url else: return url