Permalink
Browse files

[svn] doc update, setup.py update, added turbogears plugin

--HG--
branch : trunk
  • Loading branch information...
mitsuhiko committed Mar 3, 2007
1 parent 37a8851 commit 8ebf1f9b3f8277ad30b544c51e68023ea8208f50
View
@@ -0,0 +1,57 @@
+================
+Filter Functions
+================
+
+Filters are a powerful feature of Jinja taken from django which probably took
+it from UNIX. The idea is that you "pipe" a value through some filters to
+do something with it. For example convert it to upper case, escape it or
+replace a substring.
+
+Jinja comes with some builtin filters explained in the `designer documentation`_.
+
+Writing Filters
+===============
+
+A filter basically is a factory function. Thus a function that returns another
+function. We do this because filters can get an unlimited amount of position
+arguments and aditionally should gain access to the environment, context and
+piped value. A simple filter looks like this:
+
+.. sourcecode:: python
+
+ def do_join(d=u''):
+ def wrapped(env, context, value):
+ tmp = []
+ for item in value:
+ tmp.append(env.to_unicode(item))
+ return d.join(tmp)
+ return wrapped
+
+Now you have to register that filter on an environment:
+
+.. sourcecode:: python
+
+ env.filters['join'] = do_join
+
+In fact this filter is already bundled so you won't see any effect. But its
+should explain how such a filter looks like. The template designer can just
+trigger the outer code (eg: call do_join with or without arguments). The
+returned function is then processed by the jinja template engine once all
+filters are created.
+
+If you want to create filters that just operate on string (in fact unicode
+objects) you can use the `stringfilter` decorator:
+
+.. sourcecode:: python
+
+ from jinja.filters import stringfilter
+
+ @stringfilter
+ def do_strip(value):
+ return value.strip()
+
+The wrapped function is created internally by the decorator, any positional
+arguments are forwarded to the filter function. The first argument is always
+the value already converted into a string.
+
+.. _designer documentation: designerdoc.txt
View
@@ -0,0 +1,64 @@
+============
+Installation
+============
+
+Jinja requires at least Python 2.3 to work correctly.
+
+Installing a released version
+=============================
+
+As a Python egg (via easy_install)
+----------------------------------
+
+You can install the most recent Jinja version using `easy_install`_::
+
+ sudo easy_install Jinja
+
+This will install a Jinja egg in your Python installation's site-packages
+directory.
+
+
+From the tarball release
+-------------------------
+
+1. Download the most recent tarball from the `download page`_
+2. Unpack the tarball
+3. ``sudo python setup.py install``
+
+Note that the last command will automatically download and install
+`setuptools`_ if you don't already have it installed. This requires a working
+internet connection.
+
+This will install Jinja into your Python installation's site-packages directory.
+
+
+Installing the development version
+==================================
+
+If you want to play around with the code
+----------------------------------------
+
+1. Install `Subversion`_
+2. ``svn co http://trac.pocoo.org/repos/jinja/trunk jinja``
+3. ``cd jinja``
+4. ``ln -s jinja /usr/lib/python2.X/site-packages``
+
+As an alternative to steps 4 you can also do ``python setup.py develop``
+which will install the package via setuptools in development mode.
+
+If you just want the latest features and use them
+-------------------------------------------------
+
+::
+
+ sudo easy_install Jinja==dev
+
+This will install a Jinja egg containing the latest Subversion trunk code
+in your Python installation's site-packages directory. Every time the command
+is run, the sources are updated from Subversion.
+
+
+.. _download page: http://jinja.pocoo.org/download/
+.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
+.. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall
+.. _Subversion: http://subversion.tigris.org/
View
@@ -8,3 +8,61 @@ Builtin Loaders
===============
[[list_of_loaders]]
+
+Developing Loaders
+==================
+
+Template loaders are just normal python classes that have to provide some
+functions used to load and translate templates. Here a simple loader implementation
+you can use as base for your own loader:
+
+.. sourcecode:: python
+
+ from os.path import join
+ from jinja.parser import Parser
+ from jinja.exceptions import TemplateNotFound
+
+ class SimpleLoader(object):
+ """
+ Slimmed down version of the included `FileSystemLoader`.
+ """
+
+ def __init__(self, searchpath):
+ self.searchpath = searchpath
+
+ def get_source(self, environment, name, parent):
+ """
+ The get_source function is unused at the moment. However future
+ versions of jinja will use this function for the debugging
+ system. It also works as helper functions for `parse` and
+ `load`.
+ """
+ filename = join(self.searchpath, name)
+ if not path.exists(filename):
+ raise TemplateNotFound(name)
+ f = codecs.open(filename, 'r', environment.template_charset)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+ def parse(self, environment, name, parent):
+ """
+ Load and parse a template and return the syntax tree.
+ """
+ source = self.get_source(environment, name, parent)
+ return Parser(environment, source, name).parse()
+
+ def load(self, environment, name, translator):
+ """
+ Parse and translate a template. Currently only translation to
+ python code is possible, later jinja versions however will
+ support translating templates to javascript too.
+ """
+ return translator.process(environment, self.parse(environment, name, None))
+
+
+.. admonition:: Note
+
+ Once a loader is bound to an environment you have to omit the environment
+ argument for the public functions `get_source`, `parse` and `load`.
View
@@ -0,0 +1,30 @@
+==============
+Test Functions
+==============
+
+Additionally to filters Jinja also supports test functions. Test functions
+always return either ``True`` or ``False``. Inside the template they are available
+using the `is` operator.
+
+Jinja comes with some builtin tests listed in the `designer documentation`_.
+
+Writing Test Functions
+======================
+
+Test functions look exactly like filters mentioned in the `filter documentation`_:
+
+.. sourcecode:: python
+
+ def is_even():
+ def wrapped(env, context, value):
+ return value % 2 == 0
+ return wrapped
+
+Now you have to register that test on an environment:
+
+.. sourcecode:: python
+
+ env.tests['even'] = is_even
+
+.. _designer documentation: designerdoc.txt
+.. _filter documentation: filters.txt
View
@@ -0,0 +1,10 @@
+===========
+Translators
+===========
+
+Jinja translates the template sourcecode into executable python code behind
+the secenes. This is done by the python translator which is currently the
+only shipped translator. Because the interface isn't stable it's also not
+recommended to write other translators. However for the next Jinja version
+a JavaScript translator is planned which allows you to translate Jinja
+templates into executable JavaScript code.
View
@@ -3,7 +3,7 @@
Jinja Sandboxed Template Engine
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
from jinja.environment import Environment
View
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+"""
+ jinja.bakerplugin
+ ~~~~~~~~~~~~~~~~~
+
+ Provide a bridge to baker. Baker is used by some frameworks (namely
+ CherryPy, TurboGears and Pylons) to load templates.
+
+ :copyright: 2007 by Armin Ronacher.
+ :license: BSD, see LICENSE for more details.
+"""
+from jinja import Environment
+
+
+class ConfigurationError(Exception):
+ """
+ Raised if an configuration error occoured.
+ """
+
+
+class JinjaPlugin(object):
+ """
+ Implementation of the Plugin API
+ """
+ extension = 'html'
+
+ def __init__(self, extra_vars_func=None, options=None):
+ self.get_extra_vars = extra_vars_func
+ options = options or {}
+ self.extension = options.get('jinja.extension', JinjaPlugin.extension)
+ if 'jinja.environment' in options:
+ self.environment = options['jinja.environment']
+ else:
+ # this wonderful piece of code was brought to you by the turbogears
+ # ppl who want to put template configuration stuff into goddamn
+ # text/plain configuration files.
+ if 'jinja.environment.loader' in options:
+ loader = options['jinja.environment.loader']
+ else:
+ loadername = options.get('jinja.loader') or 'FileSystemLoader'
+ if '.' in loadername:
+ p = loadername.rsplit('.', 1)
+ loadercls = getattr(__import__(p[0], '', '', ['']), p[1])
+ else:
+ from jinja import loaders
+ loadercls = getattr(loaders, loadername)
+ loaderoptions = {}
+ for k, v in options.iteritems():
+ if k.startswith('jinja.loader.'):
+ loaderoptions[k[14:]] = v
+ loader = loadercls(**loaderoptions)
+ self.environment = Environment(
+ block_start_string=options.get('jinja.block_start_string', '{%'),
+ block_end_string=options.get('jinja.block_end_string', '%}'),
+ variable_start_string=options.get('jinja.variable_start_string', '{{'),
+ variable_end_string=options.get('jinja.variable_end_string', '}}'),
+ comment_start_string=options.get('jinja.comment_start_string', '{#'),
+ comment_end_string=options.get('jinja.comment_end_string', '#}'),
+ trim_blocks=str(options.get('jinja.trim_blocks')).lower() in
+ ('true', 'on', 'yes', '1'),
+ template_charset=options.get('jinja.template_charset', 'utf-8'),
+ charset=options.get('jinja.charset', 'utf-8'),
+ namespace=options.get('jinja.namespace'),
+ loader=loader,
+ filters=options.get('jinja.filters'),
+ tests=options.get('jinja.tests')
+ )
+
+ def load_template(self, templatename, template_string=None):
+ """
+ Find a template specified in python 'dot' notation, or load one from
+ a string.
+ """
+ if template_string is not None:
+ return self.environment.from_string(template_string)
+
+ # Translate TG dot notation to normal / template path
+ if '/' not in templatename and '.' not in templatename:
+ templatename = '/' + templatename.replace('.', '/') + '.' + self.extension
+
+ return self.environment.get_template(templatename)
+
+ def render(self, info, format='html', fragment=False, template=None):
+ """
+ Render a template.
+ """
+ if isinstance(template, basestring):
+ template = self.load_template(template)
+
+ if self.get_extra_vars:
+ info.update(self.get_extra_vars())
+
+ return template.render(**info)
View
@@ -5,7 +5,7 @@
Module that helds several data types used in the template engine.
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
View
@@ -5,13 +5,13 @@
Jinja default filters and tags.
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
from jinja.filters import FILTERS as DEFAULT_FILTERS
from jinja.tests import TESTS as DEFAULT_TESTS
+#: for global objects in later jinja releases. (add stuff like debug())
DEFAULT_NAMESPACE = {
- 'range': xrange
}
View
@@ -5,7 +5,7 @@
Provides a class that holds runtime and parsing time options.
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
import re
@@ -68,7 +68,7 @@ def loader(self, value):
Get or set the template loader.
"""
self._loader = LoaderWrapper(self, value)
- loader = property(lambda s: s._loader.loader, loader, loader.__doc__)
+ loader = property(lambda s: s._loader, loader, loader.__doc__)
def parse(self, source, filename=None):
"""Function that creates a new parser and parses the source."""
View
@@ -5,7 +5,7 @@
Jinja exceptions.
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
View
@@ -5,7 +5,7 @@
Bundled jinja filters.
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
from random import choice
View
@@ -3,7 +3,7 @@
jinja.lexer
~~~~~~~~~~~
- :copyright: 2006 by Armin Ronacher.
+ :copyright: 2007 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
import re
Oops, something went wrong.

0 comments on commit 8ebf1f9

Please sign in to comment.