A Buffet replacement

2 views
Skip to first unread message

Ben Bangert

unread,
Mar 3, 2008, 4:41:19 PM3/3/08
to pylons...@googlegroups.com
We've talked about Buffet replacements before, but I've talked with a
few people now about going a different route. Making it so easy to
write your own 'render' function, that Buffet and such wouldn't even
be necessary.

Disadvantages:
- It's a few more lines of code to plugin a template engine (About
5-10 lines of Python code, most of which can be copy/pasted)

Advantages:
- Powerful template language capabilities aren't smothered under a
Template API
- It's significantly easier to see how and where you'd configure
specific options
- It's easy to change template rendering for a specific app
- It's easy to change global variables used in your app
- More efficient, ie, less function calls

I've include a render_mako and render_genshi function in
pylons.templating, there's a paste of the relevant section here:
http://pylonshq.com/pasties/732

I'm thinking that in new project templates, it will merely import
render_mako as 'render'. If a user needs to tweak options for Mako,
you can see from the render_mako where it looks for the Mako
TemplateLoader, and easily make it yourself in app_globals. No config
with prefix values all over being tossed around, no big Buffet objects
holding onto who knows what (generally its imported every template
engine it can).

It's rather easy to document, and provide some sample render functions
for other template languages used as well. I've included two helper
functions for use with render_* functions, one that pulls the Pylons
globals that should be included, and one that enables cache_* options
to be used.

Currently, I'm planning on having 0.9.7 new project templates use the
render_mako function, while including a future deprecation warning for
Buffet, with more blatent deprecation warnings in 0.9.8 as 1.0 will
drop Buffet entirely.

Any other thoughts?

Cheers,
Ben

Mike Orr

unread,
Mar 3, 2008, 6:47:23 PM3/3/08
to pylons...@googlegroups.com
On Mon, Mar 3, 2008 at 1:41 PM, Ben Bangert <b...@groovie.org> wrote:
> We've talked about Buffet replacements before, but I've talked with a
> few people now about going a different route. Making it so easy to
> write your own 'render' function, that Buffet and such wouldn't even
> be necessary.

Bypassing Buffet would be nice; it would save me a ton of work in
upgrading it, and we'd be rid of those half-baked dotted-notation
entry-point-using plugins.

One thing Ian wanted was a generic template loader which could be
passed in to template engines for looking up included/inherited
templates. But since no template engine has a hook for a non-native
loader, I'm not excited about putting work into it. Giving Mako a
Mako loader and Genshi a Genshi loader makes more sense.

> Disadvantages:
> - It's a few more lines of code to plugin a template engine (About
> 5-10 lines of Python code, most of which can be copy/pasted)

We need to do something for people who want to use a different plugin
other than the one that's discovered via the entry point (if there is
an entry point), so this would take care of that.

> Advantages:
> - Powerful template language capabilities aren't smothered under a
> Template API
> - It's significantly easier to see how and where you'd configure
> specific options
> - It's easy to change template rendering for a specific app
> - It's easy to change global variables used in your app
> - More efficient, ie, less function calls

> I'm thinking that in new project templates, it will merely import


> render_mako as 'render'. If a user needs to tweak options for Mako,
> you can see from the render_mako where it looks for the Mako
> TemplateLoader, and easily make it yourself in app_globals. No config
> with prefix values all over being tossed around, no big Buffet objects
> holding onto who knows what (generally its imported every template
> engine it can).

Well, that would give an excuse for pylons.g to exist. But it's an
unusual place to do application configuration, which is normally in
load_environment().

One problem is you're combining data variables and rendering options
into the same 'kwargs' namespace, which we were trying to avoid.
Buffet 1 never specified whether keyword args were one or the other,
although I think the plugins use them only for rendering options. But
those who prefer @expose or render(template, var1="value 1") over
pylons.c would like passing data values as keyword args. Our plan for
Buffet 2 was:

render(template, data_dict, cache_bla_bla_bla=None, **rendering_args)

> Currently, I'm planning on having 0.9.7 new project templates use the
> render_mako function, while including a future deprecation warning for
> Buffet, with more blatent deprecation warnings in 0.9.8 as 1.0 will
> drop Buffet entirely.

Sounds good.

--
Mike Orr <slugg...@gmail.com>

Ben Bangert

unread,
Mar 3, 2008, 7:13:29 PM3/3/08
to pylons...@googlegroups.com
On Mar 3, 2008, at 3:47 PM, Mike Orr wrote:

