@@ -391,6 +391,9 @@ def get_module_path(module, *joins): | |||
def get_app_path(app_name, *joins): | |||
return get_pymodule_path(app_name, *joins) | |||
def get_site_path(*joins): | |||
return os.path.join(local.site_path, *joins) | |||
def get_pymodule_path(modulename, *joins): | |||
joins = [scrub(part) for part in joins] | |||
@@ -512,6 +515,10 @@ def get_application_home_page(user='Guest'): | |||
else: | |||
return conn.get_value("Control Panel", None, "home_page") | |||
def import_doclist(path, ignore_links=False, ignore_insert=False): | |||
from frappe.core.page.data_import_tool import data_import_tool | |||
data_import_tool.import_doclist(path, ignore_links=ignore_links, ignore_insert=ignore_insert) | |||
def copy_doclist(in_doclist): | |||
new_doclist = [] | |||
parent_doc = None | |||
@@ -181,6 +181,7 @@ def setup_utilities(parser): | |||
parser.add_argument("--python", action="store_true", help="get python shell for a site") | |||
parser.add_argument("--flush_memcache", action="store_true", help="flush memcached") | |||
parser.add_argument("--ipython", action="store_true", help="get ipython shell for a site") | |||
parser.add_argument("--execute", help="execute a function", nargs=1, metavar="FUNCTION") | |||
parser.add_argument("--get_site_status", action="store_true", help="Get site details") | |||
parser.add_argument("--update_site_config", nargs=1, | |||
metavar="site-CONFIG-JSON", | |||
@@ -465,6 +466,13 @@ def reset_perms(): | |||
frappe.reset_perms(d) | |||
frappe.destroy() | |||
@cmd | |||
def execute(method): | |||
frappe.connect() | |||
frappe.get_attr(method)() | |||
frappe.conn.commit() | |||
frappe.destroy() | |||
# scheduler | |||
@cmd | |||
def run_scheduler(): | |||
@@ -489,11 +489,12 @@ def delete_child_rows(rows, doctype): | |||
for p in list(set([r[1] for r in rows])): | |||
frappe.conn.sql("""delete from `tab%s` where parent=%s""" % (doctype, '%s'), p) | |||
import csv | |||
def import_file_by_path(path, ignore_links=False, overwrite=False): | |||
from frappe.utils.datautils import read_csv_content | |||
print "Importing " + path | |||
with open(path, "r") as infile: | |||
upload(rows = read_csv_content(infile.read()), ignore_links=ignore_links, overwrite=overwrite) | |||
upload(rows = read_csv_content(infile), ignore_links=ignore_links, overwrite=overwrite) | |||
def export_csv(doctype, path): | |||
with open(path, "w") as csvfile: | |||
@@ -513,18 +514,34 @@ def export_json(doctype, name, path): | |||
d["__islocal"] = 1 | |||
outfile.write(json.dumps(doclist, default=json_handler, indent=1, sort_keys=True)) | |||
def import_doclist(path, overwrite=False): | |||
def import_doclist(path, overwrite=False, ignore_links=False, ignore_insert=False): | |||
import os | |||
if os.path.isdir(path): | |||
files = [os.path.join(path, f) for f in os.listdir(path)] | |||
else: | |||
files = [path] | |||
def _import_doclist(d): | |||
b = frappe.bean(d) | |||
b.ignore_links = ignore_links | |||
try: | |||
b.insert_or_update() | |||
except NameError: | |||
if ignore_insert: | |||
pass | |||
else: | |||
raise | |||
print "Imported: " + b.doc.doctype + " / " + b.doc.name | |||
for f in files: | |||
if f.endswith(".json"): | |||
with open(f, "r") as infile: | |||
b = frappe.bean(json.loads(infile.read())).insert_or_update() | |||
print "Imported: " + b.doc.doctype + " / " + b.doc.name | |||
data = json.loads(infile.read()) | |||
if isinstance(data, list): | |||
for doc in data: | |||
_import_doclist(doc) | |||
else: | |||
_import_doclist(data) | |||
frappe.conn.commit() | |||
if f.endswith(".csv"): | |||
import_file_by_path(f, ignore_links=True, overwrite=overwrite) |
@@ -59,6 +59,8 @@ class Document: | |||
if isinstance(doctype, dict): | |||
fielddata = doctype | |||
doctype = None | |||
if doctype and isinstance(name, dict): | |||
name = frappe.conn.get_value(doctype, name, "name") or None | |||
if fielddata: | |||
self.fields = frappe._dict(fielddata) | |||
@@ -370,6 +370,9 @@ class DocTypeDocList(frappe.model.doclist.DocList): | |||
fields = self.get(filters) | |||
if fields: | |||
return fields[0] | |||
def has_field(self, fieldname): | |||
return fieldname in self.get_fieldnames() | |||
def get_fieldnames(self, filters=None): | |||
if not filters: filters = {} | |||
@@ -31,7 +31,7 @@ frappe.avatar = function(user, large, title) { | |||
} | |||
frappe.ui.set_user_background = function(src) { | |||
if(!src) src = "assets/frappe/images/ui/field.jpg"; | |||
if(!src) src = "assets/frappe/images/ui/background-4-1.jpg"; | |||
frappe.dom.set_style(repl('#page-desktop { \ | |||
position: fixed;\ | |||
left: 0px; min-width: 100%; height: 100%; overflow: auto;\ | |||
@@ -13,6 +13,7 @@ $.extend(frappe.model, { | |||
std_fields: [ | |||
{fieldname:'name', fieldtype:'Link', label:'ID'}, | |||
{fieldname:'owner', fieldtype:'Data', label:'Created By'}, | |||
{fieldname:'idx', fieldtype:'Int', label:'Index'}, | |||
{fieldname:'creation', fieldtype:'Date', label:'Created On'}, | |||
{fieldname:'modified', fieldtype:'Date', label:'Last Updated On'}, | |||
{fieldname:'modified_by', fieldtype:'Data', label:'Last Updated By'}, | |||
@@ -23,7 +24,6 @@ $.extend(frappe.model, { | |||
std_fields_table: [ | |||
{fieldname:'parent', fieldtype:'Data', label:'Parent'}, | |||
{fieldname:'idx', fieldtype:'Int', label:'Row No.'}, | |||
], | |||
new_names: {}, | |||
@@ -365,7 +365,7 @@ frappe.ui.FieldSelect = Class.extend({ | |||
if(d.fieldname=="name") opts.options = me.doctype; | |||
return $.extend(copy_dict(d), opts); | |||
}); | |||
// add parenttype column | |||
var doctype_obj = locals['DocType'][me.doctype]; | |||
if(doctype_obj && cint(doctype_obj.istable)) { | |||
@@ -13,10 +13,14 @@ frappe.ui.Tree = Class.extend({ | |||
tree: this, | |||
parent: this.$w, | |||
label: this.label, | |||
parent_label: null, | |||
expandable: true | |||
}); | |||
this.set_style(); | |||
}, | |||
get_selected_node: function() { | |||
return this.$w.find('.tree-link.selected').data('node'); | |||
}, | |||
set_style: function() { | |||
frappe.dom.set_style("\ | |||
.tree li { list-style: none; }\ | |||
@@ -33,6 +37,8 @@ frappe.ui.TreeNode = Class.extend({ | |||
this.loaded = false; | |||
this.expanded = false; | |||
this.tree.nodes[this.label] = this; | |||
if(this.parent_label) | |||
this.parent_node = this.tree.nodes[this.parent_label]; | |||
this.$a = $('<span class="tree-link">') | |||
.click(function() { | |||
if(me.expandable && me.tree.method && !me.loaded) { | |||
@@ -44,6 +50,7 @@ frappe.ui.TreeNode = Class.extend({ | |||
}) | |||
.bind('reload', function() { me.reload(); }) | |||
.data('label', this.label) | |||
.data('node', this) | |||
.appendTo(this.parent); | |||
// label with icon | |||
@@ -94,6 +101,7 @@ frappe.ui.TreeNode = Class.extend({ | |||
return new frappe.ui.TreeNode({ | |||
tree:this.tree, | |||
parent: $('<li>').appendTo(this.$ul), | |||
parent_label: this.label, | |||
label: data.value, | |||
expandable: data.expandable, | |||
data: data | |||
@@ -208,9 +208,9 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ | |||
var docfield = frappe.meta.docfield_map[c[1] || me.doctype][c[0]]; | |||
if(!docfield) { | |||
var docfield = frappe.model.get_std_field(c[0]); | |||
docfield.parent = me.doctype; | |||
if(c[0]=="name") { | |||
docfield.options = me.doctype; | |||
docfield.parent = me.doctype; | |||
} | |||
} | |||
coldef = { | |||
@@ -293,6 +293,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ | |||
if(e.target.className === "slick-resizable-handle") | |||
return; | |||
var df = args.column.docfield, | |||
sort_by = df.parent + "." + df.fieldname; | |||
@@ -1,14 +1,3 @@ | |||
<div class="blog-footer"> | |||
<p> | |||
{% if categories %} | |||
<h5>Explore posts by categories</h5> | |||
<ul class="breadcrumb" style="background-color: transparent; padding-left: 20px;"> | |||
{% for category in frappe.conn.sql_list("select name from `tabBlog Category` order by name") %} | |||
<li><a href="/blog?category={{ category }}">{{ category }}</a> | |||
{% endfor %} | |||
</ul> | |||
<br><br> | |||
{% endif %} | |||
<p>Show posts by <a href="/blog">everyone</a>. Meet the <a href="/writers">writers</a> of this blog</p> | |||
</p> | |||
<p>Show posts by <a href="/blog">everyone</a>. Meet the <a href="/writers">writers</a> of this blog</p> | |||
</div> |
@@ -1,5 +1,9 @@ | |||
{% block title %}{{ blog_title or "Blog" }}{% endblock %} | |||
{% block script %} | |||
window.category = null; | |||
{% endblock %} | |||
{% block content %} | |||
<div class="blog-list-content"> | |||
{% if blog_introduction %} | |||
@@ -11,7 +11,7 @@ from frappe.utils import encode, cstr, cint, flt | |||
def read_csv_content_from_uploaded_file(ignore_encoding=False): | |||
if getattr(frappe, "uploaded_file", None): | |||
with open(frappe.uploaded_file, "r") as upfile: | |||
fcontent = upfile.read() | |||
fcontent = upfile | |||
else: | |||
from frappe.utils.file_manager import get_uploaded_content | |||
fname, fcontent = get_uploaded_content() | |||
@@ -35,21 +35,24 @@ def read_csv_content_from_attached_file(doc): | |||
def read_csv_content(fcontent, ignore_encoding=False): | |||
rows = [] | |||
decoded = False | |||
for encoding in ["utf-8", "windows-1250", "windows-1252"]: | |||
try: | |||
fcontent = unicode(fcontent, encoding) | |||
decoded = True | |||
break | |||
except UnicodeDecodeError, e: | |||
continue | |||
if not decoded: | |||
frappe.msgprint(frappe._("Unknown file encoding. Tried utf-8, windows-1250, windows-1252."), | |||
raise_exception=True) | |||
if isinstance(fcontent, basestring): | |||
decoded = False | |||
for encoding in ["utf-8", "windows-1250", "windows-1252"]: | |||
try: | |||
fcontent = unicode(fcontent, encoding) | |||
decoded = True | |||
break | |||
except UnicodeDecodeError, e: | |||
continue | |||
if not decoded: | |||
frappe.msgprint(frappe._("Unknown file encoding. Tried utf-8, windows-1250, windows-1252."), | |||
raise_exception=True) | |||
fcontent = fcontent.encode("utf-8").splitlines(True) | |||
try: | |||
reader = csv.reader(fcontent.encode("utf-8").splitlines(True)) | |||
reader = csv.reader(fcontent) | |||
# decode everything | |||
rows = [[unicode(val, "utf-8").strip() for val in row] for row in reader] | |||
return rows | |||
@@ -56,7 +56,7 @@ def parse_date(date): | |||
def get_user_date_format(): | |||
if getattr(frappe.local, "user_date_format", None) is None: | |||
frappe.local.user_date_format = frappe.defaults.get_global_default("date_format") | |||
frappe.local.user_date_format = frappe.defaults.get_global_default("date_format") or "yyyy-mm-dd" | |||
return frappe.local.user_date_format | |||
@@ -273,6 +273,7 @@ body { | |||
.page-footer { | |||
margin: 20px 0px 0px; | |||
padding: 15px 0px; | |||
border-top: 1px solid #eee; | |||
} | |||
@@ -3,7 +3,7 @@ | |||
from __future__ import unicode_literals | |||
import frappe | |||
import frappe, re | |||
from frappe.website.website_generator import WebsiteGenerator | |||
from frappe.website.render import clear_cache | |||
@@ -21,6 +21,10 @@ class DocType(WebsiteGenerator): | |||
return frappe.conn.get_value("Website Sitemap", {"ref_doctype": "Blog Category", "docname": self.doc.blog_category}) | |||
def validate(self): | |||
if not self.doc.blog_intro: | |||
self.doc.blog_intro = self.doc.content[:140] | |||
re.sub("\<[^>]*\>", "", self.doc.blog_intro) | |||
if self.doc.blog_intro: | |||
self.doc.blog_intro = self.doc.blog_intro[:140] | |||
@@ -2,7 +2,7 @@ | |||
{ | |||
"creation": "2013-03-28 10:35:30", | |||
"docstatus": 0, | |||
"modified": "2014-01-20 17:48:25", | |||
"modified": "2014-02-17 13:00:42", | |||
"modified_by": "Administrator", | |||
"owner": "Administrator" | |||
}, | |||
@@ -25,6 +25,7 @@ | |||
}, | |||
{ | |||
"cancel": 0, | |||
"delete": 0, | |||
"doctype": "DocPerm", | |||
"email": 1, | |||
"name": "__common__", | |||
@@ -94,7 +95,7 @@ | |||
"fieldtype": "Small Text", | |||
"in_list_view": 1, | |||
"label": "Blog Intro", | |||
"reqd": 1 | |||
"reqd": 0 | |||
}, | |||
{ | |||
"doctype": "DocField", | |||
@@ -120,7 +121,6 @@ | |||
}, | |||
{ | |||
"create": 1, | |||
"delete": 1, | |||
"doctype": "DocPerm", | |||
"restrict": 1, | |||
"role": "Website Manager", | |||
@@ -128,13 +128,11 @@ | |||
}, | |||
{ | |||
"create": 1, | |||
"delete": 0, | |||
"doctype": "DocPerm", | |||
"role": "Blogger", | |||
"write": 1 | |||
}, | |||
{ | |||
"delete": 0, | |||
"doctype": "DocPerm", | |||
"role": "Guest", | |||
"write": 0 | |||
@@ -59,9 +59,11 @@ def _sync_statics(): | |||
if str(os.path.getmtime(fpath))!=sitemap.doc.static_file_timestamp \ | |||
or cint(sitemap.doc.idx) != cint(priority): | |||
page = frappe.bean("Web Page", sitemap.doc.docname) | |||
title, content = get_static_content(fpath) | |||
page.doc.main_section = content | |||
page.doc.idx = priority | |||
if not title: | |||
title = page_name.replace("-", " ").replace("_", " ").title() | |||
page.doc.title = title | |||
@@ -69,7 +71,6 @@ def _sync_statics(): | |||
sitemap = frappe.bean("Website Sitemap", url) | |||
sitemap.doc.static_file_timestamp = os.path.getmtime(fpath) | |||
sitemap.doc.idx = priority | |||
sitemap.save() | |||
synced.append(url) | |||
@@ -36,8 +36,6 @@ class DocType(DocTypeNestedSet): | |||
self.doc.idx = int(frappe.conn.sql("""select max(idx) from `tabWebsite Sitemap` | |||
where parent_website_sitemap=%s and name!=%s""", (self.doc.parent_website_sitemap, | |||
self.doc.name))[0][0] or 0) + 1 | |||
else: | |||
if self.doc.idx != 0: | |||
if not frappe.conn.get_value("Website Sitemap", { | |||
@@ -0,0 +1,188 @@ | |||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt" | |||
frappe.pages['sitemap-browser'].onload = function(wrapper) { | |||
frappe.ui.make_app_page({ | |||
parent: wrapper, | |||
title: 'Sitemap Browser', | |||
}); | |||
wrapper.appframe.add_module_icon("Website") | |||
wrapper.appframe.set_title_right('Refresh', function() { | |||
wrapper.make_tree(); | |||
}); | |||
$(wrapper) | |||
.find(".layout-side-section") | |||
.html('<div class="text-muted">'+ | |||
frappe._('Click on a link to get options to expand get options ') + | |||
frappe._('Add') + ' / ' + frappe._('Edit') + ' / '+ frappe._('Remove') + '.</div>') | |||
frappe.website.sitemap = new frappe.website.SitemapBrowser( | |||
$(wrapper) | |||
.find(".layout-main-section") | |||
.css({ | |||
"min-height": "300px", | |||
"padding-bottom": "25px" | |||
})); | |||
} | |||
frappe.provide("frappe.website"); | |||
frappe.website.SitemapBrowser = Class.extend({ | |||
init: function(parent) { | |||
$(parent).empty(); | |||
var me = this; | |||
this.tree = new frappe.ui.Tree({ | |||
parent: $(parent), | |||
label: "Sitemap", | |||
method: 'frappe.website.page.sitemap_browser.sitemap_browser.get_children', | |||
click: function(link) { | |||
if(me.cur_toolbar) | |||
$(me.cur_toolbar).toggle(false); | |||
if(!link.toolbar) | |||
me.make_link_toolbar(link); | |||
if(link.toolbar) { | |||
me.cur_toolbar = link.toolbar; | |||
$(me.cur_toolbar).toggle(true); | |||
} | |||
} | |||
}); | |||
this.tree.rootnode.$a | |||
.data('node-data', {value: "Sitemap", expandable:1}) | |||
.click(); | |||
}, | |||
make_link_toolbar: function(link) { | |||
var data = $(link).data('node-data'); | |||
if(!data) return; | |||
link.toolbar = $('<span class="tree-node-toolbar"></span>').insertAfter(link); | |||
// edit | |||
var node_links = []; | |||
node_links.push('<a onclick="frappe.website.sitemap.open();">'+frappe._('Edit')+'</a>'); | |||
node_links.push('<a onclick="frappe.website.sitemap.move();">'+frappe._('Move')+'</a>'); | |||
node_links.push('<a onclick="frappe.website.sitemap.up_or_down(\'up\');">'+frappe._('Up')+'</a>'); | |||
node_links.push('<a onclick="frappe.website.sitemap.up_or_down(\'down\');">'+frappe._('Down')+'</a>'); | |||
// if(data.expandable) { | |||
// node_links.push('<a onclick="frappe.website.sitemap.new_node();">' + frappe._('Add Child') + '</a>'); | |||
// } | |||
// | |||
// node_links.push('<a onclick="frappe.website.sitemap.delete()">' + frappe._('Delete') + '</a>'); | |||
link.toolbar.append(node_links.join(" | ")); | |||
}, | |||
new_node: function() { | |||
var me = this; | |||
var fields = [ | |||
{fieldtype:'Data', fieldname: 'name_field', | |||
label:'New ' + me.ctype + ' Name', reqd:true}, | |||
{fieldtype:'Select', fieldname:'is_group', label:'Group Node', options:'No\nYes', | |||
description: frappe._("Further nodes can be only created under 'Group' type nodes")}, | |||
{fieldtype:'Button', fieldname:'create_new', label:'Create New' } | |||
] | |||
if(me.ctype == "Sales Person") { | |||
fields.splice(-1, 0, {fieldtype:'Link', fieldname:'employee', label:'Employee', | |||
options:'Employee', description: frappe._("Please enter Employee Id of this sales parson")}); | |||
} | |||
// the dialog | |||
var d = new frappe.ui.Dialog({ | |||
title: frappe._('New ') + frappe._(me.ctype), | |||
fields: fields | |||
}) | |||
d.set_value("is_group", "No"); | |||
// create | |||
$(d.fields_dict.create_new.input).click(function() { | |||
var btn = this; | |||
$(btn).set_working(); | |||
var v = d.get_values(); | |||
if(!v) return; | |||
var node = me.selected_node(); | |||
v.parent = node.data('label'); | |||
v.ctype = me.ctype; | |||
return frappe.call({ | |||
method: 'erpnext.selling.page.sales_browser.sales_browser.add_node', | |||
args: v, | |||
callback: function() { | |||
$(btn).done_working(); | |||
d.hide(); | |||
node.trigger('reload'); | |||
} | |||
}) | |||
}); | |||
d.show(); | |||
}, | |||
selected_node: function() { | |||
return this.tree.$w.find('.tree-link.selected'); | |||
}, | |||
open: function() { | |||
var node = this.selected_node(); | |||
frappe.set_route("Form", "Website Sitemap", node.data("label")); | |||
}, | |||
up_or_down: function(up_or_down) { | |||
var node = this.tree.get_selected_node(); | |||
frappe.call({ | |||
method: "frappe.website.page.sitemap_browser.sitemap_browser.move", | |||
args: { | |||
"name": node.label, | |||
"up_or_down": up_or_down | |||
}, | |||
callback: function(r) { | |||
(node.parent_node || node).reload(); | |||
} | |||
}); | |||
}, | |||
move: function() { | |||
var me = this; | |||
var node = this.selected_node(); | |||
if(!this.move_dialog) { | |||
this.move_dialog = new frappe.ui.Dialog({ | |||
title: frappe._("Move"), | |||
fields: [ | |||
{ | |||
fieldtype: "Link", | |||
fieldname: "new_parent", | |||
label: "New Parent", | |||
reqd: 1, | |||
options: "Website Sitemap" | |||
}, | |||
{ | |||
fieldtype: "Button", | |||
fieldname: "update", | |||
label: "Update", | |||
} | |||
] | |||
}); | |||
this.move_dialog.get_input("update").on("click", function() { | |||
var values = me.move_dialog.get_values(); | |||
if(!values) return; | |||
frappe.call({ | |||
method: "frappe.website.page.sitemap_browser.sitemap_browser.update_parent", | |||
args: { | |||
"name": node.data("label"), | |||
"new_parent": values.new_parent | |||
}, | |||
callback: function(r) { | |||
me.move_dialog.hide(); | |||
me.tree.rootnode.reload(); | |||
} | |||
}); | |||
}); | |||
} | |||
this.move_dialog.show(); | |||
this.move_dialog.get_input("new_parent").val(""); | |||
} | |||
}); |
@@ -0,0 +1,72 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe.website.render import clear_cache | |||
@frappe.whitelist() | |||
def get_children(parent=None): | |||
if not frappe.has_permission("Website Sitemap"): | |||
raise frappe.PermissionError | |||
if parent=="Sitemap": | |||
parent = "" | |||
return frappe.conn.sql("""select name as value, 1 as expandable from `tabWebsite Sitemap` where | |||
ifnull(parent_website_sitemap, '')=%s order by -idx desc""", parent, as_dict=True) | |||
@frappe.whitelist() | |||
def move(name, up_or_down): | |||
ret = None | |||
if not frappe.has_permission("Website Sitemap"): | |||
raise frappe.PermissionError | |||
sitemap = frappe.doc("Website Sitemap", name) | |||
if up_or_down=="up": | |||
if sitemap.idx > 0: | |||
prev = frappe.doc("Website Sitemap", { | |||
"parent_website_sitemap": sitemap.parent_website_sitemap, | |||
"idx": sitemap.idx - 1 | |||
}) | |||
if prev.name: | |||
prev.idx = prev.idx + 1 | |||
prev.save() | |||
sitemap.idx = sitemap.idx - 1 | |||
sitemap.save() | |||
ret = "ok" | |||
else: | |||
nexts = frappe.doc("Website Sitemap", { | |||
"parent_website_sitemap": sitemap.parent_website_sitemap, | |||
"idx": sitemap.idx + 1 | |||
}) | |||
if nexts.name: | |||
nexts.idx = nexts.idx - 1 | |||
nexts.save() | |||
sitemap.idx = sitemap.idx + 1 | |||
sitemap.save() | |||
ret = "ok" | |||
clear_cache() | |||
@frappe.whitelist() | |||
def update_parent(name, new_parent): | |||
if not frappe.has_permission("Website Sitemap"): | |||
raise frappe.PermissionError | |||
sitemap = frappe.doc("Website Sitemap", name) | |||
if sitemap.ref_doctype: | |||
generator = frappe.bean(sitemap.ref_doctype, sitemap.docname) | |||
if not generator.meta.has_field("parent_website_sitemap"): | |||
frappe.throw("Does not allow moving.") | |||
generator.doc.parent_website_sitemap = new_parent | |||
generator.save() | |||
else: | |||
frappe.msgprint("Template Pages cannot be moved.") | |||
clear_cache() | |||
@@ -0,0 +1,37 @@ | |||
[ | |||
{ | |||
"creation": "2014-02-18 10:47:22", | |||
"docstatus": 0, | |||
"modified": "2014-02-18 10:47:22", | |||
"modified_by": "Administrator", | |||
"owner": "Administrator" | |||
}, | |||
{ | |||
"doctype": "Page", | |||
"icon": "icon-sitemap", | |||
"module": "Website", | |||
"name": "__common__", | |||
"page_name": "sitemap-browser", | |||
"standard": "Yes", | |||
"title": "Sitemap Browser" | |||
}, | |||
{ | |||
"doctype": "Page Role", | |||
"name": "__common__", | |||
"parent": "sitemap-browser", | |||
"parentfield": "roles", | |||
"parenttype": "Page" | |||
}, | |||
{ | |||
"doctype": "Page", | |||
"name": "sitemap-browser" | |||
}, | |||
{ | |||
"doctype": "Page Role", | |||
"role": "Website Manager" | |||
}, | |||
{ | |||
"doctype": "Page Role", | |||
"role": "System Manager" | |||
} | |||
] |
@@ -62,6 +62,13 @@ frappe.module_page["Website"] = [ | |||
icon: "icon-wrench", | |||
right: true, | |||
items: [ | |||
{ | |||
"route":"sitemap-browser", | |||
"label":frappe._("Sitemap Browser"), | |||
"description":frappe._("View or manage Website Sitemap tree."), | |||
doctype:"Website Settings", | |||
icon: "icon-sitemap" | |||
}, | |||
{ | |||
"route":"Form/Website Settings", | |||
"label":frappe._("Website Settings"), | |||
@@ -57,5 +57,5 @@ def build_sitemap_options(path): | |||
# determine templates to be used | |||
if not sitemap_options.base_template_path: | |||
sitemap_options.base_template_path = "templates/base.html" | |||
return sitemap_options |
@@ -23,6 +23,8 @@ class WebsiteGenerator(DocListController): | |||
self.doc.fields[self._website_config.page_name_field] = page_name | |||
else: | |||
frappe.conn.set(self.doc, self._website_config.page_name_field, page_name) | |||
return page_name | |||
def get_parent_website_sitemap(self): | |||
return self.doc.parent_website_sitemap | |||
@@ -94,13 +96,17 @@ class WebsiteGenerator(DocListController): | |||
opts.public_read = 1 | |||
def get_page_name(self): | |||
if not self._get_page_name(): | |||
self.set_page_name() | |||
page_name = self._get_page_name() | |||
if not page_name: | |||
page_name = self.set_page_name() | |||
return self._get_page_name() | |||
def _get_page_name(self): | |||
return self.doc.fields.get(self._website_config.page_name_field) | |||
if self.meta.has_field(self._website_config.page_name_field): | |||
return self.doc.fields.get(self._website_config.page_name_field) | |||
else: | |||
return cleanup_page_name(self.get_page_title()) | |||
def get_page_title(self): | |||
return self.doc.title or (self.doc.name.replace("-", " ").replace("_", " ").title()) |