diff options
| author | Jeremy Dunck <jdunck@gmail.com> | 2007-06-18 16:48:27 +0000 |
|---|---|---|
| committer | Jeremy Dunck <jdunck@gmail.com> | 2007-06-18 16:48:27 +0000 |
| commit | bdcc95e5cce2754d78055f86d561ba2be92ba854 (patch) | |
| tree | 08a7e4c86244cb42fe577aec5c03a57b023822c2 /docs/templates_python.txt | |
| parent | 48c9f87e1f3ba9523d79c09f52c0ccc6221f08bf (diff) | |
gis: Merged revisions 4786-5490 via svnmerge from
http://code.djangoproject.com/svn/django/trunk
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5492 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs/templates_python.txt')
| -rw-r--r-- | docs/templates_python.txt | 106 |
1 files changed, 82 insertions, 24 deletions
diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 5dd8e4fde0..c967df1a49 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -212,21 +212,24 @@ template tags. If an invalid variable is provided to one of these template tags, the variable will be interpreted as ``None``. Filters are always applied to invalid variables within these template tags. +If ``TEMPLATE_STRING_IF_INVALID`` contains a ``'%s'``, the format marker will +be replaced with the name of the invalid variable. + .. admonition:: For debug purposes only! - While ``TEMPLATE_STRING_IF_INVALID`` can be a useful debugging tool, - it is a bad idea to turn it on as a 'development default'. - - Many templates, including those in the Admin site, rely upon the - silence of the template system when a non-existent variable is + While ``TEMPLATE_STRING_IF_INVALID`` can be a useful debugging tool, + it is a bad idea to turn it on as a 'development default'. + + Many templates, including those in the Admin site, rely upon the + silence of the template system when a non-existent variable is encountered. If you assign a value other than ``''`` to - ``TEMPLATE_STRING_IF_INVALID``, you will experience rendering + ``TEMPLATE_STRING_IF_INVALID``, you will experience rendering problems with these templates and sites. - - Generally, ``TEMPLATE_STRING_IF_INVALID`` should only be enabled - in order to debug a specific template problem, then cleared + + Generally, ``TEMPLATE_STRING_IF_INVALID`` should only be enabled + in order to debug a specific template problem, then cleared once debugging is complete. - + Playing with Context objects ---------------------------- @@ -291,7 +294,8 @@ return a dictionary of items to be merged into the context. By default, ("django.core.context_processors.auth", "django.core.context_processors.debug", - "django.core.context_processors.i18n") + "django.core.context_processors.i18n", + "django.core.context_processors.media") Each processor is applied in order. That means, if one processor adds a variable to the context and a second processor adds a variable with the same @@ -345,7 +349,7 @@ If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every ``request.user.get_and_delete_messages()`` for every request. That method collects the user's messages and deletes them from the database. - Note that messages are set with ``user.add_message()``. See the + Note that messages are set with ``user.message_set.create``. See the `message docs`_ for more. * ``perms`` -- An instance of @@ -387,6 +391,15 @@ See the `internationalization docs`_ for more. .. _LANGUAGE_CODE setting: ../settings/#language-code .. _internationalization docs: ../i18n/ +django.core.context_processors.media +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every +``RequestContext`` will contain a variable ``MEDIA_URL``, providing the +value of the `MEDIA_URL setting`_. + +.. _MEDIA_URL setting: ../settings/#media-url + django.core.context_processors.request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -680,14 +693,15 @@ how the compilation works and how the rendering works. When Django compiles a template, it splits the raw template text into ''nodes''. Each node is an instance of ``django.template.Node`` and has -a ``render()`` method. A compiled template is, simply, a list of ``Node`` -objects. When you call ``render()`` on a compiled template object, the template -calls ``render()`` on each ``Node`` in its node list, with the given context. -The results are all concatenated together to form the output of the template. +either a ``render()`` or ``iter_render()`` method. A compiled template is, +simply, a list of ``Node`` objects. When you call ``render()`` on a compiled +template object, the template calls ``render()`` on each ``Node`` in its node +list, with the given context. The results are all concatenated together to +form the output of the template. Thus, to define a custom template tag, you specify how the raw template tag is converted into a ``Node`` (the compilation function), and what the node's -``render()`` method does. +``render()`` or ``iter_render()`` method does. Writing the compilation function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -714,7 +728,7 @@ object:: # split_contents() knows not to split quoted strings. tag_name, format_string = token.split_contents() except ValueError: - raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents[0] + raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0] if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name return CurrentTimeNode(format_string[1:-1]) @@ -757,7 +771,8 @@ Writing the renderer ~~~~~~~~~~~~~~~~~~~~ The second step in writing custom tags is to define a ``Node`` subclass that -has a ``render()`` method. +has a ``render()`` method (we will discuss the ``iter_render()`` alternative +in `Improving rendering speed`_, below). Continuing the above example, we need to define ``CurrentTimeNode``:: @@ -843,7 +858,7 @@ Now your tag should begin to look like this:: # split_contents() knows not to split quoted strings. tag_name, date_to_be_formatted, format_string = token.split_contents() except ValueError: - raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents[0] + raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0] if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name return FormatTimeNode(date_to_be_formatted, format_string[1:-1]) @@ -861,12 +876,12 @@ current context, available in the ``render`` method:: def __init__(self, date_to_be_formatted, format_string): self.date_to_be_formatted = date_to_be_formatted self.format_string = format_string - + def render(self, context): try: actual_date = resolve_variable(self.date_to_be_formatted, context) return actual_date.strftime(self.format_string) - except VariableDoesNotExist: + except template.VariableDoesNotExist: return '' ``resolve_variable`` will try to resolve ``blog_entry.date_updated`` and then @@ -1020,7 +1035,7 @@ The ``takes_context`` parameter defaults to ``False``. When it's set to *True*, the tag is passed the context object, as in this example. That's the only difference between this case and the previous ``inclusion_tag`` example. -.. _tutorials: ../tutorial1/#creating-models +.. _tutorials: ../tutorial01/#creating-models Setting a variable in the context ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1077,7 +1092,7 @@ class, like so:: # Splitting by None == splitting by spaces. tag_name, arg = token.contents.split(None, 1) except ValueError: - raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents[0] + raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0] m = re.search(r'(.*?) as (\w+)', arg) if not m: raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name @@ -1162,6 +1177,48 @@ For more examples of complex rendering, see the source code for ``{% if %}``, .. _configuration: +Improving rendering speed +~~~~~~~~~~~~~~~~~~~~~~~~~ + +For most practical purposes, the ``render()`` method on a ``Node`` will be +sufficient and the simplest way to implement a new tag. However, if your +template tag is expected to produce large strings via ``render()``, you can +speed up the rendering process (and reduce memory usage) using iterative +rendering via the ``iter_render()`` method. + +The ``iter_render()`` method should either be an iterator that yields string +chunks, one at a time, or a method that returns a sequence of string chunks. +The template renderer will join the successive chunks together when creating +the final output. The improvement over the ``render()`` method here is that +you do not need to create one large string containing all the output of the +``Node``, instead you can produce the output in smaller chunks. + +By way of example, here's a trivial ``Node`` subclass that simply returns the +contents of a file it is given:: + + class FileNode(Node): + def __init__(self, filename): + self.filename = filename + + def iter_render(self): + for line in file(self.filename): + yield line + +For very large files, the full file contents will never be read entirely into +memory when this tag is used, which is a useful optimisation. + +If you define an ``iter_render()`` method on your ``Node`` subclass, you do +not need to define a ``render()`` method. The reverse is true as well: the +default ``Node.iter_render()`` method will call your ``render()`` method if +necessary. A useful side-effect of this is that you can develop a new tag +using ``render()`` and producing all the output at once, which is easy to +debug. Then you can rewrite the method as an iterator, rename it to +``iter_render()`` and everything will still work. + +It is compulsory, however, to define *either* ``render()`` or ``iter_render()`` +in your subclass. If you omit them both, a ``TypeError`` will be raised when +the code is imported. + Configuring the template system in standalone mode ================================================== @@ -1193,3 +1250,4 @@ is of obvious interest. .. _settings file: ../settings/#using-settings-without-the-django-settings-module-environment-variable .. _settings documentation: ../settings/ + |
