Welcome, guest | Sign In | My Account | Store | Cart

Trivia is simple but powerful Python Template. It was designed for making nice and easy HTML templates.

Python, 97 lines
 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
95
96
97
#    Trivia
#    Copyright (C) 2005  Petko Petkov (GNUCITIZEN) ppetkov@gnucitizen.org
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import re

class Template(unicode):
    """
    Trivia Template Object
    """

    def __init__(self, string):
        self.code = None
        unicode.__init__(self, string)
        self.compile()

    def __mod__(self, globals):
        """
        x.__mod__(globals) <==> x % other

        Expand template using globals.
        """

        locals = {'_':''}

        exec self.code in globals, locals

        return locals['_']

    def tokenize(self):
        """
        tokenize(self) -> generator

        Split self into tokens and return generator object.
        """
        for token in re.split('(<\?.*?\?>)', self):
            if token.startswith('<?') and token.endswith('?>'):
                yield token

            else:
                for ref in re.split('(###[\w_.]*)', token):
                    yield ref

    def compile(self):
        """
        compile(self) -> None

        Compile self into Python code.
        """

        if self.code is not None:
            return

        level = 0
        source = ''

        for token in self.tokenize():
            indent = ' ' * level * 2

            if token.startswith('###'):
                source = source + '%s_ = _ + %s\n' % \
                    (indent, token[3:].strip())

            elif token.startswith('<?') and token.endswith('?>'):
                content = token[2:-2]

                if content == 'end':
                    level = level - 1

                elif content.startswith('if ') \
                or content.startswith('for ') \
                or content.startswith('while '):
                    source = source + '%s%s:\n' % (indent, content)
                    level = level + 1

                elif content.startswith('='):
                    source = source + '%s_ = _ + %s\n' % \
                        (indent, content[1:].strip())

            else:
                source = source + '%s_ = _ + """%s"""\n' % \
                    (indent, token.replace('"""', r'\"\"\"'))

        self.code = compile(source, '<string>', 'exec')

I coded this Template in less than 30 minutes. Trivia provides you with simple interface for building documents out of HTML templates. This package is most suitable for HTML templates as I mentioned earlier but you can use it almost on every Text format.

I spent a few minutes on the actual design. My primary idea was to make template that is as simple as Python. This is how you can use it:

from trivia import Template file = open(‘template.html’) mytemplate = Template(file.read()) print mytemplate % {‘title’:’This is the title’, ‘posts’:[]}

Once you create template the actual content will be compiled into python code.

The template syntax is as follows:

    ###title


    This is my blog page and these are some of the stuff that you can
    do with it

    DISPLAY POSTS


        ###post.title
        <p>###post.content</p>

        However we can put post.content in this way:

Read the code for more information

2 comments

Christian Wyglendowski 15 years, 11 months ago  # | flag

Code for the template. Interesting looking recipe. Could you escape the html in your template example so that it shows up?

Petko Petkov (author) 15 years, 11 months ago  # | flag

Escape. Sorry about that. Here it is.

<html>

<head>

&lt;title&gt;###title&lt;/title&gt;

</head>

<body>

These are my posts:

&lt;?for post in posts?&gt;

  Post title: ###post.title&lt;br/&gt;

  Post content:&lt;br/&gt;

  ###post.content

&lt;?end?&gt;



&lt;?if post.has_timestamp ?&gt;

  Creation data: ###post.timestamp

&lt;?end?&gt;

</body>

</html>

Created by Petko Petkov on Thu, 15 Dec 2005 (PSF)
Python recipes (4591)
Petko Petkov's recipes (1)

Required Modules

Other Information and Tasks