From 10bcf5ea255ec5bc39211100e6717d3c46086ffc Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Jun 2012 18:54:10 +0530 Subject: [PATCH] blog listing + started with products page and listing --- erpnext/patches/june_2012/cms2.py | 6 ++ erpnext/stock/doctype/item/item.py | 101 ++++++++++++------ .../website_settings/website_settings.py | 9 +- erpnext/website/templates/blog-old.html | 58 ---------- .../website/templates/{ => blog}/blog.html | 2 +- erpnext/website/templates/{ => blog}/blog.js | 0 erpnext/website/templates/blog/blog_list.html | 43 ++++++++ erpnext/website/templates/blog/blog_list.js | 48 +++++++++ erpnext/website/templates/page.html | 5 + .../website/templates/product/product.html | 31 ++++++ erpnext/website/templates/product/product.js | 68 ++++++++++++ .../templates/product/product_list.html | 23 ++++ .../website/templates/product/product_list.js | 40 +++++++ erpnext/website/web_cache.py | 24 ++++- erpnext/website/web_page.py | 13 +-- 15 files changed, 364 insertions(+), 107 deletions(-) delete mode 100644 erpnext/website/templates/blog-old.html rename erpnext/website/templates/{ => blog}/blog.html (96%) rename erpnext/website/templates/{ => blog}/blog.js (100%) create mode 100644 erpnext/website/templates/blog/blog_list.html create mode 100644 erpnext/website/templates/blog/blog_list.js create mode 100644 erpnext/website/templates/product/product.html create mode 100644 erpnext/website/templates/product/product.js create mode 100644 erpnext/website/templates/product/product_list.html create mode 100644 erpnext/website/templates/product/product_list.js diff --git a/erpnext/patches/june_2012/cms2.py b/erpnext/patches/june_2012/cms2.py index 88e70496ed..48f0152985 100644 --- a/erpnext/patches/june_2012/cms2.py +++ b/erpnext/patches/june_2012/cms2.py @@ -33,6 +33,12 @@ def save_pages(): select name from `tabBlog` where docstatus = 0 and ifnull(published, 0) = 1""" }, + { + 'doctype': 'Item', + 'query': """\ + select name from `tabItem` + where docstatus = 0 and ifnull(show_in_website, 'No') = 'Yes'""" + } ] for s in save_list: diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index f0fb5e7ecc..85af0bb73e 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.") @@ -79,9 +81,14 @@ 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)) + + import website.web_cache + website.web_cache.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): @@ -163,9 +170,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) @@ -218,35 +225,59 @@ 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': - - import website.utils - - 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 - - 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 + # def make_page(self): + # if self.doc.show_in_website=='Yes': + # + # import website.utils + # + # 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 + # + # 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'] + # + def clear_web_cache(self): + import website.web_cache + + if hasattr(self, 'old_page_name') and self.old_page_name and \ + self.doc.page_name != self.old_page_name: + website.web_cache.delete_web_cache(self.old_page_name) + + if self.doc.show_in_website == 'Yes': + website.web_cache.clear_web_cache(self.doc.doctype, self.doc.name, self.doc.page_name) + else: + website.web_cache.delete_web_cache(self.doc.page_name) + + def update_page_name(self): + import website.utils + self.doc.page_name = website.utils.page_name(self.doc.name + " " + self.doc.item_name) + 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 get_html(self): + import markdown2 + self.doc.web_description_html = markdown2.markdown(self.doc.description or '', + extras=["wiki-tables"]) + + \ No newline at end of file diff --git a/erpnext/website/doctype/website_settings/website_settings.py b/erpnext/website/doctype/website_settings/website_settings.py index 9390e740b8..aec5a39188 100644 --- a/erpnext/website/doctype/website_settings/website_settings.py +++ b/erpnext/website/doctype/website_settings/website_settings.py @@ -54,8 +54,13 @@ class DocType: 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) + import website.web_cache + for page in ['blog', 'products']: + website.web_cache.delete_web_cache(page) + website.web_cache.clear_web_cache(None, None, page) + + #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') diff --git a/erpnext/website/templates/blog-old.html b/erpnext/website/templates/blog-old.html deleted file mode 100644 index d0b9a1362b..0000000000 --- a/erpnext/website/templates/blog-old.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends "outer.html" %} - -{% block title %}{{ title }}{% endblock %} - - -{% block content %} -
-
-
-

Blog

-
-
- -
-
-
- -

Subscribe

-

- - RSS Feed -

-
-
-
-
- - \ No newline at end of file diff --git a/erpnext/website/templates/blog.html b/erpnext/website/templates/blog/blog.html similarity index 96% rename from erpnext/website/templates/blog.html rename to erpnext/website/templates/blog/blog.html index e188edf921..03a2ed7065 100644 --- a/erpnext/website/templates/blog.html +++ b/erpnext/website/templates/blog/blog.html @@ -1,4 +1,4 @@ -{% extends "blog.js" %} +{% extends "blog/blog.js" %} {% block content %}
diff --git a/erpnext/website/templates/blog.js b/erpnext/website/templates/blog/blog.js similarity index 100% rename from erpnext/website/templates/blog.js rename to erpnext/website/templates/blog/blog.js diff --git a/erpnext/website/templates/blog/blog_list.html b/erpnext/website/templates/blog/blog_list.html new file mode 100644 index 0000000000..242f814a9c --- /dev/null +++ b/erpnext/website/templates/blog/blog_list.html @@ -0,0 +1,43 @@ +{% extends "blog/blog_list.js" %} + +{% block title %}Blog{% endblock %} + +{% block css %} + +{% endblock %} + +{% block content %} +
+
+ +
+

Blog

+
+
+ +
+
+ +
+ +

Subscribe

+

+ + RSS Feed +

+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/blog/blog_list.js b/erpnext/website/templates/blog/blog_list.js new file mode 100644 index 0000000000..70628c1540 --- /dev/null +++ b/erpnext/website/templates/blog/blog_list.js @@ -0,0 +1,48 @@ +{% extends "page.html" %} + +{% block javascript %} +// 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.pages['{{ name }}'].onload = function(wrapper) { + erpnext.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 += repl('... (read on)', data); + } + 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


', data) + //Read Full Text
', data); + }, + page_length: 10 + }); + erpnext.blog_list.run(); +} + +{% endblock %} diff --git a/erpnext/website/templates/page.html b/erpnext/website/templates/page.html index a8e20f67f2..c6e0715232 100644 --- a/erpnext/website/templates/page.html +++ b/erpnext/website/templates/page.html @@ -24,9 +24,14 @@ }); {% endif %} + + {% block css %} {% if insert_style %} + + {% endif %} + {% endblock %} {% endblock %} {% block content %} diff --git a/erpnext/website/templates/product/product.html b/erpnext/website/templates/product/product.html new file mode 100644 index 0000000000..5a04e79d6b --- /dev/null +++ b/erpnext/website/templates/product/product.html @@ -0,0 +1,31 @@ +{% extends "product/product.js" %} + +{% block title %}{{ item_name }} [{{ name }}]{% endblock %} + +{% block content %} +
+
+
+

{{ item_name }}

+
+

+ +

+ {{ web_description_html }} + +
+
+
+

More Categories

+
+
+

Similar Products

+
+
+
+
+
+{% endblock %} diff --git a/erpnext/website/templates/product/product.js b/erpnext/website/templates/product/product.js new file mode 100644 index 0000000000..ee73e7f1ae --- /dev/null +++ b/erpnext/website/templates/product/product.js @@ -0,0 +1,68 @@ +{% extends "page.html" %} + +{% block javascript %} +// 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('js/product_category.js'); + +wn.pages['{{ name }}'].onload = function(wrapper) { + console.log('loaded page'); + wrapper.product_group = "{{ item_group }}"; + wrapper.product_name = "{{ 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 {{ item_name }} (Item Code:{{ name }})\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 name, item_name, website_image, \ + page_name, description \ + from tabItem \ + and ifnull(show_in_website, "No")="Yes" \ + and name != "%(name)s" \ + and item_group="%(cat)s" order by 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('
\ +
\ +
\ + %(item_name)s\ +

%(description)s

\ +
', data); + } + }); + wrapper.similar.run(); +} + +{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/product/product_list.html b/erpnext/website/templates/product/product_list.html new file mode 100644 index 0000000000..416a2fe702 --- /dev/null +++ b/erpnext/website/templates/product/product_list.html @@ -0,0 +1,23 @@ +{% extends "product/product_list.js" %} + +{% block title %}Products{% endblock %} + +{% block content %} +
+
+ +
+

+
+ +
+
+ +
+

Categories

+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/erpnext/website/templates/product/product_list.js b/erpnext/website/templates/product/product_list.js new file mode 100644 index 0000000000..82c788687d --- /dev/null +++ b/erpnext/website/templates/product/product_list.js @@ -0,0 +1,40 @@ +{% extends "page.html" %} + +{% block javascript %} +// 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.pages['{{ name }}'].onload = function(wrapper) { + erpnext.product_list = new wn.ui.Listing({ + parent: $(wrapper).find('#product-list').get(0), + query: "select name, item_code, item_name, description, page_name \ + from `tabItem` \ + where docstatus = 0 and ifnull(show_in_website, 'No')='Yes'\ + order by item_name asc", + hide_refresh: true, + no_toolbar: true, + render_row: function(parent, data) { + if(data.description && data.description.length==1000) data.description += '... (read on)'; + parent.innerHTML = repl('

%(item_name)s

\ +

%(description)s

', data); + }, + page_length: 10 + }); + erpnext.product_list.run(); +} + +{% endblock %} diff --git a/erpnext/website/web_cache.py b/erpnext/website/web_cache.py index 30e3f0015d..c9f196dc5e 100644 --- a/erpnext/website/web_cache.py +++ b/erpnext/website/web_cache.py @@ -32,7 +32,7 @@ def load_from_web_cache(page_name, comments, template): where name = %s""", page_name) # if page doesn't exist, raise exception - if not res and page_name not in ['404', 'index']: + if not res and page_name not in ['404', 'index', 'blog', 'products']: raise Exception, "Page %s not found" % page_name html, doc_type, doc_name = res and res[0] or (None, None, None) @@ -52,23 +52,37 @@ def load_into_web_cache(page_name, template, doc_type, doc_name): import webnotes outer_env_dict = get_outer_env() - if page_name == '404': + if page_name in ['404', 'blog', 'products']: args = outer_env_dict + args.update({ + 'name': page_name, + }) else: if page_name == 'index': page_name, doc_type, doc_name = get_index_page() from webnotes.model.code import get_obj obj = get_obj(doc_type, doc_name) - obj.get_html() + if hasattr(obj, 'get_html'): + obj.get_html() args = obj.doc.fields args.update(outer_env_dict) + # decide template and update args if doc_type == 'Blog': - template = 'blog.html' - args['insert_code'] = 1 + template = 'blog/blog.html' + args.update({ 'insert_code': 1 }) + elif doc_type == 'Item': + template = 'product/product.html' + args.update({ 'insert_code': 1 }) elif doc_type == 'Web Page': template = 'web_page.html' + elif page_name == 'blog': + template = 'blog/blog_list.html' + args.update({ 'insert_code': 1 }) + elif page_name == 'products': + template = 'product/product_list.html' + args.update({ 'insert_code': 1 }) html = build_html(args, template) diff --git a/erpnext/website/web_page.py b/erpnext/website/web_page.py index 4d6f9f0b6b..58ff40b868 100644 --- a/erpnext/website/web_page.py +++ b/erpnext/website/web_page.py @@ -29,18 +29,14 @@ class Page(object): def validate(self): if self.doc.name: self.old_page_name = webnotes.conn.get_value(self.doctype, self.doc.name, 'page_name') - + def on_update(self): # page name updates with the title self.update_page_name() - # delete web cache entry of old name - if hasattr(self, 'old_page_name') and self.old_page_name != self.doc.page_name: - self.delete_web_cache(self.old_page_name) - self.clear_web_cache() - self.doc.save(ignore_fields=1) + self.doc.save() def on_trash(self): """delete Web Cache entry""" @@ -63,6 +59,11 @@ class Page(object): if web cache entry doesn't exist, it creates one if duplicate entry exists for another doctype, it raises exception """ + # delete web cache entry of old name + if hasattr(self, 'old_page_name') and self.old_page_name and \ + self.old_page_name != self.doc.page_name: + self.delete_web_cache(self.old_page_name) + website.web_cache.clear_web_cache(self.doctype, self.doc.name, self.doc.page_name) def delete_web_cache(self, page_name):