Paul Seamons wrote:
It would be nice for TT to support [the COMMENT] directive.

Yes, totally agree. It's always been in the back of my mind for TT3, although I hadn't really thought it through until now.

There's a number of issues here. The first is that we definitely do want some kind of directive to indicate a block of content that shouldn't be processed. So that's a definite "yes" from me.

The second issue is what we call it. I think I prefer something more like SKIP than COMMENT. First, it's shorter to type. Second, and perhaps more importantly, I think it avoids the association that COMMENT has with "some text that is ignored by the parser". In this case, the block must contain valid, parse-able and well structured content that is subsequently ignored. So although it's relatively easy to explain that COMMENT must include valid code, I think SKIP says it better without us having to explain much at all.

The third issue is that it's still rather clumsy to have to add:

  [% SKIP %]
     ...
  [% END %]

in order to block out some code temporarily. There's little to be gained over the current work-around:

  [% IF 0 %]
     ...
  [% END %]

So I'm also in favour of having a more succinct block-level comment syntax.

It would be nice if Robert's suggestion worked:

> [%#
>      Template section that won't be shown
>      [% var_a %]
>      [% IF foo %]Foo[% END %]
> %]

Unfortunately, it doesn't, and I don't think it can be made to work without some serious effort. And then, it's almost certain to Do The Wrong Thing from time to time.

  [%# we could just about make this work if we counted and matched [% and %]
      x = [% BLAH %]
  %]
  ^^ ends here


  [%# but we can only make this work if we parse the (unparseable) comment
    # to work out which bits are strings and which bits aren't
      x = '[% BLAH' %]
  %]                ^^ does it end here?
  ^^ or here?

Something like this is more like it:

> [%#*
>
>   This is a block comment - notice the matching opening and closing comment
> tags.
>   [% foo
>
> *#%]

As Paul says:
> Using the [%#* Way is easy to check for and would allow a fast parse to the
> closing tag.

And that's the key to it. You want something that is totally distinct from regular TT tags so the parser can safely know when the comment ends. However, that particular syntax is starting to look a bit of a handful to type (or remember!)

Anyway, there's already a fairly simple solution to this in TT3, or at least the mechanism is there to implement it. The template scanner is able to recognise (theoretically) any number of different tags embedded in a document.

Unlike TT2 which first looks for [% %] tags and then goes back to interpolate $foo and ${foo} in the remaining text blocks if the INTERPOLATE option is set, TT3 matches the different tags types (and any others you want to throw in) in one pass.

The basic tags are these:
  [% %]
  ${foo}        # only enable when INTERPOLATE set
  $foo          # ditto

Then there's also a magical '\' escape tag which is activated when the INTERPOLATE flag is set. This is used to 'protect' any '$' signs that you don't want interpolated

  abc cost $price  # a variable
  xyz cost \$100   # not a variable

With this mechanism in place, we can easily define an extra tag style to match #* ... *# or something similar. I was originally considering /% ... %/ which is closer to C-style block comments, with a hint of TT-ness added.

Like this:

  /% this is a block comment
     [% INCLUDE foo %]
     blah blah blah
     [% GET x IF y ON tuesday %]
  %/

  /% [% INCLUDE blah %] %/

Hmmm... let's compare it to this:

  #* this is a block comment
     [% INCLUDE foo %]
     blah blah blah
     [% GET x IF y ON tuesday %]
  *#

  #* [% INCLUDE blah %] *#

With hindsight, there's a bit of percentage overload in that first example, and the second does stand out more visually. There may also be other possibilities worth considering, but whatever we eventually decide on can be easily changed by the end user.

Adding tags will be done something like this:

    my $tt = Template->new(
        tags = [
            comment => { start => '#*', end => '*#' }
        ],
    );

In the background, that'll load and instantiate a Template::Tag::Comment object with the specified start and end tags, and hook it into the scanner. The T::T::Comment scan() method will simply scan to the end tag and ignore the content.

I'm sure with a sprinkling of syntactic sugar, we'll be able to get that down to something like:

    my $tt = Template->new( comment => '#* *#' );

We can also provide a directive that allows you to define a comment style within the document. COMMENT or COMMENTS would be ambiguous, I think, for the same reasons mentioned above. Maybe IGNORE?

    [% IGNORE #* *# %]

In which case we might want to rename T::Tag::Comment as T::Tag::Ignore and use the 'ignore' option instead, to keep things consistent.

    my $tt = Template->new( ignore => '#* *#' );

So to summarise, my official ruling is "yes" to all of the above, while reserving the right to change names to protect the innocent. :-)

Cheers
A


_______________________________________________
templates mailing list
[email protected]
http://lists.template-toolkit.org/mailman/listinfo/templates

Reply via email to