> Well, that would give an excuse for pylons.g to exist. But it's an
> unusual place to do application configuration, which is normally in
> load_environment().

Agreed, no reason the appropriate loader couldn't be created and
attached to 'g' in load_environment. I'll recode it to do that, with a
template toggle that includes the appropriate one for Mako/Genshi at
least.

> One problem is you're combining data variables and rendering options
> into the same 'kwargs' namespace, which we were trying to avoid.
> Buffet 1 never specified whether keyword args were one or the other,
> although I think the plugins use them only for rendering options. But
> those who prefer @expose or render(template, var1="value 1") over
> pylons.c would like passing data values as keyword args. Our plan for
> Buffet 2 was:
>
> render(template, data_dict, cache_bla_bla_bla=None,
> **rendering_args)

Technically, render_mako should only take the cache args, nothing
else. Since Pylons says you should use 'c' for template args. If
someone wants to pass args themselves, they should tweak the render
function as desired for what they want to do. I'll switch it to work
like that as well.

This resolves the mixing issue, and those who want to pass variables
instead can easily change the render function as desired. With the
TemplateLoader creation in load_environment, the render function is
down to about 4-6 lines of code. I don't think it will hurt people to
write one that works as they want.

Cheers,
Ben

Ian Bicking

unread,
Mar 4, 2008, 12:18:33 PM3/4/08
to pylons...@googlegroups.com
Ben Bangert wrote:
> We've talked about Buffet replacements before, but I've talked with a
> few people now about going a different route. Making it so easy to write
> your own 'render' function, that Buffet and such wouldn't even be
> necessary.

I would prefer a pattern like:

# in, maybe, helpers.py or something...
from something import MakoRenderer
render = MakoRenderer(
base_path=os.path.join(os.path.dirname(__file__), 'templates'),
... whatever other options you might set ...)


Then you have a clear place to do app-wide configuration (stuff like
whether you are using autoquoting). MakoRenderer would have a __call__
method with the appropriate signature. The lines of code wouldn't
increase significantly, as it would reduce the size of wsgiapp by about
the same amount.

Ian

Ben Bangert

unread,
Mar 4, 2008, 2:47:17 PM3/4/08
to pylons...@googlegroups.com
On Mar 4, 2008, at 9:18 AM, Ian Bicking wrote:

> I would prefer a pattern like:
>
> # in, maybe, helpers.py or something...
> from something import MakoRenderer
> render = MakoRenderer(
> base_path=os.path.join(os.path.dirname(__file__), 'templates'),
> ... whatever other options you might set ...)

What is MakoRenderer? The goal is to have as little beyond what the
template language needs to render something. Pylons already has the
config for the templates handy in the configuration object, though of
course perhaps that can be simplified a little.

> Then you have a clear place to do app-wide configuration (stuff like
> whether you are using autoquoting). MakoRenderer would have a
> __call__
> method with the appropriate signature. The lines of code wouldn't
> increase significantly, as it would reduce the size of wsgiapp by
> about
> the same amount.

As Mike was saying, if the load_environment has a line that loads the
Mako TemplateLoader, we'd have a load_environment.py like this:

from mako.lookup import TemplateLookup

def load_environment(global_conf, app_conf):
"""Configure the Pylons environment via the ``pylons.config``
object
"""
# Pylons paths
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
paths = dict(root=root,
controllers=os.path.join(root, 'controllers'),
static_files=os.path.join(root, 'public'),
templates=[os.path.join(root, 'templates')])

# Initialize config with the basic options
config.init_app(global_conf, app_conf, package='solon',
template_engine='mako', paths=paths)

config['routes.map'] = make_map()
config['pylons.g'] = app_globals.Globals()
config['pylons.h'] = solon.lib.helpers

# Setup SQLAlchemy database engine
engine = engine_from_config(config, 'sqlalchemy.')
init_model(engine)

# Setup the Mako template loader (or whatever template engine you
want)
config['pylons.g'].mako_lookup =
TemplateLookup(directories=paths['templates'])

# CONFIGURATION OPTIONS HERE (note: all config options will
override
# any Pylons config options)


Then the render function would look like this:

def render_mako(template_name, cache_key=None, cache_type=None,
cache_expire=None):
"""Render a template with Mako

Accepts the cache options ``cache_key``, ``cache_type``, and
``cache_expire`` in addition to other keyword arguments that should
be passed into Mako's ``Template.render`` function.

"""
# First, get the globals
globs = pylons_globals()

