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

I've made a rather simplistic Image Gallery script for a web site I've recently begun to help with, using HTML::Template. However I have now come to a problem. In a particular spot I can't seem to unmix some design and presentation.

The only way I can figure out how to set the number of images per row is with a counter of the number of images found mod the number of images I want per row. However, number of images per row is definitely a presentation element, and I would like the fellow who is in charge of the site design to be able to alter the images per row. I could make use of HTML::Template::Expr, so that I can have the mod bit take place in the template and the web monkey would have access to the images per row, but that would have a potentially confusing bit of implementation in the presentation. Can anyone present any ideas for clearer seperation of implementation and design?

For reference, the code and template follow:

gallery.cgi
#!/usr/bin/perl use warnings; use strict; use File::Find; use HTML::Template; my $template = HTML::Template->new(filename => 'gallery.tpl'); my @thumbnails; my $count = 1; my %options = (wanted=>\&pics , no_chdir=>1); find(\%options, 'thumbs/'); $template->param(THUMBNAIL => [ @thumbnails ] ); print "Content-Type: text/html\n\n", $template->output; sub pics { return unless /\.((?:jpg)|(?:gif)|(?:png)$)/i; my $thumbfile = "$_"; my $imagefile = "$_"; $imagefile =~ s/thumbs/images/; push @thumbnails,{image=>$imagefile, thumb=>$thumbfile, newrow=>$count%5}; ##This is the imporant bit $count++; }
gallery.tpl
<html> <title>Image Gallery</title> <body> <table colspan=5 align=center border=1> <tr> <TMPL_LOOPTHUMBNAIL> <td border=0><a href='<TMPL_VAR IMAGE>'><img src='<TMPL_VAR THUM +B>'></a></td> <TMPL_UNLESS __last__><TMPL_UNLESS newrow></tr><tr></TMPL_UNLES +S></TMPL_UNLESS> </TMPL_LOOP> </tr> </table </body> </html>

There's also a seperate backend which actually creates the thumbnails, but I didn't think it was relavent, if you think it may be, then let me know and I'll include that also

And on an entirely unrelated note, today is my 3rd monkday, and this is my first question and root post. (Yes I've went that long and never asked a question, at least not in a post, lots of 'em in the CB)

Just Another Perl Alchemist

Replies are listed 'Best First'.
Re: How to Seperate Presentation from Implementation with HTML::Template
by wfsp (Abbot) on Jan 11, 2007 at 09:57 UTC
    You could adapt the script to get the pics/row from the query string.

    The link to the script would then control what happens and the "fellow who is in charge of the site design" would be able to alter it.

      hmm that would be fairly trivial to do, the only issue I have with it (other than an unusual method for the webmaster to set the columns in a table) is that it would make links to the gallery somewhat tricky, especially if someone were for example to link to it from the site's forum. I guess we could have a gateway page for people to link to. Or I could just set a default # of columns in the script.

      Just Another Perl Alchemist
Re: How to Seperate Presentation from Implementation with HTML::Template
by tinita (Parson) on Jan 11, 2007 at 19:43 UTC
    how about using a configuration file for this?
