kiat has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

I'm trying out something like the following to include a file dynamically using HTML::Template:

<tmpl_include name="<tmpl_var name=file>.inc">
That doesn't seem to work. There's no problem if the name of the include file is hardcoded:
<tmpl_include name="news.inc">
But is there a way to feed the name of the include file to tmpl_include?

Replies are listed 'Best First'.
Re: question on tmpl_include
by matija (Priest) on Mar 01, 2004 at 12:09 UTC
    You should have mentioned you are using HTML::Template. Otherwise, only those who recognise the variable style can answer.

    Your question is fairly common on the HTML::Template mailing list, and IIRC, the answer is "you can't do that - at least not that way".

    I see two solutions to you problem:

    • You can define a HTML::Template filter. That filter can then look for the TMPL_INCLUDE tag and insert the correct filename.
    • You can have a series of <TMPL_IF><TMPL_ELSE> statements which enclose each TMPL_INCLUDE statement you might want to execute - and the TML_IFs then determine what gets included in the usual fashion.
    • You could have a single include file, and then use the TMPL_IFs inside that include file to select which contents of that file you want.
    Each of these solutions has good points and bad points. The first is most general, the last is probably quickest.
Re: question on tmpl_include
by ViceRaid (Chaplain) on Mar 01, 2004 at 12:17 UTC

    Hi

    I'm guesings from the tag syntax that you're using HTML::Template. In which case, no, you can't put a tmpl_var inside an include. This is probably not a bad thing from a security point of view, as if it were possible, it'd be temptingly easy to do something like:

    my $tpl = HTML::Template->new(); my $q = CGI->new(); $tpl->param( 'file' => $q->param('file') ); # Then in your template <tmpl_include name="<tmpl_var name=file>">

    Which is all nice, until someone requests the page with /cgi-bin/myscript.pl?foo=bar&file=/path/to/my/secrets.

    To work round it, I'd suggest using the tmpl_if constructs to include different specified alternatives depending on a variable's values:

    <tmpl_if name="foo"> <tmpl_include name="foo.inc"> </tmpl_if> <tmpl_if name="bar"> <tmpl_include name="bar.inc"> </tmpl_if>

    IIRC, the way this is implemented means that it can be wasteful if you have lots of includes within conditionals, as all the includes get opened at the parse stage. If you have SO many alternatives that this is unwieldy, then maybe you need to rethink how your application is working - maybe what you are trying to include is data that should, in fact, be passed into the template like other params? Or maybe HTML::Template's filter facilites might help?

    cheers
    ViceRaid

Re: question on tmpl_include
by Crian (Curate) on Mar 01, 2004 at 11:51 UTC
    I think that depends on your template system. It has to do recursive substitutions (at most two times), to do what you want. Perhaps you could work around this problem by calling the substitution two times?
      In case the substitution function returns the number of performed substitutions it could be a good idea, to recall it in a loop until it does not substitutes anything more. Doing it that way enables you to use as deep structured template terms as you want (or need) to.
      I am sorry if I missed the possibility to edit my post above, but I am new to the perlmonks and did not find any such button or else.

      Now I now how to change written answers... (thanks to ViceRaid, who told me how).
Re: question on tmpl_include
by eric256 (Parson) on Mar 01, 2004 at 16:27 UTC

    One way around that is to instead put variable there in your template instead of the include. Then in your perl load the template you want dynamicaly included and then put its resulting HTML in the template variable so it shows up in the original template.

    Hope that helps.


    ___________
    Eric Hodges