# Try and grab a template reference
template = globs['g'].mako_lookup.get_template(template_name)

# Update the template variables with the Pylons globals
kwargs.update(globs)

def render_template():
return template.render(**globs)

return cached_template(template_name, render_template, cache_key,
cache_type,
cache_expire, ns_options=('fragment',))


If you wanted to change options to the Mako templateloader, it'd be
really obvious how to do that... or change it to a different engine's
template loader as appropriate. What purpose does the MakoRenderer
object have?

Mike, I believe I've updated this as you suggested, such that Mako
under Pylons expects your variables to be attached to 'c' which are
then available under 'c' in Mako. Clearly users can tweak the render
function as desired should they wish to use it in different ways.

Cheers,
Ben

Ian Bicking

unread,
Mar 5, 2008, 12:36:25 AM3/5/08
to pylons...@googlegroups.com
Ben Bangert wrote:
> On Mar 4, 2008, at 9:18 AM, Ian Bicking wrote:
>
>> I would prefer a pattern like:
>>
>> # in, maybe, helpers.py or something...
>> from something import MakoRenderer
>> render = MakoRenderer(
>> base_path=os.path.join(os.path.dirname(__file__), 'templates'),
>> ... whatever other options you might set ...)
>
> What is MakoRenderer? The goal is to have as little beyond what the
> template language needs to render something. Pylons already has the
> config for the templates handy in the configuration object, though of
> course perhaps that can be simplified a little.

It's a rendering factory someone wrote. A little like Buffet, except no
entry points, no standardized way to instantiate the object, and no
particular need to make the render callable have a completely consistent
signature.

Putting a 15-line recipe into the pylons template seems really scrappy.

MakeRenderer seems simpler than this, with no recipe stuff stuck in there.

Ian

Ben Bangert

unread,
Mar 5, 2008, 3:25:20 AM3/5/08
to pylons...@googlegroups.com
On Mar 4, 2008, at 9:36 PM, Ian Bicking wrote:

> It's a rendering factory someone wrote. A little like Buffet,
> except no
> entry points, no standardized way to instantiate the object, and no
> particular need to make the render callable have a completely
> consistent
> signature.

Yet another level of obfuscation and misunderstanding, and yet another
thing that will trip up those wanting to try and change how a template
language is configured.

> Putting a 15-line recipe into the pylons template seems really
> scrappy.

All of Pylons is a recipe. It's a recipe to configure Paste, a batch
of middleware, and do some dispatching with Routes. The entire thing
is no more scrappy than having a render function that uses the
template engine.

I don't see this MakoRenderer being any less or more scrappy than a
basic render function, but at least everyone I showed the render
function to is 100% aware of what it does, and how they could change
it. While MakoRenderer is another "what the heck is this? how come I
can't just configure the template engine?".

> MakeRenderer seems simpler than this, with no recipe stuff stuck in
> there.

I'm baffled that the hundreds of lines of code in the
templateproposal, the setuptools entry points, the plugin hooks, the
limiting render calls (which prevent you from accessing the Genshi
stream object which some ppl want...).... is simpler than a 7 line
render function. Even with TemplateProposal, 95% of the code I pasted
is still needed in pylons.templating because it handles cache
functionality and populating the template variables with the Pylons
globals. I've written some extensive docs and committed them regarding
how to use the render functions and write one:
http://pylonshq.com/project/pylonshq/browser/pylons/templating.py

Let's ask the Pylons list, whether using this package:
http://svn.pythonpaste.org/Paste/TemplateProposal/branches/TemplateProposal-MSO/

Is easier than using the few lines of code needed for the render
functions. Also, keep in mind that for someone to even start to
override one of the plugins in templateproposal, first you get to
explain setuptools entry points, how to extend them, how to register
your own, then finally you get to write a render function... ick.

The point of Pylons is to try and make things easy through simplicity
and elegance, so far Buffet and its abstraction ilk has been the exact
opposite. After seeing how simple and short it is to just write a
little render function that does *exactly* what you want, its hard to
see the advantage in accepting template language limitations and
abstractions.

Cheers,
Ben

Mike Orr

unread,
Mar 5, 2008, 4:36:08 AM3/5/08
to pylons...@googlegroups.com
On Wed, Mar 5, 2008 at 12:25 AM, Ben Bangert <b...@groovie.org> wrote:
> On Mar 4, 2008, at 9:36 PM, Ian Bicking wrote:
> > Putting a 15-line recipe into the pylons template seems really
> > scrappy.
>
> I don't see this MakoRenderer being any less or more scrappy than a

