Hello, Alex, I agree with Wim Feijen. The ability to implement a arbitrary syntax for tag parameters is too abstract problem and this causes an increase in the complexity of the solution. Tag delelopers are forced to define a grammar and deal with lexing and parsing. End users must to learn and remember a custom syntax for each of tags. A similar problem is solved by developers of python for CLI, and they came up with `http:// docs.python.org/library/argparse.html` library (however, in our case it is too complicated way, imho).
The writing of templates should be an easy work, with a low threshold to entry. It would be nice if template tags will provide us with some common basic syntax for most of them. Without the need to develop a grammar and to RTFM a tag parameters syntax when we are need to use them. The description of the custom syntax have be resorted to only when absolutely necessary. We should not be afraid of the python-like grammar for tag paramenters. There is not principal difference beetween custom {% mytag src limit 1 offset 10 %} and pythonic {% mytag src limit=1 offset=10 %}. The restrict syntax makes the solution simpler. The saving of results in context variable looks like a common task and it should be delegated to an external tool (like a filter {% mytag src| as:bar %}). There are just few cases where custom syntaxis is nesessary. For example the logic and mathematical expressions with rich grammar rules. But simplest way in those cases is to use specialized libraries, there problems of grammar definition, lexing and parsing already solved. Look http://pyparsing.wikispaces.com/ for example. Evgeny -- I'm sorry for my silly english On Sep 11, 2:11 am, Alex Gaynor <alex.gay...@gmail.com> wrote: > On Fri, Sep 9, 2011 at 6:16 PM, Wim Feijen <wimfei...@gmail.com> wrote: > > Hi Alex, > > > Probably I am thinking way too simple, but if you gave me a free > > choice of how to write templatetags in my code, I would prefer: > > > def mytag(foo, bar): > > # some code > > return output > > > or: > > > class MyTag(Tag): > > def __init__(self, foo, bar): > > self.foo = foo > > self.bar = bar > > > and > > > def mytag(src, limit=1, offset=10, ??) > > > or: > > > class MyTag(Tag): > > def __init__(self, limit=1, offset=10, ??): > > self.limit = limit > > self.offset = offset > > > def render(self): > > """do some nasty stuff to limit and offset and return something.""" > > > Just kick me if I am talking non-sense, that's ok. > > > Wim > > > On 10 sep, 02:29, Alex Gaynor <alex.gay...@gmail.com> wrote: > > > Hello all, > > > > For many years, writing templatetags has been among the most hilariously > > > complicated things we Django developers did. Anyone who has written > > parsing > > > for > > > templatetags, over and over, shares this pain. Further, the current > > syntax > > > present a tremendous problem for Armin Ronacher's GSOC towards template > > > compilation: template tags define a ``render()`` method, which takes the > > > current context (a stack of dictionaries) and perform some behavior which > > is > > > opaque to the caller. This is a problem because one of the core > > objectives > > > of > > > the template compilation infrastructure is to store the template context > > in > > > Python local variables, rather than in dictionaries. For all these > > reasons, > > > several of us (myself, Idan, Russ, Carl Meyer, Andrew Godwin, Jonas > > Obrist, > > > Chris Beaven) just sat down (we actually stood, mostly) and tried to iron > > > out a > > > proposal that solves these problems, taking inspiration from the plethora > > of > > > libraries that exist today. > > > > We ultimately created two possible solutions, one inspired primarily by > > > django-classy-tags and django-templatetag-sugar, the other mostly > > inspired > > > by > > > django-ttags. We came to a fragile agreement on the first. We primarily > > > evaluated two cases for these, one very simple, the other more complex, > > and > > > compared the resulting implementations. > > > > The first case we considered was a templatetag which takes two, required, > > > arguments. Invocation looks like ``{% mytag foo bar %}``. The two > > > definitions > > > look like: > > > > class MyTag(Tag): > > > args = [ > > > Argument("foo"), > > > Argument("bar"), > > > ] > > > > class MyTag(Tag): > > > foo = Argument() > > > bar = Argument() > > > > the second case we considered was a tag which has one required, > > positional, > > > argument, and two optional, keyword arguments, which can occur in any > > order, > > > followed by a final, optional keyword argument, meaning any of the > > following > > > invocations are valid: > > > > {% mytag src limit 1 offset 10 %} > > > {% mytag src limit 1 offset 10 with foo %} > > > {% mytag src limit 1 %} > > > {% mytag src offset 10 limit 1 %} > > > {% mytag src %} > > > > and the two implementations were: > > > > class MyTag(Tag): > > > args = [ > > > Argument("source"), > > > Unordered( > > > NamedArgument("limit", required=False), > > > NamedArgument("offset", required=False), > > > ), > > > NamedArgument("as", required=False, resolve=False) > > > ] > > > > class MyTag(Tag): > > > source = Argument() > > > limit = NamedArgument(required=False) > > > offset = NamedArgument(required=False) > > > as_ = BasicArgument(required=False) > > > > class Meta: > > > ordering = ( > > > ('source',), > > > Unordered('limit', 'offset'), > > > ('as_',) > > > ) > > > > The general consensus was that the second implementation was *very* > > slightly > > > preferable in the simple case, however it was significantly more > > complicated > > > in > > > the second case, and thus the first implementation was preferable > > overall. > > > > We notable did *not* discuss what the syntax for defining the output was, > > at > > > this stage we were only concerned with the syntax definition. This is > > > because > > > the actual ``render()`` equivalent will be orthogonal to the parsing > > stage > > > equivalent. > > > > For your consideration, > > > Alex > > > > -- > > > "I disapprove of what you say, but I will defend to the death your right > > to > > > say it." -- Evelyn Beatrice Hall (summarizing Voltaire) > > > "The people's good is the highest law." -- Cicero > > > -- > > You received this message because you are subscribed to the Google Groups > > "Django developers" group. > > To post to this group, send email to django-developers@googlegroups.com. > > To unsubscribe from this group, send email to > > django-developers+unsubscr...@googlegroups.com. > > For more options, visit this group at > >http://groups.google.com/group/django-developers?hl=en. > > This solution sounds nice, but it simply doesn't work for many examples. a) > It fails to match the template language's understanding of what a node is > (they're created once at compilation time, and reused across all > invocations) and b) doesn't work with many types of arguments, for example > the argument form "{% foo limit 3 %}" where limit is some significant name, > passes some argument to this tag, this rather falls over in the case of > things like "{% foo limit 3 as bar %}" since as is a keyword in Python, and > finally it fails to express things like the sometimes ordered, sometimes > unordered nature of arguments. > > Alex > > -- > "I disapprove of what you say, but I will defend to the death your right to > say it." -- Evelyn Beatrice Hall (summarizing Voltaire) > "The people's good is the highest law." -- Cicero -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.