diff --git a/build.json b/build.json index 7b1dfe6f3b0..6efbbc30956 100644 --- a/build.json +++ b/build.json @@ -23,7 +23,4 @@ "public/js/complete_setup.js": [ "erpnext/startup/js/complete_setup.js", ], - "public/js/product_category.js": [ - "erpnext/website/js/product_category.js", - ], } \ No newline at end of file diff --git a/data/master.sql.gz b/data/master.sql.gz index e8f45a90516..e9896e4c390 100644 Binary files a/data/master.sql.gz and b/data/master.sql.gz differ diff --git a/erpnext/patches/june_2012/cms2.py b/erpnext/patches/june_2012/cms2.py new file mode 100644 index 00000000000..cf494c01863 --- /dev/null +++ b/erpnext/patches/june_2012/cms2.py @@ -0,0 +1,88 @@ +def execute(): + import webnotes + import webnotes.model.sync + + # sync doctypes required for the patch + webnotes.model.sync.sync('website', 'web_cache') + webnotes.model.sync.sync('website', 'web_page') + webnotes.model.sync.sync('website', 'blog') + webnotes.model.sync.sync('website', 'website_settings') + webnotes.model.sync.sync('stock', 'item') + + cleanup() + + save_pages() + + save_website_settings() + +def cleanup(): + import webnotes + + # delete pages from `tabPage` of module Website or of type Webpage + webnotes.conn.sql("""\ + delete from `tabPage` + where module='Website' and ifnull(web_page, 'No') = 'Yes'""") + + # change show_in_website value in item table to 0 or 1 + webnotes.conn.sql("""\ + update `tabItem` + set show_in_website = if(show_in_website = 'Yes', 1, 0) + where show_in_website is not null""") + + # move comments from comment_doctype Page to Blog + webnotes.conn.sql("""\ + update `tabComment` comm, `tabBlog` blog + set comm.comment_doctype = 'Blog', comm.comment_docname = blog.name + where comm.comment_docname = blog.page_name""") + + # delete deprecated pages + import webnotes.model + for page in ['products', 'contact', 'blog', 'about']: + try: + webnotes.model.delete_doc('Page', page) + except Exception, e: + webnotes.modules.patch_handler.log(unicode(e)) + + import os + import conf + # delete other html files + exception_list = ['app.html', 'unsupported.html', 'blank.html'] + conf_dir = os.path.dirname(os.path.abspath(conf.__file__)) + public_path = os.path.join(conf_dir, 'public') + for f in os.listdir(public_path): + if f.endswith('.html') and f not in exception_list: + os.remove(os.path.join(public_path, f)) + +def save_pages(): + """save all web pages, blogs to create content""" + query_map = { + 'Web Page': """select name from `tabWeb Page` where docstatus=0""", + 'Blog': """\ + select name from `tabBlog` + where docstatus = 0 and ifnull(published, 0) = 1""", + 'Item': """\ + select name from `tabItem` + where docstatus = 0 and ifnull(show_in_website, 0) = 1""", + } + + import webnotes + from webnotes.model.doclist import DocList + import webnotes.modules.patch_handler + + for dt in query_map: + for result in webnotes.conn.sql(query_map[dt], as_dict=1): + try: + DocList(dt, result['name'].encode('utf-8')).save() + except Exception, e: + webnotes.modules.patch_handler.log(unicode(e)) + +def save_website_settings(): + from webnotes.model.code import get_obj + + # rewrite pages + get_obj('Website Settings').on_update() + + ss = get_obj('Style Settings') + ss.validate() + ss.doc.save() + ss.on_update() \ No newline at end of file diff --git a/erpnext/patches/may_2012/cms.py b/erpnext/patches/may_2012/cms.py deleted file mode 100644 index 2711b1d1b40..00000000000 --- a/erpnext/patches/may_2012/cms.py +++ /dev/null @@ -1,12 +0,0 @@ -import webnotes - -def execute(): - from webnotes.model.code import get_obj - - # rewrite pages - get_obj('Website Settings').rewrite_pages() - - ss = get_obj('Style Settings') - ss.validate() - ss.doc.save() - ss.on_update() \ No newline at end of file diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index ab95e9553d5..5a6748c966b 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -337,11 +337,6 @@ patch_list = [ 'patch_file': 'stock_reco_patch', 'description': 'stock reco patch: store diff info in field' }, - { - 'patch_module': 'patches.may_2012', - 'patch_file': 'cms', - 'description': 'generate html pages' - }, { 'patch_module': 'patches.may_2012', 'patch_file': 'reload_reports', @@ -487,4 +482,9 @@ patch_list = [ 'patch_file': 'deprecate_import_data_control', 'description': "deprecate doctype - Import Data Control and page - Import Data" }, + { + 'patch_module': 'patches.june_2012', + 'patch_file': 'cms2', + 'description': 'cms2 release patches' + }, ] \ No newline at end of file diff --git a/erpnext/selling/doctype/sales_order/listview.js b/erpnext/selling/doctype/sales_order/listview.js index cbe35daae1d..3fa63a5d7f8 100644 --- a/erpnext/selling/doctype/sales_order/listview.js +++ b/erpnext/selling/doctype/sales_order/listview.js @@ -3,21 +3,23 @@ wn.doclistviews['Sales Order'] = wn.views.ListView.extend({ init: function(d) { this._super(d) this.fields = this.fields.concat([ - "`tabSales Order`.customer_name", + "`tabSales Order`.customer_name", + "`tabSales Order`.status", + "`tabSales Order`.order_type", "ifnull(`tabSales Order`.per_delivered,0) as per_delivered", "ifnull(`tabSales Order`.per_billed,0) as per_billed", "`tabSales Order`.currency", "ifnull(`tabSales Order`.grand_total_export,0) as grand_total_export" ]); - this.stats = this.stats.concat(['status', 'company']); + this.stats = this.stats.concat(['status', 'order_type', 'company']); }, columns: [ {width: '3%', content: 'check'}, - {width: '5%', content:'avatar'}, - {width: '3%', content:'docstatus'}, - {width: '15%', content:'name'}, - {width: '32%', content:'customer_name+tags', css: {color:'#222'}}, + {width: '5%', content: 'avatar'}, + {width: '3%', content: 'docstatus'}, + {width: '15%', content: 'name'}, + {width: '29%', content: 'customer_name+tags', css: {color:'#222'}}, { width: '18%', content: function(parent, data) { @@ -25,7 +27,19 @@ wn.doclistviews['Sales Order'] = wn.views.ListView.extend({ }, css: {'text-align':'right'} }, - {width: '8%', content: 'per_delivered', type:'bar-graph', label:'Delivered'}, + { + width: '11%', + content: function(parent, data, me) { + var order_type = data.order_type.toLowerCase(); + + if (order_type === 'sales') { + me.render_icon(parent, 'icon-tag', data.order_type); + me.render_bar_graph(parent, data, 'per_billed', 'Delivered'); + } else if (order_type === 'maintenance') { + me.render_icon(parent, 'icon-wrench', data.order_type); + } + }, + }, {width: '8%', content: 'per_billed', type:'bar-graph', label:'Billed'}, {width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}} ] diff --git a/erpnext/startup/js/complete_setup.js b/erpnext/startup/js/complete_setup.js index 9180dfa1197..83d65671c0e 100644 --- a/erpnext/startup/js/complete_setup.js +++ b/erpnext/startup/js/complete_setup.js @@ -138,7 +138,7 @@ $.extend(erpnext.complete_setup, { 'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Federated States of Micronesia', 'Fiji', 'Finland', 'France', 'Gabon', 'Georgia', 'Germany', 'Ghana', 'Greece', - 'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', + 'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Israel', 'Italy', 'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kingdom of the Netherlands', 'Kiribati', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', @@ -147,7 +147,7 @@ $.extend(erpnext.complete_setup, { 'Mexico', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Morocco', 'Mozambique', 'Myanmar', 'Namibia', 'Nauru', 'Nepal', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'North Korea', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Panama', 'Papua New Guinea', - 'Paraguay', "People's Republic of China", 'Peru', 'Philippines', 'Poland', 'Portugal', + 'Paraguay', "China", 'Peru', 'Philippines', 'Poland', 'Portugal', 'Qatar', 'Republic of Ireland', 'Republic of the Congo', 'Romania', 'Russia', 'Rwanda', 'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent and the Grenadines', 'Samoa', 'San Marino', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', @@ -252,6 +252,11 @@ $.extend(erpnext.complete_setup, { 'Cape Verde': ['Atlantic/Cape_Verde'], 'Central African Republic': ['Africa/Bangui'], 'Chad': ['Africa/Ndjamena'], + 'China': ['Asia/Shanghai', + 'Asia/Harbin', + 'Asia/Chongqing', + 'Asia/Urumqi', + 'Asia/Kashgar'], 'Chile': ['America/Santiago', 'Pacific/Easter'], 'Colombia': ['America/Bogota'], 'Comoros': ['Indian/Comoro'], @@ -292,6 +297,7 @@ $.extend(erpnext.complete_setup, { 'Guyana': ['America/Guyana'], 'Haiti': ['America/Guatemala'], 'Honduras': ['America/Tegucigalpa'], + 'Hong Kong': ['Asia/Hong_Kong'], 'Hungary': ['Europe/Budapest'], 'Iceland': ['Atlantic/Reykjavik'], 'India': ['Asia/Calcutta'], @@ -365,11 +371,6 @@ $.extend(erpnext.complete_setup, { 'Panama': ['America/Panama'], 'Papua New Guinea': ['Pacific/Port_Moresby'], 'Paraguay': ['America/Asuncion'], - "People's Republic of China": ['Asia/Shanghai', - 'Asia/Harbin', - 'Asia/Chongqing', - 'Asia/Urumqi', - 'Asia/Kashgar'], 'Peru': ['America/Lima'], 'Philippines': ['Asia/Manila'], 'Poland': ['Europe/Warsaw'], diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 65698c1f87c..572a790264c 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -29,8 +29,23 @@ cur_frm.cscript.refresh = function(doc) { } $c_obj(make_doclist(doc.doctype, doc.name),'check_if_sle_exists','',callback); } + + cur_frm.cscript.hide_website_fields(doc); } +cur_frm.cscript.hide_website_fields = function(doc) { + var website_fields_list = ['page_name', 'website_image', 'web_short_description', + 'web_long_description'] + if (cint(doc.show_in_website)) { + unhide_field(website_fields_list); + } else { + hide_field(website_fields_list); + } +} + +cur_frm.cscript.show_in_website = function(doc, dt, dn) { + cur_frm.cscript.hide_website_fields(doc); +} cur_frm.fields_dict['default_bom'].get_query = function(doc) { //var d = locals[this.doctype][this.docname]; diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 0f6cc4c8b1c..9864fc909f0 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -46,6 +46,8 @@ class DocType: return ret def on_update(self): + self.update_page_name() + bin = sql("select stock_uom from `tabBin` where item_code = '%s' " % self.doc.item_code) if bin and cstr(bin[0][0]) != cstr(self.doc.stock_uom): msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.") @@ -78,9 +80,13 @@ class DocType: child.conversion_factor = 1 child.save() + self.clear_web_cache() + # On delete 1. Delete BIN (if none of the corrosponding transactions present, it gets deleted. if present, rolled back due to exception) def on_trash(self): sql("delete from tabBin where item_code='%s'"%(self.doc.item_code)) + + self.delete_web_cache(self.doc.page_name) # Check whether Ref Rate is not entered twice for same Price List and Currency def check_ref_rate_detail(self): @@ -162,9 +168,9 @@ class DocType: if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No': msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1) - # make product page - self.make_page() - + if self.doc.name: + self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name') + def check_non_asset_warehouse(self): if self.doc.is_asset_item == "Yes": existing_qty = sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name) @@ -217,35 +223,38 @@ Total Available Qty: %s def on_rename(self,newdn,olddn): sql("update tabItem set item_code = %s where name = %s", (newdn, olddn)) - def make_page(self): - if self.doc.show_in_website=='Yes': + def delete_web_cache(self, page_name): + import website.web_cache + website.web_cache.delete_cache(page_name) - import website.utils + def clear_web_cache(self): + if hasattr(self, 'old_page_name') and self.old_page_name and \ + self.doc.page_name != self.old_page_name: + self.delete_web_cache(self.doc.page_name) + + if self.doc.show_in_website: + import website.web_cache + website.web_cache.create_cache(self.doc.page_name, self.doc.doctype, self.doc.name) + website.web_cache.clear_cache(self.doc.page_name, self.doc.doctype, self.doc.name) + else: + self.delete_web_cache(self.doc.page_name) + + def update_page_name(self): + import website.utils + + # if same name, do not repeat twice + if self.doc.name == self.doc.item_name: + page_name = self.doc.name + else: + page_name = self.doc.name + " " + self.doc.item_name - if self.doc.page_name: - import webnotes.model - webnotes.model.delete_doc('Page', self.doc.page_name) - - p = website.utils.add_page("Product " + self.doc.item_name) - self.doc.page_name = p.name + self.doc.page_name = website.utils.page_name(page_name) - from jinja2 import Template - import markdown2 - import os - - - self.doc.long_description_html = markdown2.markdown(self.doc.description or '') - - with open(os.path.join(os.path.dirname(__file__), 'template.html'), 'r') as f: - p.content = Template(f.read()).render(doc=self.doc) - - with open(os.path.join(os.path.dirname(__file__), 'product_page.js'), 'r') as f: - p.script = Template(f.read()).render(doc=self.doc) - - p.save() - - website.utils.add_guest_access_to_page(p.name) - - del self.doc.fields['long_description_html'] - - \ No newline at end of file + webnotes.conn.set_value('Item', self.doc.name, 'page_name', self.doc.page_name) + + # no need to check for uniqueness, as name is unique + + def prepare_template_args(self): + import markdown2 + self.doc.web_description_html = markdown2.markdown(self.doc.description or '', + extras=["wiki-tables"]) diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt index 8a079b815d6..06806bac04a 100644 --- a/erpnext/stock/doctype/item/item.txt +++ b/erpnext/stock/doctype/item/item.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-04-30 18:33:53', + 'creation': '2012-06-08 12:54:51', 'docstatus': 0, - 'modified': '2012-06-07 16:16:24', + 'modified': '2012-07-04 11:10:29', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -57,73 +57,6 @@ 'name': u'Item' }, - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Material Manager', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Material Manager', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Material User', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Material User', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'cancel': 1, - 'create': 1, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Material Master Manager', - 'write': 1 - }, - - # DocPerm - { - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Material Master Manager', - 'write': 0 - }, - # DocPerm { 'cancel': 1, @@ -134,6 +67,25 @@ 'write': 1 }, + # DocPerm + { + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Material Master Manager', + 'write': 0 + }, + + # DocPerm + { + 'cancel': 1, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Material Master Manager', + 'write': 1 + }, + # DocPerm { 'doctype': u'DocPerm', @@ -141,6 +93,54 @@ 'role': u'System Manager' }, + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Material Manager', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Material Manager', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Material User', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Material User', + 'submit': 0, + 'write': 0 + }, + # DocField { 'doctype': u'DocField', @@ -731,26 +731,6 @@ 'reqd': 1 }, - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'show_in_website', - 'fieldtype': u'Select', - 'label': u'Show in Website', - 'options': u'No\nYes', - 'permlevel': 0 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'website_image', - 'fieldtype': u'Select', - 'label': u'website_image', - 'options': u'attach_files:', - 'permlevel': 0 - }, - # DocField { 'doctype': u'DocField', @@ -794,17 +774,6 @@ 'permlevel': 0 }, - # DocField - { - 'colour': u'White:FFF', - 'description': u'website page link', - 'doctype': u'DocField', - 'fieldname': u'page_name', - 'fieldtype': u'Data', - 'label': u'Page Name', - 'permlevel': 1 - }, - # DocField { 'doctype': u'DocField', @@ -994,5 +963,63 @@ 'no_copy': 1, 'permlevel': 0, 'print_hide': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'website_section', + 'fieldtype': u'Section Break', + 'label': u'Website', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'show_in_website', + 'fieldtype': u'Check', + 'label': u'Show in Website', + 'permlevel': 0 + }, + + # DocField + { + 'colour': u'White:FFF', + 'description': u'website page link', + 'doctype': u'DocField', + 'fieldname': u'page_name', + 'fieldtype': u'Data', + 'label': u'Page Name', + 'permlevel': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'website_image', + 'fieldtype': u'Select', + 'label': u'Image', + 'options': u'attach_files:', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'web_short_description', + 'fieldtype': u'Text', + 'label': u'Short Description', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'web_long_description', + 'fieldtype': u'Code', + 'label': u'Long Description', + 'options': u'Markdown', + 'permlevel': 0 } ] \ No newline at end of file diff --git a/erpnext/stock/doctype/item/product_page.js b/erpnext/stock/doctype/item/product_page.js deleted file mode 100644 index 926ef69f873..00000000000 --- a/erpnext/stock/doctype/item/product_page.js +++ /dev/null @@ -1,63 +0,0 @@ -// 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 . - -wn.require('erpnext/website/js/product_category.js'); - -pscript["onload_{{ doc.page_name }}"] = function(wrapper) { - wrapper.product_group = "{{ doc.item_group }}"; - wrapper.product_name = "{{ doc.name }}"; - erpnext.make_product_categories(wrapper); - $(wrapper).find('.product-inquiry').click(function() { - loadpage('contact', function() { - $('#content-contact-us [name="contact-message"]').val("Hello,\n\n\ - Please send me more information on {{ doc.title }} (Item Code:{{ doc.item }})\n\n\ - My contact details are:\n\nThank you!\ - "); - }) - }); - - // similar products - wrapper.similar = new wn.ui.Listing({ - parent: $(wrapper).find('.similar-products').get(0), - hide_refresh: true, - page_length: 5, - get_query: function() { - args = { - cat: wrapper.product_group, - name: wrapper.product_name - }; - return repl('select t1.name, t1.title, t1.thumbnail_image, \ - t1.page_name, t1.short_description \ - from tabProduct t1, tabItem t2 \ - where t1.item = t2.name \ - and ifnull(t1.published,0)=1 \ - and t1.name != "%(name)s" \ - and t2.item_group="%(cat)s" order by t1.modified desc', args) - }, - render_row: function(parent, data) { - if(data.short_description.length > 100) { - data.short_description = data.short_description.substr(0,100) + '...'; - } - parent.innerHTML = repl('
\ -
\ -
\ - %(title)s\ -

