Fixing this, would be as simple as changing {{{if block_content[:9] in
('verbatim', 'verbatim ')}}} to {{{if
block_content.startswith('verbatim')}}} or to {{{if block_content[:9] in
('verbatim', 'verbatim ', 'verbatim_')}}}.
Then all template tags beginning with verbatim..., would start in
"verbatim" state. I don't assume this will break any existing code; who
starts the name of a templatetag with 'verbatim...' if not for that
purpose?
Background information why this is useful:
Templates syntax for Django and AngularJS is very similar, and with some
caveats it is possible to reuse a Django template for rendering in
AngularJS. I therefore attempted to add a context sensitive variation of
the verbatim tag to this app https://github.com/jrief/django-angular, but
was hindered by this issue.
BTW: This part of the Django code did not change from 1.6 up to master.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* needs_docs: => 0
* resolution: => wontfix
* needs_tests: => 0
* needs_better_patch: => 0
Comment:
wont fix with only that modification
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:1>
Old description:
> Currently it is impossible to create custom template tags which behave
> similar to {{{ {% verbatim %} }}}.
> The reason is in {{{Lexer.create_token()}}}. There, the class member
> {{{self.verbatim}}} is set for template blocks in "verbatim" state. It is
> impossible to turn on that state from outside, ie. a template tag.
>
> Fixing this, would be as simple as changing {{{if block_content[:9] in
> ('verbatim', 'verbatim ')}}} to {{{if
> block_content.startswith('verbatim')}}} or to {{{if block_content[:9] in
> ('verbatim', 'verbatim ', 'verbatim_')}}}.
> Then all template tags beginning with verbatim..., would start in
> "verbatim" state. I don't assume this will break any existing code; who
> starts the name of a templatetag with 'verbatim...' if not for that
> purpose?
>
> Background information why this is useful:
> Templates syntax for Django and AngularJS is very similar, and with some
> caveats it is possible to reuse a Django template for rendering in
> AngularJS. I therefore attempted to add a context sensitive variation of
> the verbatim tag to this app https://github.com/jrief/django-angular, but
> was hindered by this issue.
>
> BTW: This part of the Django code did not change from 1.6 up to master.
New description:
Currently it is impossible to create custom template tags which behave
similar to {{{ {% verbatim %} }}}.
The reason is in {{{Lexer.create_token()}}}. There, the class member
{{{self.verbatim}}} is set for template blocks in "verbatim" state. It is
impossible to turn on that state from outside, ie. a template tag.
Fixing this, would be as simple as changing {{{if block_content[:9] in
('verbatim', 'verbatim ')}}} to {{{if
block_content.startswith('verbatim')}}} or to {{{if block_content[:9] in
('verbatim', 'verbatim ', 'verbatim_')}}}.
Then all template tags beginning with verbatim..., would start in
"verbatim" state. I don't assume this will break any existing code; who
starts the name of a templatetag with 'verbatim...' if not for that
purpose?
Background information why this is useful:
Templates syntax for Django and AngularJS is very similar, and with some
caveats it is possible to reuse a Django template for rendering in
AngularJS. I therefore attempted to add a context sensitive variation of
the verbatim tag to this app https://github.com/jrief/django-angular, but
was hindered by this issue.
BTW: This part of the Django code did not change from 1.6 up to master.
For the purposes of anyone coming across this ticket and pulling their
hair out over it, heres a template tag that might ease the pain;-
{{{
from django import template
register = template.Library()
@register.filter(name='specialbracket')
def specialbracket(value):
if value == 'left':
return "{{"
elif value == 'right':
return "}}"
else:
return "??"
}}}
And the above example solved with this tag;-
{{{
<td class="field-{{ident}}">{{ 'left'|specialbracket }}
computer.{{field}} {{ 'right'|specialbracket }} </td>
}}}
--
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:2>
Old description:
> Currently it is impossible to create custom template tags which behave
> similar to {{{ {% verbatim %} }}}.
> The reason is in {{{Lexer.create_token()}}}. There, the class member
> {{{self.verbatim}}} is set for template blocks in "verbatim" state. It is
> impossible to turn on that state from outside, ie. a template tag.
>
> Fixing this, would be as simple as changing {{{if block_content[:9] in
> ('verbatim', 'verbatim ')}}} to {{{if
> block_content.startswith('verbatim')}}} or to {{{if block_content[:9] in
> ('verbatim', 'verbatim ', 'verbatim_')}}}.
> Then all template tags beginning with verbatim..., would start in
> "verbatim" state. I don't assume this will break any existing code; who
> starts the name of a templatetag with 'verbatim...' if not for that
> purpose?
>
> Background information why this is useful:
> Templates syntax for Django and AngularJS is very similar, and with some
> caveats it is possible to reuse a Django template for rendering in
> AngularJS. I therefore attempted to add a context sensitive variation of
> the verbatim tag to this app https://github.com/jrief/django-angular, but
> was hindered by this issue.
>
> BTW: This part of the Django code did not change from 1.6 up to master.
>
> For the purposes of anyone coming across this ticket and pulling their
> hair out over it, heres a template tag that might ease the pain;-
> {{{
>
> from django import template
>
> register = template.Library()
>
> @register.filter(name='specialbracket')
> def specialbracket(value):
> if value == 'left':
> return "{{"
> elif value == 'right':
> return "}}"
> else:
> return "??"
> }}}
>
> And the above example solved with this tag;-
>
> {{{
> <td class="field-{{ident}}">{{ 'left'|specialbracket }}
> computer.{{field}} {{ 'right'|specialbracket }} </td>
>
> }}}
New description:
Currently it is impossible to create custom template tags which behave
similar to {{{ {% verbatim %} }}}.
The reason is in {{{Lexer.create_token()}}}. There, the class member
{{{self.verbatim}}} is set for template blocks in "verbatim" state. It is
impossible to turn on that state from outside, ie. a template tag.
Fixing this, would be as simple as changing {{{if block_content[:9] in
('verbatim', 'verbatim ')}}} to {{{if
block_content.startswith('verbatim')}}} or to {{{if block_content[:9] in
('verbatim', 'verbatim ', 'verbatim_')}}}.
Then all template tags beginning with verbatim..., would start in
"verbatim" state. I don't assume this will break any existing code; who
starts the name of a templatetag with 'verbatim...' if not for that
purpose?
Background information why this is useful:
Templates syntax for Django and AngularJS is very similar, and with some
caveats it is possible to reuse a Django template for rendering in
AngularJS. I therefore attempted to add a context sensitive variation of
the verbatim tag to this app https://github.com/jrief/django-angular, but
was hindered by this issue.
BTW: This part of the Django code did not change from 1.6 up to master.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:3>
* status: closed => new
* resolution: wontfix =>
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:4>
Comment (by liminspace):
I am creating template tag and need get code between {% mytag %}...{%
endmytag %}.
I read code and saw that similar template tag "verbatim" is hardcode using
in Lexer.
This is bad idea because nobody can't create template like "verbatim".
Please, improve this thing and make django template system more convenient
and flexible.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:5>
* has_patch: 1 => 0
* type: Uncategorized => Cleanup/optimization
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:6>
Comment (by jrief):
BTW: In the meantime I found another solution for the described problem.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:7>
* stage: Unreviewed => Accepted
Comment:
I'm open to a solution, although I'm not sure if the change proposed in
the description is ideal.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:8>
* owner: nobody => atul-bhouraskar
* status: new => assigned
Comment:
The {{{Lexer.create_token()}}} method can be greatly simplified by
removing the hard coded logic for {{{self.verbatim}}} and instead saving
the full token_string in the {{{Token}}} for tags.
Currently the {{{Lexer.create_token()}}} logic returns tokens of type
{{{TokenType.TEXT}}} if it encounters a {{{{% verbatim %}}}} tag. This
change removes this logic, ie. tokens are created as normal, instead a
simple {{{Parser.parse_verbatim()}}} method can be implemented to return
verbatim text in the parsing stage. This can be called by any tag instead
of calling {{{Parser.parse()}}}.
I've created a quick pull request
[https://github.com/django/django/pull/14686] with the above implemented -
all template tests pass.
This approach fully removes the 'special case' for the built in verbatim
tag and allows creating custom tags that need similar behaviour.
The simplified {{{Lexer.create_token()}}} should now be easier to maintain
and probably also faster than the existing code (though I haven't profiled
this).
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:9>
* has_patch: 0 => 1
Comment:
[https://github.com/django/django/pull/14686 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:10>
Comment (by Chris Jerdonek):
> Currently the `Lexer.create_token()` logic returns tokens of type
`TokenType.TEXT` if it encounters a `{% verbatim %}` tag. This change
removes this logic, ie. tokens are created as normal,
It seems like making this change would make it harder to fix #23424 and
might even be incompatible with fixing it. The reason is that changing
things in this way would require tokens to be parsed before finding the
end of the verbatim tag, whereas fixing that bug would require looking for
the end of the verbatim tag before attempting to parse tokens in between.
Thus, I would suggest fixing the bug in #23424 (and adding test cases)
before reworking the implementation into a way that might be incompatible
with fixing it.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:11>
Comment (by Atul Bhouraskar):
Thanks Chris, I wasn't aware of #23424.
In fact that ticket would be much simpler to fix using this approach -
I've updated my pull request to make a possible fix for #23424 possible
(and added tests that expose the bug).
I've also created a proof of concept fix for #23424 based of this fix -
https://github.com/django/django/pull/14786 - all tests pass in that one.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:12>
Comment (by Chris Jerdonek):
> In fact that ticket would be much simpler to fix using this approach
It seems more complicated to me, IMO, and a lot less efficient because you
need to be re-parsing multiple times. With the other approach, it would
just be one pass.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:13>
Comment (by Chris Jerdonek):
If the use cases for this ticket were spelled out in more detail, I feel
like it would be easier to discuss other ways of solving it. Currently,
it's not clear what requirements a solution needs to satisfy. It seems
like there should be a solution that preserves the "one pass" nature of
parsing. For example, maybe there can be a way to register verbatim tags
so that the list consulted in `create_token()` will no longer be hard-
coded.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:14>
* needs_better_patch: 0 => 1
Comment:
I agree with Chris that re-parsing multiple times is not an acceptable
solution. IMO we should take a step back and try to fix #23424 without
considering [https://github.com/django/django/pull/14686 PR14686], then we
can rethink solution for this ticket.
--
Ticket URL: <https://code.djangoproject.com/ticket/23356#comment:15>