Changeset 796
- Timestamp:
- 10/06/05 20:13:32 (3 years ago)
- Files:
-
- django/branches/new-admin/django/conf/admin_templates/admin_edit_inline_tabular.html (modified) (1 diff)
- django/branches/new-admin/django/conf/admin_templates/admin_submit_line.html (modified) (1 diff)
- django/branches/new-admin/django/core/defaulttags.py (modified) (2 diffs)
- django/branches/new-admin/django/core/template_file.py (modified) (3 diffs)
- django/branches/new-admin/django/core/template_loader.py (modified) (4 diffs)
- django/branches/new-admin/django/core/template.py (modified) (8 diffs)
- django/branches/new-admin/django/views/admin/main.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/new-admin/django/conf/admin_templates/admin_edit_inline_tabular.html
r740 r796 22 22 {% for bound_field in fcw.bound_fields %} 23 23 {% if not bound_field.not_in_table %} 24 <td "{{ bound_field.cell_class_attribute}}">24 <td {{bound_field.cell_class_attribute}}> 25 25 {% field_widget bound_field %} 26 26 </td> django/branches/new-admin/django/conf/admin_templates/admin_submit_line.html
r741 r796 1 1 <div class="submit-row"> 2 {% if show_delete_link %}<p class="float-left"><a href="delete/" class="deletelink">Delete</a></p>{% endif %}3 {% if show_save_as_new %}<input type="submit" value="Save as new" name="_saveasnew" {{onclick_attrib}}/>{%endif%}4 {% if show_save_and_add_another %}<input type="submit" value="Save and add another" name="_addanother" {{onclick_attrib}} />{% endif %}5 {% if show_save_and_continue %}<input type="submit" value="Save and continue editing" name="_continue" {{onclick_attrib}}/>{% endif %}6 {% if show_save %}<input type="submit" value="Save" class="default" {{onclick_attrib}}/>{% endif %} 2 {% if show_delete_link %}<p class="float-left"><a href="delete/" class="deletelink">Delete</a></p>{% endif %} 3 {% if show_save_as_new %}<input type="submit" value="Save as new" name="_saveasnew" {{onclick_attrib}}/>{%endif%} 4 {% if show_save_and_add_another %}<input type="submit" value="Save and add another" name="_addanother" {{onclick_attrib}} />{% endif %} 5 {% if show_save_and_continue %}<input type="submit" value="Save and continue editing" name="_continue" {{onclick_attrib}}/>{% endif %} 6 {% if show_save %}<input type="submit" value="Save" class="default" {{onclick_attrib}}/> 7 7 </div> django/branches/new-admin/django/core/defaulttags.py
r780 r796 231 231 class ConstantIncludeNode(template.Node): 232 232 def __init__(self, template_path): 233 t = template_loader.get_template(template_path) 234 self.nodelist = t.nodelist 235 236 def render(self, context): 237 return self.nodelist.render(context) 233 try: 234 t = template_loader.get_template(template_path) 235 self.nodelist = t.nodelist 236 except Exception, e: 237 self.nodelist = None 238 239 def render(self, context): 240 if self.nodelist: 241 return self.nodelist.render(context) 242 else: 243 return '' 238 244 239 245 class IncludeNode(template.Node): … … 248 254 return t.render(context) 249 255 except Exception, e: 250 print e251 256 return '' # Fail silently for invalid included templates. 252 257 django/branches/new-admin/django/core/template_file.py
r721 r796 5 5 import os 6 6 7 def load_template_source(template_name, template_dirs=None): 7 8 def find_template_source(template_name, template_dirs=None): 9 "Returns a tuple of (template_string, filepath)." 8 10 if not template_dirs: 9 11 template_dirs = TEMPLATE_DIRS … … 12 14 filepath = os.path.join(template_dir, template_name) + TEMPLATE_FILE_EXTENSION 13 15 try: 14 return open(filepath).read()16 return (open(filepath).read(), filepath) 15 17 except IOError: 16 18 tried.append(filepath) … … 20 22 error_msg = "Your TEMPLATE_DIRS settings is empty. Change it to point to at least one template directory." 21 23 raise TemplateDoesNotExist, error_msg 24 25 26 def load_template_source(template_name, template_dirs=None): 27 return find_template_source(template_name, template_dirs)[0] django/branches/new-admin/django/core/template_loader.py
r717 r796 1 1 "Wrapper for loading templates from storage of some sort (e.g. files or db)" 2 2 import template 3 from template_file import load_template_source3 from template_file import find_template_source 4 4 5 5 class ExtendsError(Exception): … … 11 11 handling template inheritance recursively. 12 12 """ 13 return get_template_from_string( load_template_source(template_name))13 return get_template_from_string(*find_template_source(template_name)) 14 14 15 def get_template_from_string(source ):15 def get_template_from_string(source, filename=template.UNKNOWN_SOURCE): 16 16 """ 17 17 Returns a compiled template.Template object for the given template code, 18 18 handling template inheritance recursively. 19 19 """ 20 return template.Template(source )20 return template.Template(source, filename) 21 21 22 22 def render_to_string(template_name, dictionary=None, context_instance=None): … … 91 91 raise template.TemplateSyntaxError, error_msg 92 92 try: 93 return get_template_from_string( load_template_source(parent, self.template_dirs))93 return get_template_from_string(*find_template_source(parent, self.template_dirs)) 94 94 except template.TemplateDoesNotExist: 95 95 raise template.TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent … … 143 143 This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) 144 144 uses the literal value "base" as the name of the parent template to extend, 145 or ``{% e ntends variable %}`` uses the value of ``variable`` as the name145 or ``{% extends variable %}`` uses the value of ``variable`` as the name 146 146 of the parent template to extend. 147 147 """ django/branches/new-admin/django/core/template.py
r791 r796 75 75 ALLOWED_VARIABLE_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.' 76 76 77 #What to report as the origin of templates that come from non file sources (eg strings) 78 UNKNOWN_SOURCE="<unknown source>" 79 80 81 #match starts of lines 82 newline_re = re.compile("^", re.M); 83 77 84 # match a variable or block tag and capture the entire tag, including start/end delimiters 78 85 tag_re = re.compile('(%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), 79 86 re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END))) 80 87 88 81 89 # global dict used by register_tag; maps custom tags to callback functions 82 90 registered_tags = {} … … 103 111 104 112 class Template: 105 def __init__(self, template_string ):113 def __init__(self, template_string, filename=UNKNOWN_SOURCE): 106 114 "Compilation stage" 107 self.nodelist = compile_string(template_string )115 self.nodelist = compile_string(template_string, filename) 108 116 109 117 def __iter__(self): … … 116 124 return self.nodelist.render(context) 117 125 118 def compile_string(template_string ):126 def compile_string(template_string, filename): 119 127 "Compiles template_string into NodeList ready for rendering" 120 tokens = tokenize(template_string )128 tokens = tokenize(template_string, filename) 121 129 parser = Parser(tokens) 122 130 return parser.parse() … … 169 177 170 178 class Token: 171 def __init__(self, token_type, contents ):179 def __init__(self, token_type, contents, source): 172 180 "The token_type must be TOKEN_TEXT, TOKEN_VAR or TOKEN_BLOCK" 173 181 self.token_type, self.contents = token_type, contents 182 self.source = source 174 183 175 184 def __str__(self): 176 return '<%s token: "%s..." >' % (185 return '<%s token: "%s..." from %s, line %d>' % ( 177 186 {TOKEN_TEXT:'Text', TOKEN_VAR:'Var', TOKEN_BLOCK:'Block'}[self.token_type], 178 self.contents[:20].replace('\n', '') 187 self.contents[:20].replace('\n', ''), 188 self.source[0], self.source[1] 179 189 ) 180 190 181 def tokenize(template_string): 191 192 def tokenize(template_string, filename): 182 193 "Return a list of tokens from a given template_string" 183 194 # 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): 195 linebreaks = [match.start() for match in newline_re.finditer(template_string)] 196 lastline = len(linebreaks) 197 token_tups = [] 198 upto = 0 199 line = 1 200 201 202 for match in tag_re.finditer(template_string): 203 start, end = match.span() 204 if start > upto: 205 token_tups.append( (template_string[upto:start], line) ) 206 upto = start 207 while linebreaks and line != lastline and linebreaks[line] <= upto: 208 line += 1 209 210 token_tups.append( (template_string[start:end], line) ) 211 upto = end 212 213 while linebreaks and line != lastline and linebreaks[line] <= upto: 214 line += 1 215 216 return [ create_token(tok, (filename, line)) for tok, line in token_tups] 217 218 def create_token(token_string, source): 188 219 "Convert the given token string into a new Token object and return it" 189 220 if token_string.startswith(VARIABLE_TAG_START): 190 return Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip() )221 return Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip(), source) 191 222 elif token_string.startswith(BLOCK_TAG_START): 192 return Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip() )223 return Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip(), source) 193 224 else: 194 return Token(TOKEN_TEXT, token_string) 225 return Token(TOKEN_TEXT, token_string, source) 226 195 227 196 228 class Parser: 197 229 def __init__(self, tokens): 198 230 self.tokens = tokens 231 self.command_stack = [] 199 232 200 233 def parse(self, parse_until=[]): … … 203 236 token = self.next_token() 204 237 if token.token_type == TOKEN_TEXT: 205 nodelist.append(TextNode(token.contents) )238 nodelist.append(TextNode(token.contents), token) 206 239 elif token.token_type == TOKEN_VAR: 207 240 if not token.contents: 208 raise TemplateSyntaxError, "Empty variable tag "209 nodelist.append(VariableNode(token.contents) )241 raise TemplateSyntaxError, "Empty variable tag at %s, line %d" % (token.source[0], token.source[1]) 242 nodelist.append(VariableNode(token.contents), token) 210 243 elif token.token_type == TOKEN_BLOCK: 211 244 if token.contents in parse_until: … … 219 252 try: 220 253 # execute callback function for this tag and append resulting node 221 nodelist.append(registered_tags[command](self, token)) 254 self.command_stack.append( (command, token.source) ) 255 nodelist.append(registered_tags[command](self, token), token) 256 self.command_stack.pop() 222 257 except KeyError: 223 raise TemplateSyntaxError, "Invalid block tag: '%s' " % command258 raise TemplateSyntaxError, "Invalid block tag: '%s' at %s, line %d" % (command, token.source[0], token.source[1]) 224 259 if parse_until: 225 raise TemplateSyntaxError, "Unclosed tag(s): '%s'" % ', '.join(parse_until) 260 (command, (file,line)) = self.command_stack.pop() 261 msg = "Unclosed tag '%s' starting at %s, line %d. Looking for one of: %s " % \ 262 (command, file, line, ', '.join(parse_until) ) 263 raise TemplateSyntaxError, msg 226 264 return nodelist 227 265 … … 435 473 nodes.extend(self.nodelist.get_nodes_by_type(nodetype)) 436 474 return nodes 475 437 476 438 477 class NodeList(list): … … 452 491 nodes.extend(node.get_nodes_by_type(nodetype)) 453 492 return nodes 493 494 def append(self, node, token = None): 495 if token: 496 node.source = token.source 497 super(NodeList, self).append(node) 454 498 455 499 class TextNode(Node): django/branches/new-admin/django/views/admin/main.py
r791 r796 574 574 if max([bool(f.errors()) for f in self.form_fields]): 575 575 classes.append('error') 576 self.cell_class_attribute = ' '.join(classes) 576 if classes: 577 self.cell_class_attribute = ' class="%s" ' % ' '.join(classes) 577 578 self._repr_filled = False 578 579