%(short_description)s

\ -
', data); - } - }); - wrapper.similar.run(); -} \ No newline at end of file diff --git a/erpnext/stock/doctype/item/template.html b/erpnext/stock/doctype/item/template.html deleted file mode 100644 index 8a2f4a9731d..00000000000 --- a/erpnext/stock/doctype/item/template.html +++ /dev/null @@ -1,25 +0,0 @@ -
-
-
-

{{ doc.item_name }}

-
-

- -

- {{ doc.long_description_html }} - -
-
-
-

More Categories

-
-
-

Similar Products

-
-
-
-
-
\ No newline at end of file diff --git a/erpnext/website/blog.py b/erpnext/website/blog.py new file mode 100644 index 00000000000..a890cc0fc83 --- /dev/null +++ b/erpnext/website/blog.py @@ -0,0 +1,128 @@ +import webnotes + +@webnotes.whitelist(allow_guest=True) +def get_blog_list(args=None): + """ + args = { + 'limit_start': 0, + 'limit_page_length': 10, + } + """ + import webnotes + + if not args: args = webnotes.form_dict + + query = """\ + select + cache.name as name, cache.html as content, + blog.owner as owner, blog.creation as published, + blog.title as title + from `tabWeb Cache` cache, `tabBlog` blog + where cache.doc_type = 'Blog' and blog.page_name = cache.name + order by published desc, name asc""" + + from webnotes.widgets.query_builder import add_limit_to_query + query, args = add_limit_to_query(query, args) + + result = webnotes.conn.sql(query, args, as_dict=1) + + # strip html tags from content + import webnotes.utils + import website.web_cache + + for res in result: + from webnotes.utils import global_date_format, get_fullname + res['full_name'] = get_fullname(res['owner']) + res['published'] = global_date_format(res['published']) + res['content'] = split_blog_content(res['content']) + res['content'] = res['content'][:1000] + + return result + +@webnotes.whitelist(allow_guest=True) +def get_recent_blog_list(args=None): + """ + args = { + 'limit_start': 0, + 'limit_page_length': 5, + 'name': '', + } + """ + import webnotes + + if not args: args = webnotes.form_dict + + query = """\ + select name, title, left(content, 100) as content + from tabBlog + where ifnull(published,0)=1 and + name!=%(name)s order by creation desc""" + + from webnotes.widgets.query_builder import add_limit_to_query + query, args = add_limit_to_query(query, args) + + result = webnotes.conn.sql(query, args, as_dict=1) + + # strip html tags from content + import webnotes.utils + for res in result: + res['content'] = webnotes.utils.strip_html(res['content']) + + return result + +@webnotes.whitelist(allow_guest=True) +def add_comment(args=None): + """ + args = { + 'comment': '', + 'comment_by': '', + 'comment_by_fullname': '', + 'comment_doctype': '', + 'comment_docname': '', + 'page_name': '', + } + """ + import webnotes + + if not args: args = webnotes.form_dict + + import webnotes.widgets.form.comments + comment = webnotes.widgets.form.comments.add_comment(args) + + # since comments are embedded in the page, clear the web cache + import website.web_cache + website.web_cache.clear_cache(args.get('page_name'), + args.get('comment_doctype'), args.get('comment_docname')) + + # loads fresh blog into cache + get_blog_content(args.get('page_name')) + + import webnotes.utils + + comment['comment_date'] = webnotes.utils.pretty_date(comment['creation']) + template_args = { 'comment_list': [comment], 'template': 'html/comment.html' } + + # get html of comment row + comment_html = website.web_cache.build_html(template_args) + + return comment_html + +def get_blog_content(blog_page_name): + import website.web_cache + content = website.web_cache.get_html(blog_page_name) + + content = split_blog_content(content) + + import webnotes.utils + content = webnotes.utils.escape_html(content) + + return content + +def split_blog_content(content): + content = content.split("") + content = len(content) > 1 and content[1] or content[0] + + content = content.split("") + content = content[0] + + return content \ No newline at end of file diff --git a/erpnext/website/doctype/blog/blog.py b/erpnext/website/doctype/blog/blog.py index 919b8303991..e361ece996b 100644 --- a/erpnext/website/doctype/blog/blog.py +++ b/erpnext/website/doctype/blog/blog.py @@ -22,52 +22,40 @@ naming for same name files: file.gif, file-1.gif, file-2.gif etc import webnotes import website.utils +import website.web_page -class DocType(): +class DocType(website.web_page.Page): def __init__(self, d, dl): + super(DocType, self).__init__('Blog') self.doc, self.doclist = d, dl - - def autoname(self): - """save file by its name""" - self.doc.name = website.utils.page_name(self.doc.title) - - def validate(self): - """write/update 'Page' with the blog""" - # we need the name for the templates - if not self.doc.name: - self.autoname() - - if self.doc.page_name: - webnotes.conn.sql("""delete from tabPage where name=%s""", self.doc.page_name) - - p = website.utils.add_page(self.doc.title) - - from jinja2 import Template - import markdown2 - import os - from webnotes.utils import global_date_format, get_fullname - from webnotes.model.code import get_obj - - self.doc.content_html = unicode(markdown2.markdown(self.doc.content or '')) - self.doc.full_name = get_fullname(self.doc.owner) - self.doc.updated = global_date_format(self.doc.modified) - - with open(os.path.join(os.path.dirname(__file__), 'template.html'), 'r') as f: - p.content = Template(f.read()).render(doc=self.doc) - - with open(os.path.join(os.path.dirname(__file__), 'blog_page.js'), 'r') as f: - p.script = Template(f.read()).render(doc=self.doc) - - p.web_page = 'Yes' - p.save() - get_obj(doc=p).write_cms_page() - - website.utils.add_guest_access_to_page(p.name) - self.doc.page_name = p.name - - # cleanup - for f in ['full_name', 'updated', 'content_html']: - if f in self.doc.fields: - del self.doc.fields[f] - \ No newline at end of file + def on_update(self): + super(DocType, self).on_update() + if not webnotes.utils.cint(self.doc.published): + self.delete_web_cache(self.doc.page_name) + else: + import website.blog + website.blog.get_blog_content(self.doc.page_name) + + def prepare_template_args(self): + import webnotes.utils + + # this is for double precaution. usually it wont reach this code if not published + if not webnotes.utils.cint(self.doc.published): + raise Exception, "This blog has not been published yet!" + + # temp fields + from webnotes.utils import global_date_format, get_fullname + self.doc.full_name = get_fullname(self.doc.owner) + self.doc.updated = global_date_format(self.doc.creation) + + self.markdown_to_html(['content']) + + comment_list = webnotes.conn.sql("""\ + select comment, comment_by_fullname, creation + from `tabComment` where comment_doctype="Blog" + and comment_docname=%s order by creation""", self.doc.name, as_dict=1) + + self.doc.comment_list = comment_list or [] + for comment in self.doc.comment_list: + comment['comment_date'] = webnotes.utils.pretty_date(comment['creation']) \ No newline at end of file diff --git a/erpnext/website/doctype/blog/blog.txt b/erpnext/website/doctype/blog/blog.txt index ad44d13d964..24187e3bf30 100644 --- a/erpnext/website/doctype/blog/blog.txt +++ b/erpnext/website/doctype/blog/blog.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-04-02 16:02:43', + 'creation': '2012-05-28 19:22:38', 'docstatus': 0, - 'modified': '2012-04-26 16:58:27', + 'modified': '2012-06-22 18:56:16', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -21,7 +21,7 @@ 'name': '__common__', 'section_style': u'Simple', 'show_in_menu': 0, - 'version': 5 + 'version': 1 }, # These values are common for all DocField @@ -51,6 +51,7 @@ # DocPerm { + 'cancel': 1, 'create': 1, 'doctype': u'DocPerm', 'permlevel': 0, @@ -71,7 +72,14 @@ { 'doctype': u'DocPerm', 'permlevel': 1, - 'role': u'All' + 'role': u'Website Manager' + }, + + # DocPerm + { + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Blogger' }, # DocField @@ -99,26 +107,19 @@ 'fieldname': u'content', 'fieldtype': u'Code', 'label': u'Content', + 'options': u'Markdown', 'permlevel': 0, 'reqd': 0 }, - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'content_html', - 'fieldtype': u'Text', - 'label': u'Content HTML', - 'permlevel': 1 - }, - # DocField { 'doctype': u'DocField', 'fieldname': u'page_name', 'fieldtype': u'Data', + 'hidden': 1, 'label': u'Page Name', - 'permlevel': 0 + 'permlevel': 1 }, # DocField diff --git a/erpnext/website/doctype/blog/blog_page.js b/erpnext/website/doctype/blog/blog_page.js deleted file mode 100644 index 4b283920fab..00000000000 --- a/erpnext/website/doctype/blog/blog_page.js +++ /dev/null @@ -1,83 +0,0 @@ -// 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 . - -// js inside blog page - -pscript['onload_{{ doc.name }}'] = function(wrapper) { - // sidebar - wrapper.recent_list = new wn.ui.Listing({ - parent: $(wrapper).find('.recent-posts'), - no_toolbar: true, - query: 'select name, title, left(content, 100) as content from tabBlog\ - where ifnull(published,0)=1 and name!="{{ doc.name }}" order by creation desc', - hide_refresh: true, - render_row: function(parent, data) { - //console.log(data); - if(data.content && data.content.length==100) data.content += '...'; - parent.innerHTML = repl('%(title)s\ -
%(content)s

