[svn] final jinja changes for today: implemented better filter lookup
[jinja2.git] / jinja / environment.py
1 # -*- coding: utf-8 -*-
2 """
3     jinja.environment
4     ~~~~~~~~~~~~~~~~~
5
6     Provides a class that holds runtime and parsing time options.
7
8     :copyright: 2006 by Armin Ronacher.
9     :license: BSD, see LICENSE for more details.
10 """
11 from jinja.lexer import Lexer
12 from jinja.parser import Parser
13 from jinja.datastructure import LoopContext, Undefined
14 from jinja.exceptions import FilterNotFound
15 from jinja.defaults import DEFAULT_FILTERS
16
17
18 class Environment(object):
19     """
20     The jinja environment.
21     """
22
23     def __init__(self,
24                  block_start_string='{%',
25                  block_end_string='%}',
26                  variable_start_string='{{',
27                  variable_end_string='}}',
28                  comment_start_string='{#',
29                  comment_end_string='#}',
30                  template_charset='utf-8',
31                  charset='utf-8',
32                  loader=None,
33                  filters=None):
34
35         # lexer / parser information
36         self.block_start_string = block_start_string
37         self.block_end_string = block_end_string
38         self.variable_start_string = variable_start_string
39         self.variable_end_string = variable_end_string
40         self.comment_start_string = comment_start_string
41         self.comment_end_string = comment_end_string
42
43         # other stuff
44         self.template_charset = template_charset
45         self.charset = charset
46         self.loader = loader
47         self.filters = filters or DEFAULT_FILTERS.copy()
48
49         # create lexer
50         self.lexer = Lexer(self)
51
52     def parse(self, source):
53         """Function that creates a new parser and parses the source."""
54         parser = Parser(self, source)
55         return parser.parse_page()
56
57     def to_unicode(self, value):
58         """
59         Convert a value to unicode with the rules defined on the environment.
60         """
61         if isinstance(value, unicode):
62             return value
63         else:
64             try:
65                 return unicode(value)
66             except UnicodeError:
67                 return str(value).decode(self.charset, 'ignore')
68
69     def iterate(self, seq):
70         """
71         Helper function used by the python translator runtime code to
72         iterate over a sequence.
73         """
74         try:
75             length = len(seq)
76         except TypeError:
77             seq = list(seq)
78             length = len(seq)
79         loop_data = LoopContext(0, length)
80         for item in seq:
81             loop_data.index += 1
82             yield loop_data, item
83
84     def prepare_filter(self, name, *args):
85         """
86         Prepare a filter.
87         """
88         try:
89             return self.filters[name](*args)
90         except KeyError:
91             raise FilterNotFound(name)
92
93     def apply_filters(self, value, context, filters):
94         """
95         Apply a list of filters on the variable.
96         """
97         for f in filters:
98             value = f(self, context, value)
99         return value
100
101     def get_attribute(self, obj, name):
102         """
103         Get the attribute name from obj.
104         """
105         try:
106             return getattr(obj, name)
107         except AttributeError:
108             return obj[name]
109         except:
110             return Undefined