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

Continuing the project I started with quite some time ago and just completing recently (for the regular definition of "completed" - i.e., release early release often), I've decided to make my front page a bit more dynamic. So I started by doing some simple stuff. For example, our group's meeting dates are already in a CSV table, so I just created a function in my plugin that extracted it from a table with "YEAR,MONTH,DAY,..." as the first column headers, converted it to something readable ("Monday, May 8, 2006"), et voila, I got what I wanted. Plop it into a cron entry, which both runs ttree and a small ftp upload script I also have, and it's about as dynamic as it needs to be.

The next step was to put descriptions of upcoming events. However, I'm figuring that I don't need to continue advertising upcoming events after they passed. So a bit more magic, and I came up with this:

[%- USE date %] [%- SET today = date.format(date.now, "%Y%m%d") %]
and then ...
[% IF today < 20060406 %] <p>Guess what. On April 6, 2006, we're going to do something special! On April 7th, this paragraph disappears! Neat!</p> [% END %]
The only minor annoyance is that my editor of choice seems to think that the < sign there is the open character for an HTML tag. But that's really quite minor.

What I'm wondering is if anyone can see, or better yet, already uses, a more elegant solution. Perhaps a filter? Is there such a beast built in that I'm missing? Or perhaps that I haven't figured out the right keywords for searching on CPAN? I imagine this would be easy for TT2 experts, but I'm just not seeing it today for some reason.

By "elegant" I mean a few things. First, the template must be readable. Putting in unix timestamps (seconds since epoch) isn't readable ;-). Second, it should be able to handle both begin and end dates. So I may not want to start displaying some text until a certain date, and/or I may want to stop displaying some text after a certain date. The simple numeric comparison above meets that through simple numeric comparisons. However, a bit more obvious to me would be something like:

[% FILTER ByDate start = '2006-04-15' until = '2006-06-28' %] This is only visible from April 15 through June 28, 2006. [% END %]
Obviously, since this is a static document, I'll have to ensure the cron job gets run daily at an appropriate time. But that's somewhat outside the scope of my question.

Is this reasonable/normal usage of TT2? Is there something I'm overlooking?

Replies are listed 'Best First'.
Re: Date-sensitive output with Template Toolkit
by merlyn (Sage) on Apr 05, 2006 at 02:32 UTC
    Wow... that looks a whole lot simpler than my embargo code where my columns are embargoed. Doh. Here's what I've done:
    [% META class='lm_columns' instance='79' title='Building a static website with Template Toolkit (Mar 06)' # use Date::Manip; print UnixDate(ParseDateString("4/1/2006 00:00 GM +T"), "embargo=%s") embargo=1143849600 %]
    And yes, that Date::Manip line sets "embargo" according to the execution of that Perl code, which then gets checked by:
    USE date(gmt => 1); WRAPPER splash/panel style = splash.style.default; IF date.now > template.embargo; content; ELSE; "[Content embargoed until "; date.format(template.embargo); " per publisher's agreement.]"; END; END;
    I'm gonna be switching to your way soon.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: Date-sensitive output with Template Toolkit
by perrin (Chancellor) on Apr 05, 2006 at 04:19 UTC
    Not really what you want to hear, but I would make my Perl script grab DateTime, see if it's April Fool's Day, and then pass something to the template that lets me say [%IF april_fool %]. If you're determined to jam this into your template you could probably get Template::Plugin::DateTime to do it.
Re: Date-sensitive output with Template Toolkit
by CountZero (Bishop) on Apr 05, 2006 at 06:28 UTC
    The most obvious and flexible solution would be to store all the events and its beginning and ending "show"-dates in a database and SELECT them through a suitable SQL-command. If I'm not mistaken, you can USE DBI in the Template Toolkit; so the interface to the database would be already there.

    As the SQL of the most popular databases sport some kind of date or now function you would not even have to code that in your template, it could all be done in the database itself.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Date-sensitive output with Template Toolkit
by nferraz (Monk) on Apr 05, 2006 at 09:53 UTC

    In my opinion, the most elegant solution would be to take the dates from the template, so you could manage your data elsewhere. For instance:

    [% USE MessageOfTheDay %] [% MessageOfTheDay.Message %]

    Data file:

    New Year's Day *-01-01 April Fools' Day *-04-01 Independence Day *-07-04 Christmas Day *-12-25 Any given week 2006-04-09 2006-04-15

    The actual code is left as an exercise for the reader.

Re: Date-sensitive output with Template Toolkit
by Herkum (Parson) on Apr 05, 2006 at 13:07 UTC

    The only minor annoyance is that my editor of choice seems to think that the < sign there is the open character for an HTML tag. But that's really quite minor.

    When you are trying to take advantage of an editor's highlighting for checking syntax it is a major nuisance.

    However, TT has a solution! You can change the beginning and end tags for your templates. I would be suprised if your editor did not support basic ASP syntax detection so you can use '<%' and '%>' for your beginning and end tags. TT will allow you to set those tags to whatever you want though so if you are happier with something else you can use it.

    Refer to http://www.template-toolkit.org/docs/plain/Manual/Config.html and look for TAG_STYLE

Re: Date-sensitive output with Template Toolkit
by amw1 (Friar) on Apr 05, 2006 at 20:32 UTC
    You could make your own filter. For 100% accurate details on how to set this up take a look at the TT docs. But something like this should be close (there is extra stuff you need to do to package this routine i.e. putting it in a package, telling TT how to find the package etc. I don't have a ton of time right now so I'll leave you to dig.
    sub ByDate { my ($self, $text, $args, $conf) = @_; # Do appropriate time formatting $cooked_now = TimeFormat(time); if($cooked_now > $args->[0] && $cooked_now < $args->[1]) { return $text; } else { return ""; } }
    The TT code would look something like this
    [% USE MyFilter %] [% FILTER $MyFilter <start> <end> %] Don't display this before <start> or after <end> [% END %]
    As I said, I forget exactly how the linkage between MyFilter and your code works, I do remember it's explained very well in the docs. Hope this helps.
      Hm. This looks like a problem I had with a family schedule that had to accomodate changing work shifts and several grandchildrens' school dates.
      My amateurish result can be seen at
      http:www.oceandreams.net/fam_sched/
      using a text file as a database.
      I'll e-mail the code if it's at all usefull to you; I can't do it from work, otherwise I'd attach it here.

      Regards,
      Clachair
      Never lick a gift horse in the mouth.