', data); - }, - page_length: 5, - }); - wrapper.recent_list.run(); - - wrapper.comment_list = new wn.ui.Listing({ - parent: $(wrapper).find('.blog-comments').get(0), - no_toolbar: true, - query: 'select comment, comment_by_fullname, creation\ - from `tabComment` where comment_doctype="Page"\ - and comment_docname="{{ doc.name }}" order by creation desc', - no_result_message: 'Be the first one to comment', - render_row: function(parent, data) { - data.comment_date = prettyDate(data.creation); - $(parent).html(repl("
\ - %(comment_by_fullname)s | %(comment_date)s:\ -
\ -

%(comment)s


", data)) - }, - hide_refresh: true - }); - wrapper.comment_list.run(); - - // add comment - $(wrapper).find('.layout-main-section').append('
'); - $(wrapper).find('button.add-comment').click(function(){ - d = new wn.widgets.Dialog({ - title: 'Add Comment', - fields: [ - {fieldname:'comment_by_fullname', label:'Your Name', reqd:1, fieldtype:'Data'}, - {fieldname:'comment_by', label:'Email Id', reqd:1, fieldtype:'Data'}, - {fieldname:'comment', label:'Comment', reqd:1, fieldtype:'Text'}, - {fieldname:'post', label:'Post', fieldtype:'Button'} - ] - }); - d.fields_dict.post.input.onclick = function() { - var btn = this; - var args = d.get_values(); - if(!args) return; - args.comment_doctype = 'Page'; - args.comment_docname = '{{ doc.name }}'; - $(btn).set_working(); - $c('webnotes.widgets.form.comments.add_comment', args, function(r) { - $(btn).done_working(); - d.hide(); - wrapper.comment_list.refresh(); - }) - } - d.show(); - }) -} \ No newline at end of file diff --git a/erpnext/website/doctype/blog/template.html b/erpnext/website/doctype/blog/template.html deleted file mode 100644 index 510f1bed5f5..00000000000 --- a/erpnext/website/doctype/blog/template.html +++ /dev/null @@ -1,24 +0,0 @@ -
-
-
-

{{ doc.title }}

-
By {{ doc.full_name }} on {{ doc.updated }}
-
- {{ doc.content_html }} -

Comments

-
-
-
-
-

All Blogs

-

Recent Posts

-
-

Subscribe

-

- - RSS Feed -

-
-
-
-
\ No newline at end of file diff --git a/erpnext/website/page/about/__init__.py b/erpnext/website/doctype/web_cache/__init__.py similarity index 100% rename from erpnext/website/page/about/__init__.py rename to erpnext/website/doctype/web_cache/__init__.py diff --git a/erpnext/website/doctype/web_cache/web_cache.txt b/erpnext/website/doctype/web_cache/web_cache.txt new file mode 100644 index 00000000000..98a48918a7f --- /dev/null +++ b/erpnext/website/doctype/web_cache/web_cache.txt @@ -0,0 +1,99 @@ +# DocType, Web Cache +[ + + # These values are common in all dictionaries + { + 'creation': '2012-06-21 12:01:17', + 'docstatus': 0, + 'modified': '2012-06-21 17:25:52', + 'modified_by': u'Administrator', + 'owner': u'Administrator' + }, + + # These values are common for all DocType + { + 'doctype': 'DocType', + 'document_type': u'System', + 'module': u'Website', + 'name': '__common__', + 'version': 1 + }, + + # These values are common for all DocField + { + 'doctype': u'DocField', + 'name': '__common__', + 'parent': u'Web Cache', + 'parentfield': u'fields', + 'parenttype': u'DocType', + 'permlevel': 0 + }, + + # These values are common for all DocPerm + { + 'doctype': u'DocPerm', + 'name': '__common__', + 'parent': u'Web Cache', + 'parentfield': u'permissions', + 'parenttype': u'DocType', + 'permlevel': 0, + 'read': 1, + 'write': 1 + }, + + # DocType, Web Cache + { + 'doctype': 'DocType', + 'name': u'Web Cache' + }, + + # DocPerm + { + 'create': 0, + 'doctype': u'DocPerm', + 'role': u'All' + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'role': u'Website Manager' + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'role': u'Blogger' + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'doc_type', + 'fieldtype': u'Link', + 'in_filter': 1, + 'label': u'DocType', + 'options': u'DocType', + 'reqd': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'doc_name', + 'fieldtype': u'Data', + 'in_filter': 0, + 'label': u'DocName', + 'reqd': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'html', + 'fieldtype': u'Long Text', + 'label': u'HTML' + } +] \ No newline at end of file diff --git a/erpnext/website/doctype/web_page/template.html b/erpnext/website/doctype/web_page/template.html deleted file mode 100644 index c6d4b407f08..00000000000 --- a/erpnext/website/doctype/web_page/template.html +++ /dev/null @@ -1,30 +0,0 @@ -
-
- - {% if doc.layout and doc.layout.startswith('Two column') %} -
- {% else %} -
- {% endif %} - {{ doc.main_section_html }} - {% if doc.next_page_html %} - {{ doc.next_page_html }} - {% endif %} - -
- - {% if doc.layout and doc.layout.startswith('Two column') %} -
- {{ doc.side_section_html }} - {% if doc.see_also %} -
-

