Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^4: Here documents in blocks

by Bod (Parson)
on Dec 20, 2020 at 12:49 UTC ( [id://11125492]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Here documents in blocks
in thread Here documents in blocks

Separation of data from code is a good first step

Previously I have attempted to separate an HTML template from the functional code, admittedly not using a pre-built templating system. This was for a system that provides a business overview of KPIs to my senior management team both on demand as a webpage and as an email twice weekly. This code that was produced quite a few years ago is still operational and providing good service.

Here is an extract from the template file:

<div style="float:right"> <p class="sectionHead"><b>FHL Properties:</b></p> <table> <tr> <th class="itemHead">Bookings this month:</th> <td>%BOOK_MTH% </td> </tr><tr> <th class="itemHead">Previous 30 days:</th> <td>%BOOK_PREV% </td> </tr><tr> <th class="itemHead">Forthcoming 30 days:</th> <td>%BOOK_30% </td> </tr><tr> <th class="itemHead">Forthcoming 60 days:</th> <td>%BOOK_60% </td> </tr> </table> </div> <hr style="clear:both"> <p class="sectionHead"><b>Progress in Property Event:</b></p> <p class="itemHeadLarge">%EVENT_COUNT% people have registered their in +terest</p> <hr> <p class="sectionHead"><b>Customer Contentment Call List:</b></p> <p class="itemHeadLarge">There are %CALLLIST% people are on the Call L +ist</p> <hr>
with the %MARKUP% being substituted for the calculated values by the delivery code
$pulse =~ s/%EMAIL_VIEW_PERCENT%/$empview/g; $pulse =~ s/%EMAIL_CLICK_PERCENT%/$empclick/g; $pulse =~ s/%EMAIL_UNSUB_PERCENT%/$empunsub/g; $pulse =~ s/%SHORTLIST%/$shortlist/g; $pulse =~ s/%CALLLIST%/$calllist/g;
In practice this is difficult to maintain as there are some 50 items of data to substitute as some KPIs have multiple values and some require pluralisation whilst other don't. From this limited experience quite some time ago, templating seems more trouble than value...or is this not what you mean?

If there is a way to simplify it which can be quickly implemented then I would certainly change my approach.

One problem I have faced in the past with this code is that the path to the template file is hard-coded to the production version so I have to remember to change this in the test environment before making changes and swap it back before releasing it back to the wild. It was done this way because the script runs from cron to provide the twice weekly emails. It will be simpler in future because fellow Monks have introduced me to use FindBin; and use lib; that will make this particular application a great deal simpler...perhaps that change alone will revise my experience of HTML templates.

Replies are listed 'Best First'.
Re^5: Here documents in blocks
by hippo (Bishop) on Dec 20, 2020 at 17:21 UTC
    some require pluralisation whilst other don't.

    Have you seen Lingua::EN::Inflexion? It allows you to construct a generic pattern (a template of sorts) to handle various cases like this.

    If there is a way to simplify it which can be quickly implemented then I would certainly change my approach.

    It can be quickly implemented, if not quickly learnt. Because these are modules with which I am familiar I would use Template for the templating system with the Template::Plugin::Lingua::EN::Inflexion plugin which would allow for a simple loop to produce the table contents and proper pluralisation of the prose. TIMTOWTDI, of course.

    #!/usr/bin/env perl use strict; use warnings; use Template; # Set up your data my $data = { table => [ { head => 'Bookings this month', val => 132, }, { head => 'Previous 30 days', val => 99, }, { head => 'Forthcoming 30 days', val => 150, }, { head => 'Forthcoming 60 days', val => 189, }, ], event_count => 1, call_list => 5 }; # Set up your template (easiest/commonest in an external datastore (fi +le # or DB) my $template = <<EOT; <div style="float:right"> <p class="sectionHead"><b>FHL Properties:</b></p> <table> [% FOR k IN table %] <tr> <th class="itemHead">[% k.head %]:</th> <td>[% k.val %] </td> </tr> [% END %] </table> </div> <hr style="clear:both"> [% USE infl = Lingua.EN.Inflexion; FILTER inflect; -%] <p class="sectionHead"><b>Progress in Property Event:</b></p> <p class="itemHeadLarge"><#:[% event_count %]> <N:person> <V:has> regi +stered their interest.</p> <hr> <p class="sectionHead"><b>Customer Contentment Call List:</b></p> <p class="itemHeadLarge"><#d:[% call_list %]> There <V:is> [% call_lis +t %] <N:person> who <V:is> on the Call List.</p> <hr> [% END %] EOT # Run it Template->new->process (\$template, $data); exit;

    🦛

      It can be quickly implemented, if not quickly learnt. Because these are modules with which I am familiar I would use Template for the templating system

      Thanks hippo. Last evening my bedtime reading was Template along with Template::Manual and Templete::Tutorial. Nothing like a bit of light bedtime reading!

      I'm convinced!!!

      There is an immediate use I see for this solving a problem that is going to need addressing next year - allowing non-techie team members to create company branded emails without having to manipulate HTML.

      But...it strikes me that there are a number of Perl templating systems. hippo (and others), if you were starting again today, would you use Template or might you be looking at others?

        There is indeed a range of templating modules and this is a good thing because one size does not necessarily fit all. I am happy with Template and would choose it again if starting from scratch because it has everything I need with very few downsides. It has a steeper learning curve that many of the alternatives, but the docs are good and a novice can still construct fairly simple but effective templates using it. It is well maintained, suitable for any output format (HTML, CSV, XML, JSON, plain text, LaTeX source, SVG, you name it), comes with command-line utilities (ttree, tpage) and is widely used.


        🦛

      Have you seen Lingua::EN::Inflexion?

      No I haven't...well - I have now :) Thanks

      Coincidentally, I have been looking at Lingua::EN::Fathom recently for a different project.

Re^5: Here documents in blocks (why templates)
by LanX (Saint) on Dec 20, 2020 at 19:41 UTC
    You seem to think that templates are just about replacing variables.

    There are more techniques like "includes", were sub-templates are integrated which have sub-templates and so on.

    Or embedding programming code inside the HTML for loops or conditional snippets.

    And there is reusability, like hacking once a generic "table" template and applying it to different projects.

    I have to admit all of this can also be done with pure Perl and no regexing at all, thanks to it's flexibility.

    But a framework has a lot of benefits in a team, for instance I don't have teach my colleagues a bunch of best practices if there is already a well documented trail to do it.

    Separated HTML-code is not only easier to edit - if it's well done the browser can display it , my editor can highlight it properly and formatting, validation and indentation is easy.

    Last but not least, isolated HTML code can be handled by a web specialist without any knowledge of the controlling programming langue, much like SQL-Statements don't need expertise in Perl. That's the main idea of the MVC pattern.

    Example from another perspective ... You've spend much time criticizing the design of the monastery, but it's a monolithic framework in pure Perl written 20 years ago.

    We can't simply ask several design expert to overhaul the templates, because a lot of HTML is interspersed inside Perl code. (actually it's even much more complicated, because many people added parts in the past)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      You seem to think that templates are just about replacing variables

      No - I know there is much more too it than that...I just don't understand exactly what and how yet. My foray into 'templates' (of a kind) was just about variable replacement and I didn't get any further.

      But a framework has a lot of benefits in a team

      I can totally see that and my limited experience of working in development teams many years ago means that makes a great deal of sense.

      My 'team' (as far as coding goes) is just me which is an advantage in that I don't have anyone else to worry about regarding maintenance, consistency and best practice...it is also a huge disadvantage as I have nobody else to ensure I think about maintenance, consistency and best practice!

      Frameworks are high on my list of things to look into over the festive break...
      ...one of many things thanks to the Wisdom of the Monastry!

        Even your HTML needs some work, a mix of css classes and inline styles. Is it functional, sure. Does it make sense from a maintenance point of view, no. In response to this (and other replies) If what you have works for you and you don't have the time or inclination to learn modern practices nobody has a problem with that, but they way you write code "does nothing to dispel the image of Perl being old fashioned, outdated and obsolete.", and if you keep asking how to improve things you're likely only going to get the same answer you've had before, which has seemingly been dismissed without proper evaluation. At work (and elsewhere) I'm a lone developer frameworks and modern methods help me in my life, you don't need to be in a team to benefit from this. If you were to go down this path I'd suggest familiarising yourself with MVC and the Mojolicious docs, for me this along with just playing around with the thing was the way forwards.

        > My "team" (as far as coding goes) is just me which is an advantage in that I don't have anyone else to worry about regarding maintenance

        My team are often me, myself and I.

        When working at several projects at the same time one will often have gaps of several weeks in between. All things stored in short memory are wiped out and you start swearing about this "colleague".

        To be fair, I haven't used any template engine yet, because my vice are the dark arts of Perl wizardry (and because web dev is only a part of my endeavors)

        But the community around a framework like Mojolicious is effectively a team giving you support. So I'd certainly chose it for a serious project.

        And by all means, printing HTML line by line makes me speechless. Oo

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11125492]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (3)
As of 2024-03-29 04:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found