def parse(self, parser): lineno = next(parser.stream).lineno node = nodes.Extends(lineno) template_path = parser.filename # find where in the search path this template is from index = 0 if not hasattr(self, 'searchpath'): return node for searchpath in self.searchpath: if template_path.startswith(searchpath): break index += 1 # get filename from full path filename = template_path[len(searchpath) + 1:] # Providing template path violently deprecated if parser.stream.current.type != 'block_end': provided_template = parser.parse_expression().value if provided_template != filename: raise Exception('ckan_extends tag wrong path %s in %s' % (provided_template, template_path)) else: log.critical('Remove path from ckan_extend tag in %s' % template_path) # provide our magic format # format is *<search path parent index>*<template name> magic_filename = '*' + str(index) + '*' + filename # set template node.template = nodes.Const(magic_filename) return node
def parse(self, parser): lineno = next(parser.stream).lineno template = None block_name = self.environment.default_layout_block if not parser.stream.current.test("block_end"): template = parser.parse_expression() if parser.stream.skip_if("comma"): block_name = parser.parse_expression().name if not template: template = nodes.Const(self.environment.default_layout) parser.stream.skip_if('comma') parser.stream.expect('block_end') # parse remaining tokens until EOF body = parser.subparse() # the parser expects a TOKEN_END_BLOCK after an # extension. fake this token and set the token # stream iterator with a single EOF token parser.stream.current = lexer.Token(1, lexer.TOKEN_BLOCK_END, "%}") parser.stream._iter = iter([lexer.Token(1, lexer.TOKEN_EOF, "")]) blocks = [] wrap_block = True wrap_nodes = [] default_block = None # extracts blocks node out of the body for node in body: if isinstance(node, nodes.Block): if node.name == block_name: wrap_block = False default_block = node blocks.append(node) else: wrap_nodes.append(node) if wrap_block and wrap_nodes: # wrap nodes which were not wrapped in a block node default_block = nodes.Block(block_name, wrap_nodes, False, lineno=lineno) blocks.append(default_block) if self.environment.disable_layout: return default_block return [nodes.Extends(template, lineno=lineno)] + blocks
def parse(self, parser): token = next(parser.stream) lineno = token.lineno meta = parser.parse_statements(['name:endmeta'], drop_needle=True) try: config = meta[0].nodes[0].data except IndexError: config = '' # there was no data args = [nodes.Name('entry', 'load'), nodes.Const(config)] output = [ nodes.CallBlock(self.call_method('_update_entry', args=args), [], [], '').set_lineno(lineno), nodes.Extends(self.call_method('_determine_parent', args=args[:1])) ] return output
def parse(self, parser): lineno = next(parser.stream).lineno node = nodes.Extends(lineno) template_file = parser.filename template_path = parser.filename # We need to have a list of template paths to look for if not hasattr(self, "searchpath"): return node # First we remove the templates path from the file # so to have the just the template file or a template file in a subdirectory of templates for searchpath in self.searchpath: template_file = template_file.replace(searchpath, "") # Here we get the template path of the file template_path = template_path.replace(template_file, "") # Find the position of the template's path in the list of paths index = -1 try: index = self.searchpath.index(template_path) except: pass if index == -1: return node # index is the position of the this template's path # so we search down stream for the template in other paths file_to_extend = "" for pos in range(index + 1, len(self.searchpath)): if os.path.exists(self.searchpath[pos] + template_file): file_to_extend = self.searchpath[pos] + template_file break # If the file to extend from exits then set it as a template if file_to_extend == "": return node else: node.template = nodes.Const(file_to_extend) return node
def parse_extends(self): node = nodes.Extends(lineno=next(self.stream).lineno) node.template = self.parse_expression() return node
def test_complex(): title_block = nodes.Block( "title", [nodes.Output([nodes.TemplateData(u"Page Title")])], False) render_title_macro = nodes.Macro( "render_title", [nodes.Name("title", "param")], [], [ nodes.Output([ nodes.TemplateData(u'\n <div class="title">\n <h1>'), nodes.Name("title", "load"), nodes.TemplateData(u"</h1>\n <p>"), nodes.Name("subtitle", "load"), nodes.TemplateData(u"</p>\n "), ]), nodes.Assign(nodes.Name("subtitle", "store"), nodes.Const("something else")), nodes.Output([ nodes.TemplateData(u"\n <p>"), nodes.Name("subtitle", "load"), nodes.TemplateData(u"</p>\n </div>\n"), nodes.If( nodes.Name("something", "load"), [ nodes.Assign( nodes.Name("title_upper", "store"), nodes.Filter( nodes.Name("title", "load"), "upper", [], [], None, None, ), ), nodes.Output([ nodes.Name("title_upper", "load"), nodes.Call( nodes.Name("render_title", "load"), [nodes.Const("Aha")], [], None, None, ), ]), ], [], [], ), ]), ], ) for_loop = nodes.For( nodes.Name("item", "store"), nodes.Name("seq", "load"), [ nodes.Output([ nodes.TemplateData(u"\n <li>"), nodes.Name("item", "load"), nodes.TemplateData(u"</li>\n <span>"), ]), nodes.Include(nodes.Const("helper.html"), True, False), nodes.Output([nodes.TemplateData(u"</span>\n ")]), ], [], None, False, ) body_block = nodes.Block( "body", [ nodes.Output([ nodes.TemplateData(u"\n "), nodes.Call( nodes.Name("render_title", "load"), [nodes.Name("item", "load")], [], None, None, ), nodes.TemplateData(u"\n <ul>\n "), ]), for_loop, nodes.Output([nodes.TemplateData(u"\n </ul>\n")]), ], False, ) tmpl = nodes.Template([ nodes.Extends(nodes.Const("layout.html")), title_block, render_title_macro, body_block, ]) tmpl_sym = symbols_for_node(tmpl) assert tmpl_sym.refs == { "render_title": "l_0_render_title", } assert tmpl_sym.loads == { "l_0_render_title": ("undefined", None), } assert tmpl_sym.stores == set(["render_title"]) assert tmpl_sym.dump_stores() == { "render_title": "l_0_render_title", } macro_sym = symbols_for_node(render_title_macro, tmpl_sym) assert macro_sym.refs == { "subtitle": "l_1_subtitle", "something": "l_1_something", "title": "l_1_title", "title_upper": "l_1_title_upper", } assert macro_sym.loads == { "l_1_subtitle": ("resolve", "subtitle"), "l_1_something": ("resolve", "something"), "l_1_title": ("param", None), "l_1_title_upper": ("resolve", "title_upper"), } assert macro_sym.stores == set(["title", "title_upper", "subtitle"]) assert macro_sym.find_ref("render_title") == "l_0_render_title" assert macro_sym.dump_stores() == { "title": "l_1_title", "title_upper": "l_1_title_upper", "subtitle": "l_1_subtitle", "render_title": "l_0_render_title", } body_sym = symbols_for_node(body_block) assert body_sym.refs == { "item": "l_0_item", "seq": "l_0_seq", "render_title": "l_0_render_title", } assert body_sym.loads == { "l_0_item": ("resolve", "item"), "l_0_seq": ("resolve", "seq"), "l_0_render_title": ("resolve", "render_title"), } assert body_sym.stores == set([]) for_sym = symbols_for_node(for_loop, body_sym) assert for_sym.refs == { "item": "l_1_item", } assert for_sym.loads == { "l_1_item": ("param", None), } assert for_sym.stores == set(["item"]) assert for_sym.dump_stores() == { "item": "l_1_item", }
def test_complex(): title_block = nodes.Block('title', [ nodes.Output([nodes.TemplateData(u'Page Title')]) ], False) render_title_macro = nodes.Macro('render_title', [nodes.Name('title', 'param')], [], [ nodes.Output([ nodes.TemplateData(u'\n <div class="title">\n <h1>'), nodes.Name('title', 'load'), nodes.TemplateData(u'</h1>\n <p>'), nodes.Name('subtitle', 'load'), nodes.TemplateData(u'</p>\n ')]), nodes.Assign( nodes.Name('subtitle', 'store'), nodes.Const('something else')), nodes.Output([ nodes.TemplateData(u'\n <p>'), nodes.Name('subtitle', 'load'), nodes.TemplateData(u'</p>\n </div>\n'), nodes.If( nodes.Name('something', 'load'), [ nodes.Assign(nodes.Name('title_upper', 'store'), nodes.Filter(nodes.Name('title', 'load'), 'upper', [], [], None, None)), nodes.Output([ nodes.Name('title_upper', 'load'), nodes.Call(nodes.Name('render_title', 'load'), [ nodes.Const('Aha')], [], None, None)])], [])])]) for_loop = nodes.For( nodes.Name('item', 'store'), nodes.Name('seq', 'load'), [ nodes.Output([ nodes.TemplateData(u'\n <li>'), nodes.Name('item', 'load'), nodes.TemplateData(u'</li>\n <span>')]), nodes.Include(nodes.Const('helper.html'), True, False), nodes.Output([ nodes.TemplateData(u'</span>\n ')])], [], None, False) body_block = nodes.Block('body', [ nodes.Output([ nodes.TemplateData(u'\n '), nodes.Call(nodes.Name('render_title', 'load'), [ nodes.Name('item', 'load')], [], None, None), nodes.TemplateData(u'\n <ul>\n ')]), for_loop, nodes.Output([nodes.TemplateData(u'\n </ul>\n')])], False) tmpl = nodes.Template([ nodes.Extends(nodes.Const('layout.html')), title_block, render_title_macro, body_block, ]) tmpl_sym = symbols_for_node(tmpl) assert tmpl_sym.refs == { 'render_title': 'l_0_render_title', } assert tmpl_sym.loads == { 'l_0_render_title': ('undefined', None), } assert tmpl_sym.stores == set(['render_title']) assert tmpl_sym.dump_stores() == { 'render_title': 'l_0_render_title', } macro_sym = symbols_for_node(render_title_macro, tmpl_sym) assert macro_sym.refs == { 'subtitle': 'l_1_subtitle', 'something': 'l_1_something', 'title': 'l_1_title', 'title_upper': 'l_1_title_upper', } assert macro_sym.loads == { 'l_1_subtitle': ('resolve', 'subtitle'), 'l_1_something': ('resolve','something'), 'l_1_title': ('param', None), 'l_1_title_upper': ('resolve', 'title_upper'), } assert macro_sym.stores == set(['title', 'title_upper', 'subtitle']) assert macro_sym.find_ref('render_title') == 'l_0_render_title' assert macro_sym.dump_stores() == { 'title': 'l_1_title', 'title_upper': 'l_1_title_upper', 'subtitle': 'l_1_subtitle', 'render_title': 'l_0_render_title', } body_sym = symbols_for_node(body_block) assert body_sym.refs == { 'item': 'l_0_item', 'seq': 'l_0_seq', 'render_title': 'l_0_render_title', } assert body_sym.loads == { 'l_0_item': ('resolve', 'item'), 'l_0_seq': ('resolve', 'seq'), 'l_0_render_title': ('resolve', 'render_title'), } assert body_sym.stores == set([]) for_sym = symbols_for_node(for_loop, body_sym) assert for_sym.refs == { 'item': 'l_1_item', } assert for_sym.loads == { 'l_1_item': ('param', None), } assert for_sym.stores == set(['item']) assert for_sym.dump_stores() == { 'item': 'l_1_item', }