@@ -304,6 +304,19 @@ class Document: | |||||
# pick default naming series | # pick default naming series | ||||
self.naming_series = get_default_naming_series(self.doctype) | self.naming_series = get_default_naming_series(self.doctype) | ||||
def append_number_if_name_exists(self): | |||||
if frappe.db.exists(self.doctype, self.name): | |||||
last = frappe.db.sql("""select name from `tab{}` | |||||
where name regexp '{}-[[:digit:]]*' | |||||
order by name desc limit 1""".format(self.doctype, self.name)) | |||||
if last: | |||||
count = str(cint(last[0][0].rsplit("-", 1)[1]) + 1) | |||||
else: | |||||
count = "1" | |||||
self.name = "{0}-{1}".format(self.name, count) | |||||
def set(self, key, value): | def set(self, key, value): | ||||
self.modified = now() | self.modified = now() | ||||
self.modified_by = frappe.session["user"] | self.modified_by = frappe.session["user"] | ||||
@@ -252,7 +252,8 @@ fieldset { | |||||
} | } | ||||
.sidebar-item a.active { | .sidebar-item a.active { | ||||
border-bottom: 2px solid #999; | |||||
color: #000; | |||||
font-weight: bold; | |||||
} | } | ||||
html, | html, | ||||
@@ -409,6 +410,10 @@ a.active { | |||||
font-size: 85%; | font-size: 85%; | ||||
} | } | ||||
.breadcrumb a { | |||||
color: inherit; | |||||
} | |||||
@media (min-width: 768px) { | @media (min-width: 768px) { | ||||
.page-sidebar { | .page-sidebar { | ||||
padding-left: 3em; | padding-left: 3em; | ||||
@@ -10,19 +10,8 @@ from frappe.utils import cint | |||||
class DocType(WebsiteGenerator): | class DocType(WebsiteGenerator): | ||||
def autoname(self): | def autoname(self): | ||||
self.doc.name = cleanup_page_name(self.doc.title) | self.doc.name = cleanup_page_name(self.doc.title) | ||||
if frappe.db.exists("Web Page", self.doc.name): | |||||
last = frappe.db.sql("""select name from `tabWeb Page` | |||||
where name regexp '{name}-[[:digit:]]*' | |||||
order by name desc limit 1""".format(name=self.doc.name)) | |||||
self.doc.append_number_if_name_exists() | |||||
if last: | |||||
count = str(cint(last[0][0].rsplit("-", 1)[1]) + 1) | |||||
else: | |||||
count = "1" | |||||
self.doc.name = "{0}-{1}".format(self.doc.name, count) | |||||
def validate(self): | def validate(self): | ||||
for d in self.doclist.get({"parentfield": "toc"}): | for d in self.doclist.get({"parentfield": "toc"}): | ||||
if d.web_page == self.doc.name: | if d.web_page == self.doc.name: | ||||
@@ -31,7 +31,6 @@ class DocType(DocTypeNestedSet): | |||||
self.make_private_if_parent_is_private() | self.make_private_if_parent_is_private() | ||||
if not self.doc.is_new(): | if not self.doc.is_new(): | ||||
self.renumber_if_moved() | self.renumber_if_moved() | ||||
self.set_idx() | |||||
def renumber_if_moved(self): | def renumber_if_moved(self): | ||||
current_parent = frappe.db.get_value("Website Route", self.doc.name, "parent_website_route") | current_parent = frappe.db.get_value("Website Route", self.doc.name, "parent_website_route") | ||||
@@ -48,30 +47,38 @@ class DocType(DocTypeNestedSet): | |||||
(current_parent, self.doc.idx)) | (current_parent, self.doc.idx)) | ||||
self.doc.idx = None | self.doc.idx = None | ||||
def on_update(self): | |||||
self.set_idx() | |||||
if not frappe.flags.in_rebuild_config: | |||||
DocTypeNestedSet.on_update(self) | |||||
self.clear_cache() | |||||
def set_idx(self): | def set_idx(self): | ||||
if self.doc.parent_website_route: | if self.doc.parent_website_route: | ||||
if self.doc.idx == None: | if self.doc.idx == None: | ||||
self.doc.idx = int(frappe.db.sql("""select ifnull(max(ifnull(idx, -1)), -1) | |||||
from `tabWebsite Route` | |||||
where ifnull(parent_website_route, '')=%s and name!=%s""", | |||||
(self.doc.parent_website_route or '', | |||||
self.doc.name))[0][0]) + 1 | |||||
self.set_idx_as_last() | |||||
else: | else: | ||||
self.doc.idx = cint(self.doc.idx) | |||||
previous_idx = frappe.db.sql("""select max(idx) | |||||
from `tab{}` where ifnull(parent_website_route, '')=%s | |||||
and ifnull(idx, -1) < %s""".format(self.doc.ref_doctype), | |||||
(self.doc.parent_website_route, self.doc.idx))[0][0] | |||||
self.validate_previous_idx_exists() | |||||
def set_idx_as_last(self): | |||||
# new, append | |||||
self.doc.idx = int(frappe.db.sql("""select ifnull(max(ifnull(idx, -1)), -1) | |||||
from `tabWebsite Route` | |||||
where ifnull(parent_website_route, '')=%s and name!=%s""", | |||||
(self.doc.parent_website_route or '', | |||||
self.doc.name))[0][0]) + 1 | |||||
if previous_idx and previous_idx != self.doc.idx - 1: | |||||
frappe.throw("{}: {}, {}".format( | |||||
_("Sitemap Ordering Error. Index missing"), self.doc.name, self.doc.idx-1)) | |||||
def validate_previous_idx_exists(self): | |||||
self.doc.idx = cint(self.doc.idx) | |||||
previous_idx = frappe.db.sql("""select max(idx) | |||||
from `tab{}` where ifnull(parent_website_route, '')=%s | |||||
and ifnull(idx, -1) < %s""".format(self.doc.ref_doctype), | |||||
(self.doc.parent_website_route, self.doc.idx))[0][0] | |||||
if previous_idx and previous_idx != self.doc.idx - 1: | |||||
frappe.throw("{}: {}, {}".format( | |||||
_("Sitemap Ordering Error. Index missing"), self.doc.name, self.doc.idx-1)) | |||||
def on_update(self): | |||||
if not frappe.flags.in_rebuild_config: | |||||
DocTypeNestedSet.on_update(self) | |||||
def rename(self): | def rename(self): | ||||
from frappe.website.render import clear_cache | from frappe.website.render import clear_cache | ||||
self.old_name = self.doc.name | self.old_name = self.doc.name | ||||
@@ -127,8 +134,12 @@ class DocType(DocTypeNestedSet): | |||||
to_remove = frappe.db.sql_list("""select name from `tabWebsite Route Permission` | to_remove = frappe.db.sql_list("""select name from `tabWebsite Route Permission` | ||||
where website_route=%s""", (self.doc.name,)) | where website_route=%s""", (self.doc.name,)) | ||||
frappe.delete_doc("Website Route Permission", to_remove, ignore_permissions=True) | frappe.delete_doc("Website Route Permission", to_remove, ignore_permissions=True) | ||||
self.clear_cache() | |||||
def clear_cache(self): | |||||
clear_cache(self.doc.name) | clear_cache(self.doc.name) | ||||
if self.doc.parent_website_route: | |||||
clear_cache(self.doc.parent_website_route) | |||||
def add_to_sitemap(options): | def add_to_sitemap(options): | ||||
bean = frappe.new_bean("Website Route") | bean = frappe.new_bean("Website Route") | ||||
@@ -314,6 +314,20 @@ $.extend(frappe, { | |||||
$.each((frappe.page_ready_events[frappe.get_pathname()] || []), function(i, fn) { | $.each((frappe.page_ready_events[frappe.get_pathname()] || []), function(i, fn) { | ||||
fn(); | fn(); | ||||
}) | }) | ||||
}, | |||||
make_navbar_active: function() { | |||||
var pathname = window.location.pathname; | |||||
$(".navbar a.active").removeClass("active"); | |||||
$(".navbar a").each(function() { | |||||
var href = $(this).attr("href"); | |||||
if(pathname.indexOf(href)===0) { | |||||
var more = pathname.replace(href, ""); | |||||
if(!more || more.substr(0, 1)==="/") { | |||||
$(this).addClass("active"); | |||||
return false; | |||||
} | |||||
} | |||||
}) | |||||
} | } | ||||
}); | }); | ||||
@@ -474,4 +488,5 @@ $(document).on("page_change", function() { | |||||
$(document).trigger("apply_permissions"); | $(document).trigger("apply_permissions"); | ||||
frappe.datetime.refresh_when(); | frappe.datetime.refresh_when(); | ||||
frappe.trigger_ready(); | frappe.trigger_ready(); | ||||
frappe.make_navbar_active(); | |||||
}); | }); |
@@ -28,36 +28,48 @@ def build_sitemap_options(path): | |||||
sitemap_options.get("website_template")).fields | sitemap_options.get("website_template")).fields | ||||
# get sitemap config fields too | # get sitemap config fields too | ||||
for fieldname in ("base_template_path", "template_path", "controller", "no_cache", "no_sitemap", | |||||
"page_name_field", "condition_field"): | |||||
for fieldname in ("base_template_path", "template_path", "controller", | |||||
"no_cache", "no_sitemap", "page_name_field", "condition_field"): | |||||
sitemap_options[fieldname] = sitemap_config.get(fieldname) | sitemap_options[fieldname] = sitemap_config.get(fieldname) | ||||
sitemap_options.doctype = sitemap_options.ref_doctype | sitemap_options.doctype = sitemap_options.ref_doctype | ||||
sitemap_options.title = sitemap_options.page_title | sitemap_options.title = sitemap_options.page_title | ||||
sitemap_options.pathname = sitemap_options.name | sitemap_options.pathname = sitemap_options.name | ||||
def set_sidebar_items(pathname): | |||||
if pathname==home_page or not pathname: | |||||
sitemap_options.children = frappe.db.sql("""select url as name, label as page_title, | |||||
1 as public_read from `tabTop Bar Item` where parentfield='sidebar_items' order by idx""", as_dict=True) | |||||
else: | |||||
sitemap_options.children = frappe.db.sql("""select * from `tabWebsite Route` | |||||
where ifnull(parent_website_route,'')=%s | |||||
and public_read=1 order by -idx desc, page_title asc""", pathname, as_dict=True) | |||||
# establish hierarchy | # establish hierarchy | ||||
sitemap_options.parents = frappe.db.sql("""select name, page_title from `tabWebsite Route` | sitemap_options.parents = frappe.db.sql("""select name, page_title from `tabWebsite Route` | ||||
where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True) | where lft < %s and rgt > %s order by lft asc""", (sitemap_options.lft, sitemap_options.rgt), as_dict=True) | ||||
if not sitemap_options.no_sidebar: | if not sitemap_options.no_sidebar: | ||||
set_sidebar_items(sitemap_options.pathname) | |||||
set_sidebar_items(sitemap_options, sitemap_options.pathname, home_page) | |||||
if not sitemap_options.children: | if not sitemap_options.children: | ||||
set_sidebar_items(sitemap_options.parent_website_route) | |||||
set_sidebar_items(sitemap_options, sitemap_options.parent_website_route, home_page) | |||||
# determine templates to be used | # determine templates to be used | ||||
if not sitemap_options.base_template_path: | if not sitemap_options.base_template_path: | ||||
app_base = frappe.get_hooks("base_template") | app_base = frappe.get_hooks("base_template") | ||||
print app_base | |||||
sitemap_options.base_template_path = app_base[0] if app_base else "templates/base.html" | sitemap_options.base_template_path = app_base[0] if app_base else "templates/base.html" | ||||
return sitemap_options | return sitemap_options | ||||
def set_sidebar_items(sitemap_options, pathname, home_page): | |||||
if pathname==home_page or not pathname: | |||||
sitemap_options.children = frappe.db.sql("""select url as name, label as page_title, | |||||
1 as public_read from `tabTop Bar Item` where parentfield='sidebar_items' order by idx""", as_dict=True) | |||||
else: | |||||
sitemap_options.children = frappe.db.sql("""select * from `tabWebsite Route` | |||||
where ifnull(parent_website_route,'')=%s | |||||
and public_read=1 order by -idx desc, page_title asc""", pathname, as_dict=True) | |||||
if sitemap_options.children: | |||||
# if children are from generator and sort order is specified, then get that condition | |||||
website_template = frappe.doc("Website Template", sitemap_options.children[0].website_template) | |||||
if website_template.sort_by: | |||||
sitemap_options.children = frappe.db.sql("""select t1.* from | |||||
`tabWebsite Route` t1, `tab{ref_doctype}` t2 | |||||
where ifnull(t1.parent_website_route,'')=%s | |||||
and t1.public_read=1 | |||||
and t1.docname = t2.name | |||||
order by t2.{sort_by} {sort_order}""".format(**website_template.fields), | |||||
pathname, as_dict=True) | |||||
@@ -37,12 +37,12 @@ class sync(object): | |||||
def sync_folder(self, basepath, folders, files): | def sync_folder(self, basepath, folders, files): | ||||
self.has_index = False | |||||
folder_route = os.path.relpath(basepath, self.statics_path) | |||||
self.get_index_txt(basepath, files) | self.get_index_txt(basepath, files) | ||||
self.sync_index_page(basepath, files) | self.sync_index_page(basepath, files) | ||||
if not self.has_index and basepath!=self.statics_path: | |||||
# index.md or index.html is required, else skip | |||||
if not frappe.db.exists("Website Route", folder_route): | |||||
# not synced either by generator or by index.html | |||||
return | return | ||||
if self.index: | if self.index: | ||||
@@ -63,7 +63,6 @@ class sync(object): | |||||
fname = "index." + extn | fname = "index." + extn | ||||
if fname in files: | if fname in files: | ||||
self.sync_file(fname, os.path.join(basepath, fname), None) | self.sync_file(fname, os.path.join(basepath, fname), None) | ||||
self.has_index = True | |||||
return | return | ||||
def sync_using_given_index(self, basepath, folders, files): | def sync_using_given_index(self, basepath, folders, files): | ||||
@@ -85,9 +85,9 @@ class WebsiteGenerator(DocListController): | |||||
idx = update_sitemap(existing_site_map, opts) | idx = update_sitemap(existing_site_map, opts) | ||||
else: | else: | ||||
idx = add_to_sitemap(opts) | idx = add_to_sitemap(opts) | ||||
if idx!=None and self.doc.idx != idx: | if idx!=None and self.doc.idx != idx: | ||||
frappe.db.set(self.doc, "idx", idx) | |||||
frappe.db.set(self.doc, "idx", idx) | |||||
def update_permissions(self, opts): | def update_permissions(self, opts): | ||||
if self.meta.get_field("public_read"): | if self.meta.get_field("public_read"): | ||||