My favorites | Sign in
Project Home Downloads Wiki Issues Source
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 4: Provide a standard way for formatters to take arguments, e.g. for implementing include statement
6 people starred this issue and may be notified of changes. Back to list
Status:  Started
Owner:  ----


Sign in to add a comment
 
Project Member Reported by dlikhten, Mar 30, 2009
It would be quite useful to allow a template to include another template
passing it a section as the "root". Here is an example:

Template 1:
{.section items}
  <h1>{name}</h1>
  {.repeater section @}
    <a href="{urlbase}{url}"></a>
  {.end}
{.end}

Template 2:
{.section shoppingCart}
  {.template 'Template 1' @}
{.end}

OR

Template 2:
{.template 'Template 1' shoppingCart}


Its a tad bit funky since currently templating (I am using the javascript
version) takes in a string and substitutes.

What would be nice is the ability to pass in custom template finders so we
can specify the rules of how to retrieve another template string.
Mar 31, 2009
Project Member #1 gtempacc...@yahoo.com
I just documented two template reuse patterns that I think are superior to adding an
include feature:

https://code.google.com/p/json-template/source/browse/trunk/python/examples/reusing_the_outside.py

https://code.google.com/p/json-template/source/browse/trunk/python/examples/reusing_the_inside.py

There's an explanation inline with the comments.

Live examples are here:

http://chubot.org/json-template/cgi-bin/examples/reusing_the_inside.py/
http://chubot.org/json-template/cgi-bin/examples/reusing_the_outside.py/

(Note the trailing slash)

Let me know what you think.  I'm going to write a "Design Minimalism" blog post the
explains this point and another design decision (about the metacharacters).  One of
the virtues is that I'm trying to cover a lot of use cases with the bare minimum of
features.  This keeps the code size small, and lowers the barrier for implementations
in other languages.


Apr 5, 2009
Project Member #2 andyc...@gmail.com
I wrote a very long-winded response to this (you weren't the only one to ask for
this; it was the most obvious hole):

http://json-template.googlecode.com/svn/trunk/doc/On-Design-Minimalism.html

If there's some problem you have that you those methods won't solve, or you find them
deficient in some way, feel free to comment here.  Closing for now.

Status: WontFix
Apr 5, 2009
Project Member #3 dlikhten
Sorry I just have to press on for my idea. Though not in the same incarnation as it
was originally.

After first seeing your response on my blackberry I could not really read the full
examples normally, but it got some gears turning in my head, after reading your
inside method I think I finally refined what exactly we want to do... There is still
one major limitation which cannot be resolved by either methods I provided OR you.

Formatter parameters is the necessary features... example:

{userProfile|template(user/profiles/v1.tpl)}

I think you can pretty much see where I am going with this. This is a slight
modification of the inside pattern that you have except that I don't need to specify
EVERY type of template inclusion fomratter I will ever need globally, instead I just
create a "template" formatter which finds the template files in the way that I define
in my server. I just need the ability to pass it parameters like which template to
render.



Now for the problem with all methods (and this is more of a nice-to-have than a
necessity like the formatter parameters):

Each template has different .js and .css requirements. It would be great if I could
have templates really define "what they need" to work. Without the includer ever
having to know/care about it (leaky abstractions but you get the idea).

Example:

Page1 (shell) -- no requirements.
user-summary.tpl (inner template) -- user-summary.css, user-summary.js requirements. 

the inner template wants to tell the shell that where it renders .css files it must
also render user-summary.css, where it renders .js files it must render user-summary.js.


The question is: Do the dependency statements that I describe above fit in with the
JSON template philosophy or do they go somewhere to the side?
Apr 5, 2009
Project Member #4 gtempacc...@yahoo.com
Ah I just added that to the article!  Someone else didn't like the level of
indirection between formatter names and templates.  I used the % character, but
there's no reason you can't use template(<filename>) -- since formatter names are raw
strings that the application interprets.  (See the second definition of MoreFormatters)

I didn't even realize this at first, but this scheme is turning out to be quite flexible.

Good point about .js and .css dependencies.  Perhaps we could define extensible
metadata per template.  There already is constructor metadata (FromFile/FromString).
 I'll have to think about this a bit.  Do other template systems have a solution for
this problem?

But try out the first thing and see if it works for you.
Apr 5, 2009
Project Member #5 dlikhten
You do have a nice point about the fact that MoreFormatters in your inner example can
easily parse out the template\((.*)\) and keep going. I just feel that maybe that's
what the framework should provide. I see this construct being useful for other cases
beyond simply templates. The way the formatter function could be constructed is:

MoreFormatters(format,args /* an array */ )

Definitely a recipe for template inclusions should be specified in the API for the
framework. I realize this is not "part of the framework" but it is just as important
as it might not be immediately obvious to people about how to approach this when they
first see JSON template.



Regarding dependencies... Ruby on Rails has a sort-of kind-of thingy like this.
Basically the <% yeild for='foo' %>

