@@ -982,7 +982,7 @@ def respond_as_web_page(title, html, success=None, http_status_code=None, contex | |||
local.message = html | |||
local.message_success = success | |||
local.response['type'] = 'page' | |||
local.response['page_name'] = 'message' | |||
local.response['route'] = 'message' | |||
if http_status_code: | |||
local.response['http_status_code'] = http_status_code | |||
@@ -4,55 +4,6 @@ import os | |||
import frappe | |||
from frappe.commands import pass_context | |||
@click.command('make-docs') | |||
@pass_context | |||
@click.argument('app') | |||
@click.argument('docs_version') | |||
def make_docs(context, app, docs_version): | |||
"Setup docs in target folder of target app" | |||
from frappe.utils.setup_docs import setup_docs | |||
for site in context.sites: | |||
try: | |||
frappe.init(site=site) | |||
frappe.connect() | |||
make = setup_docs(app) | |||
make.build(docs_version) | |||
finally: | |||
frappe.destroy() | |||
@click.command('sync-docs') | |||
@pass_context | |||
@click.argument('app') | |||
def sync_docs(context, app): | |||
"Sync docs from /docs folder into the database (Web Page)" | |||
from frappe.utils.setup_docs import setup_docs | |||
for site in context.sites: | |||
try: | |||
frappe.init(site=site) | |||
frappe.connect() | |||
make = setup_docs(app) | |||
make.sync_docs() | |||
finally: | |||
frappe.destroy() | |||
@click.command('write-docs') | |||
@pass_context | |||
@click.argument('app') | |||
@click.argument('target') | |||
@click.option('--local', default=False, is_flag=True, help='Run app locally') | |||
def write_docs(context, app, target, local=False): | |||
"Setup docs in target folder of target app" | |||
from frappe.utils.setup_docs import setup_docs | |||
for site in context.sites: | |||
try: | |||
frappe.init(site=site) | |||
frappe.connect() | |||
make = setup_docs(app) | |||
make.make_docs(target, local) | |||
finally: | |||
frappe.destroy() | |||
@click.command('build-docs') | |||
@pass_context | |||
@click.argument('app') | |||
@@ -93,7 +44,6 @@ def _build_docs_once(site, app, docs_version, target, local, only_content_update | |||
if not only_content_updated: | |||
make.build(docs_version) | |||
make.sync_docs() | |||
make.make_docs(target, local) | |||
@@ -101,8 +51,5 @@ def _build_docs_once(site, app, docs_version, target, local, only_content_update | |||
frappe.destroy() | |||
commands = [ | |||
build_docs, | |||
make_docs, | |||
sync_docs, | |||
write_docs, | |||
build_docs | |||
] |
@@ -148,8 +148,8 @@ def update_comments_in_parent(reference_doctype, reference_name, _comments): | |||
else: | |||
if not frappe.flags.in_patch: | |||
reference_doc = frappe.get_doc(reference_doctype, reference_name) | |||
if getattr(reference_doc, "get_route", None): | |||
clear_cache(reference_doc.get_route()) | |||
if getattr(reference_doc, "route", None): | |||
clear_cache(reference_doc.route) | |||
def add_info_comment(**kwargs): | |||
kwargs.update({ | |||
@@ -11,10 +11,6 @@ from frappe.utils.user import get_enabled_system_users | |||
weekdays = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] | |||
class Event(Document): | |||
def get_route(self): | |||
"""for test-case""" | |||
return "/Event/" + self.name | |||
def validate(self): | |||
if self.starts_on and self.ends_on and self.starts_on > self.ends_on: | |||
frappe.msgprint(frappe._("Event end must be after start"), raise_exception=True) | |||
@@ -127,7 +127,7 @@ def dropbox_callback(oauth_token=None, not_approved=False): | |||
frappe.db.commit() | |||
frappe.response['type'] = 'page' | |||
frappe.response['page_name'] = 'message.html' | |||
frappe.response['route'] = 'message.html' | |||
def backup_to_dropbox(): | |||
if not frappe.db: | |||
@@ -131,3 +131,4 @@ frappe.patches.v7_0.update_send_after_in_bulk_email | |||
frappe.patches.v7_0.setup_list_settings | |||
execute:frappe.db.sql('''delete from `tabSingles` where doctype="Email Settings"''') # 2016-06-13 | |||
execute:frappe.db.sql("delete from `tabWeb Page` where ifnull(template_path, '')!=''") | |||
frappe.patches.v7_0.re_route |
@@ -0,0 +1,13 @@ | |||
import frappe | |||
def execute(): | |||
update_routes(['Blog Post', 'Blog Category', 'Web Page']) | |||
def update_routes(doctypes): | |||
"""Patch old routing system""" | |||
for d in doctypes: | |||
try: | |||
frappe.db.sql("""update `tab{0}` set route = concat(ifnull(parent_website_route, ""), | |||
if(ifnull(parent_website_route, "")="", "", "/"), page_name)""".format(d)) | |||
except Exception, e: | |||
if e.args[0]!=1054: raise e |
@@ -11,7 +11,7 @@ | |||
<p class="post-by text-muted"> | |||
<a href="/blog?by={{ blogger }}&by_name={{ full_name }}" class="no-decoration">By {{ blogger_info and blogger_info.full_name or full_name }}</a> | |||
<i class="blog-dot"></i> {{ frappe.format_date(published_on) }} | |||
<i class="blog-dot"></i> <a href="/{{ parent_website_route }}" class="no-decoration">{{ blog_category }}</a> | |||
<i class="blog-dot"></i> <a href="/{{ category.route }}" class="no-decoration">{{ blog_category }}</a> | |||
<i class="blog-dot"></i> {{ comment_text }} | |||
</p> | |||
</div> | |||
@@ -147,7 +147,7 @@ | |||
<div class="row"> | |||
<div class="col-sm-9"> | |||
<p class="text-muted"> | |||
<a class="btn btn-default btn-sm" href="{{ ('/' + doc.parent_website_route) if doc.parent_website_route else '' }}/{{ doc.page_name }}" target="_blank"> | |||
<a class="btn btn-default btn-sm" href="{{ doc.route }}" target="_blank"> | |||
{{ web_page_link_text }}</a> | |||
</p> | |||
</div> | |||
@@ -2,13 +2,13 @@ | |||
<div class="web-list-item blog-list-item"> | |||
<div class="row"> | |||
<div class="col-xs-12"> | |||
<h1 class="blog-header"><a href="/{{ post.page_name }}">{{ post.title }}</a></h1> | |||
<h1 class="blog-header"><a href="/{{ post.route }}">{{ post.title }}</a></h1> | |||
<p class="post-description">{{ post.intro }}</p> | |||
<p class="post-by text-muted small"> | |||
<a href="/blog?by={{ post.blogger }}&by_name={{ post.full_name }}" class="no-decoration">By {{ post.full_name }}</a> | |||
<i class="blog-dot"></i> {{ frappe.format_date(post.published_on) }} | |||
<a href="/blog?by={{ post.blogger }}&by_name={{ post.full_name }}" class="no-decoration">By {{ post.full_name }}</a> | |||
<i class="blog-dot"></i> {{ frappe.format_date(post.published_on) }} | |||
<i class="blog-dot"></i> | |||
<a href="/{{ post.parent_website_route }}" class="no-decoration">{{ post.blog_category }}</a> | |||
<a href="/{{ post.blog_category_route }}" class="no-decoration">{{ post.blog_category }}</a> | |||
<i class="blog-dot"></i> {{ post.comment_text }} | |||
</p> | |||
</div> | |||
@@ -3,7 +3,7 @@ | |||
<li> | |||
<span class="icon icon-angle-left"></span> | |||
<a href="{{ url_prefix }}{{ parents[-1].name | abs_url }}"> | |||
{{ parents[-1].page_title or parents[-1].title or "" }}</a> | |||
{{ parents[-1].page_title or parents[-1].title or parents[-1].label or "" }}</a> | |||
</li> | |||
{# | |||
<!-- {% for parent in parents %} | |||
@@ -20,7 +20,7 @@ | |||
</div> | |||
<div class="comment-form-wrapper"> | |||
<a class="add-comment btn btn-default btn-sm">{{ _("Add Comment") }}</a> | |||
<a class="add-comment btn btn-default btn-sm">{{ _("Add Comment") }}</a> | |||
<div style="display: none;" id="comment-form"> | |||
<p>{{ _("Leave a Comment") }}</p> | |||
<div class="alert" style="display:none;"></div> | |||
@@ -62,8 +62,8 @@ | |||
$(".add-comment").toggle(false) | |||
.parent().append("<div class='text-muted'>Comments are closed.</div>") | |||
} | |||
$(".add-comment").click(function() { | |||
$(this).toggle(false); | |||
$(".add-comment").click(function() { | |||
$(this).toggle(false); | |||
$("#comment-form").toggle(); | |||
var full_name = "", user_id = ""; | |||
if(frappe.is_user_logged_in()) { | |||
@@ -85,7 +85,7 @@ | |||
reference_doctype: "{{ reference_doctype or doctype }}", | |||
reference_name: "{{ reference_name or name }}", | |||
comment_type: "Comment", | |||
page_name: "{{ pathname }}", | |||
route: "{{ pathname }}", | |||
} | |||
if(!args.comment_by_fullname || !args.comment_by || !args.comment) { | |||
@@ -17,14 +17,14 @@ def add_comment(args=None): | |||
'comment_by_fullname': '', | |||
'reference_doctype': '', | |||
'reference_name': '', | |||
'page_name': '', | |||
'route': '', | |||
} | |||
""" | |||
if not args: | |||
args = frappe.local.form_dict | |||
page_name = args.get("page_name") | |||
route = args.get("route") | |||
doc = frappe.get_doc(args["reference_doctype"], args["reference_name"]) | |||
comment = doc.add_comment("Comment", args["comment"], comment_by=args["comment_by"]) | |||
@@ -33,7 +33,7 @@ def add_comment(args=None): | |||
comment.save() | |||
# since comments are embedded in the page, clear the web cache | |||
clear_cache(page_name) | |||
clear_cache(route) | |||
# notify commentors | |||
commentors = [d[0] for d in frappe.db.sql("""select sender from `tabCommunication` | |||
@@ -47,7 +47,7 @@ def add_comment(args=None): | |||
message = _("{0} by {1}").format(frappe.utils.markdown(args.get("comment")), comment.sender_full_name) | |||
message += "<p><a href='{0}/{1}' style='font-size: 80%'>{2}</a></p>".format(frappe.utils.get_request_site_address(), | |||
page_name, _("View it in your browser")) | |||
route, _("View it in your browser")) | |||
from frappe.email.queue import send | |||
@@ -1,9 +1,11 @@ | |||
{% macro make_item_list(item_list) %} | |||
{% macro make_item_list(route, children_map) %} | |||
<ol> | |||
{% for item in item_list %} | |||
{% for item in children_map[route] %} | |||
<li> | |||
<a href="{{ url_prefix }}{{ item.url }}">{{ item.title }}</a> | |||
{% if item.children %}{{ make_item_list(item.children) }}{% endif %} | |||
<a href="{{ url_prefix }}{{ item.route }}.html">{{ item.title }}</a> | |||
{% if children_map[item.route] %} | |||
{{ make_item_list(item.route, children_map) }} | |||
{% endif %} | |||
</li> | |||
{% endfor %} | |||
</ol> | |||
@@ -4,7 +4,7 @@ | |||
<ol> | |||
{% for item in items %} | |||
<li> | |||
<a href="{% if relative_links %}{{ item.page_name }}{% else %}/{{ item.name }}{% endif %}{{ item.extn or '' }}">{{ item.title }}</a> | |||
<a href="{% if relative_links %}{{ item.route }}{% else %}/{{ item.route }}{% endif %}{{ item.extn or '' }}">{{ item.title }}</a> | |||
</li> | |||
{% endfor %} | |||
</ol> | |||
@@ -2,7 +2,7 @@ | |||
{% block hero %}{% endblock %} | |||
{% block content %} | |||
<div class="page-container" id="page-{{ name or page_name }}" data-path="{{ pathname }}" | |||
<div class="page-container" id="page-{{ name or route }}" data-path="{{ pathname }}" | |||
{% if page_or_generator=="Generator" %}data-doctype="{{ doctype }}"{% endif %}> | |||
<div class="row {% if show_sidebar %}vert-line{% endif %}"> | |||
{% if show_sidebar %} | |||
@@ -107,7 +107,7 @@ def json_handler(obj): | |||
def as_page(): | |||
"""print web page""" | |||
return render(frappe.response['page_name'], http_status_code=frappe.response.get("http_status_code")) | |||
return render(frappe.response['route'], http_status_code=frappe.response.get("http_status_code")) | |||
def redirect(): | |||
return werkzeug.utils.redirect(frappe.response.location) | |||
@@ -153,15 +153,6 @@ class setup_docs(object): | |||
self.update_index_txt(self.docs_path) | |||
def sync_docs(self): | |||
"""Sync docs from /docs folder to **Web Page**. | |||
Called as `bench --site [sitename] sync-docs [appname]` | |||
""" | |||
frappe.db.sql("delete from `tabWeb Page`") | |||
sync = frappe.website.statics.sync() | |||
sync.start(path="docs", rebuild=True, apps = [self.app]) | |||
def make_docs(self, target, local = False): | |||
self.target = target | |||
self.local = local | |||
@@ -0,0 +1,8 @@ | |||
// Copyright (c) 2016, Frappe Technologies and contributors | |||
// For license information, please see license.txt | |||
frappe.ui.form.on('Blog Category', { | |||
refresh: function(frm) { | |||
} | |||
}); |
@@ -3,6 +3,7 @@ | |||
"allow_import": 1, | |||
"allow_rename": 0, | |||
"autoname": "field:category_name", | |||
"beta": 0, | |||
"creation": "2013-03-08 09:41:11", | |||
"custom": 0, | |||
"docstatus": 0, | |||
@@ -17,6 +18,7 @@ | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 1, | |||
"label": "Category Name", | |||
@@ -24,6 +26,7 @@ | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 1, | |||
@@ -39,6 +42,7 @@ | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 1, | |||
"label": "Title", | |||
@@ -46,6 +50,7 @@ | |||
"no_copy": 1, | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 1, | |||
@@ -61,6 +66,7 @@ | |||
"fieldtype": "Check", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 1, | |||
"label": "Published", | |||
@@ -68,6 +74,7 @@ | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
@@ -79,60 +86,41 @@ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"default": "blog", | |||
"fieldname": "parent_website_route", | |||
"fieldtype": "Read Only", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"in_filter": 0, | |||
"in_list_view": 1, | |||
"label": "Parent Website Route", | |||
"length": 0, | |||
"no_copy": 0, | |||
"options": "", | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 1, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"fieldname": "page_name", | |||
"depends_on": "published", | |||
"fieldname": "route", | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 1, | |||
"label": "Page Name", | |||
"in_list_view": 0, | |||
"label": "Route", | |||
"length": 0, | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"precision": "", | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
"unique": 1 | |||
} | |||
], | |||
"hide_heading": 0, | |||
"hide_toolbar": 0, | |||
"icon": "icon-tag", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 0, | |||
"modified": "2015-11-16 06:29:42.454218", | |||
"modified": "2016-06-23 14:45:10.682909", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Blog Category", | |||
@@ -179,6 +167,9 @@ | |||
"write": 0 | |||
} | |||
], | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0 | |||
"read_only_onload": 0, | |||
"sort_order": "DESC", | |||
"track_seen": 0 | |||
} |
@@ -2,7 +2,6 @@ | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe.website.website_generator import WebsiteGenerator | |||
from frappe.website.render import clear_cache | |||
@@ -16,5 +15,6 @@ class BlogCategory(WebsiteGenerator): | |||
clear_cache() | |||
def validate(self): | |||
self.parent_website_route = "blog" | |||
if not self.route: | |||
self.route = 'blog/' + self.scrub(self.name) | |||
super(BlogCategory, self).validate() |
@@ -2,10 +2,12 @@ | |||
"allow_copy": 0, | |||
"allow_import": 1, | |||
"allow_rename": 0, | |||
"beta": 0, | |||
"creation": "2013-03-28 10:35:30", | |||
"custom": 0, | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
"document_type": "Setup", | |||
"fields": [ | |||
{ | |||
"allow_on_submit": 0, | |||
@@ -156,26 +158,26 @@ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"fieldname": "parent_website_route", | |||
"fieldtype": "Read Only", | |||
"hidden": 1, | |||
"fieldname": "route", | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Parent Website Route", | |||
"label": "Route", | |||
"length": 0, | |||
"no_copy": 0, | |||
"options": "", | |||
"permlevel": 0, | |||
"precision": "", | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 1, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
"unique": 1 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
@@ -249,30 +251,6 @@ | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"fieldname": "page_name", | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Page Name", | |||
"length": 0, | |||
"no_copy": 1, | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
@@ -302,13 +280,14 @@ | |||
"hide_toolbar": 0, | |||
"icon": "icon-quote-left", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 5, | |||
"modified": "2016-02-22 09:16:25.270128", | |||
"modified": "2016-06-23 14:44:59.883545", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Blog Post", | |||
@@ -355,8 +334,10 @@ | |||
"write": 1 | |||
} | |||
], | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"sort_order": "ASC", | |||
"title_field": "title" | |||
"title_field": "title", | |||
"track_seen": 0 | |||
} |
@@ -16,7 +16,6 @@ class BlogPost(WebsiteGenerator): | |||
condition_field = "published", | |||
template = "templates/generators/blog_post.html", | |||
order_by = "published_on desc", | |||
parent_website_route_field = "blog_category", | |||
page_title_field = "title" | |||
) | |||
@@ -80,10 +79,8 @@ class BlogPost(WebsiteGenerator): | |||
else: | |||
context.comment_text = _('{0} comments').format(len(context.comment_list)) | |||
context.children = get_children() | |||
category = frappe.db.get_value("Blog Category", context.doc.blog_category, ["title", "page_name"], as_dict=1) | |||
context.parents = [{"title": category.title, "name": "blog/{0}".format(category.page_name)}] | |||
context.category = frappe.db.get_value("Blog Category", context.doc.blog_category, ["title", "route"], as_dict=1) | |||
context.parents = [{"title": context.category.title, "name": context.category.route}] | |||
def get_list_context(context=None): | |||
list_context = frappe._dict( | |||
@@ -109,7 +106,7 @@ def get_list_context(context=None): | |||
return list_context | |||
def get_children(): | |||
return frappe.db.sql("""select concat("blog/", page_name) as name, | |||
return frappe.db.sql("""select route as name, | |||
title from `tabBlog Category` | |||
where published = 1 | |||
and exists (select name from `tabBlog Post` | |||
@@ -117,14 +114,14 @@ def get_children(): | |||
order by title asc""", as_dict=1) | |||
def clear_blog_cache(): | |||
for blog in frappe.db.sql_list("""select page_name from | |||
for blog in frappe.db.sql_list("""select route from | |||
`tabBlog Post` where ifnull(published,0)=1"""): | |||
clear_cache(blog) | |||
clear_cache("writers") | |||
def get_blog_category(page_name): | |||
return frappe.db.get_value("Blog Category", {"page_name": page_name }) or page_name | |||
def get_blog_category(route): | |||
return frappe.db.get_value("Blog Category", {"route": route }) or route | |||
def get_blog_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20): | |||
conditions = [] | |||
@@ -142,8 +139,7 @@ def get_blog_list(doctype, txt=None, filters=None, limit_start=0, limit_page_len | |||
query = """\ | |||
select | |||
t1.title, t1.name, t1.blog_category, t1.parent_website_route, t1.published_on, | |||
concat(t1.parent_website_route, "/", t1.page_name) as page_name, | |||
t1.title, t1.name, t1.blog_category, t1.route, t1.published_on, | |||
t1.published_on as creation, | |||
t1.content as content, | |||
ifnull(t1.blog_intro, t1.content) as intro, | |||
@@ -177,6 +173,7 @@ def get_blog_list(doctype, txt=None, filters=None, limit_start=0, limit_page_len | |||
post.comment_text = _('{0} comments').format(str(post.comments)) | |||
post.avatar = post.avatar or "" | |||
post.blog_category_route = frappe.db.get_value('Blog Post', post.blog_category, 'route') | |||
if (not "http:" in post.avatar or "https:" in post.avatar) and not post.avatar.startswith("/"): | |||
post.avatar = "/" + post.avatar | |||
@@ -3,6 +3,7 @@ | |||
"allow_import": 0, | |||
"allow_rename": 0, | |||
"autoname": "", | |||
"beta": 0, | |||
"creation": "2014-09-01 14:08:48.624556", | |||
"custom": 0, | |||
"docstatus": 0, | |||
@@ -37,26 +38,26 @@ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"description": "Website URL", | |||
"fieldname": "page_name", | |||
"fieldname": "route", | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Page Name", | |||
"label": "Route", | |||
"length": 0, | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"precision": "", | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 1, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
"unique": 1 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
@@ -509,13 +510,14 @@ | |||
"hide_toolbar": 0, | |||
"icon": "icon-edit", | |||
"idx": 0, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 0, | |||
"modified": "2016-03-30 01:11:55.221086", | |||
"modified": "2016-06-23 14:44:17.799560", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Web Form", | |||
@@ -543,6 +545,7 @@ | |||
"write": 1 | |||
} | |||
], | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"sort_field": "modified", | |||
@@ -100,7 +100,7 @@ class WebForm(WebsiteGenerator): | |||
if frappe.form_dict.name or frappe.form_dict.new: | |||
context.layout = self.get_layout() | |||
context.parents = [{"name": self.get_route(), "title": self.title }] | |||
context.parents = [{"name": self.route, "title": self.title }] | |||
if frappe.form_dict.name: | |||
context.doc = frappe.get_doc(self.doc_type, frappe.form_dict.name) | |||
@@ -1,35 +1,35 @@ | |||
[ | |||
{ | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 1", | |||
"published": 1, | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 1", | |||
"published": 1, | |||
"title": "Test Web Page 1" | |||
}, | |||
}, | |||
{ | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 2", | |||
"parent_website_route": "test-web-page-1", | |||
"published": 1, | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 2", | |||
"route": "test-web-page-1/test-web-page-2", | |||
"published": 1, | |||
"title": "Test Web Page 2" | |||
}, | |||
}, | |||
{ | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 3", | |||
"parent_website_route": "test-web-page-1", | |||
"published": 1, | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 3", | |||
"route": "test-web-page-1/test-web-page-3", | |||
"published": 1, | |||
"title": "Test Web Page 3" | |||
}, | |||
}, | |||
{ | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 4", | |||
"published": 1, | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 4", | |||
"published": 1, | |||
"title": "Test Web Page 4" | |||
}, | |||
}, | |||
{ | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 5", | |||
"parent_website_route": "test-web-page-1", | |||
"published": 1, | |||
"doctype": "Web Page", | |||
"main_section": "Test Content 5", | |||
"route": "test-web-page-1/test-web-page-5", | |||
"published": 1, | |||
"title": "Test Web Page 5" | |||
} | |||
] |
@@ -14,16 +14,4 @@ class TestWebPage(unittest.TestCase): | |||
def test_check_sitemap(self): | |||
resolve_route("test-web-page-1") | |||
resolve_route("test-web-page-1/test-web-page-2") | |||
resolve_route("test-web-page-1/test-web-page-3") | |||
def test_check_rename(self): | |||
web_page = frappe.get_doc("Web Page", "test-web-page-1") | |||
web_page.parent_website_route = "test-web-page-4" | |||
web_page.save() | |||
resolve_route("test-web-page-4/test-web-page-1/test-web-page-2") | |||
web_page.parent_website_route = "" | |||
web_page.save() | |||
resolve_route("test-web-page-1/test-web-page-2") | |||
resolve_route("test-web-page-1/test-web-page-3") |
@@ -2,6 +2,7 @@ | |||
"allow_copy": 0, | |||
"allow_import": 0, | |||
"allow_rename": 0, | |||
"beta": 0, | |||
"creation": "2013-03-28 10:35:30", | |||
"custom": 0, | |||
"description": "Page to show on the website\n", | |||
@@ -138,18 +139,18 @@ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"description": "Page url name (auto-generated)", | |||
"fieldname": "page_name", | |||
"fieldname": "route", | |||
"fieldtype": "Data", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Page Name", | |||
"label": "Route", | |||
"length": 0, | |||
"no_copy": 1, | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"precision": "", | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
@@ -503,56 +504,6 @@ | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"fieldname": "parent_web_page", | |||
"fieldtype": "Link", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Parent Web Page", | |||
"length": 0, | |||
"no_copy": 0, | |||
"options": "Web Page", | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"fieldname": "parent_website_route", | |||
"fieldtype": "Read Only", | |||
"hidden": 1, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Parent Website Route", | |||
"length": 0, | |||
"no_copy": 1, | |||
"options": "", | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 0, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
@@ -578,30 +529,6 @@ | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
"collapsible": 0, | |||
"fieldname": "template_path", | |||
"fieldtype": "Small Text", | |||
"hidden": 0, | |||
"ignore_user_permissions": 0, | |||
"ignore_xss_filter": 0, | |||
"in_filter": 0, | |||
"in_list_view": 0, | |||
"label": "Template Path", | |||
"length": 0, | |||
"no_copy": 0, | |||
"permlevel": 0, | |||
"print_hide": 0, | |||
"print_hide_if_no_value": 0, | |||
"read_only": 1, | |||
"report_hide": 0, | |||
"reqd": 0, | |||
"search_index": 0, | |||
"set_only_once": 0, | |||
"unique": 0 | |||
}, | |||
{ | |||
"allow_on_submit": 0, | |||
"bold": 0, | |||
@@ -683,13 +610,14 @@ | |||
"hide_toolbar": 0, | |||
"icon": "icon-file-alt", | |||
"idx": 1, | |||
"image_view": 0, | |||
"in_create": 0, | |||
"in_dialog": 0, | |||
"is_submittable": 0, | |||
"issingle": 0, | |||
"istable": 0, | |||
"max_attachments": 20, | |||
"modified": "2016-02-22 08:00:02.354788", | |||
"modified": "2016-06-23 12:29:31.442059", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Web Page", | |||
@@ -716,9 +644,11 @@ | |||
"write": 1 | |||
} | |||
], | |||
"quick_entry": 0, | |||
"read_only": 0, | |||
"read_only_onload": 0, | |||
"search_fields": "title", | |||
"sort_order": "ASC", | |||
"title_field": "title" | |||
"title_field": "title", | |||
"track_seen": 0 | |||
} |
@@ -8,10 +8,9 @@ from frappe.utils import strip_html | |||
from frappe.website.website_generator import WebsiteGenerator | |||
from frappe.website.router import resolve_route | |||
from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow | |||
from frappe.website.utils import find_first_image, get_comment_list, get_full_index | |||
from frappe.website.utils import find_first_image, get_comment_list | |||
from frappe.utils.jinja import render_template | |||
from jinja2.exceptions import TemplateSyntaxError | |||
from frappe import _ | |||
class WebPage(WebsiteGenerator): | |||
save_versions = True | |||
@@ -19,20 +18,11 @@ class WebPage(WebsiteGenerator): | |||
template = "templates/generators/web_page.html", | |||
condition_field = "published", | |||
page_title_field = "title", | |||
parent_website_route_field = "parent_web_page" | |||
) | |||
def get_feed(self): | |||
return self.title | |||
def validate(self): | |||
# avoid recursive parent_web_page. | |||
if self.parent_web_page == self.page_name: | |||
self.parent_web_page = "" | |||
self.parent_website_route = "" | |||
super(WebPage, self).validate() | |||
def get_context(self, context): | |||
# if static page, get static content | |||
if context.slideshow: | |||
@@ -41,10 +31,6 @@ class WebPage(WebsiteGenerator): | |||
if self.enable_comments: | |||
context.comment_list = get_comment_list(self.doctype, self.name) | |||
# for sidebar and breadcrumbs | |||
context.children = self.get_children() | |||
context.parents = self.get_parents(context) | |||
context.update({ | |||
"style": self.css or "", | |||
"script": self.javascript or "", | |||
@@ -62,7 +48,6 @@ class WebPage(WebsiteGenerator): | |||
self.set_metatags(context) | |||
self.set_breadcrumbs(context) | |||
self.set_title_and_header(context) | |||
self.add_index(context) | |||
return context | |||
@@ -114,48 +99,6 @@ class WebPage(WebsiteGenerator): | |||
if not context.title and context.header: | |||
context.title = strip_html(context.header) | |||
def add_index(self, context): | |||
"""Add index, next button if `{index}`, `{next}` is present.""" | |||
# table of contents | |||
extn = "" | |||
if context.page_links_with_extn: | |||
extn = ".html" | |||
if "{index}" in context.main_section and context.get("children") and len(context.children): | |||
full_index = get_full_index(context.pathname, extn = extn) | |||
if full_index: | |||
html = frappe.get_template("templates/includes/full_index.html").render({ | |||
"full_index": full_index, | |||
"url_prefix": context.url_prefix | |||
}) | |||
context.main_section = context.main_section.replace("{index}", html) | |||
# next and previous | |||
if "{next}" in context.main_section: | |||
next_item = self.get_next() | |||
next_item.extn = "" if self.has_children(next_item.name) else extn | |||
if next_item and next_item.page_name: | |||
if context.relative_links: | |||
if next_item.next_parent: | |||
next_item.name = "../" + next_item.page_name or "" | |||
else: | |||
next_item.name = next_item.page_name or "" | |||
else: | |||
if next_item and next_item.name and next_item.name[0]!="/": | |||
next_item.name = "/" + next_item.name | |||
if not next_item.title: | |||
next_item.title = "" | |||
html = ('<p class="btn-next-wrapper">'+_("Next")\ | |||
+': <a class="btn-next" href="{name}{extn}">{title}</a></p>').format(**next_item) | |||
else: | |||
html = "" | |||
context.main_section = context.main_section.replace("{next}", html) | |||
def add_hero(self, context): | |||
"""Add a hero element if specified in content or hooks. | |||
Hero elements get full page width.""" | |||
@@ -6,6 +6,7 @@ import frappe, os | |||
from frappe.website.utils import can_cache, delete_page_cache | |||
from frappe.model.document import get_controller | |||
from frappe import _ | |||
def get_page_context(path): | |||
page_context = None | |||
@@ -87,24 +88,17 @@ def get_page_info_from_doctypes(path=None): | |||
for doctype in frappe.get_hooks("website_generators", app_name = app): | |||
condition = "" | |||
values = [] | |||
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 {0}=1".format(controller.website.condition_field) | |||
if path: | |||
condition += ' {0} {1}=%s limit 1'.format(('and' if 'where' in condition else 'where'), | |||
route_column_name) | |||
condition += ' {0} `route`=%s limit 1'.format('and' if 'where' in condition else 'where') | |||
values.append(path) | |||
for r in frappe.db.sql("""select {0} as route, name, modified from `tab{1}` | |||
{2}""".format(route_column_name, doctype, condition), values=values, as_dict=True): | |||
for r in frappe.db.sql("""select route, name, modified from `tab{0}` | |||
{1}""".format(doctype, condition), values=values, as_dict=True): | |||
routes[r.route] = {"doctype": doctype, "name": r.name, "modified": r.modified} | |||
# just want one path, return it! | |||
@@ -115,18 +109,20 @@ def get_page_info_from_doctypes(path=None): | |||
def get_pages(): | |||
'''Get all pages. Called for docs / sitemap''' | |||
pages = [] | |||
pages = {} | |||
frappe.local.flags.in_get_all_pages = True | |||
for app in frappe.get_installed_apps(): | |||
app_path = frappe.get_app_path(app) | |||
for start in ('templates/pages', 'www'): | |||
path = os.path.join(app_path, start) | |||
pages += get_pages_from_path(path, app, app_path) | |||
pages.update(get_pages_from_path(path, app, app_path)) | |||
frappe.local.flags.in_get_all_pages = False | |||
return pages | |||
def get_pages_from_path(path, app, app_path): | |||
pages = [] | |||
pages = {} | |||
if os.path.exists(path): | |||
for basepath, folders, files in os.walk(path): | |||
# add missing __init__.py | |||
@@ -141,7 +137,8 @@ def get_pages_from_path(path, app, app_path): | |||
continue | |||
if extn in ("html", "xml", "js", "css", "md"): | |||
pages.append(get_page_info(path, app, basepath, app_path, fname)) | |||
page_info = get_page_info(path, app, basepath, app_path, fname) | |||
pages[page_info.route] = page_info | |||
# print frappe.as_json(pages[-1]) | |||
return pages | |||
@@ -163,6 +160,7 @@ def get_page_info(path, app, basepath=None, app_path=None, fname=None): | |||
page_info = frappe._dict() | |||
page_info.basename = page_name if extn in ('html', 'md') else fname | |||
page_info.basepath = basepath | |||
page_info.page_or_generator = "Page" | |||
page_info.template = os.path.relpath(os.path.join(basepath, fname), app_path) | |||
@@ -170,8 +168,8 @@ def get_page_info(path, app, basepath=None, app_path=None, fname=None): | |||
if page_info.basename == 'index': | |||
page_info.basename = os.path.dirname(path).strip('.').strip('/') | |||
page_info.name = page_info.page_name = os.path.join(os.path.relpath(basepath, path), | |||
page_info.basename).strip('.').strip('/') | |||
page_info.route = page_info.name = page_info.page_name = os.path.join(os.path.relpath(basepath, path), | |||
page_info.basename).strip('/.') | |||
# controller | |||
page_info.controller_path = os.path.join(basepath, page_name.replace("-", "_") + ".py") | |||
@@ -182,7 +180,7 @@ def get_page_info(path, app, basepath=None, app_path=None, fname=None): | |||
page_info.controller = controller | |||
# get the source | |||
page_info.source = get_source(page_info, basepath) | |||
page_info.source = get_source(page_info) | |||
if page_info.only_content: | |||
# extract properties from HTML comments | |||
@@ -191,8 +189,7 @@ def get_page_info(path, app, basepath=None, app_path=None, fname=None): | |||
return page_info | |||
def get_source(page_info, basepath): | |||
def get_source(page_info): | |||
'''Get the HTML source of the template''' | |||
from markdown2 import markdown | |||
jenv = frappe.get_jenv() | |||
@@ -208,11 +205,11 @@ def get_source(page_info, basepath): | |||
page_info.only_content = True | |||
js, css = '', '' | |||
js_path = os.path.join(basepath, page_info.basename + '.js') | |||
js_path = os.path.join(page_info.basepath, page_info.basename + '.js') | |||
if os.path.exists(js_path): | |||
js = unicode(open(js_path, 'r').read(), 'utf-8') | |||
css_path = os.path.join(basepath, page_info.basename + '.css') | |||
css_path = os.path.join(page_info.basepath, page_info.basename + '.css') | |||
if os.path.exists(css_path): | |||
js = unicode(open(css_path, 'r').read(), 'utf-8') | |||
@@ -228,8 +225,48 @@ def get_source(page_info, basepath): | |||
else: | |||
html = source | |||
# show table of contents | |||
setup_index(page_info) | |||
return html | |||
def setup_index(page_info): | |||
'''Insert full index (table of contents) for {index} tag''' | |||
from frappe.website.utils import get_full_index | |||
if page_info.basename=='index': | |||
if frappe.local.flags.in_get_all_pages: | |||
# load index.txt if loading all pages | |||
index_txt_path = os.path.join(page_info.basepath, 'index.txt') | |||
if os.path.exists(index_txt_path): | |||
page_info.index = open(index_txt_path, 'r').read().splitlines() | |||
elif '\n{index}' in page_info.source: | |||
html = frappe.get_template("templates/includes/full_index.html").render({ | |||
"full_index": get_full_index(), | |||
"url_prefix": None | |||
}) | |||
page_info.source.replace('{index}', html) | |||
if (not frappe.local.flags.in_get_all_pages) and ('\n{next}' in page_info.source): | |||
# insert next link | |||
next_item = None | |||
children_map = get_full_index() | |||
parent_route = os.path.dirname(page_info.route) | |||
children = children_map[parent_route] | |||
if parent_route and children: | |||
for i, c in enumerate(children): | |||
if c.route == page_info.route and i < (len(children) - 1): | |||
next_item = children[i+1] | |||
if next_item: | |||
html = ('<p class="btn-next-wrapper">'+_("Next")\ | |||
+': <a class="btn-next" href="{route}.html">{title}</a></p>').format(**next_item) | |||
page_info.source.replace('{next}', html) | |||
def load_properties(page_info): | |||
'''Load properties like no_cache, title from raw''' | |||
import re | |||
@@ -182,28 +182,35 @@ def abs_url(path): | |||
path = "/" + path | |||
return path | |||
def get_full_index(route=None, doctype="Web Page", extn = False): | |||
"""Returns full index of the website (on Web Page) upto the n-th level""" | |||
all_routes = [] | |||
def get_children(parent): | |||
children = frappe.db.get_all(doctype, ["parent_website_route", "page_name", "title", "template_path"], | |||
{"parent_website_route": parent}, order_by="idx asc") | |||
for d in children: | |||
d.url = abs_url(os.path.join(d.parent_website_route or "", d.page_name)) | |||
if d.url not in all_routes: | |||
d.children = get_children(d.url.lstrip("/")) | |||
all_routes.append(d.url) | |||
if extn and os.path.basename(d.template_path).split(".")[0] != "index": | |||
d.url = d.url + ".html" | |||
# no index.html for home page | |||
# home should not be in table of contents | |||
if not parent: | |||
children = [d for d in children if d.page_name not in ("index.html", "index", | |||
"", "contents")] | |||
return children | |||
return get_children(route or "") | |||
def get_full_index(route=None, extn = False): | |||
"""Returns full index of the website for www upto the n-th level""" | |||
if not frappe.local.flags.children_map: | |||
from frappe.websites.router import get_pages | |||
children_map = {} | |||
pages = get_pages() | |||
# make children map | |||
for route, page_info in pages.iteritems(): | |||
parent_route = os.path.dirname(route) | |||
children_map.setdefault(parent_route, []).append(page_info) | |||
# order as per index if present | |||
for route, children in children_map.items(): | |||
page_info = pages[route] | |||
if page_info.index: | |||
new_children = [] | |||
for name in page_info.index: | |||
child_route = page_info.route + '/' + name | |||
if pages[child_route]: | |||
new_children.append(pages[child_route]) | |||
# add remaining pages not in index.txt | |||
for c in children: | |||
if c not in new_children: | |||
new_children.append(c) | |||
children_map[route] = new_children | |||
frappe.local.flags.children_map = children_map | |||
return frappe.local.flags.children_map |
@@ -3,7 +3,7 @@ | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe.utils import now | |||
from frappe.utils import quoted | |||
from frappe.model.document import Document | |||
from frappe.model.naming import append_number_if_name_exists | |||
from frappe.website.utils import cleanup_page_name, get_home_page | |||
@@ -18,63 +18,37 @@ class WebsiteGenerator(Document): | |||
def autoname(self): | |||
if self.meta.autoname != "hash": | |||
self.name = self.get_page_name() | |||
append_number_if_name_exists(self) | |||
self.name = self.make_route() | |||
def onload(self): | |||
self.get("__onload").update({ | |||
"is_website_generator": True, | |||
"website_route": self.get_route(), | |||
"published": self.website_published() | |||
}) | |||
def validate(self): | |||
self.set_parent_website_route() | |||
if not self.route: | |||
self.route = self.make_route() | |||
if not self.page_name: | |||
self.page_name = self.make_page_name() | |||
self.route = self.route.strip('/.') | |||
if self.meta.get_field("page_name") and not self.get("__islocal"): | |||
current_route = self.get_route() | |||
current_page_name = self.page_name | |||
# page name changed, rename everything | |||
if current_page_name and current_page_name != self.page_name: | |||
self.update_routes_of_descendants(current_route) | |||
def make_route(self): | |||
return self.scrub(self.get(self.website.page_title_field or "name")) | |||
def on_update(self): | |||
clear_cache(self.get_route()) | |||
clear_cache(self.route) | |||
if getattr(self, "save_versions", False): | |||
frappe.add_version(self) | |||
def get_route(self, doc = None): | |||
self.get_page_name() | |||
return make_route(self) | |||
def clear_cache(self): | |||
clear_cache(self.get_route()) | |||
def get_page_name(self): | |||
return self.get_or_make_page_name() | |||
def get_or_make_page_name(self): | |||
page_name = self.get("page_name") | |||
if not page_name: | |||
page_name = self.make_page_name() | |||
self.set("page_name", page_name) | |||
clear_cache(self.route) | |||
return page_name | |||
def make_page_name(self): | |||
return cleanup_page_name(self.get(self.website.page_title_field or "name")) | |||
def before_rename(self, oldname, name, merge): | |||
self._local = self.get_route() | |||
self.clear_cache() | |||
def scrub(self, text): | |||
return quoted(cleanup_page_name(text).replace('_', '-')) | |||
def after_rename(self, olddn, newdn, merge): | |||
if getattr(self, "_local"): | |||
self.update_routes_of_descendants(self._local) | |||
self.clear_cache() | |||
def get_parents(self, context): | |||
'''Return breadcrumbs''' | |||
pass | |||
def on_trash(self): | |||
self.clear_cache() | |||
@@ -85,38 +59,6 @@ class WebsiteGenerator(Document): | |||
else: | |||
return True | |||
def set_parent_website_route(self): | |||
parent_website_route_field = self.website.parent_website_route_field | |||
if parent_website_route_field: | |||
field = self.meta.get_field(parent_website_route_field) | |||
parent = self.get(parent_website_route_field) | |||
if parent: | |||
parent_doc = frappe.get_doc(field.options, parent) | |||
if parent_doc.website_published(): | |||
self.parent_website_route = parent_doc.get_route() | |||
else: | |||
self.parent_website_route = None | |||
def update_routes_of_descendants(self, old_route = None): | |||
if not self.is_new() and self.meta.get_field("parent_website_route"): | |||
if not old_route: | |||
old_route = frappe.get_doc(self.doctype, self.name).get_route() | |||
if old_route and old_route != self.get_route(): | |||
# clear cache of old routes | |||
old_routes = frappe.get_all(self.doctype, filters={"parent_website_route": ("like", old_route + "%")}) | |||
if old_routes: | |||
for like_old_route in old_routes: | |||
clear_cache(frappe.get_doc(self.doctype, like_old_route.name).get_route()) | |||
frappe.db.sql("""update `tab{0}` set | |||
parent_website_route = replace(parent_website_route, %s, %s), | |||
modified = %s, | |||
modified_by = %s | |||
where parent_website_route like %s""".format(self.doctype), | |||
(old_route, self.get_route(), now(), frappe.session.user, old_route + "%")) | |||
def get_page_info(self): | |||
route = frappe._dict() | |||
route.update({ | |||
@@ -125,7 +67,7 @@ class WebsiteGenerator(Document): | |||
"ref_doctype":self.doctype, | |||
"idx": self.idx, | |||
"docname": self.name, | |||
"page_name": self.get_page_name(), | |||
"route": route, | |||
"controller": get_module_name(self.doctype, self.meta.module), | |||
}) | |||
@@ -135,125 +77,3 @@ class WebsiteGenerator(Document): | |||
route.page_title = self.get(self.website.page_title_field or "name") | |||
return route | |||
def get_parents(self, context): | |||
# already set | |||
if context.parents: | |||
return context.parents | |||
home_page = get_home_page() | |||
parents = [] | |||
me = self | |||
while me: | |||
_parent_field = me.website.parent_website_route_field | |||
_parent_val = me.get(_parent_field) if _parent_field else None | |||
# if no parent and not home page, then parent is home page | |||
if not _parent_val and me.get_route() != home_page: | |||
# parents.append(frappe._dict(name=home_page, title=get_page_context(home_page).title)) | |||
break | |||
elif _parent_val: | |||
df = me.meta.get_field(_parent_field) | |||
if not df: | |||
break | |||
parent_doc = frappe.get_doc(df.options, _parent_val) | |||
if not parent_doc.website_published(): | |||
break | |||
if parent_doc: | |||
parent_info = frappe._dict(name = parent_doc.get_route(), | |||
title= parent_doc.get(parent_doc.website.page_title_field or "name")) | |||
else: | |||
parent_info = frappe._dict(name=self.parent_website_route, | |||
title=self.parent_website_route.replace("_", " ").title()) | |||
if parent_info.name in [p.name for p in parents]: | |||
raise frappe.ValidationError, "Recursion in parent link" | |||
parents.append(parent_info) | |||
me = parent_doc | |||
else: | |||
# parent route is a page e.g. "blog" | |||
if me.get("parent_website_route"): | |||
page_route = get_page_context_from_template(me.parent_website_route) | |||
if page_route: | |||
parents.append(frappe._dict(name = page_route.name, | |||
title=page_route.page_title)) | |||
me = None | |||
parents.reverse() | |||
return parents | |||
def get_parent(self): | |||
parent_website_route_field = self.website.parent_website_route_field | |||
if parent_website_route_field: | |||
return self.get(parent_website_route_field) | |||
def get_children(self, context=None): | |||
children = [] | |||
route = self.get_route() | |||
if route==get_home_page(): | |||
children = frappe.db.sql("""select url as name, label as page_title | |||
from `tabTop Bar Item` where parentfield='sidebar_items' | |||
order by idx""", as_dict=True) | |||
route = "" | |||
if not children and self.meta.get_field("parent_website_route"): | |||
children = self.get_children_of(route) | |||
if not children and self.parent_website_route: | |||
children = self.get_children_of(self.parent_website_route) | |||
return children | |||
def get_children_of(self, route): | |||
"""Return list of children of given route, for generating index in Web Page""" | |||
condition = 'parent_website_route = %s' | |||
if route=="index" or not route: | |||
condition = 'ifnull(parent_website_route, "") = %s and name != "index"' | |||
route = "" | |||
children = frappe.db.sql("""select name, page_name, | |||
parent_website_route, {title_field} as title from `tab{doctype}` | |||
where {condition} | |||
order by {order_by}""".format( | |||
doctype = self.doctype, | |||
title_field = self.website.page_title_field or "name", | |||
order_by = self.website.order_by or "idx asc", | |||
condition = condition | |||
), route, as_dict=True) | |||
for c in children: | |||
c.name = make_route(c) | |||
return children | |||
def has_children(self, route): | |||
return frappe.db.sql('''select name from `tab{0}` | |||
where parent_website_route = %s limit 1'''.format(self.doctype), route) | |||
def get_next(self): | |||
if self.meta.get_field("parent_website_route") and self.parent_website_route: | |||
route = self.get_route() | |||
parent = frappe.get_doc(self.doctype, self.get_parent()) | |||
siblings = parent.get_children() | |||
for i, r in enumerate(siblings): | |||
if i < len(siblings) - 1: | |||
if route==r.name: | |||
return siblings[i+1] | |||
out = parent.get_next() | |||
out.next_parent = True | |||
return out | |||
else: | |||
return frappe._dict() | |||
def make_route(doc): | |||
parent = doc.get("parent_website_route", "") | |||
return ((parent + "/") if parent else "") + doc.page_name | |||
@@ -26,7 +26,7 @@ def get(doctype, txt=None, limit_start=0, **kwargs): | |||
limit_start = cint(limit_start) | |||
limit_page_length = 20 | |||
next_start = limit_start + limit_page_length | |||
if not txt and frappe.form_dict.search: | |||
txt = frappe.form_dict.search | |||
del frappe.form_dict['search'] | |||
@@ -75,8 +75,8 @@ def set_route(context): | |||
'''Set link for the list item''' | |||
if context.is_web_form: | |||
context.route = "{0}?name={1}".format(context.pathname, quoted(context.doc.name)) | |||
elif context.doc and getattr(context.doc, 'get_route', None): | |||
context.route = context.doc.get_route() | |||
elif context.doc and getattr(context.doc, 'route', None): | |||
context.route = context.doc.route | |||
else: | |||
context.route = "{0}/{1}".format(context.pathname or quoted(context.doc.doctype), | |||
quoted(context.doc.name)) | |||
@@ -84,14 +84,14 @@ def set_route(context): | |||
def prepare_filters(doctype, kwargs): | |||
filters = frappe._dict(kwargs) | |||
meta = frappe.get_meta(doctype) | |||
if filters.pathname: | |||
# resolve additional filters from path | |||
resolve_path(filters.pathname) | |||
for key, val in frappe.local.form_dict.items(): | |||
if key not in filters: | |||
filters[key] = val | |||
# filter the filters to include valid fields only | |||
for fieldname, val in filters.items(): | |||
if not meta.has_field(fieldname): | |||
@@ -3,7 +3,7 @@ | |||
from __future__ import unicode_literals | |||
import frappe | |||
import os, urllib | |||
import urllib | |||
from frappe.utils import escape_html, get_request_site_address, now, cstr | |||
no_cache = 1 | |||
@@ -15,12 +15,12 @@ def get_context(context): | |||
host = get_request_site_address() | |||
blog_list = frappe.db.sql("""\ | |||
select page_name as name, published_on, modified, title, content from `tabBlog Post` | |||
select route as name, published_on, modified, title, content from `tabBlog Post` | |||
where ifnull(published,0)=1 | |||
order by published_on desc limit 20""", as_dict=1) | |||
for blog in blog_list: | |||
blog_page = cstr(urllib.quote(blog.name.encode("utf-8"))) + ".html" | |||
blog_page = cstr(urllib.quote(blog.route.encode("utf-8"))) | |||
blog.link = urllib.basejoin(host, blog_page) | |||
blog.content = escape_html(blog.content or "") | |||
@@ -16,7 +16,7 @@ def get_context(context): | |||
"""generate the sitemap XML""" | |||
host = get_request_site_address() | |||
links = [] | |||
for page in get_pages(): | |||
for route, page in get_pages().iteritems(): | |||
if not page.no_sitemap: | |||
links.append({ | |||
"loc": urllib.basejoin(host, urllib.quote(page.name.encode("utf-8"))), | |||