Attachment 'template.py'
Download 1 """ template - simple template using wiki macro syntax
2
3 The template does not contain any logic, just static source and macro
4 calls whenever you need dynamic data
5
6 Each template has a controller object, that must support all macro calls
7 in runtime. The controller decide if an item should print, and it can
8 call model objects to get the data needed for the template.
9
10 The template is parsed and formated as python code thats write to
11 out. Each macro call is formated as python code thats write the output
12 of the call to controller.macro_name
13
14 The template could be pickled or cached in memory.
15 """
16
17 import re
18
19
20 class Parser:
21 """ Minimal parser with wiki macro support """
22 macro_re = re.compile(r'\[\[(?P<name>.+?)\]\]', re.MULTILINE)
23
24 def __init__(self, formatter):
25 self.formatter = formatter
26
27 def parse(self, text):
28 location = 0
29 for match in self.macro_re.finditer(text):
30 # Format text up to match
31 self.formatter.text(text[location:match.start()])
32 # Format match
33 self.formatter.macro(match.group('name'))
34 location = match.end()
35 # Format rest
36 self.formatter.text(text[location:])
37
38
39 class Formatter:
40 """ text_python like formatter """
41 def __init__(self):
42 self._output = []
43
44 def text(self, text):
45 """ Create python code that write text when run """
46 self._output.append('out.write("""%s""")' % text)
47
48 def macro(self, name):
49 """ Create Python code that prints function output """
50 self._output.append('out.write(controller.macro_%s())' % name)
51
52 def output(self):
53 return '\n'.join(self._output)
54
55
56 class Template:
57 """ Compiled template """
58 def __init__(self, path):
59 self.path = path
60
61 def compile(self):
62 template = file(self.path).read()
63 template = template.strip()
64 formatter = Formatter()
65 parser = Parser(formatter)
66 parser.parse(template)
67 self.code = compile(formatter.output(), '<string>', 'exec')
68
69 def render(self, controller, out):
70 exec self.code
71
72
73 import os
74 import sys
75
76 class Controller:
77 def macro_title(self):
78 return "Quick Test"
79 def macro_author(self):
80 return os.environ.get('USER', 'unknown author')
81 def macro_filelist(self):
82 items = ['<li>%s</li>' % item for item in os.listdir(os.getcwd())
83 if not item.startswith('.')]
84 items.sort()
85 return '\n'.join(items)
86
87
88
89 if __name__ == '__main__':
90 t = Template('test.txt')
91 t.compile()
92 t.render(Controller(), sys.stdout)
93
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.