Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add template keyword to output block unchanged #318

Closed
wants to merge 1 commit into from

3 participants

@benweatherman

Using javascript templates is tricky because it often requires you to use similar syntax to Tornado templates. While you can use the {{! and {{% syntax, this is often pretty cumbersome for large chunks of javascript templates. I propose we have a verbatim/raw/cdata keyword that would output my template code unchanged.

For more information, see this thread: http://groups.google.com/group/python-tornado/browse_thread/thread/8d0383a76324e0a6/741315ab35621caa?lnk=gst&q=templates#

Add "verbatim" template keyword that will output the text within the block unchanged

@bdarnell
Owner

As I said in that thread, I think it's generally a bad idea to put templates inside templates even when their syntaxes don't clash (you'd have to make sure that tornado templates never inject a "{{" into your javascript templates, etc). We now have "{{!" (which is a big improvement over the old "{{'{{'}}"), so I'd need to see a compelling argument for putting JS templates verbatim in tornado templates (as opposed to loading the JS templates from some external source) before adding a new bulk-escaping interface.

@benweatherman

The new syntax is indeed an improvement, but using that syntax ensures that I can't develop something using a static page and then copy/paste it over to a Tornado template. Loading the template from an external source doesn't always make sense, such as when I want to have the initial page load contain all of my JS templates.

I can understand your hesitation for adding this code for performance reasons, but I don't understand your hesitation because you don't like the idea of embedding JS inside of Tornado templates. Can you help me understand your reasoning there?

@bdarnell
Owner

My main objection is about complexity, not performance (especially since it gets even more complex if you relax the requirement for exactly one space on each side of {% end %} to be consistent with everything else). I think that keeping the JS templates out of the tornado templates is actually a better solution for your problem even if the {% verbatim %} block existed. Just keep the JS templates in a separate source file, then use a UIModule to pull them into the rendered page. You can keep your source templates organized in separate files without requiring multiple http fetches from the browser.

@shanehyde

Except if you are using tornado for localization, then you need tornado to process the JS template before it goes to the client. This is a good reason to use both templating solutions at once.

@bdarnell
Owner

But if you're using tornado for localization, then you won't be able to use {% verbatim %} because you still need the translations to be substituted.

@shanehyde

I agree, myself, I am using a modified jquery-tmpl library so that they both dont use {{ }} and I can mix the two together. For myself {% verbatim %} is not a solution, but I still need a mix of templates together. If jquery-tmpl offered localization, (or I could find a different good jquery template library), I wouldnt need the mix.

@shanehyde

I just noticed that there is already an escape in template.py for jquery templates... so all is cool

        # Template directives may be escaped as "{{!" or "{%!".
        # In this case output the braces and consume the "!".
        # This is especially useful in conjunction with jquery templates,
        # which also use double braces.
        if reader.remaining() and reader[0] == "!":
            reader.consume(1)
            body.chunks.append(_Text(start_brace))
            continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 27, 2011
  1. @benweatherman

    Add "verbatim" template keyword that will output the text within the …

    benweatherman authored
    …block unchanged
    
    Implements issue #317
This page is out of date. Refresh to see the latest.
Showing with 14 additions and 1 deletion.
  1. +14 −1 tornado/template.py
View
15 tornado/template.py
@@ -533,6 +533,17 @@ def _format_code(code):
def _parse(reader, template, in_block=None):
+ # Skip everything if we're in a verbatim block
+ if in_block == "verbatim":
+ block_end = reader.find("{% end %}")
+ if block_end == -1 or block_end + 1 == reader.remaining():
+ raise ParseError("Missing {%% end %%} block for verbatim")
+ unparsed_text = reader.consume(block_end)
+ # Consume the end block
+ # NOTE: the magic number 9 comes from: len('{% end %}') == 9
+ reader.consume(9)
+ return unparsed_text
+
body = _ChunkList([])
while True:
# Find next template directive
@@ -658,7 +669,7 @@ def _parse(reader, template, in_block=None):
body.chunks.append(block)
continue
- elif operator in ("apply", "block", "try", "if", "for", "while"):
+ elif operator in ("apply", "block", "try", "if", "for", "while", "verbatim"):
# parse inner body recursively
block_body = _parse(reader, template, operator)
if operator == "apply":
@@ -669,6 +680,8 @@ def _parse(reader, template, in_block=None):
if not suffix:
raise ParseError("block missing name on line %d" % line)
block = _NamedBlock(suffix, block_body, template)
+ elif operator == "verbatim":
+ block = _Text(block_body)
else:
block = _ControlBlock(contents, block_body)
body.chunks.append(block)
Something went wrong with that request. Please try again.