Opened 7 years ago

Closed 6 years ago

#8296 closed (duplicate)

Allow template parser to parse until "complex" block node

Reported by: julien Owned by: nobody
Component: Template system Version: master
Severity: Keywords:
Cc: me@… Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

For info, this was brought up in [1].

Currently, with block tags, you can only parse until a "simple" closure tag. For example: {% endif %} or {% endfor %}.

Now, it would be nice if you could parse until something more "complex" like {% elseif blah and blahblah %}. By "complex" I mean a tag that requires some parameters.

Here I'm not asking for an elseif tag in particular, but I'd like to allow the parser to also consider "complex" closure tags.

For example, a direct application of this would be a suggestion for a {% withblock %} tag. Here's a suggested syntax:

{% withblock as myurl %}
   {% url path.to.some_view arg1,arg2,name1=value1 %}
{% and as var %}
   {% whatever %}
{% in %}
       Click the link: <a href="{{ myurl }}">{{ var }}</a>.
{% endwithblock %}

Currently the {% and as var %} tag cannot be recognized. The problem is in django.template.Parser.parse():

...
elif token.token_type == TOKEN_BLOCK:
    if token.contents in parse_until:
    ...

It basically checks if the tag's hard string name is in the list. The attached patch, which is *backward compatible*, only looks at the first piece of text in the node, namely the tag's name. With that, in your tag you could parse the block like follows:

    nodelist = parser.parse(('and', 'in')) # Parse until {% and as var %} or {% in %} 

[1] http://groups.google.com/group/django-developers/browse_thread/thread/c81a9fe156af71e7

Attachments (2)

8296.parser.diff (729 bytes) - added by julien 7 years ago.
8296.diff (1.2 KB) - added by adurdin 6 years ago.
Slightly more robust patch.

Download all attachments as: .zip

Change History (7)

Changed 7 years ago by julien

comment:1 Changed 7 years ago by julien

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Just for the record, #8297 would make use of this change to implement a suggested {% withblock tag %}.

comment:2 Changed 7 years ago by mtredinnick

  • Triage Stage changed from Unreviewed to Design decision needed

comment:3 Changed 6 years ago by anonymous

  • milestone post-1.0 deleted

Milestone post-1.0 deleted

comment:4 Changed 6 years ago by adurdin

  • Cc me@… added

In the meantime, here's a slightly ugly workaround that you can put in your tag:

    class BlockTagList(object):
        # This is a bit of a hack, as it embeds knowledge of the behaviour
        # of Parser.parse() relating to the "parse_until" argument.
        def __init__(self, *names):
            self.names = set(names)
        def __contains__(self, token_contents):
            name = token_contents.split()[0]
            return name in self.names

    # Skip over everything before the first {% case %} tag
    parser.parse(BlockTagList('case', 'endswitch'))

Changed 6 years ago by adurdin

Slightly more robust patch.

comment:5 Changed 6 years ago by Tarken

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #3090. In fact, the patch is almost identical.

Note: See TracTickets for help on using tickets.
Back to Top