TurboKid-1.0.5/ 0000755 0001750 0001750 00000000000 11327371776 011734 5 ustar cito cito TurboKid-1.0.5/turbokid/ 0000755 0001750 0001750 00000000000 11327371776 013557 5 ustar cito cito TurboKid-1.0.5/turbokid/tests/ 0000755 0001750 0001750 00000000000 11327371776 014721 5 ustar cito cito TurboKid-1.0.5/turbokid/tests/simple.kid 0000644 0001750 0001750 00000000021 11327371765 016672 0 ustar cito cito
Check: $v
TurboKid-1.0.5/turbokid/tests/extra.kid 0000644 0001750 0001750 00000000031 11327371765 016525 0 ustar cito cito Another check: $x
TurboKid-1.0.5/turbokid/tests/site.kid 0000644 0001750 0001750 00000001073 11327371765 016355 0 ustar cito cito
top
bottom
TurboKid-1.0.5/turbokid/tests/b.kid 0000644 0001750 0001750 00000000440 11327371765 015627 0 ustar cito cito
B
B
TurboKid-1.0.5/turbokid/tests/e.kid 0000644 0001750 0001750 00000000440 11327371765 015632 0 ustar cito cito
E
E
TurboKid-1.0.5/turbokid/tests/__init__.py 0000644 0001750 0001750 00000000021 11327371765 017021 0 ustar cito cito # turbokid.tests
TurboKid-1.0.5/turbokid/tests/d.kid 0000644 0001750 0001750 00000000440 11327371765 015631 0 ustar cito cito
D
D
TurboKid-1.0.5/turbokid/tests/a.kid 0000644 0001750 0001750 00000001134 11327371765 015627 0 ustar cito cito
page content
TurboKid-1.0.5/turbokid/tests/c.kid 0000644 0001750 0001750 00000000440 11327371765 015630 0 ustar cito cito
C
C
TurboKid-1.0.5/turbokid/tests/fruits.kid 0000644 0001750 0001750 00000000435 11327371765 016726 0 ustar cito cito
This is replaced.
These are some of my favorite fruits:
TurboKid-1.0.5/turbokid/tests/hello.kid 0000644 0001750 0001750 00000000664 11327371765 016521 0 ustar cito cito
Welcome to TurboKid
Hello, !
TurboKid-1.0.5/turbokid/tests/test_template.py 0000644 0001750 0001750 00000015523 11327371765 020151 0 ustar cito cito """TurboKid tests."""
import os
import sys
import time
from turbokid import KidSupport
values = dict(v='My value!', one=1)
def extra_vars():
return dict(x='Extra value!', two=2)
options = {
'kid.assume_encoding': 'utf-8',
'kid.encoding': 'utf-8',
'kid.precompiled': False,
'kid.sitetemplate': 'turbokid.tests.site',
'dummy': 'does nothing'
}
def get_engine():
return KidSupport(extra_vars, options)
def test_options():
"""Make sure all engine options are set."""
engine = get_engine()
opt = engine.options
assert opt['dummy'] == 'does nothing'
assert opt['kid.assume_encoding'] == engine.assume_encoding == 'utf-8'
assert opt['kid.encoding'] == engine.encoding == 'utf-8'
assert opt['kid.precompiled'] == engine.precompiled == False
assert opt['kid.sitetemplate'] == engine.stname == 'turbokid.tests.site'
def test_simple():
"""Make sure a simple test works."""
engine = get_engine()
s = engine.render(values, template='turbokid.tests.simple')
s = s.splitlines()[-1]
assert s == 'Check: My value!
'
def test_kid():
"""Make sure kid directives work."""
engine = get_engine()
values = {'title': 'Fruit Test', 'fruits': 'apple orange kiwi M&M'.split()}
s = engine.render(values, template='turbokid.tests.fruits')
assert s == """
Fruit Test
These are some of my favorite fruits:
-
I like apples
-
I like oranges
-
I like kiwis
-
I like M&Ms
"""
def test_not_found():
"""Make sure undefined variables do not go unnoticed."""
engine = get_engine()
try:
s = engine.render(None, template='turbokid.tests.simple')
except NameError:
pass
except Exception, e:
assert False, 'Undefined name raised wrong exception (%s)' % str(e)
else:
assert s.splitlines()[-1] != 'Check:', 'Undefined name was ignored'
assert False, 'Undefined name did not raise any exception'
def test_extra():
"""Make sure extra variables work."""
engine = get_engine()
s = engine.render(None, template='turbokid.tests.extra')
s = s.splitlines()[-1]
assert s == 'Another check: Extra value!
'
def test_unicode():
"""Make sure unicode values work."""
engine = get_engine()
s = engine.render({'v': u"K\xe4se!"}, template='turbokid.tests.simple')
assert isinstance(s, str)
s = s.splitlines()[-1]
assert s == u'Check: K\xe4se!
'.encode('utf-8')
def test_extend():
"""Make sure one template can inherit from another."""
engine = get_engine()
values = {'name': 'World', 'flash': 'flash',
'header': 'head', 'footer': 'foot'}
s = engine.render(values, template='turbokid.tests.hello')
assert s == """
Welcome to TurboKid
top
head
flash
Hello, World!
foot
bottom
"""
def test_template_string():
"""Check rendering of template strings."""
engine = get_engine()
t = engine.load_template(values, template_string='String: $v
')
s = t(**values).serialize().splitlines()[-1]
assert s == 'String: My value!
'
def load_and_render(engine, template, **kwargs):
"""Auxiliary function for loading and rendering a template."""
template = engine.load_template('turbokid.tests.%s' % template)
engine.render(kwargs, template=template)
return template
def touch(template, times=None):
"""Auxiliary function for changing the modification time of a template."""
fname = sys.modules['turbokid.tests.%s' % template].__file__
fhandle = file(fname, 'a')
try:
for n in range(6):
mtime = os.stat(fname).st_mtime
os.utime(fname, times)
if times or os.stat(fname).st_mtime != mtime:
break
time.sleep(0.5)
else:
raise OSError("Could not change modification time of %s." % fname)
finally:
fhandle.close()
def test_use_cache():
"""Make sure that load_template returns cached templates if there are no changes."""
engine = get_engine()
a1 = load_and_render(engine, 'a')
b1 = load_and_render(engine, 'b')
a2 = load_and_render(engine, 'a')
b2 = load_and_render(engine, 'b')
assert a1 is a2
assert b1 is b2
def test_template_reloads():
"""Make sure that templates reloads when it was changed."""
engine = get_engine()
a1 = load_and_render(engine, 'a')
b1 = load_and_render(engine, 'b')
touch('a')
a2 = load_and_render(engine, 'a')
b2 = load_and_render(engine, 'b')
assert a1 is not a2
assert b1 is not b2
def test_relations_1():
"""Make sure that template reloads in relations 1."""
engine = get_engine()
a1 = load_and_render(engine, 'a')
b1 = load_and_render(engine, 'b')
c1 = load_and_render(engine, 'c')
d1 = load_and_render(engine, 'd')
touch('a')
a2 = load_and_render(engine, 'a')
b2 = load_and_render(engine, 'b')
c2 = load_and_render(engine, 'c')
d2 = load_and_render(engine, 'd')
assert a1 is not a2
assert b1 is not b2
assert c1 is not c2
assert d1 is not d2
def test_relations_2():
"""Make sure that template reloads in relations 2."""
engine = get_engine()
a1 = load_and_render(engine, 'a')
b1 = load_and_render(engine, 'b')
c1 = load_and_render(engine, 'c')
d1 = load_and_render(engine, 'd')
touch('a')
c2 = load_and_render(engine, 'c')
a2 = load_and_render(engine, 'a')
d2 = load_and_render(engine, 'd')
b2 = load_and_render(engine, 'b')
assert a1 is not a2
assert b1 is not b2
assert c1 is not c2
assert d1 is not d2
def test_relations_3():
"""Make sure that template reloads in relations 3."""
engine = get_engine()
tmpls = 'abcde'
for t1 in tmpls:
for t2 in tmpls:
load_and_render(engine, t2)
touch(t1)
for t2 in tmpls:
load_and_render(engine, t2)
def test_relations_4():
"""Make sure that template reloads in relations 4."""
engine = get_engine()
tmpls = 'cebae' # use random order
for t1 in tmpls:
for t2 in tmpls:
load_and_render(engine, t2)
touch(t1)
for t2 in tmpls:
load_and_render(engine, t2)
TurboKid-1.0.5/turbokid/tests/master.kid 0000644 0001750 0001750 00000001626 11327371765 016710 0 ustar cito cito
Your title goes here
Header
Flash
page content
Footer
TurboKid-1.0.5/turbokid/__init__.py 0000644 0001750 0001750 00000000135 11327371765 015665 0 ustar cito cito from turbokid import kidsupport
KidSupport = kidsupport.KidSupport
__all__ = ["KidSupport"] TurboKid-1.0.5/turbokid/kidsupport.py 0000644 0001750 0001750 00000024256 11327371765 016344 0 ustar cito cito """Template support for Kid"""
import sys
from os import stat
from itertools import count
from threading import RLock
from logging import getLogger
from pkg_resources import resource_filename
import kid
log = getLogger('turbokid.kidsupport')
def _compile_template(package, basename, tfile, classname):
mod = kid.load_template(tfile, name=classname)
setattr(sys.modules[package], basename, mod)
return mod
def _get_extended_modules(template):
"""Recursively builds and returns a list containing all modules
of the templates extended from the template passed as parameter."""
excluded_modules = ['__builtin__', 'kid']
modules_list = []
for base_template in template.__bases__:
if base_template.__module__ not in excluded_modules:
modules_list.append(base_template.__module__)
if hasattr(base_template, '__bases__'):
modules_list.extend(_get_extended_modules(base_template))
return modules_list
class KidSupport(object):
extension = '.kid'
assume_encoding = encoding = 'utf-8'
precompiled = False
# sequence generator, should be thread-safe (at least in CPython)
string_template_serial = count()
def __init__(self, extra_vars_func=None, options=None):
if options is None:
options = dict()
self.options = options
self.get_extra_vars = extra_vars_func
self.assume_encoding = options.get(
'kid.assume_encoding', KidSupport.assume_encoding)
self.encoding = options.get(
'kid.encoding', KidSupport.encoding)
self.precompiled = options.get(
'kid.precompiled', KidSupport.precompiled)
if not self.precompiled:
self.compile_lock = RLock()
self.serializer = kid.HTMLSerializer(encoding=self.encoding)
self.sitetemplate = None
self.stname = options.get('kid.sitetemplate', None)
if options.get('kid.i18n.run_template_filter', False):
template_filter = options.get('kid.i18n_filter')
if not callable(template_filter):
template_filter = None
else:
template_filter = None
self.filter = template_filter
self.compiled_templates = {}
def load_template_string(self, template_string):
if not isinstance(template_string, basestring):
raise ValueError('You must pass a template string')
serial = self.string_template_serial.next()
tempclass = kid.load_template(template_string,
name="KidTemplateFromString-%d" % serial).Template
tempclass.serializer = self.serializer
return tempclass
def load_template(self,
classname=None, template_string=None, loadingSite=False):
"""Searches for a template along the Python path.
Template files must end in ".kid" and be in legitimate packages.
If the templates are precompiled to ".pyc" files, you can set the
"kid.precompiled" option to just do a straight import of the template.
"""
if template_string is not None:
return self.load_template_string(template_string)
elif classname is None:
raise ValueError('You must pass at least a classsname'
' or template_string as parameters')
if not loadingSite:
if self.stname and (not self.sitetemplate
or self.stname not in sys.modules):
self.load_template(self.stname, loadingSite=True)
sys.modules['sitetemplate'] = sys.modules[self.stname]
self.sitetemplate = sys.modules['sitetemplate']
lastdot = classname.rfind('.')
if lastdot < 0:
raise ValueError('All Kid templates must be in a package')
package, basename = classname[:lastdot], classname[lastdot+1:]
if self.precompiled:
# Always use the precompiled template since this is what
# the config says.
mod = __import__(classname, dict(), dict(), [basename])
else:
tfile = resource_filename(package, basename + self.extension)
ct = self.compiled_templates
self.compile_lock.acquire()
try:
if classname in sys.modules and classname in ct:
# This means that in sys.modules there is already
# the compiled template along with its bases templates
# and ct has their associated mtime.
# In this case we may need to recompile because the template
# itself or one of its bases could have been modified.
tclass = sys.modules[classname].Template
ttime = ct[classname]
mtime = stat(sys.modules[classname].__file__).st_mtime
reload_modules = mtime > ttime
if reload_modules:
ttime = mtime
# check the status of all base modules
for module in _get_extended_modules(tclass):
ctime = ct.get(module)
try:
mtime = stat(sys.modules[module].__file__).st_mtime
except KeyError:
if ctime is None:
mtime = ttime
else:
mtime = ctime
if ctime is None or mtime > ctime:
# base template is new or has changed
reload_modules = True
if mtime > ttime:
# base template has changed
reload_template = True
ttime = mtime
if reload_modules:
# we need to recompile the template
log.debug('Recompiling template for %s' % classname)
# This may have been also loaded as base from other templates
# by the Kid importer using a hashed module name,
# so we first invalidate the module loaded under that name.
temp_name = kid.importer.get_template_name(None, tfile)
if temp_name != classname and temp_name in sys.modules:
sys.modules[temp_name] = kid.load_template(tfile, temp_name)
# then we invalidate the template under its real name
del sys.modules[classname]
ct[classname] = ttime
# now we reload and recompile the template
mod = _compile_template(
package, basename, tfile, classname)
else:
# No need to recompile the template or its bases,
# just reuse the existing modules.
mod = __import__(classname, dict(), dict(), [basename])
else:
# This means that in sys.modules there isn't yet the
# compiled template, let's compile it along with its bases
# and store in self.compiled_templates their mtime.
log.debug('Compiling template for %s' % classname)
mod = _compile_template(package, basename, tfile, classname)
tclass = mod.Template
ttime = stat(sys.modules[classname].__file__).st_mtime
for module in _get_extended_modules(tclass):
mtime = stat(sys.modules[module].__file__).st_mtime
ct[module] = mtime
if mtime > ttime:
ttime = mtime
# store max of mtimes of template and all of its bases
ct[classname] = ttime
finally:
self.compile_lock.release()
tempclass = mod.Template
tempclass.serializer = self.serializer
return tempclass
def render(self, info, format='html', fragment=False, template=None):
"""Renders data in the desired format.
@param info: the data itself
@type info: dict
@param format: Kid output method and format, separated by whitespace
@type format: string
@param fragment: passed through to tell the template if only a
fragment of a page is desired
@type fragment: bool
@param template: the name of the template to use
@type template: string
"""
if isinstance(template, type):
tclass = template
else:
tclass = self.load_template(template)
log.debug('Applying template %s' % (tclass.__module__))
data = dict()
if self.get_extra_vars:
data.update(self.get_extra_vars())
if info:
data.update(info)
template = tclass(**data)
if self.assume_encoding:
template.assume_encoding = self.assume_encoding
if self.filter and self.filter not in template._filters:
template._filters.append(self.filter)
if isinstance(format, str):
if format.endswith('-straight'):
# support old notation 'html-straight' instead 'html straight'
format = (format[:-9], format[-8:])
else:
format = format.split()
elif not isinstance(format, (tuple, list)):
format = (format,)
if len(format) < 2:
output, format = format[0], None
else:
output, format = format[:2]
return template.serialize(encoding=self.encoding, fragment=fragment,
output=output, format=format)
def transform(self, info, template):
if isinstance(template, type):
tclass = template
else:
tclass = self.load_template(template)
data = dict()
if self.get_extra_vars:
data.update(self.get_extra_vars())
data.update(info)
template = tclass(**data)
if self.filter and self.filter not in template._filters:
template._filters.append(self.filter)
return kid.ElementStream(template.transform()).expand()
TurboKid-1.0.5/TurboKid.egg-info/ 0000755 0001750 0001750 00000000000 11327371776 015151 5 ustar cito cito TurboKid-1.0.5/TurboKid.egg-info/requires.txt 0000644 0001750 0001750 00000000014 11327371776 017544 0 ustar cito cito kid >= 0.9.6 TurboKid-1.0.5/TurboKid.egg-info/dependency_links.txt 0000644 0001750 0001750 00000000001 11327371776 021217 0 ustar cito cito
TurboKid-1.0.5/TurboKid.egg-info/not-zip-safe 0000644 0001750 0001750 00000000001 11327371776 017377 0 ustar cito cito
TurboKid-1.0.5/TurboKid.egg-info/PKG-INFO 0000644 0001750 0001750 00000001307 11327371776 016247 0 ustar cito cito Metadata-Version: 1.0
Name: TurboKid
Version: 1.0.5
Summary: TurboGears plugin to support use of Kid templates
Home-page: http://docs.turbogears.org/TurboKid
Author: Christoph Zwerschke
Author-email: cito@online.de
License: MIT
Download-URL: http://pypi.python.org/pypi/TurboKid
Description: UNKNOWN
Keywords: python.templating.engines,turbogears
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: TurboGears
Classifier: Environment :: Web Environment :: Buffet
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Software Development :: Libraries :: Python Modules
TurboKid-1.0.5/TurboKid.egg-info/top_level.txt 0000644 0001750 0001750 00000000011 11327371776 017673 0 ustar cito cito turbokid
TurboKid-1.0.5/TurboKid.egg-info/SOURCES.txt 0000644 0001750 0001750 00000001146 11327371776 017037 0 ustar cito cito README.txt
setup.cfg
setup.py
TurboKid.egg-info/PKG-INFO
TurboKid.egg-info/SOURCES.txt
TurboKid.egg-info/dependency_links.txt
TurboKid.egg-info/entry_points.txt
TurboKid.egg-info/not-zip-safe
TurboKid.egg-info/requires.txt
TurboKid.egg-info/top_level.txt
turbokid/__init__.py
turbokid/kidsupport.py
turbokid/tests/__init__.py
turbokid/tests/a.kid
turbokid/tests/b.kid
turbokid/tests/c.kid
turbokid/tests/d.kid
turbokid/tests/e.kid
turbokid/tests/extra.kid
turbokid/tests/fruits.kid
turbokid/tests/hello.kid
turbokid/tests/master.kid
turbokid/tests/simple.kid
turbokid/tests/site.kid
turbokid/tests/test_template.py TurboKid-1.0.5/TurboKid.egg-info/entry_points.txt 0000644 0001750 0001750 00000000116 11327371776 020445 0 ustar cito cito
[python.templating.engines]
kid = turbokid.kidsupport:KidSupport
TurboKid-1.0.5/setup.cfg 0000644 0001750 0001750 00000000073 11327371776 013555 0 ustar cito cito [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
TurboKid-1.0.5/setup.py 0000644 0001750 0001750 00000002120 11327371765 013437 0 ustar cito cito from setuptools import setup, find_packages
setup(
name="TurboKid",
version="1.0.5",
description="TurboGears plugin to support use of Kid templates",
author="Kevin Dangoor et al",
author_email="dangoor+turbogears@gmail.com",
maintainer="Christoph Zwerschke",
maintainer_email="cito@online.de",
url="http://docs.turbogears.org/TurboKid",
download_url="http://pypi.python.org/pypi/TurboKid",
keywords=["python.templating.engines", "turbogears"],
license="MIT",
install_requires = ["kid >= 0.9.6"],
zip_safe=False,
packages=find_packages(),
classifiers = [
'Development Status :: 4 - Beta',
'Framework :: TurboGears',
'Environment :: Web Environment :: Buffet',
'Operating System :: OS Independent',
'Programming Language :: Python',
'License :: OSI Approved :: MIT License',
'Topic :: Software Development :: Libraries :: Python Modules'
],
entry_points="""
[python.templating.engines]
kid = turbokid.kidsupport:KidSupport
""",
test_suite = 'nose.collector',
)
TurboKid-1.0.5/PKG-INFO 0000644 0001750 0001750 00000001307 11327371776 013032 0 ustar cito cito Metadata-Version: 1.0
Name: TurboKid
Version: 1.0.5
Summary: TurboGears plugin to support use of Kid templates
Home-page: http://docs.turbogears.org/TurboKid
Author: Christoph Zwerschke
Author-email: cito@online.de
License: MIT
Download-URL: http://pypi.python.org/pypi/TurboKid
Description: UNKNOWN
Keywords: python.templating.engines,turbogears
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: TurboGears
Classifier: Environment :: Web Environment :: Buffet
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Software Development :: Libraries :: Python Modules
TurboKid-1.0.5/README.txt 0000644 0001750 0001750 00000001472 11327371765 013434 0 ustar cito cito TurboKid
========
This package provides a template engine plugin, allowing you
to easily use Kid with TurboGears, Buffet or other systems
that support python.templating.engines.
There are plans to integrate this functionality into Kid,
so this package may eventually become superfluous.
Kid templates are assumed to have a "kid" extension.
For information on the Kid templating engine, go here:
http://kid-templating.org
Kid is the standard templating engine for TurboGears 1.0, so
for information on using Kid templates with TurboGears, go here:
http://docs.turbogears.org/1.0/GettingStarted/Kid
For general information on using a template engine plugin
with TurboGears or writing a template engine plugin, go here:
http://docs.turbogears.org/1.0/TemplatePlugins
http://docs.turbogears.org/1.0/AlternativeTemplating