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.
  • [get | view] (2004-08-06 23:29:47, 2.6 KB) [[attachment:template.py]]
  • [get | view] (2004-08-10 15:53:39, 2.2 KB) [[attachment:template2.py]]
  • [get | view] (2004-08-06 23:13:10, 0.2 KB) [[attachment:test.txt]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.