So my shell can have:

<html>
  <head>
    <% yield for='css' %> 
    ... 
    <% yield for='js' %>
  </head>
  <body>
    <% yield %>
  </body>
</html>

Or something similar sorry the ruby syntax is fading from my brain I haven't used it
in over a year.

However that is NOT what I meant... its more of a repeating section in how JSON
template defines it... my ideal solution quickly manifested, I haven't given this
syntax much thought but hopefully it illustrates what I am trying to get at.

<html>
  <head>
    <!-- some css that is statically included in the page -->
    <link ...>

    {.dependencySection css}
      {.repeat section @}
        <link rel="Stylesheet" media="{media}" href="{server-base}/{relpath}">
      {.end}
    {.end}

    <title>Hello Templating World!</title>

    <!-- some js files that are statically included -->
    <script type="text/javascript src="{server-base}/..."></script>
    {.dependencySection js}
      {.repeat section @}
        <script type="text/javascript src="{server-base}/{relpath}"></script>
      {.end}
    {.end}

  </head>
  <body>
    {mainData|template(foo.tpl)}
  </body>
</html>
Apr 5, 2009
Project Member #6 gtempacc...@yahoo.com
Yeah I do see the need for standardization around the formatters.  Actually the
syntax I chose in example was bad, because the %filename syntax conflicts with %.3f
Python formatter syntax I had written earlier.  So those could be expressed:
{var|template(filename)} and {floating-point|printf(%.3f)}.  If people like brevity
they can always define their own syntax, but there should be a standard one.

I would make this another module next to jsontemplate.py, called formatters.py.  And
then we can add all the common use cases there, so that everybody doesn't invent
their own.

To get real reuse, I think there might need to be some higher order function
chaining, like:

