Django

Code

Changeset 876

Show
Ignore:
Timestamp:
10/14/05 18:53:03 (3 years ago)
Author:
rjwittams
Message:

Merged to r670. Moved decorators.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/new-admin/django/conf/global_settings.py

    r864 r876  
    6161# Extension on all templates. 
    6262TEMPLATE_FILE_EXTENSION = '.html' 
     63 
     64# List of callables that know how to import templates from various sources. 
     65# See the comments in django/core/template/loader.py for interface 
     66# documentation. 
     67TEMPLATE_LOADERS = ( 
     68    'django.core.template.loaders.filesystem.load_template_source', 
     69#     'django.core.template.loaders.eggs.load_template_source', 
     70) 
    6371 
    6472# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 
  • django/branches/new-admin/django/core/extensions.py

    r673 r876  
    33# for convenience's sake. 
    44 
    5 from django.core import template_loader 
    65from django.core.exceptions import Http404, ObjectDoesNotExist 
    7 from django.core.template import Context 
     6from django.core.template import Context, loader 
    87from django.conf.settings import DEBUG, INTERNAL_IPS 
    98from django.utils.httpwrappers import HttpResponse 
    109 
    1110def render_to_response(*args, **kwargs): 
    12     return HttpResponse(template_loader.render_to_string(*args, **kwargs)) 
     11    return HttpResponse(loader.render_to_string(*args, **kwargs)) 
    1312load_and_render = render_to_response # For backwards compatibility. 
    1413 
  • django/branches/new-admin/django/core/rss.py

    r749 r876  
    1 from django.core import template_loader 
    21from django.core.exceptions import ObjectDoesNotExist 
    3 from django.core.template import Context 
     2from django.core.template import Context, loader 
    43from django.models.core import sites 
    54from django.utils import feedgenerator 
     
    2928        get_list_kwargs_cb -- Function that takes the param and returns a 
    3029        dictionary to use in addition to get_list_kwargs (if applicable). 
    31          
     30 
    3231        get_pubdate_cb -- Function that takes the object and returns a datetime 
    3332        to use as the publication date in the feed. 
     
    5049        self.enc_length = enc_length 
    5150        self.enc_mime_type = enc_mime_type 
    52          
     51 
    5352    def get_feed(self, param_slug=None): 
    5453        """ 
     
    6564        current_site = sites.get_current() 
    6665        f = self._get_feed_generator_object(param) 
    67         title_template = template_loader.get_template('rss/%s_title' % self.slug) 
    68         description_template = template_loader.get_template('rss/%s_description' % self.slug) 
     66        title_template = loader.get_template('rss/%s_title' % self.slug) 
     67        description_template = loader.get_template('rss/%s_description' % self.slug) 
    6968        kwargs = self.get_list_kwargs.copy() 
    7069        if param and self.get_list_kwargs_cb: 
     
    103102            ) 
    104103        return f 
    105          
     104 
    106105    def _get_feed_generator_object(self, param): 
    107106        current_site = sites.get_current() 
  • django/branches/new-admin/django/core/template/defaulttags.py

    r867 r876  
    228228        return output 
    229229 
     230 
    230231class LoadNode(Node): 
    231232    def __init__(self, taglib): 
     
    624625    try: 
    625626        LoadNode.load_taglib(taglib) 
    626     except ImportError
    627         raise TemplateSyntaxError, "'%s' is not a valid tag library" % taglib 
     627    except ImportError, e
     628        raise TemplateSyntaxError, "'%s' is not a valid tag library: %s" % (taglib, e) 
    628629    return LoadNode(taglib) 
    629630 
  • django/branches/new-admin/django/core/template/__init__.py

    r867 r876  
    5656""" 
    5757import re 
    58 from django.conf.settings import DEFAULT_CHARSET 
     58from django.conf.settings import DEFAULT_CHARSET, DEBUG 
    5959 
    6060__all__ = ('Template','Context','compile_string') 
     
    7575ALLOWED_VARIABLE_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.' 
    7676 
     77#What to report as the origin of templates that come from non file sources (eg strings) 
     78UNKNOWN_SOURCE="<unknown source>" 
     79 
     80#match starts of lines 
     81newline_re = re.compile("^", re.M); 
     82 
    7783# match a variable or block tag and capture the entire tag, including start/end delimiters 
    7884tag_re = re.compile('(%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), 
     
    103109 
    104110class Template: 
    105     def __init__(self, template_string): 
     111    def __init__(self, template_string, filename=UNKNOWN_SOURCE): 
    106112        "Compilation stage" 
    107         self.nodelist = compile_string(template_string
    108  
     113        self.nodelist = compile_string(template_string, filename
     114        
    109115    def __iter__(self): 
    110116        for node in self.nodelist: 
     
    116122        return self.nodelist.render(context) 
    117123 
    118 def compile_string(template_string): 
     124def compile_string(template_string, filename): 
    119125    "Compiles template_string into NodeList ready for rendering" 
    120     tokens = tokenize(template_string) 
    121     parser = Parser(tokens) 
     126    if DEBUG: 
     127        lexer_factory = DebugLexer 
     128        parser_factory = DebugParser 
     129    else: 
     130        lexer_factory = Lexer 
     131        parser_factory = Parser 
     132         
     133    lexer = lexer_factory(template_string, filename) 
     134    parser = parser_factory(lexer.tokenize()) 
    122135    return parser.parse() 
    123136 
     
    179192            ) 
    180193 
    181 def tokenize(template_string): 
    182     "Return a list of tokens from a given template_string" 
    183     # remove all empty strings, because the regex has a tendency to add them 
    184     bits = filter(None, tag_re.split(template_string)) 
    185     return map(create_token, bits) 
    186  
    187 def create_token(token_string): 
    188     "Convert the given token string into a new Token object and return it" 
    189     if token_string.startswith(VARIABLE_TAG_START): 
    190         return Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip()) 
    191     elif token_string.startswith(BLOCK_TAG_START): 
    192         return Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip()) 
    193     else: 
    194         return Token(TOKEN_TEXT, token_string) 
    195  
    196 class Parser: 
     194class Lexer(object): 
     195    def __init__(self, template_string, filename): 
     196        self.template_string = template_string 
     197        self.filename = filename 
     198     
     199    def tokenize(self): 
     200        "Return a list of tokens from a given template_string" 
     201        bits = filter(None, tag_re.split(self.template_string)) 
     202        return map(self.create_token, bits) 
     203         
     204    def create_token(self,token_string): 
     205        "Convert the given token string into a new Token object and return it" 
     206        if token_string.startswith(VARIABLE_TAG_START): 
     207            token = Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip()) 
     208        elif token_string.startswith(BLOCK_TAG_START): 
     209            token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip()) 
     210        else: 
     211            token = Token(TOKEN_TEXT, token_string) 
     212        return token  
     213 
     214class DebugLexer(Lexer): 
     215    def __init__(self, template_string, filename): 
     216        super(DebugLexer,self).__init__(template_string, filename) 
     217 
     218    def find_linebreaks(self, template_string): 
     219        for match in newline_re.finditer(template_string): 
     220            yield match.start() 
     221 
     222    def tokenize(self): 
     223        "Return a list of tokens from a given template_string" 
     224         
     225        token_tups = [] 
     226        upto = 0 
     227        line = 1 
     228        #TODO:Py2.4 generator expression  
     229        linebreaks = self.find_linebreaks(self.template_string) 
     230        next_linebreak = linebreaks.next() 
     231        try: 
     232            for match in tag_re.finditer(self.template_string): 
     233                start, end = match.span() 
     234                if start > upto: 
     235                    token_tups.append( (self.template_string[upto:start], line) ) 
     236                    upto = start 
     237                     
     238                    while next_linebreak <= upto: 
     239                        next_linebreak = linebreaks.next() 
     240                        line += 1 
     241                 
     242                token_tups.append( (self.template_string[start:end], line) ) 
     243                upto = end 
     244         
     245                while next_linebreak <= upto: 
     246                    next_linebreak = linebreaks.next() 
     247                    line += 1 
     248        except StopIteration: 
     249            pass 
     250         
     251        last_bit = self.template_string[upto:] 
     252        if len(last_bit): 
     253           token_tups.append( (last_bit, line) ) 
     254         
     255        return [ self.create_token(tok, (self.filename, line)) for tok, line in token_tups] 
     256 
     257 
     258    def create_token(self, token_string, source): 
     259        token = super(DebugLexer, self).create_token(token_string) 
     260        token.source = source 
     261        return token 
     262 
     263 
     264class Parser(object): 
    197265    def __init__(self, tokens): 
    198266        self.tokens = tokens 
     
    203271            token = self.next_token() 
    204272            if token.token_type == TOKEN_TEXT: 
    205                 nodelist.append(TextNode(token.contents)
     273                self.extend_nodelist(nodelist, TextNode(token.contents), token
    206274            elif token.token_type == TOKEN_VAR: 
    207275                if not token.contents: 
    208                     raise TemplateSyntaxError, "Empty variable tag" 
    209                 nodelist.append(VariableNode(token.contents)
     276                    self.empty_variable(token) 
     277                self.extend_nodelist(nodelist, VariableNode(token.contents), token
    210278            elif token.token_type == TOKEN_BLOCK: 
    211279                if token.contents in parse_until: 
     
    216284                    command = token.contents.split()[0] 
    217285                except IndexError: 
    218                     raise TemplateSyntaxError, "Empty block tag" 
     286                    self.empty_block_tag(token) 
     287                 
     288                # execute callback function for this tag and append resulting node 
     289                self.enter_command(command, token); 
    219290                try: 
    220                     # execute callback function for this tag and append resulting node 
    221                     nodelist.append(registered_tags[command](self, token)) 
     291                    compile_func = registered_tags[command] 
    222292                except KeyError: 
    223                     raise TemplateSyntaxError, "Invalid block tag: '%s'" % command 
     293                    self.invalid_block_tag(token, command) 
     294                     
     295                self.extend_nodelist(nodelist, compile_func(self, token), token) 
     296                self.exit_command(); 
     297                 
    224298        if parse_until: 
    225             raise TemplateSyntaxError, "Unclosed tag(s): '%s'" % ', '.join(parse_until) 
     299            self.unclosed_block_tag(token) 
     300             
    226301        return nodelist 
    227302 
     303    def extend_nodelist(self, nodelist, node, token): 
     304        nodelist.append(node) 
     305 
     306    def enter_command(self, command, token): 
     307        pass 
     308         
     309    def exit_command(self): 
     310        pass 
     311 
     312    def empty_variable(self, token): 
     313        raise TemplateSyntaxError, "Empty variable tag"  
     314     
     315    def empty_block_tag(self, token): 
     316        raise TemplateSyntaxError, "Empty block tag" 
     317     
     318    def invalid_block_tag(self, token, command): 
     319        raise TemplateSyntaxError, "Invalid block tag: %s" % (command) 
     320     
     321    def unclosed_block_tag(self, token): 
     322        raise TemplateSyntaxError, "Unclosed tags: %s " %  ', '.join(parse_until) 
     323         
    228324    def next_token(self): 
    229325        return self.tokens.pop(0) 
     
    234330    def delete_first_token(self): 
    235331        del self.tokens[0] 
     332 
     333 
     334class DebugParser(Parser): 
     335    def __init__(self, lexer): 
     336        super(DebugParser, self).__init__(lexer) 
     337        self.command_stack = [] 
     338 
     339    def enter_command(self, command, token): 
     340        self.command_stack.append( (command, token.source) ) 
     341         
     342    def exit_command(self): 
     343        self.command_stack.pop() 
     344 
     345    def format_source(self, source): 
     346        return "at %s, line %d" % source 
     347 
     348    def extend_nodelist(self, nodelist, node, token): 
     349        node.source = token.source 
     350        super(DebugParser, self).extend_nodelist(nodelist, node, token) 
     351 
     352    def empty_variable(self, token): 
     353        raise TemplateSyntaxError, "Empty variable tag %s" % self.format_source(token.source) 
     354     
     355    def empty_block_tag(self, token): 
     356        raise TemplateSyntaxError, "Empty block tag %s" % self.format_source(token.source) 
     357     
     358    def invalid_block_tag(self, token, command): 
     359        raise TemplateSyntaxError, "Invalid block tag: '%s' %s" % (command, self.format_source(token.source)) 
     360     
     361    def unclosed_block_tag(self, token): 
     362        (command, (file,line)) = self.command_stack.pop() 
     363        msg = "Unclosed tag '%s' starting at %s, line %d. Looking for one of: %s " % \ 
     364              (command, file, line, ', '.join(parse_until) )  
     365        raise TemplateSyntaxError, msg 
    236366 
    237367class FilterParser: 
  • django/branches/new-admin/django/core/template_loader.py

    r796 r876  
    1 "Wrapper for loading templates from storage of some sort (e.g. files or db)" 
    2 import template 
    3 from template_file import find_template_source 
     1# This module is DEPRECATED! 
     2
     3# You should no longer be using django.core.template_loader. 
     4
     5# Use django.core.template.loader instead. 
    46 
    5 class ExtendsError(Exception): 
    6     pass 
    7  
    8 def get_template(template_name): 
    9     """ 
    10     Returns a compiled template.Template object for the given template name, 
    11     handling template inheritance recursively. 
    12     """ 
    13     return get_template_from_string(*find_template_source(template_name)) 
    14  
    15 def get_template_from_string(source, filename=template.UNKNOWN_SOURCE): 
    16     """ 
    17     Returns a compiled template.Template object for the given template code, 
    18     handling template inheritance recursively. 
    19     """ 
    20     return template.Template(source, filename) 
    21  
    22 def render_to_string(template_name, dictionary=None, context_instance=None): 
    23     """ 
    24     Loads the given template_name and renders it with the given dictionary as 
    25     context. The template_name may be a string to load a single template using 
    26     get_template, or it may be a tuple to use select_template to find one of 
    27     the templates in the list.  Returns a string.  
    28     """ 
    29     dictionary = dictionary or {} 
    30     if isinstance(template_name, (list, tuple)): 
    31         t = select_template(template_name) 
    32     else: 
    33         t = get_template(template_name) 
    34     if context_instance: 
    35         context_instance.update(dictionary) 
    36     else: 
    37         context_instance = template.Context(dictionary) 
    38     return t.render(context_instance) 
    39  
    40 def select_template(template_name_list): 
    41     "Given a list of template names, returns the first that can be loaded." 
    42     for template_name in template_name_list: 
    43         try: 
    44             return get_template(template_name) 
    45         except template.TemplateDoesNotExist: 
    46             continue 
    47     # If we get here, none of the templates could be loaded 
    48     raise template.TemplateDoesNotExist, ', '.join(template_name_list) 
    49  
    50 class BlockNode(template.Node): 
    51     def __init__(self, name, nodelist, parent=None): 
    52         self.name, self.nodelist, self.parent = name, nodelist, parent 
    53  
    54     def __repr__(self): 
    55         return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) 
    56  
    57     def render(self, context): 
    58         context.push() 
    59         # Save context in case of block.super(). 
    60         self.context = context 
    61         context['block'] = self 
    62         result = self.nodelist.render(context) 
    63         context.pop() 
    64         return result 
    65  
    66     def super(self): 
    67         if self.parent: 
    68             return self.parent.render(self.context) 
    69         return '' 
    70  
    71     def add_parent(self, nodelist): 
    72         if self.parent: 
    73             self.parent.add_parent(nodelist) 
    74         else: 
    75             self.parent = BlockNode(self.name, nodelist) 
    76  
    77 class ExtendsNode(template.Node): 
    78     def __init__(self, nodelist, parent_name, parent_name_var, template_dirs=None): 
    79         self.nodelist = nodelist 
    80         self.parent_name, self.parent_name_var = parent_name, parent_name_var 
    81         self.template_dirs = template_dirs 
    82  
    83     def get_parent(self, context): 
    84         if self.parent_name_var: 
    85             self.parent_name = template.resolve_variable_with_filters(self.parent_name_var, context) 
    86         parent = self.parent_name 
    87         if not parent: 
    88             error_msg = "Invalid template name in 'extends' tag: %r." % parent 
    89             if self.parent_name_var: 
    90                 error_msg += " Got this from the %r variable." % self.parent_name_var 
    91             raise template.TemplateSyntaxError, error_msg 
    92         try: 
    93             return get_template_from_string(*find_template_source(parent, self.template_dirs)) 
    94         except template.TemplateDoesNotExist: 
    95             raise template.TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent 
    96  
    97     def render(self, context): 
    98         compiled_parent = self.get_parent(context) 
    99         parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode) 
    100         parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) 
    101         for block_node in self.nodelist.get_nodes_by_type(BlockNode): 
    102             # Check for a BlockNode with this node's name, and replace it if found. 
    103             try: 
    104                 parent_block = parent_blocks[block_node.name] 
    105             except KeyError: 
    106                 # This BlockNode wasn't found in the parent template, but the 
    107                 # parent block might be defined in the parent's *parent*, so we 
    108                 # add this BlockNode to the parent's ExtendsNode nodelist, so 
    109                 # it'll be checked when the parent node's render() is called. 
    110                 if parent_is_child: 
    111                     compiled_parent.nodelist[0].nodelist.append(block_node) 
    112             else: 
    113                 # Keep any existing parents and add a new one. Used by BlockNode. 
    114                 parent_block.parent = block_node.parent 
    115                 parent_block.add_parent(parent_block.nodelist) 
    116                 parent_block.nodelist = block_node.nodelist 
    117         return compiled_parent.render(context) 
    118  
    119 def do_block(parser, token): 
    120     """ 
    121     Define a block that can be overridden by child templates. 
    122     """ 
    123     bits = token.contents.split() 
    124     if len(bits) != 2: 
    125         raise template.TemplateSyntaxError, "'%s' tag takes only one argument" % bits[0] 
    126     block_name = bits[1] 
    127     # Keep track of the names of BlockNodes found in this template, so we can 
    128     # check for duplication. 
    129     try: 
    130         if block_name in parser.__loaded_blocks: 
    131             raise template.TemplateSyntaxError, "'%s' tag with name '%s' appears more than once" % (bits[0], block_name) 
    132         parser.__loaded_blocks.append(block_name) 
    133     except AttributeError: # parser._loaded_blocks isn't a list yet 
    134         parser.__loaded_blocks = [block_name] 
    135     nodelist = parser.parse(('endblock',)) 
    136     parser.delete_first_token() 
    137     return BlockNode(block_name, nodelist) 
    138  
    139 def do_extends(parser, token): 
    140     """ 
    141     Signal that this template extends a parent template. 
    142  
    143     This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) 
    144     uses the literal value "base" as the name of the parent template to extend, 
    145     or ``{% extends variable %}`` uses the value of ``variable`` as the name 
    146     of the parent template to extend. 
    147     """ 
    148     bits = token.contents.split() 
    149     if len(bits) != 2: 
    150         raise template.TemplateSyntaxError, "'%s' takes one argument" % bits[0] 
    151     parent_name, parent_name_var = None, None 
    152     if (bits[1].startswith('"') and bits[1].endswith('"')) or (bits[1].startswith("'") and bits[1].endswith("'")): 
    153         parent_name = bits[1][1:-1] 
    154     else: 
    155         parent_name_var = bits[1] 
    156     nodelist = parser.parse() 
    157     if nodelist.get_nodes_by_type(ExtendsNode): 
    158         raise template.TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0] 
    159     return ExtendsNode(nodelist, parent_name, parent_name_var) 
    160  
    161 template.register_tag('block', do_block) 
    162 template.register_tag('extends', do_extends) 
     7from django.core.template.loader import * 
  • django/branches/new-admin/django/core/template/loader.py

    r867 r876  
    1 "Wrapper for loading templates from storage of some sort (e.g. files or db)" 
    2  
    3 from django.core.template import Template, Context, Node, TemplateDoesNotExist, TemplateSyntaxError, resolve_variable_with_filters, register_tag 
    4 from django.core.template.loaders.filesystem import load_template_source 
     1# Wrapper for loading templates from storage of some sort (e.g. filesystem, database). 
     2
     3# This uses the TEMPLATE_LOADERS setting, which is a list of loaders to use. 
     4# Each loader is expected to have this interface: 
     5
     6#    callable(name, dirs=[]) 
     7
     8# name is the template name. 
     9# dirs is an optional list of directories to search instead of TEMPLATE_DIRS. 
     10# The loader should return a tuple of (template_source, path). The path returned 
     11# will be shown to the user for debugging purposes, so it should identify where the template  
     12# was loaded from.   
     13
     14# Each loader should have an "is_usable" attribute set. This is a boolean that 
     15# specifies whether the loader can be used in this Python installation. Each 
     16# loader is responsible for setting this when it's initialized. 
     17
     18# For example, the eggs loader (which is capable of loading templates from 
     19# Python eggs) sets is_usable to False if the "pkg_resources" module isn't 
     20# installed, because pkg_resources is necessary to read eggs. 
     21 
     22from django.core.exceptions import ImproperlyConfigured 
     23from django.core.template import Template, Context, Node, TemplateDoesNotExist, TemplateSyntaxError, resolve_variable_with_filters, register_tag, UNKNOWN_SOURCE 
     24from django.conf.settings import TEMPLATE_LOADERS 
     25 
     26template_source_loaders = [] 
     27for path in TEMPLATE_LOADERS: 
     28    i = path.rfind('.') 
     29    module, attr = path[:i], path[i+1:] 
     30    try: 
     31        mod = __import__(module, globals(), locals(), [attr]) 
     32    except ImportError, e: 
     33        raise ImproperlyConfigured, 'Error importing template source loader %s: "%s"' % (module, e) 
     34    try: 
     35        func = getattr(mod, attr) 
     36    except AttributeError: 
     37        raise ImproperlyConfigured, 'Module "%s" does not define a "%s" callable template source loader' % (module, attr) 
     38    if not func.is_usable: 
     39        import warnings 
     40        warnings.warn("Your TEMPLATE_LOADERS setting includes %r, but your Python installation doesn't support that type of template loading. Consider removing that line from TEMPLATE_LOADERS." % path) 
     41    else: 
     42        template_source_loaders.append(func) 
     43 
     44def find_template_source(name, dirs=None): 
     45    for loader in template_source_loaders: 
     46        try: 
     47            return loader(name, dirs) 
     48        except TemplateDoesNotExist: 
     49            pass 
     50    raise TemplateDoesNotExist, name 
     51 
     52def load_template_source(name, dirs=None): 
     53    find_template_source(name, dirs)[0] 
    554 
    655class ExtendsError(Exception): 
     
    1261    handling template inheritance recursively. 
    1362    """ 
    14     return get_template_from_string(load_template_source(template_name)) 
    15  
    16 def get_template_from_string(source): 
     63    return get_template_from_string(*find_template_source(template_name)) 
     64 
     65def get_template_from_string(source, filename=UNKNOWN_SOURCE): 
    1766    """ 
    1867    Returns a compiled Template object for the given template code, 
    1968    handling template inheritance recursively. 
    2069    """ 
    21     return Template(source
     70    return Template(source, filename
    2271 
    2372def render_to_string(template_name, dictionary=None, context_instance=None): 
     
    2675    context. The template_name may be a string to load a single template using 
    2776    get_template, or it may be a tuple to use select_template to find one of 
    28     the templates in the list. Returns a string. 
     77    the templates in the list. Returns a string.  
    2978    """ 
    3079    dictionary = dictionary or {} 
     
    92141            raise TemplateSyntaxError, error_msg 
    93142        try: 
    94             return get_template_from_string(load_template_source(parent, self.template_dirs)) 
     143            return get_template_from_string(*find_template_source(parent, self.template_dirs)) 
    95144        except TemplateDoesNotExist: 
    96145            raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent 
     
    118167        return compiled_parent.render(context) 
    119168 
     169class ConstantIncludeNode(Node): 
     170    def __init__(self, template_path): 
     171        try: 
     172            t = get_template(template_path) 
     173            self.nodelist = t.nodelist 
     174        except Exception, e: 
     175            self.nodelist = None 
     176 
     177    def render(self, context): 
     178        if self.nodelist: 
     179            return self.nodelist.render(context) 
     180        else: 
     181            return '' 
     182 
     183class IncludeNode(Node): 
     184    def __init__(self, template_path_var): 
     185        self.template_path_var = template_path_var 
     186 
     187    def render(self, context): 
     188         try: 
     189             template_path = resolve_variable(self.template_path_var, context) 
     190             print "IncludeNode rendering %s" % template_path 
     191             t = template_loader.get_template(template_path) 
     192             return t.render(context) 
     193         except Exception, e: 
     194             return '' # Fail silently for invalid included templates. 
     195 
     196 
    120197def do_block(parser, token): 
    121198    """ 
     
    144221    This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) 
    145222    uses the literal value "base" as the name of the parent template to extend, 
    146     or ``{% entends variable %}`` uses the value of ``variable`` as the name 
     223    or ``{% extends variable %}`` uses the value of ``variable`` as the name 
    147224    of the parent template to extend. 
    148225    """ 
     
    160237    return ExtendsNode(nodelist, parent_name, parent_name_var) 
    161238 
     239def do_include(parser, token): 
     240    """ 
     241    Loads a template using standard resolution mechanisms, and renders it in the current context. 
     242    """ 
     243    bits = token.contents.split() 
     244    if len(bits) != 2: 
     245        raise TemplateSyntaxError, "'include' tag takes one argument: the path to the template to be included" 
     246 
     247    path = bits[1] 
     248    if path[0] in ('"', "'") and path[-1] == path[0]: 
     249        return ConstantIncludeNode(path[1:-1]) 
     250    return IncludeNode(bits[1]) 
     251 
    162252register_tag('block', do_block) 
    163253register_tag('extends', do_extends) 
     254register_tag('include', do_include) 
  • django/branches/new-admin/django/core/template/loaders/eggs.py

    r870 r876  
    1919        for app in INSTALLED_APPS: 
    2020            try: 
    21                 return resource_string(app, pkg_name) 
     21                return (resource_string(app, pkg_name), 'egg:%s:%s ' % (app, pkg_name))  
    2222            except: 
    2323                pass 
  • django/branches/new-admin/django/core/template/loaders/filesystem.py

    r867 r876  
    1212        filepath = os.path.join(template_dir, template_name) + TEMPLATE_FILE_EXTENSION 
    1313        try: 
    14             return open(filepath).read(
     14            return (open(filepath).read(), filepath
    1515        except IOError: 
    1616            tried.append(filepath) 
     
    2020        error_msg = "Your TEMPLATE_DIRS settings is empty. Change it to point to at least one template directory." 
    2121    raise TemplateDoesNotExist, error_msg 
     22load_template_source.is_usable = True 
  • django/branches/new-admin/django/middleware/admin.py

    r669 r876  
    11from django.utils import httpwrappers 
    2 from django.core import template_loader 
    3 from django.core.extensions import DjangoContext as Context 
     2from django.core.extensions import DjangoContext 
     3from django.core.extensions import render_to_response 
    44from django.models.auth import users 
    55from django.views.registration import passwords 
     
    9797        else: 
    9898            post_data = encode_post_data({}) 
    99         t = template_loader.get_template(self.get_login_template_name()) 
    100         c = Context(request, { 
     99        return render_to_response(self.get_login_template_name(), { 
    101100            'title': 'Log in', 
    102101            'app_path': request.path, 
    103102            'post_data': post_data, 
    104103            'error_message': error_message 
    105         }) 
    106         return httpwrappers.HttpResponse(t.render(c)) 
     104        }, context_instance=DjangoContext(request)) 
    107105 
    108106    def authenticate_user(self, user, password): 
  • django/branches/new-admin/django/templatetags/admin_modify.py

    r854 r876  
    66from django.utils.functional import curry 
    77 
    8 from django.core.template_decorators import simple_tag, inclusion_tag 
     8from django.core.template.decorators import simple_tag, inclusion_tag 
    99 
    1010from django.views.admin.main import AdminBoundField 
  • django/branches/new-admin/django/views/admin/doc.py

    r665 r876  
    55from django.core.extensions import DjangoContext, render_to_response 
    66from django.core.exceptions import Http404, ViewDoesNotExist 
    7 from django.core import template, template_loader, defaulttags, defaultfilters, urlresolvers 
     7from django.core import template, template_loader, urlresolvers 
     8from django.core.template import defaulttags, defaultfilters 
    89try: 
    910    from django.parts.admin import doc 
  • django/branches/new-admin/django/views/admin/template.py

    r675 r876  
    1 from django.core import formfields, template_loader, validators 
     1from django.core import formfields, validators 
    22from django.core import template 
     3from django.core.template import loader 
    34from django.core.extensions import DjangoContext, render_to_response 
    45from django.models.core import sites 
     
    5051        # for "extends" that uses the site's TEMPLATE_DIR instead 
    5152        def new_do_extends(parser, token): 
    52             node = template_loader.do_extends(parser, token) 
     53            node = loader.do_extends(parser, token) 
    5354            node.template_dirs = settings_module.TEMPLATE_DIRS 
    5455            return node 
     
    5960        error = None 
    6061        try: 
    61             tmpl = template_loader.get_template_from_string(field_data) 
     62            tmpl = loader.get_template_from_string(field_data) 
    6263            tmpl.render(template.Context({})) 
    6364        except template.TemplateSyntaxError, e: 
    6465            error = e 
    65         template.register_tag('extends', template_loader.do_extends) 
     66        template.register_tag('extends', loader.do_extends) 
    6667        if error: 
    6768            raise validators.ValidationError, e.args 
  • django/branches/new-admin/django/views/auth/login.py

    r669 r876  
    11from django.parts.auth.formfields import AuthenticationForm 
    2 from django.core import formfields, template_loader 
     2from django.core import formfields 
    33from django.core.extensions import DjangoContext, render_to_response 
    44from django.models.auth import users 
  • django/branches/new-admin/django/views/defaults.py

    r549 r876  
    1 from django.core import template_loader 
    21from django.core.exceptions import Http404, ObjectDoesNotExist 
    3 from django.core.template import Context 
     2from django.core.template import Context, loader 
    43from django.models.core import sites 
    54from django.utils import httpwrappers 
     
    5756            return httpwrappers.HttpResponseGone() 
    5857        return httpwrappers.HttpResponseRedirect(r.new_path) 
    59     t = template_loader.get_template('404') 
     58    t = loader.get_template('404') 
    6059    c = Context() 
    6160    return httpwrappers.HttpResponseNotFound(t.render(c)) 
     
    6867    Context: None 
    6968    """ 
    70     t = template_loader.get_template('500') 
     69    t = loader.get_template('500') 
    7170    c = Context() 
    7271    return httpwrappers.HttpResponseServerError(t.render(c)) 
  • django/branches/new-admin/django/views/registration/passwords.py

    r665 r876  
    1 from django.core import formfields, template_loader, validators 
     1from django.core import formfields, validators 
    22from django.core.extensions import DjangoContext, render_to_response 
     3from django.core.template import loader 
    34from django.models.auth import users 
    45from django.views.decorators.auth import login_required 
     
    3334        else: 
    3435            site_name = domain = domain_override 
    35         t = template_loader.get_template('registration/password_reset_email') 
     36        t = loader.get_template('registration/password_reset_email') 
    3637        c = { 
    3738            'new_password': new_pass, 
  • django/branches/new-admin/docs/forms.txt

    r610 r876  
    6666POSTed data from the browser and creates a new ``Place`` object:: 
    6767 
    68     from django.core import template_loader