Paul Seamons wrote:
Maybe the FILE name is only used when throwing errors - I can sort of see that one - but not too much.

Yep, that's it.  When TT compiles the template down to Perl code, it adds

   #file $file line $line

lines which tell Perl where to report errors from. It's these, and only these, that the FILE/LINE directives would control. (err... I think).

I see them being used mostly for debugging purposes. Or those edge cases like Brad's where you need to fix up what's not quite right. So they probably won't be enabled by default.

The words FILE and LINE and particularly file and line are used extensively in existing templates. I don't think that the proposed directives add enough functionality to warrant making them reserved words.

I agree that they're of limited value. However, TT3 allows you to enable or disable individual directives. So if you're using a lot of FILE variables, then you could disable (or more like, not enable) the FILE directive.

Also, we don't have to be as worried about reserved words in TT3 as we do in TT2 because a directive keyword isn't actually a reserved word. A keyword only has significance in a position where keywords are expected. ISTR Template::Alloy is the same.

  [% GET FILE     %]    # no problem
  [% wibble(FILE) %]    # cool

The more general solution to this problem is namespaces. By using an explicit namespace prefix you can tell the parser what you really mean:

  [% var:FILE  %]        # the variable 'FILE'
  [% dir:FILE  %]        # the directive 'FILE'
  [% file:FILE %]        # the file called 'FILE'

(I'm not sure about 'dir:' as a prefix, BTW. It could be confused with a directory, but whatever it's called, you get the idea).

Namespaces provide general purpose parser hooks. As well as being used to disambiguating tokens for the parser, they can be used to implement all kinds of other interesting compile time behaviour.

So we'll have a namespace handler that you can enable/disable which provides access to the file/line data and anything else relating to the template. e.g.

  [% template:file = 'badger' %]
  [% template:line = 42 %]

  The is line [% template:line %] of [% template:file %] which was last
  modified at [% template:time %] on [% template:date %].

The nice thing is that these "variables" are resolved at compile time, but can be used at runtime. So if you write:

  [% call_my_sub(template:file, template:line) %]

Then the code generated is more like:

  [% call_my_sub('Badger', 42) %]

As an aside, this also gives you an easy way to define your own constants. Something like this:

  Template->new(
    namespaces => {
      site => {
        constants => {
          title  => 'Badger World',
          images => '/images',
          logo   => '/images/badger.png',
        },
      },
    },
  );

And then this:

  Welcome to [% site:title %].
  <img src="[% site:logo %]"/>

Which is compiled down to this:

  Welcome to Badger World
  <img src="/images/badger.png" />

Rather than add FILE and LINE, I would greatly suggest adding the CONFIG directive that was proposed some time ago but seemed to be warnocked.

Given the ability to enable/disable directives at will, there's no reason why we can't have all three and let the end user decide what they need on a case-by-case basis (assuming that in most cases, they'll be using the sensible set of defaults that we provide).

I'm not opposed to the idea of having one master CONFIG directive, but then I'm not sure that I'm totally for it.

On the positive side, it provides somewhere for all the different config data to go. On the negative side, it dumps all the different config data in one place, where it becomes harder to manage...

So you'd have [% CONFIG FILE => 'foo', LINE => 42 %].
You are on line [% CONFIG LINE %].
[...]
TAGS directive ought to be deprecated in favor of using [% CONFIG TAGS => ['[%', '%]'] %] or [% CONFIG TAGS => 'html' %].

[thinking out loud]

The problem I have with this from an implementation point of view is that it could result in one monolithic CONFIG directive that has to know about all the different possible options, how to parse them, and what to do with them after that.

It's not particularly difficult to implement that way, but I think it will lead to an implementation which is less flexible than the current one where each directive does just one thing and can be enabled or disabled at will.

So if we do have a CONFIG directive then it should just act as a container for other directives. Rather than doing any parsing itself, it would just enable a bunch of other directives within that scope (i.e. to the end of the current
tag)

That way we can keep TAGS, EMBED, IGNORE, etc., as self-contained directives that each do one thing and do it well. In this scenario, they would be disabled by default until you hit a CONFIG directive. At that point, they become enabled (in the same way that 'CASE' is "enabled" within the context of a 'SWITCH' directive, for example).

Hope that makes some kind of sense. In essence, yes, I think we can do that, or something like it.

Cheers
A


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

Reply via email to