See Also

- {{ doc.see_also }} -
- {% endif %} -
- {% endif %} -
-
-
diff --git a/erpnext/website/doctype/web_page/web_page.py b/erpnext/website/doctype/web_page/web_page.py index 27ce5c053e3..2a3e84ab179 100644 --- a/erpnext/website/doctype/web_page/web_page.py +++ b/erpnext/website/doctype/web_page/web_page.py @@ -16,82 +16,25 @@ import webnotes import website.utils +import website.web_page -class DocType: +class DocType(website.web_page.Page): def __init__(self, d, dl): + super(DocType, self).__init__('Web Page') self.doc, self.doclist = d, dl - - def autoname(self): - """name from title""" - self.doc.name = website.utils.page_name(self.doc.title) def on_update(self): - """make page for this product""" - from jinja2 import Template - from webnotes.utils import global_date_format - from webnotes.model.code import get_obj - import os - - # we need the name for the templates - if self.doc.name.startswith('New Web Page'): - self.autoname() - - if self.doc.page_name: - webnotes.conn.sql("""delete from tabPage where name=%s""", self.doc.page_name) - - p = website.utils.add_page(self.doc.name) - self.doc.page_name = p.name - - self.doc.updated = global_date_format(self.doc.modified) - website.utils.markdown(self.doc, ['head_section','main_section', 'side_section']) - - with open(os.path.join(os.path.dirname(__file__), 'template.html'), 'r') as f: - p.content = Template(f.read()).render(doc=self.doc) - - p.title = self.doc.title - p.web_page = 'Yes' - - if self.doc.insert_code: - p.script = self.doc.javascript - - if self.doc.insert_style: - p.style = self.doc.css - - p.save() - get_obj(doc=p).write_cms_page() - - website.utils.add_guest_access_to_page(p.name) - self.cleanup_temp() - - self.doc.save() - + super(DocType, self).on_update() self.if_home_clear_cache() - - def add_page_links(self): - """add links for next_page and see_also""" - if self.doc.next_page: - self.doc.next_page_html = """
- Next: - %(title)s
""" % {"name":self.doc.next_page, \ - "title": webnotes.conn.get_value("Page", self.doc.next_page, "title")} - self.doc.see_also = '' - for d in self.doclist: - if d.doctype=='Related Page': - tmp = {"page":d.page, "title":webnotes.conn.get_value('Page', d.page, 'title')} - self.doc.see_also += """
%(title)s
""" % tmp - - def cleanup_temp(self): - """cleanup temp fields""" - fl = ['main_section_html', 'side_section_html', 'see_also', \ - 'next_page_html', 'head_section_html', 'updated'] - for f in fl: - if f in self.doc.fields: - del self.doc.fields[f] - def if_home_clear_cache(self): """if home page, clear cache""" if webnotes.conn.get_value("Website Settings", None, "home_page")==self.doc.name: from webnotes.session_cache import clear_cache - clear_cache('Guest') - \ No newline at end of file + clear_cache('Guest') + import website.web_cache + website.web_cache.clear_cache(self.doc.page_name) + website.web_cache.clear_cache('index') + + def prepare_template_args(self): + self.markdown_to_html(['head_section','main_section', 'side_section']) \ No newline at end of file diff --git a/erpnext/website/doctype/web_page/web_page.txt b/erpnext/website/doctype/web_page/web_page.txt index c40caff7de9..a1fd8949f90 100644 --- a/erpnext/website/doctype/web_page/web_page.txt +++ b/erpnext/website/doctype/web_page/web_page.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-04-02 16:02:43', + 'creation': '2012-06-19 15:02:20', 'docstatus': 0, - 'modified': '2012-05-02 15:24:31', + 'modified': '2012-06-22 18:49:02', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -36,13 +36,15 @@ # These values are common for all DocPerm { + 'amend': 0, 'doctype': u'DocPerm', 'name': '__common__', 'parent': u'Web Page', 'parentfield': u'permissions', 'parenttype': u'DocType', 'read': 1, - 'role': u'Website Manager' + 'role': u'Website Manager', + 'submit': 0 }, # DocType, Web Page @@ -53,6 +55,7 @@ # DocPerm { + 'cancel': 1, 'create': 1, 'doctype': u'DocPerm', 'permlevel': 0, @@ -61,8 +64,11 @@ # DocPerm { + 'cancel': 0, + 'create': 0, 'doctype': u'DocPerm', - 'permlevel': 1 + 'permlevel': 1, + 'write': 0 }, # DocField @@ -86,6 +92,17 @@ 'reqd': 1 }, + # DocField + { + 'colour': u'White:FFF', + 'description': u'Page url name (auto-generated) ', + 'doctype': u'DocField', + 'fieldname': u'page_name', + 'fieldtype': u'Data', + 'label': u'Page Name', + 'permlevel': 1 + }, + # DocField { 'doctype': u'DocField', @@ -101,7 +118,7 @@ 'fieldname': u'layout', 'fieldtype': u'Select', 'label': u'Layout', - 'options': u'Two column with header\nTwo column\nSingle column', + 'options': u'Single column\nTwo column\nTwo column with header', 'permlevel': 0 }, @@ -176,6 +193,7 @@ # DocField { 'colour': u'White:FFF', + 'description': u'Add code as <script>', 'doctype': u'DocField', 'fieldname': u'insert_code', 'fieldtype': u'Check', @@ -212,15 +230,6 @@ 'permlevel': 0 }, - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'page_name', - 'fieldtype': u'Data', - 'label': u'Page Name', - 'permlevel': 1 - }, - # DocField { 'doctype': u'DocField', diff --git a/erpnext/website/doctype/website_settings/website_settings.py b/erpnext/website/doctype/website_settings/website_settings.py index 9390e740b8d..eb304d2155b 100644 --- a/erpnext/website/doctype/website_settings/website_settings.py +++ b/erpnext/website/doctype/website_settings/website_settings.py @@ -28,38 +28,17 @@ class DocType: self.validate_domain_list() def on_update(self): - self.rewrite_pages() - - from webnotes.session_cache import clear_cache - clear_cache('Guest') - - def rewrite_pages(self): - """rewrite all web pages""" - import webnotes - from webnotes.model.doclist import DocList - from webnotes.model.code import get_obj - - # rewrite all web pages - for name in webnotes.conn.sql("""select name, modified from `tabWeb Page` - where docstatus=0"""): - DocList('Web Page', name[0]).save() - webnotes.conn.set_value('Web Page', name[0], 'modified', name[1]) - - # rewrite all blog pages - for name in webnotes.conn.sql("""select name, modified from `tabBlog` - where docstatus=0 and ifnull(published,0)=1"""): - DocList('Blog', name[0]).save() - webnotes.conn.set_value('Blog', name[0], 'modified', name[1]) - + # make js and css from webnotes.cms.make import make_web_core make_web_core() - get_obj('Page', 'blog').write_cms_page(force=True) - get_obj('Page', 'Login Page').write_cms_page(force=True) - - webnotes.msgprint('Rebuilt all blogs and pages') - - + # clear web cache + import website.web_cache + website.web_cache.refresh_cache(build=['Blog']) + + from webnotes.session_cache import clear_cache + clear_cache('Guest') + def set_home_page(self): import webnotes diff --git a/erpnext/website/doctype/website_settings/website_settings.txt b/erpnext/website/doctype/website_settings/website_settings.txt index 368f963c24e..3ae0fbe2441 100644 --- a/erpnext/website/doctype/website_settings/website_settings.txt +++ b/erpnext/website/doctype/website_settings/website_settings.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-05-03 18:43:46', + 'creation': '2012-05-21 15:54:09', 'docstatus': 0, - 'modified': '2012-05-21 14:59:25', + 'modified': '2012-07-09 16:20:58', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -18,7 +18,7 @@ 'doctype': 'DocType', 'document_type': u'Other', 'issingle': 1, - 'max_attachments': 1, + 'max_attachments': 10, 'module': u'Website', 'name': '__common__', 'section_style': u'Simple', @@ -180,21 +180,21 @@ # DocField { 'doctype': u'DocField', - 'fieldname': u'file_list', - 'fieldtype': u'Text', - 'hidden': 1, - 'label': u'File List', - 'no_copy': 1, - 'permlevel': 0, - 'print_hide': 1 + 'fieldname': u'misc_section', + 'fieldtype': u'Section Break', + 'label': u'Misc', + 'permlevel': 0 }, # DocField { + 'colour': u'White:FFF', + 'description': u'An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [favicon-generator.org]', 'doctype': u'DocField', - 'fieldname': u'domains', - 'fieldtype': u'Section Break', - 'label': u'Domains', + 'fieldname': u'favicon', + 'fieldtype': u'Select', + 'label': u'FavIcon', + 'options': u'attach_files:', 'permlevel': 0 }, @@ -221,6 +221,18 @@ 'reqd': 0 }, + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'file_list', + 'fieldtype': u'Text', + 'hidden': 1, + 'label': u'File List', + 'no_copy': 1, + 'permlevel': 0, + 'print_hide': 1 + }, + # DocField { 'doctype': u'DocField', diff --git a/erpnext/website/js/topbar.js b/erpnext/website/js/topbar.js deleted file mode 100644 index 88cbe8b035a..00000000000 --- a/erpnext/website/js/topbar.js +++ /dev/null @@ -1,130 +0,0 @@ -// 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 . - -wn.provide('erpnext.navbar'); - -/* -\ -*/ - -erpnext.navbar.Navbar = Class.extend({ - init: function() { - this.make(); - $('.brand').html(wn.boot.website_settings.brand_html || sys_defaults.company); - this.make_items(); - $('.dropdown-toggle').dropdown(); - }, - make: function() { - $('header').append(''); - $('.brand').attr('href', '#!' + (wn.boot.website_settings.home_page || 'Login Page')) - }, - make_items: function() { - var items = wn.boot.website_menus; - - // parent labels - for(var i=0;i\ - %(label)s', item)); - } - } - - // child labels - for(var i=0;i') - .click(function() { - return false; - }); - $parent_li.append(''); - } - erpnext.header_link_settings(item); - $parent_li.find('.dropdown-menu').append(repl('
  • \ - %(label)s
  • ', item)) - } - } - } -}); - -// footer -erpnext.Footer = Class.extend({ - init: function() { - if(!wn.boot.website_settings.copyright) { - wn.boot.website_settings.copyright = sys_defaults.company; - } - if(!wn.boot.website_settings.address) { - wn.boot.website_settings.address = ''; - } - $('footer').html(repl('', wn.boot.website_settings)); - this.make_items(); - }, - make_items: function() { - var items = wn.boot.website_menus - for(var i=0;i%(label)s', item)) - } - } - } -}); - -// customize hard / soft links -erpnext.header_link_settings = function(item) { - item.route = item.url || item.custom_page; - if(item.route && item.route.substr(0,4)=='http') { - item.target = 'target="_blank"'; - } else { - item.target = ''; - item.route = '#!' + item.route; - } -} - -$(document).bind('startup', function() { - erpnext.footer = new erpnext.Footer(); - //erpnext.navbar.navbar = new erpnext.navbar.Navbar(); -}) diff --git a/erpnext/website/page/about/about.txt b/erpnext/website/page/about/about.txt deleted file mode 100644 index a10651308a5..00000000000 --- a/erpnext/website/page/about/about.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Page, about -[ - - # These values are common in all dictionaries - { - 'creation': '2012-01-27 11:37:57', - 'docstatus': 0, - 'modified': '2012-01-27 13:26:42', - 'modified_by': 'Administrator', - 'owner': 'Administrator' - }, - - # These values are common for all Page - { - 'doctype': 'Page', - 'module': 'Website', - 'name': '__common__', - 'page_name': 'about', - 'standard': 'Yes', - 'title': 'About Us' - }, - - # These values are common for all Page Role - { - 'doctype': 'Page Role', - 'name': '__common__', - 'parent': 'about', - 'parentfield': 'roles', - 'parenttype': 'Page', - 'role': 'Guest' - }, - - # Page, about - { - 'doctype': 'Page', - 'name': 'about' - }, - - # Page Role - { - 'doctype': 'Page Role' - } -] \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.html b/erpnext/website/page/blog/blog.html deleted file mode 100644 index 8d7cd00345c..00000000000 --- a/erpnext/website/page/blog/blog.html +++ /dev/null @@ -1,23 +0,0 @@ -
    -
    -
    -

    Blog

    -
    -
    -
    -
    - -

    Subscribe

    -

    - - RSS Feed -

    -
    -
    -
    -
    \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.js b/erpnext/website/page/blog/blog.js deleted file mode 100644 index 5a10998c6f8..00000000000 --- a/erpnext/website/page/blog/blog.js +++ /dev/null @@ -1,59 +0,0 @@ -// 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 . - - -pscript.onload_blog = function(wrapper) { - wrapper.blog_list = new wn.ui.Listing({ - parent: $(wrapper).find('#blog-list').get(0), - query: 'select tabBlog.name, title, left(content, 1000) as content, tabBlog.creation, \ - ifnull(first_name, "") as first_name, ifnull(last_name, "") as last_name \ - from tabProfile, tabBlog\ - where ifnull(published,0)=1 and tabBlog.owner = tabProfile.name \ - order by tabBlog.creation desc', - hide_refresh: true, - no_toolbar: true, - render_row: function(parent, data) { - if(data.content && data.content.length==1000) data.content += '... (read on)'; - data.content = wn.markdown(data.content); - if(data.last_name) data.last_name = ' ' + data.last_name; - data.date = prettyDate(data.creation); - parent.innerHTML = repl('

    %(title)s

    \ -

    By %(first_name)s%(last_name)s, %(date)s

    \ -

    %(content)s

    \ - Read Full Text
    ', data); - }, - page_length: 10 - }); - wrapper.blog_list.run(); - - // subscribe button - $('#blog-subscribe').click(function() { - var email = $(wrapper).find('input[name="blog-subscribe"]').val(); - if(!validate_email(email)) { - msgprint('Please enter a valid email!'); - } - wn.call({ - module:'website', - page:'blog', - method:'subscribe', - args:email, - btn: this, - callback: function() { - $(wrapper).find('input[name="blog-subscribe"]').val(''); - } - }); - }) -} \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.py b/erpnext/website/page/blog/blog.py deleted file mode 100644 index 97901141544..00000000000 --- a/erpnext/website/page/blog/blog.py +++ /dev/null @@ -1,29 +0,0 @@ -# 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 . - -import webnotes - -@webnotes.whitelist() -def subscribe(arg): - """subscribe to blog (blog_subscriber)""" - if webnotes.conn.sql("""select name from `tabBlog Subscriber` where name=%s""", arg): - webnotes.msgprint("Already a subscriber. Thanks!") - else: - from webnotes.model.doc import Document - d = Document('Blog Subscriber') - d.name = arg - d.save() - webnotes.msgprint("Thank you for subscribing!") \ No newline at end of file diff --git a/erpnext/website/page/blog/blog.txt b/erpnext/website/page/blog/blog.txt deleted file mode 100644 index 4443ec813d9..00000000000 --- a/erpnext/website/page/blog/blog.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Page, blog -[ - - # These values are common in all dictionaries - { - 'creation': '2012-01-27 15:47:52', - 'docstatus': 0, - 'modified': '2012-01-27 15:47:52', - 'modified_by': 'Administrator', - 'owner': 'Administrator' - }, - - # These values are common for all Page - { - 'doctype': 'Page', - 'module': 'Website', - 'name': '__common__', - 'page_name': 'blog', - 'standard': 'Yes', - 'title': 'Blog' - }, - - # These values are common for all Page Role - { - '__islocal': 1, - 'doctype': 'Page Role', - 'name': '__common__', - 'parent': 'blog', - 'parentfield': 'roles', - 'parenttype': 'Page', - 'role': 'Guest' - }, - - # Page, blog - { - 'doctype': 'Page', - 'name': 'blog' - }, - - # Page Role - { - 'doctype': 'Page Role' - } -] \ No newline at end of file diff --git a/erpnext/website/page/contact/__init__.py b/erpnext/website/page/contact/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/website/page/contact/contact.js b/erpnext/website/page/contact/contact.js deleted file mode 100644 index c7943256319..00000000000 --- a/erpnext/website/page/contact/contact.js +++ /dev/null @@ -1,46 +0,0 @@ -// 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 . - -pscript.onload_contact = function(wrapper) { - $('#content-contact-us .btn.primary').click(function() { - var me = this; - var args = {}; - args.name = $('#content-contact-us [name="contact-name"]').val(); - args.email = $('#content-contact-us [name="contact-email"]').val(); - args.message = $('#content-contact-us [name="contact-message"]').val(); - - if(!validate_email(args.email)) { - msgprint('Please enter a valid email id'); - return; - } - - if(args.name && args.email && args.message) { - $(this).set_working(); - $c_page('website', 'contact', 'send', args, function(r) { - $('#content-contact-us [name*="contact"]').val(''); - $(me).done_working(); - }); - } else { - msgprint("Please enter info in all the fields.") - } - }); - - $('#content-contact-us :input').keyup(function(ev) { - if(ev.which == 13) { - $('#content-contact-us .btn.primary').click(); - } - }); -} \ No newline at end of file diff --git a/erpnext/website/page/contact/contact.py b/erpnext/website/page/contact/contact.py deleted file mode 100644 index 1ee3ab9efc3..00000000000 --- a/erpnext/website/page/contact/contact.py +++ /dev/null @@ -1,32 +0,0 @@ -# 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 . - -import json, webnotes - -@webnotes.whitelist(allow_guest=True) -def send(args): - """create support ticket""" - args = json.loads(args) - - from webnotes.model.doc import Document - d = Document('Support Ticket') - d.raised_by = args['email'] - d.description = 'From: ' + args['name'] + '\n\n' + args['message'] - d.subject = 'Website Query' - d.status = 'Open' - d.owner = 'Guest' - d.save(1) - webnotes.msgprint("Thank you for your query. We will respond as soon as we can.") \ No newline at end of file diff --git a/erpnext/website/page/contact/contact.txt b/erpnext/website/page/contact/contact.txt deleted file mode 100644 index 6051c6f2c95..00000000000 --- a/erpnext/website/page/contact/contact.txt +++ /dev/null @@ -1,42 +0,0 @@ -# Page, contact -[ - - # These values are common in all dictionaries - { - 'creation': '2012-01-25 16:02:15', - 'docstatus': 0, - 'modified': '2012-01-25 16:02:15', - 'modified_by': 'Administrator', - 'owner': 'Administrator' - }, - - # These values are common for all Page - { - 'doctype': 'Page', - 'module': 'Website', - 'name': '__common__', - 'page_name': 'contact', - 'standard': 'Yes' - }, - - # These values are common for all Page Role - { - 'doctype': 'Page Role', - 'name': '__common__', - 'parent': 'contact', - 'parentfield': 'roles', - 'parenttype': 'Page', - 'role': 'Guest' - }, - - # Page, contact - { - 'doctype': 'Page', - 'name': 'contact' - }, - - # Page Role - { - 'doctype': 'Page Role' - } -] \ No newline at end of file diff --git a/erpnext/website/page/products/README.md b/erpnext/website/page/products/README.md deleted file mode 100644 index e40b44629f1..00000000000 --- a/erpnext/website/page/products/README.md +++ /dev/null @@ -1,27 +0,0 @@ -## Products - -Contains - -- List of Products tagged by Item master - - image - - short description (md) - - pricing info (if public) (public pricelist) - - stock info (website warehouse) -- Search -- Sidebar contains categories (# of items in each category) - -When Item is Saved, a page for that item is created with - -- Large image -- Smaller images -- Long Description -- Pricing info -- Stock info -- Contact Button (instead of Buy / Add to cart) - -### Steps - -- update item master -- update item category (show in web + priority) (or in a products settings page) -- # of public items in each category -- validation - item cannot have show in item if parent does not have it \ No newline at end of file diff --git a/erpnext/website/page/products/__init__.py b/erpnext/website/page/products/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/erpnext/website/page/products/products.html b/erpnext/website/page/products/products.html deleted file mode 100644 index 30eca4a2e13..00000000000 --- a/erpnext/website/page/products/products.html +++ /dev/null @@ -1,14 +0,0 @@ -
    -
    -

    - -
    -
    -
    -

    Categories

    -
    -
    -
    -
    \ No newline at end of file diff --git a/erpnext/website/page/products/products.txt b/erpnext/website/page/products/products.txt deleted file mode 100644 index f00a05b8e84..00000000000 --- a/erpnext/website/page/products/products.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Page, products -[ - - # These values are common in all dictionaries - { - 'creation': '2012-01-30 10:49:01', - 'docstatus': 0, - 'modified': '2012-01-30 10:49:01', - 'modified_by': 'Administrator', - 'owner': 'Administrator' - }, - - # These values are common for all Page - { - 'doctype': 'Page', - 'module': 'Website', - 'name': '__common__', - 'page_name': 'products', - 'standard': 'Yes', - 'title': 'Products' - }, - - # These values are common for all Page Role - { - 'doctype': 'Page Role', - 'name': '__common__', - 'parent': 'products', - 'parentfield': 'roles', - 'parenttype': 'Page', - 'role': 'Guest' - }, - - # Page, products - { - 'doctype': 'Page', - 'name': 'products' - }, - - # Page Role - { - 'doctype': 'Page Role' - } -] \ No newline at end of file diff --git a/erpnext/website/product.py b/erpnext/website/product.py new file mode 100644 index 00000000000..aff15d95f3f --- /dev/null +++ b/erpnext/website/product.py @@ -0,0 +1,116 @@ +import webnotes + +@webnotes.whitelist(allow_guest=True) +def get_product_list(args=None): + """ + args = { + 'limit_start': 0, + 'limit_page_length': 20, + 'search': '', + 'product_group': '', + } + """ + import webnotes + from webnotes.utils import cstr, cint + + if not args: args = webnotes.form_dict + + # base query + query = """\ + select name, item_name, page_name, website_image, + description, web_short_description + from `tabItem` + where is_sales_item = 'Yes' + and docstatus = 0 + and show_in_website = 1""" + + # search term condition + if args.get('search'): + query += """ + and ( + web_short_description like %(search)s or + web_long_description like %(search)s or + description like %(search)s or + item_name like %(search)s or + name like %(search)s + )""" + args['search'] = "%" + cstr(args.get('search')) + "%" + + # product group condition + if args.get('product_group') and args.get('product_group') != 'All Products': + query += """ + and item_group = %(product_group)s""" + + # order by + query += """ + order by item_name asc, name asc""" + + from webnotes.widgets.query_builder import add_limit_to_query + query, args = add_limit_to_query(query, args) + + return webnotes.conn.sql(query, args, as_dict=1) + +@webnotes.whitelist(allow_guest=True) +def get_product_category_list(args=None): + """ + args = { + 'limit_start': 0, + 'limit_page_length': 5, + } + """ + import webnotes + + if not args: args = webnotes.form_dict + + query = """\ + select count(name) as items, item_group + from `tabItem` + where is_sales_item = 'Yes' + and docstatus = 0 + and show_in_website = 1 + group by item_group + order by items desc""" + + from webnotes.widgets.query_builder import add_limit_to_query + query, args = add_limit_to_query(query, args) + + + result = webnotes.conn.sql(query, args, as_dict=1) + + # add All Products link + total_count = sum((r.get('items') or 0 for r in result)) + result = [{'items': total_count, 'item_group': 'All Products'}] + (result or []) + + return result + +@webnotes.whitelist(allow_guest=True) +def get_similar_product_list(args=None): + """ + args = { + 'limit_start': 0, + 'limit_page_length': 5, + 'product_name': '', + 'product_group': '', + } + """ + import webnotes + + if not args: args = webnotes.form_dict + + query = """\ + select name, item_name, page_name, website_image, + description, web_short_description + from `tabItem` + where is_sales_item = 'Yes' + and docstatus = 0 + and show_in_website = 1 + and name != %(product_name)s + and item_group = %(product_group)s + order by item_name""" + + from webnotes.widgets.query_builder import add_limit_to_query + query, args = add_limit_to_query(query, args) + + result = webnotes.conn.sql(query, args, as_dict=1) + + return result \ No newline at end of file diff --git a/erpnext/website/page/blog/__init__.py b/erpnext/website/templates/__init__.py similarity index 100% rename from erpnext/website/page/blog/__init__.py rename to erpnext/website/templates/__init__.py diff --git a/erpnext/website/templates/css/blog.css b/erpnext/website/templates/css/blog.css new file mode 100644 index 00000000000..199df1ac779 --- /dev/null +++ b/erpnext/website/templates/css/blog.css @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/erpnext/website/templates/css/blog_page.css b/erpnext/website/templates/css/blog_page.css new file mode 100644 index 00000000000..928b8acb373 --- /dev/null +++ b/erpnext/website/templates/css/blog_page.css @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/erpnext/website/templates/css/login.css b/erpnext/website/templates/css/login.css new file mode 100644 index 00000000000..4e3e4b122ce --- /dev/null +++ b/erpnext/website/templates/css/login.css @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/erpnext/website/templates/css/product_page.css b/erpnext/website/templates/css/product_page.css new file mode 100644 index 00000000000..2708625cf23 --- /dev/null +++ b/erpnext/website/templates/css/product_page.css @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/erpnext/website/templates/css/products.css b/erpnext/website/templates/css/products.css new file mode 100644 index 00000000000..73289c4e203 --- /dev/null +++ b/erpnext/website/templates/css/products.css @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/erpnext/website/templates/html/base.html b/erpnext/website/templates/html/base.html new file mode 100644 index 00000000000..8639a8f546e --- /dev/null +++ b/erpnext/website/templates/html/base.html @@ -0,0 +1,27 @@ + + + + {% block title %}{% endblock %} + + + + + + + + {% if favicon %} + + + {% else %} + + + {% endif %} + + + {% block header %} + {% endblock %} + + + {% block body %} + {% endblock %} + \ No newline at end of file diff --git a/erpnext/website/templates/html/blog_page.html b/erpnext/website/templates/html/blog_page.html new file mode 100644 index 00000000000..e9c16461748 --- /dev/null +++ b/erpnext/website/templates/html/blog_page.html @@ -0,0 +1,58 @@ +{% extends "html/page.html" %} + +{% block javascript %} + {% include "js/blog_page.js" %} +{% endblock %} + +{% block css %} + {% include "css/blog_page.css" %} +{% endblock %} + +{% block content %} +
    +
    + +
    + +

    {{ title }}

    + + +
    By {{ full_name }} on {{ updated }}
    +
    + {{ content_html }} + + +
    +

    Comments


    +
    + + {% if not comment_list %} +
    +

    Be the first one to comment

    +
    +
    + {% endif %} + + {% include 'html/comment.html' %} + + +
    +
    + +
    +

    All Blogs

    +
    +

    Subscribe

    +

    + + RSS Feed +

    +
    +

    Recent Posts

    +
    +
    + +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/html/comment.html b/erpnext/website/templates/html/comment.html new file mode 100644 index 00000000000..1323e094d22 --- /dev/null +++ b/erpnext/website/templates/html/comment.html @@ -0,0 +1,14 @@ +{# + this template generates comment rows for a blog + it is to be included in the blog/blog.html template +#} + +{% for comment in comment_list %} +
    +
    + {{ comment.comment_by_fullname }} - {{ comment.comment_date }}: +
    +

    {{ comment.comment }}

    +
    +
    +{% endfor %} \ No newline at end of file diff --git a/erpnext/website/templates/html/outer.html b/erpnext/website/templates/html/outer.html new file mode 100644 index 00000000000..47184fa28c9 --- /dev/null +++ b/erpnext/website/templates/html/outer.html @@ -0,0 +1,59 @@ +{# + requires, brand, top_bar_items, footer_items, copyright, content +#} + +{% extends "html/base.html" %} + +{% block body %} + +
    + +
    +
    +
    + {% block content %} + {% endblock %} +
    +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/html/page.html b/erpnext/website/templates/html/page.html new file mode 100644 index 00000000000..e2eb6f48242 --- /dev/null +++ b/erpnext/website/templates/html/page.html @@ -0,0 +1,36 @@ +{% extends "html/outer.html" %} + +{% block title %}{{ title }}{% endblock %} + +{% block header %} + {{ super() }} + + + {% block css %} + {% if insert_style %} + + + + {% endif %} + {% endblock %} +{% endblock %} + +{% block content %} + {{ content }} +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/html/product_page.html b/erpnext/website/templates/html/product_page.html new file mode 100644 index 00000000000..646bba95011 --- /dev/null +++ b/erpnext/website/templates/html/product_page.html @@ -0,0 +1,48 @@ +{% extends "html/page.html" %} + +{% block javascript %} + {% include "js/product_page.js" %} +{% endblock %} + +{% block css %} + {% include "css/product_page.css" %} +{% endblock %} + +{% block title %} + {% if item_name != name %} + {{ item_name }} [{{ name }}] + {% else %} + {{ item_name }} + {% endif %} +{% endblock %} + +{% block content %} +
    +
    +
    +

    {{ item_name }}

    +
    +

    + {% if website_image %} + + {% else %} +
    + This is an auto-generated Image + {% endif %} +

    +
    + {{ web_description_html }} +
    +
    +
    +
    +

    More Categories

    +
    +
    +

    Similar Products

    +
    +
    +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/html/web_page.html b/erpnext/website/templates/html/web_page.html new file mode 100644 index 00000000000..6fa7d27b99b --- /dev/null +++ b/erpnext/website/templates/html/web_page.html @@ -0,0 +1,29 @@ +{% extends "html/page.html" %} + +{% block javascript %} + {% if insert_code %} + {{ javascript }} + {% endif %} +{% endblock %} + +{% block content %} +
    +
    + + {% if layout and layout.startswith('Two column') %} +
    + {% else %} +
    + {% endif %} + {{ main_section_html }} +
    + + {% if layout and layout.startswith('Two column') %} +
    + {{ side_section_html }} +
    + {% endif %} +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/js/product_category.js b/erpnext/website/templates/js/blog.js similarity index 61% rename from erpnext/website/js/product_category.js rename to erpnext/website/templates/js/blog.js index 8d3f8988838..78dd3b774fd 100644 --- a/erpnext/website/js/product_category.js +++ b/erpnext/website/templates/js/blog.js @@ -14,17 +14,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -erpnext.make_product_categories = function(wrapper) { - wrapper.category_list = new wn.ui.Listing({ - parent: $(wrapper).find('.more-categories').get(0), - query: 'select count(name) as items, item_group \ - from tabItem where is_sales_item="Yes" \ - group by item_group order by items desc', +// js inside blog page +wn.pages['{{ name }}'].onload = function(wrapper) { + erpnext.blog_list = new wn.ui.Listing({ + parent: $(wrapper).find('#blog-list').get(0), + method: 'website.blog.get_blog_list', hide_refresh: true, + no_toolbar: true, render_row: function(parent, data) { - parent.innerHTML = repl('%(item_group)s (%(items)s)', - data); - } + if(data.content && data.content.length==1000) { + data.content += repl('... (read on)', data); + } + parent.innerHTML = repl('

    %(title)s

    \ + %(content)s

    ', data); + }, + page_length: 10 }); - wrapper.category_list.run(); -} + erpnext.blog_list.run(); +} \ No newline at end of file diff --git a/erpnext/website/templates/js/blog_page.js b/erpnext/website/templates/js/blog_page.js new file mode 100644 index 00000000000..71216778555 --- /dev/null +++ b/erpnext/website/templates/js/blog_page.js @@ -0,0 +1,180 @@ +// 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 . + +// js inside blog page + +wn.provide('erpnext.blog'); +wn.pages['{{ name }}'].onload = function(wrapper) { + erpnext.blog.wrapper = wrapper; + + // sidebar + erpnext.blog.render_recent_list(wrapper); + + // unhide no-result if no comments found + erpnext.blog.toggle_no_result(wrapper); + + // bind add comment button to comment dialog + erpnext.blog.make_comment_dialog(wrapper); + + // hide add comment button after 50 comments + erpnext.blog.toggle_add_comment_btn(wrapper); +} + +erpnext.blog.adjust_page_height = function(wrapper) { + if (!wrapper) { wrapper = erpnext.blog.wrapper; } + if (!wrapper) { return; } + + // adjust page height based on sidebar height + var $main_page = $(wrapper).find('.layout-main-section'); + var $sidebar = $(wrapper).find('.layout-side-section'); + if ($sidebar.height() > $main_page.height()) { + $main_page.height($sidebar.height()); + } +} + +erpnext.blog.render_recent_list = function(wrapper) { + if (!wrapper) { wrapper = erpnext.blog.wrapper; } + if (!wrapper) { return; } + + wrapper.recent_list = new wn.ui.Listing({ + parent: $(wrapper).find('.recent-posts'), + no_toolbar: true, + method: 'website.blog.get_recent_blog_list', + get_args: function() { + return { name: '{{ name }}' } + }, + hide_refresh: true, + render_row: function(parent, data) { + if(data.content && data.content.length>=100) data.content += '...'; + parent.innerHTML = repl('%(title)s\ +
    %(content)s

    ', data); + + // adjust page height depending on sidebar height + erpnext.blog.adjust_page_height(wrapper); + }, + page_length: 5, + }); + wrapper.recent_list.run(); +} + +erpnext.blog.toggle_no_result = function(wrapper) { + if (!wrapper) { wrapper = erpnext.blog.wrapper; } + if (!wrapper) { return; } + + var $blog_comments = $(wrapper).find('.blog-comments'); + var $comment_rows = $blog_comments.find('.comment-row'); + var $no_result = $blog_comments.find('.no-result'); + + if ($comment_rows.length == 0) { + $no_result.removeClass('hide'); + } else { + $no_result.addClass('hide'); + } +} + +erpnext.blog.make_comment_dialog = function(wrapper) { + if (!wrapper) { wrapper = erpnext.blog.wrapper; } + if (!wrapper) { return; } + + var $comment_btn = $(wrapper).find('button.add-comment'); + + $comment_btn.click(function() { + if(!erpnext.blog.comment_dialog) { + var d = new wn.widgets.Dialog({ + title: 'Add Comment', + fields: [ + { + fieldname: 'comment_by_fullname', label: 'Your Name', + reqd: 1, fieldtype: 'Data' + }, + { + fieldname: 'comment_by', label: 'Email Id', + reqd: 1, fieldtype: 'Data' + }, + { + fieldname: 'comment', label: 'Comment', + reqd: 1, fieldtype: 'Text' + }, + { + fieldname: 'post_comment', label: 'Post Comment', + fieldtype: 'Button' + }, + ], + }); + + erpnext.blog.comment_dialog = d; + } + + erpnext.blog.comment_dialog.fields_dict.post_comment + .input.onclick = function() { + erpnext.blog.add_comment(wrapper); + } + + erpnext.blog.comment_dialog.show(); + }); + +} + +erpnext.blog.add_comment = function(wrapper) { + var args = erpnext.blog.comment_dialog.get_values(); + + if(!args) return; + + args.comment_doctype = 'Blog'; + args.comment_docname = '{{ name }}'; + args.page_name = '{{ page_name }}'; + + wn.call({ + method: 'website.blog.add_comment', + args: args, + btn: this, + callback: function(r) { + if(!r.exc) { + erpnext.blog.add_comment_to_page(wrapper, r.message); + erpnext.blog.comment_dialog.hide(); + } + } + }); +} + +erpnext.blog.add_comment_to_page = function(wrapper, comment) { + $blog_comments = $(wrapper).find('.blog-comments'); + $comment_rows = $blog_comments.find('.comment-row'); + + if ($comment_rows.length) { + $blog_comments.append(comment); + } else { + $blog_comments.append(comment); + } + + erpnext.blog.toggle_no_result(wrapper); + erpnext.blog.toggle_add_comment_btn(wrapper); +} + +erpnext.blog.toggle_add_comment_btn = function(wrapper) { + var $wrapper = $(wrapper); + if ($wrapper.find('.blog-comments .comment-row').length > 50) { + var $comment_btn = $wrapper.find('button.add-comment'); + $comment_btn.addClass('hide'); + + // show comments are close + $wrapper.find('.blog-comments').append("\ +
    \ +

    Comments Closed

    \ +
    \ +
    "); + } +} \ No newline at end of file diff --git a/erpnext/website/templates/js/login.js b/erpnext/website/templates/js/login.js new file mode 100644 index 00000000000..29e49226fcc --- /dev/null +++ b/erpnext/website/templates/js/login.js @@ -0,0 +1,91 @@ +// 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 . + +wn.provide('erpnext.login'); + +wn.pages["{{ name }}"].onload = function(wrapper) { + wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area')); + wrapper.appframe.title('Login'); + wrapper.appframe.$w.find('.close').toggle(false); + + var lw = $i('login_wrapper'); + $bs(lw, '1px 1px 3px #888'); + + $('#login_btn').click(erpnext.login.doLogin) + + $('#password').keypress(function(ev){ + if(ev.which==13 && $('#password').val()) { + $('form').submit(function() { + erpnext.login.doLogin(); + return false; + }); + } + }); + $(document).trigger('login_rendered'); +} + +// Login Callback +erpnext.login.onLoginReply = function(r, rtext) { + $('#login_btn').done_working(); + if(r.message=="Logged In"){ + window.location.href='app.html' + (get_url_arg('page') ? ('?page='+get_url_arg('page')) : ''); + } else { + $i('login_message').innerHTML = ''+(r.message)+''; + //if(r.exc)alert(r.exc); + } +} + + +// Login +erpnext.login.doLogin = function(){ + + var args = {}; + args['usr']=$i("login_id").value; + args['pwd']=$i("password").value; + if($i('remember_me').checked) + args['remember_me'] = 1; + + $('#login_btn').set_working(); + + $c("login", args, erpnext.login.onLoginReply); + + return false; +} + + +erpnext.login.show_forgot_password = function(){ + // create dialog + var d = new wn.ui.Dialog({ + title:"Forgot Password", + fields: [ + {'label':'Email Id', 'fieldname':'email_id', 'fieldtype':'Data', 'reqd':true}, + {'label':'Email Me A New Password', 'fieldname':'run', 'fieldtype':'Button'} + ] + }); + + $(d.fields_dict.run.input).click(function() { + var values = d.get_values(); + if(!values) return; + wn.call({ + method:'reset_password', + args: { user: values.email_id }, + callback: function() { + d.hide(); + } + }) + }) + d.show(); +} \ No newline at end of file diff --git a/erpnext/website/templates/js/product_category.js b/erpnext/website/templates/js/product_category.js new file mode 100644 index 00000000000..4229d00c6c5 --- /dev/null +++ b/erpnext/website/templates/js/product_category.js @@ -0,0 +1,18 @@ +wn.provide('erpnext.products'); + +erpnext.products.make_product_categories = function(wrapper) { + if (!wrapper) { wrapper = erpnext.products.wrapper; } + if (!wrapper) { return; } + + wrapper.category_list = new wn.ui.Listing({ + parent: $(wrapper).find('.more-categories').get(0), + method: 'website.product.get_product_category_list', + hide_refresh: true, + render_row: function(parent, data) { + parent.innerHTML = repl( + '%(item_group)s (%(items)s)', + data); + } + }); + wrapper.category_list.run(); +} \ No newline at end of file diff --git a/erpnext/website/templates/js/product_page.js b/erpnext/website/templates/js/product_page.js new file mode 100644 index 00000000000..0c4abb4195e --- /dev/null +++ b/erpnext/website/templates/js/product_page.js @@ -0,0 +1,92 @@ +// 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 . + +{% include "js/product_category.js" %} + +wn.pages['{{ name }}'].onload = function(wrapper) { + wrapper.product_group = "{{ item_group }}"; + wrapper.product_name = "{{ name }}"; + erpnext.products.make_product_categories(wrapper); + erpnext.products.make_similar_products(wrapper); + + // if website image missing, autogenerate one + var $img = $(wrapper).find('.product-page-content .img-area'); + if ($img && $img.length > 0) { + $img.append(wn.dom.placeholder(160, "{{ item_name }}")); + } + + erpnext.products.adjust_page_height(wrapper); + +} + +erpnext.products.adjust_page_height = function(wrapper) { + if (!wrapper) { wrapper = erpnext.products.wrapper; } + if (!wrapper) { return; } + + // adjust page height based on sidebar height + var $main_page = $(wrapper).find('.layout-main-section'); + var $sidebar = $(wrapper).find('.layout-side-section'); + if ($sidebar.height() > $main_page.height()) { + $main_page.height($sidebar.height()); + } +} + +erpnext.products.make_similar_products = function(wrapper) { + if (!wrapper) { wrapper = erpnext.products.wrapper; } + if (!wrapper) { return; } + + // similar products + wrapper.similar = new wn.ui.Listing({ + parent: $(wrapper).find('.similar-products').get(0), + hide_refresh: true, + page_length: 5, + method: 'website.product.get_similar_product_list', + get_args: function() { + return { + product_group: wrapper.product_group, + product_name: wrapper.product_name + } + }, + render_row: function(parent, data) { + if (!data.web_short_description) { + data.web_short_description = data.description; + } + if(data.web_short_description.length > 100) { + data.web_short_description = + data.web_short_description.substr(0,100) + '...'; + } + parent.innerHTML = repl('\ +
    \ +
    \ +
    %(item_name)s
    \ + %(web_short_description)s\ +
    \ +
    ', data); + + if(data.website_image) { + $(parent).find('.img-area').append(repl( + '', data)) + } else { + $(parent).find('.img-area').append(wn.dom.placeholder(55, + data.item_name)); + } + + // adjust page height, if sidebar height keeps increasing + erpnext.products.adjust_page_height(wrapper); + } + }); + wrapper.similar.run(); +} \ No newline at end of file diff --git a/erpnext/website/page/products/products.js b/erpnext/website/templates/js/products.js similarity index 56% rename from erpnext/website/page/products/products.js rename to erpnext/website/templates/js/products.js index 1e8dcaab039..f4c68cbf80e 100644 --- a/erpnext/website/page/products/products.js +++ b/erpnext/website/templates/js/products.js @@ -14,20 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -erpnext.products = {} +// js inside blog page -wn.require('js/product_category.js'); - -pscript.onload_products = function(wrapper) { - erpnext.make_product_categories(wrapper); - erpnext.products.wrapper = wrapper; +{% include "js/product_category.js" %} +wn.pages['{{ name }}'].onload = function(wrapper) { + erpnext.products.wrapper = wrapper; + + // make product categories in the sidebar + erpnext.products.make_product_categories(wrapper); + // make lists erpnext.products.make_product_list(wrapper); - // button + // bind search button or enter key $(wrapper).find('.products-search .btn').click(function() { - wrapper.mainlist.run(); + erpnext.products.product_list.run(); }); $(wrapper).find('.products-search input').keypress(function(ev) { @@ -35,75 +37,70 @@ pscript.onload_products = function(wrapper) { }); } -pscript.onshow_products = function(wrapper) { - // show default product category - erpnext.products.set_group(); -} - -erpnext.products.get_group = function() { - route = wn.get_route(); - if(route.length>1) { - // from url - var grp = route[1]; - var label = route[1]; - } else { - // default - var grp = wn.boot.website_settings.default_product_category; - var label = wn.boot.website_settings.default_product_category; - } - erpnext.products.cur_group = grp; - return {grp:grp, label:label}; -} - erpnext.products.make_product_list = function(wrapper) { - wrapper.mainlist = new wn.ui.Listing({ - parent: $(wrapper).find('.products-list').get(0), + if (!wrapper) { wrapper = erpnext.products.wrapper; } + if (!wrapper) { return; } + + erpnext.products.product_list = new wn.ui.Listing({ + parent: $(wrapper).find('#products-list').get(0), run_btn: $(wrapper).find('.products-search .btn').get(0), no_toolbar: true, - get_query: function() { - var srch = $('input[name="products-search"]').val() - var search_cond = 'and (description like "%%(srch)s%"\ - or item_name like "%%(srch)s%")'; - args = { - search_cond: srch ? repl(search_cond, {srch:srch}) : '', - cat: erpnext.products.cur_group + method: 'website.product.get_product_list', + get_args: function() { + return { + search: $('input[name="products-search"]').val() || '', + product_group: erpnext.products.cur_group || '', }; - return repl('select name, item_name, website_image, \ - description, page_name \ - from tabItem \ - where is_sales_item="Yes" \ - and item_group="%(cat)s" \ - %(search_cond)s', args) }, render_row: function(parent, data) { - parent.innerHTML = repl('
    \ -
    \ -
    \ -

    %(item_name)s

    \ -

    %(description)s

    \ + if (!data.web_short_description) { + data.web_short_description = data.description; + } + parent.innerHTML = repl('\ +
    \ +
    \ +

    %(item_name)s

    \ +

    %(web_short_description)s

    \
    ', data); if(data.website_image) { $(parent).find('.img-area').append(repl( '', data)) } else { - $(parent).find('.img-area').append(wn.dom.placeholder(70, + $(parent).find('.img-area').append(wn.dom.placeholder(100, data.item_name)); } } }); } +wn.pages['{{ name }}'].onshow = function(wrapper) { + // show default product category + erpnext.products.set_group(); +} + erpnext.products.set_group = function() { var cat = erpnext.products.get_group(); - if(!cat.grp) { - // still nothing - setTimeout('erpnext.products.set_group()', 1000); - return; - } + // get erpnext.products.default_category var wrapper = erpnext.products.wrapper; $(wrapper).find('h1').html(cat.label); - wrapper.mainlist.run(); + erpnext.products.product_list.run(); } + +erpnext.products.get_group = function() { + route = wn.get_route(); + if(route && route.length>1) { + // from url + var grp = route[1]; + var label = route[1]; + erpnext.products.cur_group = grp; + } else { + // default + var grp = 'Products'; + var label = 'Products'; + erpnext.products.cur_group = null; + } + return {grp:grp, label:label}; +} \ No newline at end of file diff --git a/erpnext/website/templates/pages/404.html b/erpnext/website/templates/pages/404.html new file mode 100644 index 00000000000..042360823fb --- /dev/null +++ b/erpnext/website/templates/pages/404.html @@ -0,0 +1,12 @@ +{% extends "html/outer.html" %} + +{% block content %} +
    +
    +

    Page missing or moved

    +
    +

    We are very sorry for this, but the page you are looking for is missing + (this could be because of a typo in the address) or moved.

    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/pages/blog.html b/erpnext/website/templates/pages/blog.html new file mode 100644 index 00000000000..40c90c29a35 --- /dev/null +++ b/erpnext/website/templates/pages/blog.html @@ -0,0 +1,41 @@ +{% extends "html/page.html" %} + +{% block javascript %} + {% include "js/blog.js" %} +{% endblock %} + +{% block css %} + {% include "css/blog.css" %} +{% endblock %} + +{% block title %}Blog{% endblock %} + +{% block content %} +
    +
    + +
    +

    Blog

    +
    +
    + +
    +
    + +
    + +

    Subscribe

    +

    + + RSS Feed +

    +
    +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/pages/index.html b/erpnext/website/templates/pages/index.html new file mode 100644 index 00000000000..1307872d4e0 --- /dev/null +++ b/erpnext/website/templates/pages/index.html @@ -0,0 +1 @@ +{% extends "html/web_page.html" %} \ No newline at end of file diff --git a/erpnext/website/templates/pages/login.html b/erpnext/website/templates/pages/login.html new file mode 100644 index 00000000000..9bc31711288 --- /dev/null +++ b/erpnext/website/templates/pages/login.html @@ -0,0 +1,52 @@ +{% extends "html/page.html" %} + +{% block javascript %} + {% include "js/login.js" %} +{% endblock %} + +{% block css %} + {% include "css/login.css" %} +{% endblock %} + +{% block title %} + Login Page +{% endblock %} + +{% block content %} +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Login Id
    Password
    Remember Me
      
      + +
    +
    +

    Forgot Password

    +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/pages/products.html b/erpnext/website/templates/pages/products.html new file mode 100644 index 00000000000..aa23ea29c41 --- /dev/null +++ b/erpnext/website/templates/pages/products.html @@ -0,0 +1,37 @@ +{% extends "html/page.html" %} + +{% block javascript %} + {% include "js/products.js" %} +{% endblock %} + +{% block css %} + {% include "css/products.css" %} +{% endblock %} + +{% block title %} + Products +{% endblock %} + +{% block content %} +
    +
    + +
    +

    + +
    + +
    +
    + +
    +

    Categories

    +
    +
    +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/utils.py b/erpnext/website/utils.py index 57e940a755f..22fcce741f2 100644 --- a/erpnext/website/utils.py +++ b/erpnext/website/utils.py @@ -17,6 +17,12 @@ import webnotes from webnotes.model.doc import Document +def scrub_page_name(page_name): + if page_name.endswith('.html'): + page_name = page_name[:-5] + + return page_name + def make_template(doc, path, convert_fields = ['main_section', 'side_section']): """make template""" import os, jinja2 @@ -29,119 +35,9 @@ def make_template(doc, path, convert_fields = ['main_section', 'side_section']): return temp.render(doc = doc.fields) -def markdown(doc, fields): - """convert fields to markdown""" - import markdown2 - # markdown - for f in fields: - doc.fields[f + '_html'] = markdown2.markdown(doc.fields[f] or '', \ - extras=["wiki-tables"]) - - def page_name(title): - """make page name from title, and check that there is no duplicate""" - import webnotes.cms - return webnotes.cms.page_name(title) - -def add_page(title): - """add a custom page with title""" - name = page_name(title) - if webnotes.conn.sql("""select name from tabPage where name=%s""", name): - p = Document('Page', name) - else: - p = Document('Page') - - p.title = title - p.name = p.page_name = name - p.module = 'Website' - p.standard = 'No' - - return p - -def add_guest_access_to_page(page): - """add Guest in Page Role""" - if not webnotes.conn.sql("""select parent from `tabPage Role` - where role='Guest' and parent=%s""", page): - d = Document('Page Role') - d.parent = page - d.role = 'Guest' - d.save() - -def get_header(page_name): - """get page header""" - - from webnotes.model.doc import Document - from jinja2 import Template - import webnotes.utils - - def get_item(l, label): - for i in l: - if i['label']==label: - return i - - top_bar_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) - - # build child items - for t in top_bar_items: - if t.get('parent_label'): - pi = get_item(top_bar_items, t['parent_label']) - if 'child_items' not in pi: - pi['child_items'] = [] - pi['child_items'].append(t) - - website_settings = Document('Website Settings', 'Website Settings') - - return Template("""""").render(top_bar_items = top_bar_items, - brand=website_settings.brand_html or webnotes.utils.get_defaults('company') or 'ERPNext') - -def get_footer(page_name): - """get page footer""" - - from webnotes.model.doc import Document - from jinja2 import Template - - website_settings = Document('Website Settings', 'Website Settings') - - website_settings.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) - - return Template("""