<s> from collections import defaultdict <EOL> from django . conf import settings <EOL> from django . template . base import TemplateSyntaxError , Library , Node , TextNode , token_kwargs , Variable <EOL> from django . template . loader import get_template <EOL> from django . utils . safestring import mark_safe <EOL> from django . utils import six <EOL> register = Library ( ) <EOL> BLOCK_CONTEXT_KEY = '<STR_LIT>' <EOL> class ExtendsError ( Exception ) : <EOL> pass <EOL> class BlockContext ( object ) : <EOL> def __init__ ( self ) : <EOL> self . blocks = defaultdict ( list ) <EOL> def add_blocks ( self , blocks ) : <EOL> for name , block in six . iteritems ( blocks ) : <EOL> self . blocks [ name ] . insert ( <NUM_LIT:0> , block ) <EOL> def pop ( self , name ) : <EOL> try : <EOL> return self . blocks [ name ] . pop ( ) <EOL> except IndexError : <EOL> return None <EOL> def push ( self , name , block ) : <EOL> self . blocks [ name ] . append ( block ) <EOL> def get_block ( self , name ) : <EOL> try : <EOL> return self . blocks [ name ] [ - <NUM_LIT:1> ] <EOL> except IndexError : <EOL> return None <EOL> class BlockNode ( Node ) : <EOL> def __init__ ( self , name , nodelist , parent = None ) : <EOL> self . name , self . nodelist , self . parent = name , nodelist , parent <EOL> def __repr__ ( self ) : <EOL> return "<STR_LIT>" % ( self . name , self . nodelist ) <EOL> def render ( self , context ) : <EOL> block_context = context . render_context . get ( BLOCK_CONTEXT_KEY ) <EOL> context . push ( ) <EOL> if block_context is None : <EOL> context [ '<STR_LIT>' ] = self <EOL> result = self . nodelist . render ( context ) <EOL> else : <EOL> push = block = block_context . pop ( self . name ) <EOL> if block is None : <EOL> block = self <EOL> block = BlockNode ( block . name , block . nodelist ) <EOL> block . context = context <EOL> context [ '<STR_LIT>' ] = block <EOL> result = block . nodelist . render ( context ) <EOL> if push is not None : <EOL> block_context . push ( self . name , push ) <EOL> context . pop ( ) <EOL> return result <EOL> def super ( self ) : <EOL> render_context = self . context . render_context <EOL> if ( BLOCK_CONTEXT_KEY in render_context and <EOL> render_context [ BLOCK_CONTEXT_KEY ] . get_block ( self . name ) is not None ) : <EOL> return mark_safe ( self . render ( self . context ) ) <EOL> return '<STR_LIT>' <EOL> class ExtendsNode ( Node ) : <EOL> must_be_first = True <EOL> def __init__ ( self , nodelist , parent_name , template_dirs = None ) : <EOL> self . nodelist = nodelist <EOL> self . parent_name = parent_name <EOL> self . template_dirs = template_dirs <EOL> self . blocks = dict ( [ ( n . name , n ) for n in nodelist . get_nodes_by_type ( BlockNode ) ] ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % self . parent_name . token <EOL> def get_parent ( self , context ) : <EOL> parent = self . parent_name . resolve ( context ) <EOL> if not parent : <EOL> error_msg = "<STR_LIT>" % parent <EOL> if self . parent_name . filters or isinstance ( self . parent_name . var , Variable ) : <EOL> error_msg += "<STR_LIT>" % self . parent_name . token <EOL> raise TemplateSyntaxError ( error_msg ) <EOL> if hasattr ( parent , '<STR_LIT>' ) : <EOL> return parent <EOL> return get_template ( parent ) <EOL> def render ( self , context ) : <EOL> compiled_parent = self . get_parent ( context ) <EOL> if BLOCK_CONTEXT_KEY not in context . render_context : <EOL> context . render_context [ BLOCK_CONTEXT_KEY ] = BlockContext ( ) <EOL> block_context = context . render_context [ BLOCK_CONTEXT_KEY ] <EOL> block_context . add_blocks ( self . blocks ) <EOL> for node in compiled_parent . nodelist : <EOL> if not isinstance ( node , TextNode ) : <EOL> if not isinstance ( node , ExtendsNode ) : <EOL> blocks = dict ( [ ( n . name , n ) for n in <EOL> compiled_parent . nodelist . get_nodes_by_type ( BlockNode ) ] ) <EOL> block_context . add_blocks ( blocks ) <EOL> break <EOL> return compiled_parent . _render ( context ) <EOL> class BaseIncludeNode ( Node ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . extra_context = kwargs . pop ( '<STR_LIT>' , { } ) <EOL> self . isolated_context = kwargs . pop ( '<STR_LIT>' , False ) <EOL> super ( BaseIncludeNode , self ) . __init__ ( * args , ** kwargs ) <EOL> def render_template ( self , template , context ) : <EOL> values = dict ( [ ( name , var . resolve ( context ) ) for name , var <EOL> in six . iteritems ( self . extra_context ) ] ) <EOL> if self . isolated_context : <EOL> return template . render ( context . new ( values ) ) <EOL> context . update ( values ) <EOL> output = template . render ( context ) <EOL> context . pop ( ) <EOL> return output <EOL> class ConstantIncludeNode ( BaseIncludeNode ) : <EOL> def __init__ ( self , template_path , * args , ** kwargs ) : <EOL> super ( ConstantIncludeNode , self ) . __init__ ( * args , ** kwargs ) <EOL> try : <EOL> t = get_template ( template_path ) <EOL> self . template = t <EOL> except : <EOL> if settings . TEMPLATE_DEBUG : <EOL> raise <EOL> self . template = None <EOL> def render ( self , context ) : <EOL> if not self . template : <EOL> return '<STR_LIT>' <EOL> return self . render_template ( self . template , context ) <EOL> class IncludeNode ( BaseIncludeNode ) : <EOL> def __init__ ( self , template_name , * args , ** kwargs ) : <EOL> super ( IncludeNode , self ) . __init__ ( * args , ** kwargs ) <EOL> self . template_name = template_name <EOL> def render ( self , context ) : <EOL> try : <EOL> template_name = self . template_name . resolve ( context ) <EOL> template = get_template ( template_name ) <EOL> return self . render_template ( template , context ) <EOL> except : <EOL> if settings . TEMPLATE_DEBUG : <EOL> raise <EOL> return '<STR_LIT>' <EOL> @ register . tag ( '<STR_LIT>' ) <EOL> def do_block ( parser , token ) : <EOL> """<STR_LIT>""" <EOL> bits = token . contents . split ( ) <EOL> if len ( bits ) != <NUM_LIT:2> : <EOL> raise TemplateSyntaxError ( "<STR_LIT>" % bits [ <NUM_LIT:0> ] ) <EOL> block_name = bits [ <NUM_LIT:1> ] <EOL> try : <EOL> if block_name in parser . __loaded_blocks : <EOL> raise TemplateSyntaxError ( "<STR_LIT>" % ( bits [ <NUM_LIT:0> ] , block_name ) ) <EOL> parser . __loaded_blocks . append ( block_name ) <EOL> except AttributeError : <EOL> parser . __loaded_blocks = [ block_name ] <EOL> nodelist = parser . parse ( ( '<STR_LIT>' , ) ) <EOL> endblock = parser . next_token ( ) <EOL> acceptable_endblocks = ( '<STR_LIT>' , '<STR_LIT>' % block_name ) <EOL> if endblock . contents not in acceptable_endblocks : <EOL> parser . invalid_block_tag ( endblock , '<STR_LIT>' , acceptable_endblocks ) <EOL> return BlockNode ( block_name , nodelist ) <EOL> @ register . tag ( '<STR_LIT>' ) <EOL> def do_extends ( parser , token ) : <EOL> """<STR_LIT>""" <EOL> bits = token . split_contents ( ) <EOL> if len ( bits ) != <NUM_LIT:2> : <EOL> raise TemplateSyntaxError ( "<STR_LIT>" % bits [ <NUM_LIT:0> ] ) <EOL> parent_name = parser . compile_filter ( bits [ <NUM_LIT:1> ] ) <EOL> nodelist = parser . parse ( ) <EOL> if nodelist . get_nodes_by_type ( ExtendsNode ) : <EOL> raise TemplateSyntaxError ( "<STR_LIT>" % bits [ <NUM_LIT:0> ] ) <EOL> return ExtendsNode ( nodelist , parent_name ) <EOL> @ register . tag ( '<STR_LIT>' ) <EOL> def do_include ( parser , token ) : <EOL> """<STR_LIT>""" <EOL> bits = token . split_contents ( ) <EOL> if len ( bits ) < <NUM_LIT:2> : <EOL> raise TemplateSyntaxError ( "<STR_LIT>" % bits [ <NUM_LIT:0> ] ) <EOL> options = { } <EOL> remaining_bits = bits [ <NUM_LIT:2> : ] <EOL> while remaining_bits : <EOL> option = remaining_bits . pop ( <NUM_LIT:0> ) <EOL> if option in options : <EOL> raise TemplateSyntaxError ( '<STR_LIT>' <EOL> '<STR_LIT>' % option ) <EOL> if option == '<STR_LIT>' : <EOL> value = token_kwargs ( remaining_bits , parser , support_legacy = False ) <EOL> if not value : <EOL> raise TemplateSyntaxError ( '<STR_LIT>' <EOL> '<STR_LIT>' % bits [ <NUM_LIT:0> ] ) <EOL> elif option == '<STR_LIT>' : <EOL> value = True <EOL> else : <EOL> raise TemplateSyntaxError ( '<STR_LIT>' % <EOL> ( bits [ <NUM_LIT:0> ] , option ) ) <EOL> options [ option ] = value <EOL> isolated_context = options . get ( '<STR_LIT>' , False ) <EOL> namemap = options . get ( '<STR_LIT>' , { } ) <EOL> path = bits [ <NUM_LIT:1> ] <EOL> if path [ <NUM_LIT:0> ] in ( '<STR_LIT:">' , "<STR_LIT:'>" ) and path [ - <NUM_LIT:1> ] == path [ <NUM_LIT:0> ] : <EOL> return ConstantIncludeNode ( path [ <NUM_LIT:1> : - <NUM_LIT:1> ] , extra_context = namemap , <EOL> isolated_context = isolated_context ) <EOL> return IncludeNode ( parser . compile_filter ( bits [ <NUM_LIT:1> ] ) , extra_context = namemap , <EOL> isolated_context = isolated_context ) </s>