Scrappy is a bad thing? Not in basketball or wrestling, or if you're
a little canine detective.

Let's also keep in mind that for TemplateProposal to get off the
ground, somebody needs to finish it and integrate it into Pylons, and
neither Ian nor I nor anybody else has had time to do it for three
months.

The fundamental point is that what a Pylons user needs is a render()
function that does the right thing, where "right" means following the
Pylons c/cache/templatedir policy with a popular template engine by
default, and ideally offering a choice of template engines. Replacing
a render() function is no more or less difficult than changing a
Buffet configuration, but it has the advantage of simplicity and
obviousness. A function is better than a class unless the class has
some other reason for existing (which usually means bundling up
methods and data in a way a function can't).

So if a choice of render() functions *can* work, by all means use it.
Renderer (generic) might be useful if it abstracted away some common
data and initialization code, but the template engines are so
different that there's no point. Mako has a loader the others don't,
Genshi has a very unusual API, they both use completely different
options for encodings, etc. If Pylons really means PylonsApp, then
render() has never been a part of it at all; it has always been
something the user called. So why not let the user build their own
from some utility functions, and provide a couple prebuilt ones for
convenience.

One glaring problem with Buffet 1 is there was no way to customize the
plugins' behavior, which was compounded by most of the plugins being
braindead. Writing and installing an alternate plugin was a herculean
task of learning entry points and figuring out the undocumented plugin
specs. Users just wanted to instantiate their own plugin class and
pass it to Buffet. Voila, here's what you have now. You take one of
the prebuilt functions or write your own. You don't even have to
register it anywhere, you just call it. Easy as py. (Groan.)

--
Mike Orr <slugg...@gmail.com>

Ian Bicking

unread,
Mar 5, 2008, 12:20:19 PM3/5/08
to pylons...@googlegroups.com
Ben Bangert wrote:
> On Mar 4, 2008, at 9:36 PM, Ian Bicking wrote:
>
>> It's a rendering factory someone wrote. A little like Buffet, except no
>> entry points, no standardized way to instantiate the object, and no
>> particular need to make the render callable have a completely consistent
>> signature.
>
> Yet another level of obfuscation and misunderstanding, and yet another
> thing that will trip up those wanting to try and change how a template
> language is configured.
>
>> Putting a 15-line recipe into the pylons template seems really scrappy.
>
> All of Pylons is a recipe. It's a recipe to configure Paste, a batch of
> middleware, and do some dispatching with Routes. The entire thing is no
> more scrappy than having a render function that uses the template engine.

Putting that code into Pylons is fine, but I think Pylons already has
too much code in the project template, and your proposal puts more code
in the project template. That code would need to be updated for any
kind of public change in a templating system's API.

> I don't see this MakoRenderer being any less or more scrappy than a
> basic render function, but at least everyone I showed the render
> function to is 100% aware of what it does, and how they could change it.
> While MakoRenderer is another "what the heck is this? how come I can't
> just configure the template engine?".

MakoRenderer is more a suggestion that templating engines expose an API
that is useful/friendly in the context of Pylons.

A useful API for Mako (at least with respect to Pylons) is one where you
configure a rendering instance, and then that rendering instance is
callable like the current render() function.

>> MakeRenderer seems simpler than this, with no recipe stuff stuck in
>> there.
>
> I'm baffled that the hundreds of lines of code in the templateproposal,
> the setuptools entry points, the plugin hooks, the limiting render calls
> (which prevent you from accessing the Genshi stream object which some
> ppl want...).... is simpler than a 7 line render function. Even with
> TemplateProposal, 95% of the code I pasted is still needed in
> pylons.templating because it handles cache functionality and populating
> the template variables with the Pylons globals. I've written some
> extensive docs and committed them regarding how to use the render
> functions and write one:
> http://pylonshq.com/project/pylonshq/browser/pylons/templating.py
>
> Let's ask the Pylons list, whether using this package:
> http://svn.pythonpaste.org/Paste/TemplateProposal/branches/TemplateProposal-MSO/

I agree that the entry point stuff and other aspects of that are
overdesigned. It was inherited from Buffet (and somewhat motivated by
paster create), but in the context of Pylons I agree there is no reason
to use an entry point.

MakoRenderer is a suggestion for how pylons.templating could work,
making it more similar to how helpers works, and less tied into things
like wsgiapp, pylons.config, etc.

I do agree with your proposal in terms of moving the render function
into projects directly, instead of importing it from Pylons. This makes
ad hoc render functions obvious, and I'm not suggesting that ad hoc
functions are bad. But there's no reason to make *every* render
function ad hoc.

Ian

Ben Bangert

unread,
Mar 5, 2008, 1:23:08 PM3/5/08
to pylons...@googlegroups.com
On Mar 5, 2008, at 9:20 AM, Ian Bicking wrote:

> Putting that code into Pylons is fine, but I think Pylons already has
> too much code in the project template, and your proposal puts more
> code
> in the project template. That code would need to be updated for any
> kind of public change in a templating system's API.

When you look at the existing template options being configured in the
project template, replacing the config lines for the template with
actually making the Mako TemplateLookup instance is a pretty close
tradeoff. There's only 3 lines added, and the result is significantly
more obvious. Consider these two, and tell me what the config options
are for Mako in the first case:

0.9.6 projects
# Customize templating options via this variable
tmpl_options = config['buffet.template_options']

0.9.7 project
# Create the Mako TemplateLookup
config['pylons.g'].mako_lookup = TemplateLookup(
directories=paths['templates'], input_encoding='utf-8',
output_encoding='utf-8', module_directory=os.path.join(
app_conf['cache_dir'], 'templates'),
)

If you wanted to change the template engine options in the first case,
how would you do it? What are the defaults it came with? I will
happily accept a line or two of extra code for obviousness and ease of
use/customization.

If you're using Genshi, its actually a zero-sum trade:

# Create the Genshi TemplateLoader
config['pylons.g'].genshi_loader =
TemplateLoader(paths['templates'])

Also, you can't see this, but by having the template engine created
here, I will get to drop about 100 lines of code from
pylons.configuration and things are cleaner both for the user, and for
Pylons.

With regards to the templating system's API, including
TemplateProposal in Pylons would have the same effect to needing to
change when the template system changes if it has the renderer objects
in it. That was the only saving grace of Buffet, was that the template
system API could change, and its included Buffet adapter could change
with it.

How often do the templating system API's actually change though? Is
that a strong argument for something that occurs frequently, or
something thats once in a blue moon (which could also be screwed up by
the existing pylons.configuration template system defaults)?

So far, Mako's TemplateLookup has stayed the same for many revisions,
and Genshi's is not changing in the next release either. But Pylons
has always had code that generally depends on specific revisions of
supporting packages. Mako and Genshi are both stable, fairly mature
template systems, they're the only ones Pylons is including a render
function for.

In the worst case scenario, that a user should upgrade Mako/Genshi
beyond a version Pylons recommends, and the template system API does
change slightly, it will be trivial for the user to fix it (and of
course a new Pylons version will address it as well). They can change
the loader in their environment, and tweak the render function if
needed. There is no waiting on a commit to the template system for an
updating plugin, no waiting for a commit/release of a new Pylons as
some default inside of Pylons might be screwing things up.

> MakoRenderer is more a suggestion that templating engines expose an
> API
> that is useful/friendly in the context of Pylons.
>
> A useful API for Mako (at least with respect to Pylons) is one where
> you
> configure a rendering instance, and then that rendering instance is
> callable like the current render() function.

I think current template systems do have friendly API's. Look at how
brief it is to do the basic template lookup creation, then render a
template with either Genshi or Mako. It's downright trivial, and
seriously makes you wonder what the hundreds of lines of code in
TemplateProposal are supposed to 'simplify'. I'm am consistently
seeing a trend where users prefer something obvious, even if its just
a wee bit more verbose, for the sake of not being left with a big
learning curve later when they want to change just one option in how
something works.

I should mention that I've had more than a few users ask me why they
have to dive though a big ol Template/Buffet thing to change a few
things about how a template system is used, when they can setup and
use the template engine in 5 lines of code in CherryPy or Django.
Saying, "In the very off chance that the template system API changes
dramatically, its slightly easier!" is hardly a good response.

> I agree that the entry point stuff and other aspects of that are
> overdesigned. It was inherited from Buffet (and somewhat motivated by
> paster create), but in the context of Pylons I agree there is no
> reason
> to use an entry point.

Though without the entry point scanning, I don't see how it'll be any
better than what I wrote up, as it won't be able to find the
appropriate render function automatically in installed template
systems. At which point, its just like what I wrote up except more
verbose.

> MakoRenderer is a suggestion for how pylons.templating could work,
> making it more similar to how helpers works, and less tied into things
> like wsgiapp, pylons.config, etc.

As Mike said, I'm curious what the point is for a class. It's not
holding any state data, why not just the render function?

> I do agree with your proposal in terms of moving the render function
> into projects directly, instead of importing it from Pylons. This
> makes
> ad hoc render functions obvious, and I'm not suggesting that ad hoc
> functions are bad. But there's no reason to make *every* render
> function ad hoc.

If you're using Genshi/Mako in the standard 'Pylons way' of using 'c'
for variables, the included render_ functions are provided by Pylons.
No need to write them yourself.

MakoRenderer is 'ad hoc' as much as render_mako. Can you clarify what
makes one of them less ad hoc purely because its a class rather than a
function?

Cheers,
Ben

Mike Orr

unread,
Mar 5, 2008, 2:21:47 PM3/5/08
to pylons...@googlegroups.com
On Wed, Mar 5, 2008 at 10:23 AM, Ben Bangert <b...@groovie.org> wrote:
> 0.9.7 project
> # Create the Mako TemplateLookup
>
> config['pylons.g'].mako_lookup = TemplateLookup(
> directories=paths['templates'], input_encoding='utf-8',
> output_encoding='utf-8', module_directory=os.path.join(
> app_conf['cache_dir'], 'templates'),
> )

Hmm, Cheetah does not have a loader, so looking for templates in a
certain directly would have to be provided by an external
(function|class). But render_cheetah() could do that itself from
config['pylons.paths']['templates']), and wouldn't need anything in
pylons.g. Most of the other template engines would also be in this
situation.