Re: How to Separate Presentation from Implementation with HTML::Template
by ww (Archbishop) on Jan 11, 2007 at 16:28 UTC
    wfsp offers a good plan for doing what you ask,

    but this (heretical) "webmonkey" (hmm, is that vaguely deprecatory?) can't resist observing that - - IMO, ymmv - -

    Much of the current rage for separating content and structure is another case of a (relatively new) advance in our thinking about "TBW ("The BEST way," © 1984 - 2007 by ww) to do something being carried to a counterproductive extreme.
    As McLuhan tells us, "the medium is the message;" ww's corollary holds that "presentation is an essential quality of the medium, and hence, part of the message."

    ...or, :-}), you may chose to simply view this as yet another rant.

      For the most part I agree, however, I don't think the perl guts to the system are relavent to the medium or the message, and more importantly, The web side of things is to be maintained by someone else other than me, someone who, at best, knows of perl, so it'd be bad for him to need to dig into my code to alter a presentation element, I was hoping someone might have some ingenius idea of a way to allow the webmaster (that better than monkey for yah? :P ) to edit the template just as though it were any other page.

      I wonder if perhaps another templating system would lead to my solution, I just went with the only one I could find that I could get on my home box that'd run w/ activeperl, so I could test before I messed around with something live.

      Just Another Perl Alchemist
        I think that that 'someone' will have to learn the basics of your templating engine, if she is to maintain the web site without your further involvement as a web service programmer. If she is to be in control of things, then I suggest that you develop an API-like system: for every template define bunch of variables of the system, that the designer can work with. You write the docs about the meaning of each variable and present them to the designer. She is then able to change the presentation as she likes.
        I am in somewhat similar position; I am the web design maintainer and the programmer on the server side (I got finished design of our site). And I did just what I described: so if I want to change something I don't have to browse through server-side source, my template already 'knows' a lot.
        Also, if you plan some serious programming stuff on the template side, I suggest you try Template::Toolkit as HTML::Template is somewhat limited to simple expressions.
Re: How to Seperate Presentation from Implementation with HTML::Template
by spatterson (Pilgrim) on Jan 12, 2007 at 10:17 UTC
    You can do this kind of thing with just html & css for positioning, just let perl generate the page.
    CSS .image { float: right; } img { width: 200px; height: 200px; }
    Then perl only needs to generate this for each image:
    <div class="image"><img src='foo.jpg'></div>

    just another cpan module author

      Hmm, this just might work, with a little tweaking, maybe some padding, I may well get the effect I wanted. I guess this is a case of me looking for to specific an answer, instead of a solution to a general problem, and also looking on the wrong side for the solution.

      Of course, this goes to show just one of the many things I love about this community, and stayed here so long (I tend to wonder from most places after a couple months). Even though the eventual solution was... off-topic, I suppose, it was offered without the usual sort of shouting that so many other places see. Also goes to show why I'm not in charge of the HTML side of things, my html and CSS are rather rusty.

      Just Another Perl Alchemist

      This is by far the most elegant solution. I, too, have written a gallery that uses H::T, and it used a config setting that specified how many images per row. But that was because I always used tables for layout, and I was never happy with the solution. Now I simply use divs which float to take up the available display space - and gone is the pain of setting up the H::T dimensions as array references of hash references

Re: How to Seperate Presentation from Implementation with HTML::Template
by Rhandom (Curate) on Jan 12, 2007 at 15:56 UTC
    The CSS solution is good and is a solution that I would advocate.

    But sometimes it is hard to make CSS fit your case and sometimes you really do want to use tables (ie for non-changing grid layouts). In these cases - you can use a template to do everything - if the template language has enough mini-language to it. The following is a sample from the Template Toolkit 2 dialect (even though I show CGI::Ex::Template - it would also work with Template::Toolkit).
    use CGI::Ex::Template; my @a = qw(one two three four five six seven eight); my $temp = q{ [%~ cols = 3 %] [%~ rows = a.size DIV cols %] [%~ IF a.size % cols ; rows = rows + 1 ; END -%] <table> [%- FOR i IN [1 .. rows] %] <tr> [%- FOR j IN [1 .. cols] %] [%~ k = (i - 1) * cols + (j - 1) %] <td>[% a.$k %]</td> [%- END %] </tr> [%- END %] </table> }; CGI::Ex::Template->new->process(\$temp, {a => \@a}) || die $CGI::Ex::T +emplate::error;
    The number of columns is adjusted by changing cols = 3 to whatever you'd like. That code prints out:
    <table> <tr> <td>one</td> <td>two</td> <td>three</td> </tr> <tr> <td>four</td> <td>five</td> <td>six</td> </tr> <tr> <td>seven</td> <td>eight</td> <td></td> </tr> </table>


    my @a=qw(random brilliant braindead); print $a[rand(@a)];