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

O wise and experienced Brethren! I seek the canonical answer to a simple question.

What's the best (as in Best Practices) template system to use for incidental and trivial formatted printing tasks like this one, which includes conditional content?

# Fabricated but verisimilar example printf "UPDATE %s SET\n", $table_name; printf "CUSTOMER_NAME = '%s'", $customer_name; printf ",\nAGE = %d", $age if defined $age; printf ",\nSTATUS = '%s'", $status if defined $status; printf ",\nADDRESS = '%s'", $address if defined $address; printf ",\nPHONE = '%s'", $phone if defined $phone; printf "\nWHERE CUSTOMER_NUMBER = %d;\n\n", $customer_number;
I don't mind using a CPAN module, of course; indeed, I expect I'll have to. But I'm hoping to avoid being overwhelmed by the surfeit of available choices. This commonplace task has got to be easier than it seems from my research of the many options.

Thank you!

Jim

Replies are listed 'Best First'.
Re: Simple Template System That Supports Conditional Content?
by suaveant (Parson) on Aug 28, 2007 at 17:44 UTC
    I'd have to vote for Template Toolkit... it is powerful yet pretty easy to use. Therefore when you need some other functionality in a few months, you'll already have a good solution.

                    - Ant
                    - Some of my best work - (1 2 3)

Re: Simple Template System That Supports Conditional Content?
by eric256 (Parson) on Aug 28, 2007 at 17:35 UTC

    I like HTML::Template, despite the name it does regular text templates as well as HTML.

    Recently i've started using Template as well (not sure how to link to that one), its a bit heavier to use and install but comes with tons and tons of options.

    These two have fit for me every time so I don't even look for others, might be out there but these are two that have been around the block.

    Update:I assumed that your sample was just a sample, if you are actually working with SQL you probably want to use a different solution.

    Something like:

    my $update = { ADDRESS => 'test', customer_name => 'eric' }; my @cols = sort grep { defined $update->{$_}} keys %$update; my $sql = join (",", map { "$_ = ?" } @cols ); print "UPDATE test SET $sql WHERE id = ?"; #then you can use it like: # $dbh->execute("UPDATE test SET $sql WHERE id = ?",undef, map {%updat +e{$_}} @cols, $id);

    ___________
    Eric Hodges
Re: Simple Template System That Supports Conditional Content?
by shmem (Chancellor) on Aug 28, 2007 at 19:54 UTC
    Your example doesn't indicate use of any templating system. Templates are used if the signal to noise ratio (read: perl to "not perl stuff") is pretty low, i.e. you have lots of non-perl stuff controlled by some perl statements (conditionals and maybe flow control), where the template gives the static structure and perl delivers the content that matters into that structure.

    Templating is always about embedding results of perl expressions into "foreign" content. Since there's not much "foreign" stuff in your example, any pointers to templating solutions based on your question are wild shots in the dark with a preferred target in mind.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Simple Template System That Supports Conditional Content?
by caelifer (Scribe) on Aug 28, 2007 at 19:41 UTC
    Just to note, when doing a dynamic SQL statement building, it is usually a very bad idea to do simple string substitution based on the user input. You open yourself to SQL injection attacks among other things, like proper special character handling, etc. There is a much better option of using binding with prepare method of DBI package.
    my $dbh = DBI->connect($data_source, $opts...); my $update_stmt = $dbh->prepare("UPDATE tbl_name SET `CUSTOMER NAME` = + ?, AGE = ?, STATUS = ?, ..."); ... $update_stmt->execute( defined $customer_name ? $customer_name : undef, defined $age ? $age : undef, defined $status ? $status : undef, ...);
    Regards,

    - caelifer

      Yours doesn't do the same thing. It actually updates fields they didn't mean to update setting them to undef/null.


      ___________
      Eric Hodges
        This was never intended to be a working code or an actual solution to the user's problem. I only wanted to show how to use binding with prepare.

        Regards,

        - caelifer

Re: Simple Template System That Supports Conditional Content?
by runrig (Abbot) on Aug 28, 2007 at 17:44 UTC
Re: Simple Template System That Supports Conditional Content?
by andreas1234567 (Vicar) on Aug 29, 2007 at 05:33 UTC
    I very much agree with shmem above. In practice I would separate the code in two parts:
    • Code that retrieves the data from database and manipulates it. SQL, argument validation, sorting, access, control, etc goes here.
    • Code that presents the data to the user. User interface (e.g. HTML) generation (possibly using one of the suggested frameworks) goes here.
    This is consistent with the Model-view-controller (MVC) architectural pattern.
    --
    Andreas
Re: Simple Template System That Supports Conditional Content?
by andreas1234567 (Vicar) on Aug 28, 2007 at 17:44 UTC
      There is no doubt Mason is powerful, but in my experience it doesn't really fit the "simple" catgeory. A lot to set up for a basic template.

                      - Ant
                      - Some of my best work - (1 2 3)

Re: Simple Template System That Supports Conditional Content?
by naikonta (Curate) on Aug 29, 2007 at 15:47 UTC
    I'd like to solve my sql syntax tasks with SQL::Abstract and process the execution with DBI.
    use strict; use warnings; use DBI; use SQL::Abstract; my $dbh = DBI->connect( 'dbi:mysql:test', 'user', 'pass', {RaiseError => 1, AutoCommit => 1, ShowErrorStatement => 1}); my $sql = SQL::Abstract->new; my $table_name = 'CUSTOMER'; my $customer_number = some_param_method('customer_id'); # defined some +where my @customer_data = get_customer_data(); # defined somewhere my @columns = qw(CUSTOMER_NAME AGE STATUS ADDRESS PHONE); my %values; for (0 .. $#columns) { $values{$columns[$_]} = $customer_data[$_] if defined $customer_data[$_]; } my($query, @binds) = $sql->update( $table_name, \%values, # handles SET COLUMN = ? { CUSTOMER_NUMBER => $customer_number }, # handles WHERE clause ); my $sth = $dbh->prepare($query); $sth->execute(@binds);

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!