> With regards to the templating system's API, including
> TemplateProposal in Pylons would have the same effect to needing to
> change when the template system changes if it has the renderer objects
> in it. That was the only saving grace of Buffet, was that the template
> system API could change, and its included Buffet adapter could change
> with it.

The plan was to release TemplateProposal (Buffet 2) as a separate
package, so Pylons would just need some glue code to gather the
options and present them, plus a render function/class (which Pylons
has to provide due in order to inject the Pylons globals). The reason
Buffet 1 was in Pylons was it needed a lot of customization to be
compatible.

--
Mike Orr <slugg...@gmail.com>

Ben Bangert

unread,
Mar 5, 2008, 2:38:29 PM3/5/08
to pylons...@googlegroups.com
On Mar 5, 2008, at 11:21 AM, Mike Orr wrote:

> Hmm, Cheetah does not have a loader, so looking for templates in a
> certain directly would have to be provided by an external
> (function|class). But render_cheetah() could do that itself from
> config['pylons.paths']['templates']), and wouldn't need anything in
> pylons.g. Most of the other template engines would also be in this
> situation.

Most of the ones I've seen have an option to give it a directory
search path. In any case, the best way to encourage a template system
author to have a sane API, is to actually *use it*. If we wipe away
its issues under Buffet/TemplateProposal, they have little reason to
make a solid and sane template loader/render API in the template
system itself. Most of the time though, when a template system needs
more configuration, its for a good reason, and the user generally
wants to participate in ensuring the configuration meets their needs.
At which point, exposing that to the user directly is ideal to avoid
confusion and retain ease of use.

> The plan was to release TemplateProposal (Buffet 2) as a separate
> package, so Pylons would just need some glue code to gather the
> options and present them, plus a render function/class (which Pylons
> has to provide due in order to inject the Pylons globals). The reason
> Buffet 1 was in Pylons was it needed a lot of customization to be
> compatible.

Yea, thats exactly what I was afraid of. Yet another external
dependency package to track. Ian's argument about template system
API's also applies to tracking external TemplateRenderer packages,
both may change requiring a change in Pylons. Pretty much anything not
in Pylons itself, requires careful consideration to depend on as a new
version of said external package may change causing integration
issues. I know the TemplateProposal is supposed to be solid forever,
but you can't account for all options for all, or even most template
languages and hold out hope for stability any long than hoping they
can at least keep their template loader mechanism mostly the same over
revisions (which so far, they have).

At least with the render_ functions, if one of them breaks, and a
project *needs* to use the latest template system before a new Pylons
release can be issued, they can easily write their own render function.

Cheers,
Ben

Reply all
Reply to author
Forward
0 new messages