Template("...", more_formatters=Chain([formatters.FileLoader('root-directory'),
formatters.PythonPrintfFormat()])

or something like that.  Now you can include template() and printf() as formatters. 
Are you interested in providing a patch for this?

-----

As for the dependencies, did you look at the example linked in the Design Minimalism
article about how it's generated?  That already has repeated sections for js and css.
 There's no need for another section type there.

Is the issue that you want to package the .css and .js paths (which are part of the
data dictionary) in the same file as the template?

Status: New
Apr 6, 2009
Project Member #7 dlikhten
Dependencies is more along the lines of, an inner template specified what
dependencies it has (it knows how the outer template accepts data, but that's it) and
the outer template will render the inner's dependencies.

An example is the html skeleton which defines where .js and .css files go, but
user-summary.tpl needs a js and css file, so it gives those two to the outer template
to be placed in the header. Sort of like a static JSON object declaration. This is
NOT part of the JSON data given to the template, it is purely a construct inside the
templates.


As for template... I just want a parametrized formatters pattern. This way I (working
in a javascript server) can implement how to retrieve other files. Actually I never
had a need to do python programming (a good time to start is now :) but I might be
really slow making these python implementations :(, or I can make the javascript side
and you can port to py). However once you have the parametrized stuff that detail is
removed from things like printf(%0.3f)

I like the printf idea as well, definitely helps since it handles most necessary cases.

My idea of the template formatter is to have it ask for a file finder function which
takes a path and finds it. We can have a default one for django or w/e, its just that
each web server has their own methodology of how to find files, so it might be
problematic to actually implement a real finder.



Apr 6, 2009
Project Member #8 dlikhten
Sorry to add to the above... Once we have parametrized formatters, we can just give a
recipes page of all sorts of cool recipes people come up with when designing JSON
template. These recipes will be things you (or the community) decides are necessary
but don't need to be in the language.
Apr 6, 2009
Project Member #9 andyc...@gmail.com
OK, well if you want to hack something up for the JavaScript version, I'll look at it
and implement the Python version.  I think that in both cases it should be a separate
module.  Particularly in the JavaScript case, people care about download size.

Do you see what I'm saying about the chaining?  The compiler has resolve a formatter
string to an actual formatter, so first it will try "template()", and then
"printf()", etc.   So we would have to compose functions to create a single
more_formatters= function.

I agree about having "recipes"; there should be a standard set.  The thing is that
all implementations won't always be in sync, so it's important to have a standard to
follow.

Django already has a large list of formatters.  Where possible we should borrow them
(but they're not all named greatly):

http://docs.djangoproject.com/en/dev/ref/templates/builtins/#add
Apr 6, 2009
Project Member #10 dlikhten
Since currently the only way to make custom formatters is to have one, we need to
chain... Right.

Right we can give the users the ability to make their own formatter lookup and
whatever funky syntax they want, or use the default to add multiple formatters and
use them by a key lookup. Definitely a necessity as well.

May I recommend we take this discussion off the bug post and post a strategy as the
next comment? This is turning into a back-and-forth conversation. Email me at gmail.
Apr 6, 2009
Project Member #11 andyc...@gmail.com
Yeah let's take this to the discussion list.  There are enough people on it that they
might provide some feedback.

Apr 6, 2009
Project Member #12 gtempacc...@yahoo.com
(No comment was entered for this change.)
Summary: Provide a standard way for formatters to take arguments, e.g. for implementing include statement
Apr 9, 2009
Project Member #13 gtempacc...@yahoo.com
We've agreed on a way to do this -- it still needs to be implemented in JavaScript
and documented everywhere.

Status: Started
May 14, 2009
#14 Robert.David.Williams
I recommend implementing a simple template recursion feature such as in
StringTemplate.  On the other hand, I strongly recommend against the idea of tracking
dependencies between templates as described here.  Please allow me to explain...

My desired usage scenario is that I want a simple API for creating an empty instance
of a template, assembling and inserting my data, then rendering the template with
that data to obtain a String.  The template engine should be aware of and properly
handle character encoding, probably by forcing me to declare the encoding of the
template(s) prior to loading.

So, I should be able to do something like the following:

    instance = template.create("name")
    data = ...(whatever I want, independent of the template API)...
    output = instance.render(data)

A crucial feature of this approach is that I should be able to refactor the template
"name" as much as I want without having to edit the code to use it.  In particular, I
should be able to refactor gracefully from a template in a single file (known by
"name") to splitting the template up into as many named pieces (separate files) as I
want.  Typically, template "name" represents a single web page, report, or whatever
other output that I desire.

This feature necessitates a means of invoking the template engine with a
configuration for finding all the template pieces.  This might mean a constructor
that takes a directory (with named templates as files within the subdirectory tree).
 This might mean a single file with templates as named sections within it.  This
might mean a constructor for the template engine that creates an empty template
holder that allows the user to add named templates at will, via whatever mechanism
that the user chooses.  In JavaScript, the engine could make AJAX calls to request
empty templates by name from the server (where relevant).

As a consequence, each template instance must have a parent object that knows how to
resolve and provide any references to other templates.  StringTemplate does this via
a StringTemplateGroup.

However, one of StringTemplate's problems is that the API has gotten way too complex,
in large part because of this addition of the StringTemplateGroup, plus some special
syntax to support it, etc.  I STRONGLY advocate for keeping your template language
and the API simple and clean.  In particular, if you add such a feature then I would
make it a separate deliverable/artifact that is optional and separately testable
(which StringTemplate did not do).

As for the whole dependency thing, I consider it to be a nonissue.  If I am
templating a web page, then the browser will trigger the rendering of the HTML
template by the initial web request.  When the browser finds a reference to the
"external" CSS file, then that web request will trigger the rendering of the CSS
template.  Likewise, the reference to the "external" JavaScript file in the HTML
template will trigger a web request for the JavaScript template.  If I edit the HTML
template to no longer reference the "external" CSS or JavaScript, then the browser
won't find them and it won't issue web requests for them.  However, I want to be able
to make that CSS and JavaScript internal by replacing the "external" references with
"internal" references to the same (sub)templates.  I should be able to switch back
and forth between those implementations without changing my code, and I can with
StringTemplate.

However, StringTemplate has gotten too complex and they seem to have lost sight of
the real usage patterns, so their test suite is incomplete and does not adequately
cover these features.  Therefore, in recent versions, this behavior has become buggy
and the code base has become bloated.

I think that we can avoid a repetition with json-template, and I am committed to
helping do so.

Best wishes...
May 14, 2009
Project Member #15 andyc...@gmail.com
You know I think you'll be pleased with the reuse mechanism(s).  It satisfies the
properties you request, and the API for JSON Template is still dead simple.

The key is that the include mechanisms are implemented as a special case of
"formatters".  It's completely on top of the engine, and user configurable.  I wrote
the file system include mechanism in formatters.py, but you can also write one that
does AJAX calls, etc. like you said.  All without modification of the API.

Definitely read this if you haven't:

http://json-template.googlecode.com/svn/trunk/doc/On-Design-Minimalism.html

The implementation now basically a demo, and not really "standardized".  But the idea
is all there.  I think it's too early to standardize; we need some more feedback
based on actual usage.

I hadn't seen StringTemplate until now.  It sounds like it has some of the same
problems in mind.  But I took one look at this page:
http://www.antlr.org/wiki/display/ST/StringTemplate+Documentation

And my initial thought is that it's way too complicated.

It's interesting that there's a paper about how it's a functional language:
http://www.cs.usfca.edu/~parrt/papers/ST.pdf

I'll have to read this sometime.  JSON Template is also a functional language as I
wrote in that article... in particular all language constructs can be evaluated in
any order whatsoever.
Nov 7, 2009
Project Member #16 gtempacc...@yahoo.com
Done in JS and Python

This is the FunctionRegistry set of APIs
Labels: Todo-Java Todo-PHP
Sign in to add a comment

Powered by Google Project Hosting