Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 7e2e210426
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 94 lines (73 sloc) 2.794 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
from pystache import Template
import os.path
import re
from types import *

def get_or_attr(context_list, name, default=None):
    if not context_list:
        return default

    for obj in context_list:
        try:
            return obj[name]
        except KeyError:
            pass
        except:
            try:
                return getattr(obj, name)
            except AttributeError:
                pass
    return default

class View(object):
    
    template_name = None
    template_path = None
    template = None
    template_encoding = None
    template_extension = 'mustache'
    
    def __init__(self, template=None, context=None, **kwargs):
        self.template = template
        context = context or {}
        context.update(**kwargs)

        self.context_list = [context]
        
    def get(self, attr, default=None):
        attr = get_or_attr(self.context_list, attr, getattr(self, attr, default))
        if hasattr(attr, '__call__') and type(attr) is UnboundMethodType:
            return attr()
        else:
            return attr
    
    def get_template(self, template_name):
        if not self.template:
            from pystache import Loader
            template_name = self._get_template_name(template_name)
            self.template = Loader().load_template(template_name, self.template_path, encoding=self.template_encoding, extension=self.template_extension)
        
        return self.template

    def _get_template_name(self, template_name=None):
        """TemplatePartial => template_partial
Takes a string but defaults to using the current class' name or
the `template_name` attribute
"""
        if template_name:
            return template_name

        template_name = self.__class__.__name__

        def repl(match):
            return '_' + match.group(0).lower()

        return re.sub('[A-Z]', repl, template_name)[1:]

    def _get_context(self):
        context = {}
        for item in self.context_list:
            if hasattr(item, 'keys') and hasattr(item, '__getitem__'):
                context.update(item)
        return context

    def render(self, encoding=None):
        return Template(self.get_template(self.template_name), self).render(encoding=encoding)

    def __contains__(self, needle):
        return needle in self.context or hasattr(self, needle)

    def __getitem__(self, attr):
        val = self.get(attr, None)

        if not val and val is not 0:
            raise KeyError("Key '%s' does not exist in View" % attr)
        return val

    def __getattr__(self, attr):
        if attr == 'context':
            return self._get_context()

        raise AttributeError("Attribute '%s' does not exist in View" % attr)

    def __str__(self):
        return self.render()
Something went wrong with that request. Please try again.