blob: cde5217e6166fbc208583186b5f9a2884f2e04bb [file] [log] [blame]
Rushabh Mehta2fa2f712012-09-24 19:13:42 +05301# ERPNext - web based ERP (http://erpnext.com)
2# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17# html generation functions
18
19from __future__ import unicode_literals
20template_map = {
21 'Web Page': 'html/web_page.html',
22 'Blog': 'html/blog_page.html',
23 'Item': 'html/product_page.html',
24}
25
26def get_html(page_name, comments=''):
27 import conf
28
29 html = ''
30
31 # load from cache, if auto cache clear is falsy
32 if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0):
33 html = load_from_cache(page_name)
34
35 if not html:
36 html = load_into_cache(page_name)
37 comments += "\n\npage load status: fresh"
38
39 # insert comments
40 import webnotes.utils
41 html += """\n<!-- %s -->""" % webnotes.utils.cstr(comments)
42
43 return html
44
45def load_from_cache(page_name):
46 import webnotes
47
48 result = search_cache(page_name)
49
50 if not result:
51 if page_name in get_predefined_pages():
52 # if a predefined page doesn't exist, load it into cache
53 return None
54 else:
55 # if page doesn't exist, raise exception
56 raise Exception, "Page %s not found" % page_name
57
58 return result[0][0]
59
60def load_into_cache(page_name):
61 args = prepare_args(page_name)
62
63 html = build_html(args)
64
65 # create cache entry for predefined pages, if not exists
66 if page_name in get_predefined_pages():
67 create_cache(page_name)
68
69 import webnotes
70 webnotes.conn.begin()
71 webnotes.conn.set_value('Web Cache', page_name, 'html', html)
72 webnotes.conn.commit()
73
74 return html
75
76def get_predefined_pages():
77 """
78 gets a list of predefined pages
79 they do not exist in `tabWeb Page`
80 """
81 import os
82 import conf
83 import website.utils
84
85 pages_path = os.path.join(os.path.dirname(conf.__file__), 'app', 'website', 'templates', 'pages')
86
87 page_list = []
88
89 for page in os.listdir(pages_path):
90 page_list.append(website.utils.scrub_page_name(page))
91
92 return page_list
93
94def prepare_args(page_name):
95 import webnotes
96 if page_name == 'index':
97 page_name = get_home_page()
98
99 if page_name in get_predefined_pages():
100 args = {
101 'template': 'pages/%s.html' % page_name,
102 'name': page_name,
103 'webnotes': webnotes
104 }
105 else:
106 args = get_doc_fields(page_name)
107
108 args.update(get_outer_env())
109
110 return args
111
112def get_home_page():
113 import webnotes
114 doc_name = webnotes.conn.get_value('Website Settings', None, 'home_page')
115 if doc_name:
116 page_name = webnotes.conn.get_value('Web Page', doc_name, 'page_name')
117 else:
118 page_name = 'login'
119
120 return page_name
121
122def get_doc_fields(page_name):
123 import webnotes
124 doc_type, doc_name = webnotes.conn.get_value('Web Cache', page_name, ['doc_type', 'doc_name'])
125
126 import webnotes.model.code
127 obj = webnotes.model.code.get_obj(doc_type, doc_name)
128
129 if hasattr(obj, 'prepare_template_args'):
130 obj.prepare_template_args()
131
132 args = obj.doc.fields
133 args['template'] = template_map[doc_type]
134
135 return args
136
137def get_outer_env():
138 """
139 env dict for outer template
140 """
141 import webnotes
142
143 all_top_items = webnotes.conn.sql("""\
144 select * from `tabTop Bar Item`
145 where parent='Website Settings' and parentfield='top_bar_items'
146 order by idx asc""", as_dict=1)
147
148 top_items = [d for d in all_top_items if not d['parent_label']]
149
150 # attach child items to top bar
151 for d in all_top_items:
152 if d['parent_label']:
153 for t in top_items:
154 if t['label']==d['parent_label']:
155 if not 'child_items' in t:
156 t['child_items'] = []
157 t['child_items'].append(d)
158 break
159
160 return {
161 'top_bar_items': top_items,
162
163 'footer_items': webnotes.conn.sql("""\
164 select * from `tabTop Bar Item`
165 where parent='Website Settings' and parentfield='footer_items'
166 order by idx asc""", as_dict=1),
167
168 'brand': webnotes.conn.get_value('Website Settings', None, 'brand_html') or 'ERPNext',
169 'copyright': webnotes.conn.get_value('Website Settings', None, 'copyright'),
170 'favicon': webnotes.conn.get_value('Website Settings', None, 'favicon')
171 }
172
173def build_html(args):
174 """
175 build html using jinja2 templates
176 """
177 import os
178 import conf
179 templates_path = os.path.join(os.path.dirname(conf.__file__), 'app', 'website', 'templates')
180
181 from jinja2 import Environment, FileSystemLoader
182 jenv = Environment(loader = FileSystemLoader(templates_path))
183 html = jenv.get_template(args['template']).render(args)
184 return html
185
186# cache management
187def search_cache(page_name):
188 if not page_name: return ()
189 import webnotes
190 return webnotes.conn.sql("""\
191 select html, doc_type, doc_name
192 from `tabWeb Cache`
193 where name = %s""", page_name)
194
195def create_cache(page_name, doc_type=None, doc_name=None):
196 # check if a record already exists
197 result = search_cache(page_name)
198 if result: return
199
200 # create a Web Cache record
201 import webnotes.model.doc
202 d = webnotes.model.doc.Document('Web Cache')
203 d.name = page_name
204 d.doc_type = doc_type
205 d.doc_name = doc_name
206 d.html = None
207 d.save()
208
209def clear_cache(page_name, doc_type=None, doc_name=None):
210 """
211 * if no page name, clear whole cache
212 * if page_name, doc_type and doc_name match, clear cache's copy
213 * else, raise exception that such a page already exists
214 """
215 import webnotes
216
217 if not page_name:
218 webnotes.conn.sql("""update `tabWeb Cache` set html = ''""")
219 return
220
221 result = search_cache(page_name)
222
223 if not doc_type or (result and result[0][1] == doc_type and result[0][2] == doc_name):
224 webnotes.conn.set_value('Web Cache', page_name, 'html', '')
225 else:
226 webnotes.msgprint("""Page with name "%s" already exists as a %s.
227 Please save it with another name.""" % (page_name, result[0][1]),
228 raise_exception=1)
229
230def delete_cache(page_name):
231 """
232 delete entry of page_name from Web Cache
233 used when:
234 * web page is deleted
235 * blog is un-published
236 """
237 import webnotes
238 webnotes.conn.sql("""delete from `tabWeb Cache` where name=%s""", page_name)
239
240def refresh_cache(build=None):
241 """delete and re-create web cache entries"""
242 import webnotes
243
244 # webnotes.conn.sql("delete from `tabWeb Cache`")
245
246 clear_cache(None)
247
248 query_map = {
249 'Web Page': """select page_name, name from `tabWeb Page` where docstatus=0""",
250 'Blog': """\
251 select page_name, name from `tabBlog`
252 where docstatus = 0 and ifnull(published, 0) = 1""",
253 'Item': """\
254 select page_name, name from `tabItem`
255 where docstatus = 0 and ifnull(show_in_website, 0) = 1""",
256 }
257
258 for dt in query_map:
259 if build and dt in build:
260 for result in webnotes.conn.sql(query_map[dt], as_dict=1):
261 create_cache(result['page_name'], dt, result['name'])
262 load_into_cache(result['page_name'])
263
264 for page_name in get_predefined_pages():
265 create_cache(page_name, None, None)
266 if build: load_into_cache(page_name)