Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: sitescripts/cms/converters.py

Issue 6439145228468224: Added custom template loader to CMS in order to enable {% include %} and {% import %} in jinja temp… (Closed)
Patch Set: Adressed comments Created Dec. 12, 2013, 12:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | sitescripts/utils.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # coding: utf-8 1 # coding: utf-8
2 2
3 # This file is part of the Adblock Plus web scripts, 3 # This file is part of the Adblock Plus web scripts,
4 # Copyright (C) 2006-2013 Eyeo GmbH 4 # Copyright (C) 2006-2013 Eyeo GmbH
5 # 5 #
6 # Adblock Plus is free software: you can redistribute it and/or modify 6 # Adblock Plus is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3 as 7 # it under the terms of the GNU General Public License version 3 as
8 # published by the Free Software Foundation. 8 # published by the Free Software Foundation.
9 # 9 #
10 # Adblock Plus is distributed in the hope that it will be useful, 10 # Adblock Plus is distributed in the hope that it will be useful,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 def resolve_include(match): 119 def resolve_include(match):
120 global converters 120 global converters
121 name = match.group(1) 121 name = match.group(1)
122 for format, converter_class in converters.iteritems(): 122 for format, converter_class in converters.iteritems():
123 if self._params["source"].has_include(name, format): 123 if self._params["source"].has_include(name, format):
124 self._params["includedata"] = self._params["source"].read_include(name , format) 124 self._params["includedata"] = self._params["source"].read_include(name , format)
125 converter = converter_class(self._params, key="includedata") 125 converter = converter_class(self._params, key="includedata")
126 return converter() 126 return converter()
127 raise Exception("Failed to resolve include %s in page %s" % (name, self._p arams["page"])) 127 raise Exception("Failed to resolve include %s in page %s" % (name, self._p arams["page"]))
128 128
129 return re.sub(r'<\?\s*include\s+([^\s<>"]+)\s*\?>', resolve_include, text) 129 return re.sub(r'(?:<|\&lt\;)\?\s*include\s+([^\s<>"]+)\s*\?(?:>|\&gt\;)', re solve_include, text)
Wladimir Palant 2013/12/12 12:51:06 Nope, we really don't want to do this in raw HTML
Sebastian Noack 2013/12/12 13:54:39 I agree that we should do that only for markdown.
Wladimir Palant 2013/12/13 14:01:45 The other regexp applied to processing instruction
130 130
131 def __call__(self): 131 def __call__(self):
132 result = self.get_html(self._params[self._key]) 132 result = self.get_html(self._params[self._key])
133 result = self.resolve_includes(result) 133 result = self.resolve_includes(result)
134 if self._key == "pagedata": 134 if self._key == "pagedata":
135 head = [] 135 head = []
136 def add_to_head(match): 136 def add_to_head(match):
137 head.append(match.group(1)) 137 head.append(match.group(1))
138 return "" 138 return ""
139 body = re.sub(r"<head>(.*?)</head>", add_to_head, result, flags=re.S) 139 body = re.sub(r"<head>(.*?)</head>", add_to_head, result, flags=re.S)
(...skipping 25 matching lines...) Expand all
165 md = markdown.Markdown(output="html5", extensions=["attr_list"]) 165 md = markdown.Markdown(output="html5", extensions=["attr_list"])
166 md.preprocessors["html_block"].markdown_in_raw = True 166 md.preprocessors["html_block"].markdown_in_raw = True
167 167
168 result = self.insert_localized_strings(source, escapes) 168 result = self.insert_localized_strings(source, escapes)
169 result = md.convert(result) 169 result = md.convert(result)
170 result = re.sub(r"&#(\d+);", remove_unnecessary_entities, result) 170 result = re.sub(r"&#(\d+);", remove_unnecessary_entities, result)
171 result = self.process_links(result) 171 result = self.process_links(result)
172 return result 172 return result
173 173
174 class TemplateConverter(Converter): 174 class TemplateConverter(Converter):
175 class _SourceLoader(jinja2.BaseLoader):
176 def __init__(self, source):
177 self.source = source
178
179 def get_source(self, environment, template):
180 try:
181 return self.source.read_file(template + ".tmpl"), None, None
182 except Exception:
183 raise jinja2.TemplateNotFound(template)
184
175 def __init__(self, *args, **kwargs): 185 def __init__(self, *args, **kwargs):
176 Converter.__init__(self, *args, **kwargs) 186 Converter.__init__(self, *args, **kwargs)
177 187
178 filters = { 188 filters = {
179 "translate": self.translate, 189 "translate": self.translate,
180 "linkify": self.linkify, 190 "linkify": self.linkify,
181 "toclist": self.toclist, 191 "toclist": self.toclist,
182 } 192 }
183 193
184 for filename in self._params["source"].list_files("filters"): 194 for filename in self._params["source"].list_files("filters"):
185 root, ext = os.path.splitext(filename) 195 root, ext = os.path.splitext(filename)
186 if ext.lower() != ".py": 196 if ext.lower() != ".py":
187 continue 197 continue
188 198
189 path = "%s/%s" % ("filters", filename) 199 path = "%s/%s" % ("filters", filename)
190 code = self._params["source"].read_file(path) 200 code = self._params["source"].read_file(path)
191 module = imp.new_module(root.replace("/", ".")) 201 module = imp.new_module(root.replace("/", "."))
192 exec code in module.__dict__ 202 exec code in module.__dict__
193 203
194 func = os.path.basename(root) 204 func = os.path.basename(root)
195 if not hasattr(module, func): 205 if not hasattr(module, func):
196 raise Exception("Expected function %s not found in filter file %s" % (fu nc, filename)) 206 raise Exception("Expected function %s not found in filter file %s" % (fu nc, filename))
197 filters[func] = getattr(module, func) 207 filters[func] = getattr(module, func)
198 filters[func].module_ref = module # Prevent garbage collection 208 filters[func].module_ref = module # Prevent garbage collection
199 209
200 self._env = get_custom_template_environment(filters) 210 self._env = get_custom_template_environment(filters, self._SourceLoader(self ._params["source"]))
201 211
202 def get_html(self, source): 212 def get_html(self, source):
203 template = self._env.from_string(source) 213 template = self._env.from_string(source)
204 return template.render(self._params) 214 return template.render(self._params)
205 215
206 def translate(self, name, page=None, links=[]): 216 def translate(self, name, page=None, links=[]):
207 if page == None: 217 if page == None:
208 localedata = self._params["localedata"] 218 localedata = self._params["localedata"]
209 else: 219 else:
210 localedata = self._params["source"].read_locale(self._params["locale"], pa ge) 220 localedata = self._params["source"].read_locale(self._params["locale"], pa ge)
(...skipping 26 matching lines...) Expand all
237 stack.pop() 247 stack.pop()
238 stack[-1]["subitems"].append(item) 248 stack[-1]["subitems"].append(item)
239 stack.append(item) 249 stack.append(item)
240 return structured 250 return structured
241 251
242 converters = { 252 converters = {
243 "raw": RawConverter, 253 "raw": RawConverter,
244 "md": MarkdownConverter, 254 "md": MarkdownConverter,
245 "tmpl": TemplateConverter, 255 "tmpl": TemplateConverter,
246 } 256 }
OLDNEW
« no previous file with comments | « no previous file | sitescripts/utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld