""" template - simple template using python % syntax

The template does not contain any logic, just static source and macro
calls whenever you need dynamic data

Each template has a controller object, that must support all macro calls
in runtime. The controller decide if an item should print, and it can
call model objects to get the data needed for the template.

This is being a bit naughty and relying on __str__() being implicitly
called. This isn't necessary with a bit of code cleaning.
"""

class TextTemplate:
    def __init__(self, text, controller):
        self.text = text.strip()
        self.controller = controller
    def __str__(self):
        return self.text%(self.controller)

class FileTemplate(TextTemplate):
    def __init__(self, path, controller):
        text = file(path).read().strip()
        TextTemplate.__init__(self, text, controller)

class MacroBase:
    def _get(self,item):
        return getattr(self, item, None)
    def __getitem__(self, item):
        """
         This is the clever bit
        """
        macro = self._get(item)
        if callable(macro):
            return macro()
        elif macro is not None:
            return macro
        else:
            # we have a choice here between throwing an exception and returning an empty string
            return ""
    def __contains__(self, item):
        """
         May not be neccessary but good form if we're acting like a dict
        """
        func = self._get(item)
        return (func is not None)

import os

class MacroController(MacroBase):
    """
     Static strings can be member variables.
     Computed strings are member functions that will only be called if used.
    """
    title = "Quick Test"
    def author(self):
        return os.environ.get('USER', 'unknown author')
    def filelist(self):
        items = ['<li>%s</li>' % item for item in os.listdir(os.getcwd())
                 if not item.startswith('.')]
        items.sort()
        return '\n'.join(items)
    def recursive(self):
        """
         A bit of silliness that may turn out to be useful
        """
        return TextTemplate('<em>Author is %(author)s</em>', self)

if __name__ == '__main__':
    c = MacroController()
    t = FileTemplate('test.txt', c)
    print t
