Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
OK, well, as I suspected there's definitely strong opinions associated with template systems.

Here's what I've got going then.

The basic premise is that the main Perl code is going to do all the work of preparing the data. The template system is simply a means to put it into the page. To that end I guess my style most closely matches Template-Toolkit, even down to the use of '[%' and '%]' which we both seem to have chosen independantly, go figure. I didn't want to take HTML::Template's approach of wrapping things up in tags (that are easily lost in the rest of the HTML, not to mention harder to search for and just plain wordy)

A $session object is created (my session object does all the usual session management stuff, config files, login, session verification, etc). The $session is used by the page script, which then stuffs it full of what ever data it digs up, in what ever format it needs to be stored as. At the end of the script the $session object is passed into the template processing to generate the page.

A simple session data example might look like this:
$session = { data1 => 'test1', # scalar data2 => ['array0', 'array1'], # array ref data3 => { # hash ref data1 => 'test4', data2 => ['array50', 'array51'], data3 => { data_x => 'data2_array_count', data_y => 2, } } };

A simple template to display this sesion might look like this:
data1: [%data1%]<br> data2: <br> [%data2:%] &nbsp; [%$_%]<br> [%:data2%] data3: <br> [%data3:%] &nbsp; data1: [%$_.data1%]<br> &nbsp; data2: <br> [%$_.data2:%] &nbsp;&nbsp; [%$_%]<br> [%:$_.data2%] &nbsp; data3: <br> [%$_.data3:%] &nbsp;&nbsp; data_x: [%$_.data_x%] data_y: [%$_.data_y%]<br> [%:$_data3%] [%:data3%] [%data4:%] There's nothing in this data and the entire block will simply be left +out of the output. [%:data4%] Here's a direct reference to a nested key<br> data2 array count is: [%data3.data3.data_y%]<br> <br> Since data_x and data_y are unique here's another way to get to them:< +br> [%data3.data3:%] data_x: [%data_x%]<br> data_y: [%data_y%]<br> [%:data3.data3%] <br> And yet another:<br> [%data3:%] data_x: [%$_.data3.data_x%]<br> data_y: [%$_.data3.data_y%]<br> [%:data3%]

The key points are:
- CGI->header() takes care of wrapping the template inside a body
- Every substitution is enclosed by [% %]
- Substitution key relates directly to the key/value pairs in $session
- Nested levels can be reached prefixing the key path to the level ie [%level1key.level2key.level3key%]
(Of course this presumes that you can't have a '.' in a key name to do this)
- A block starts when the substitution key ends with a ':', the block ends with the first matching key that starts with a ':'
- Inside a block, something magic happens. A symolic key '$_' takes on a reference to the value of the block key. If the value is a hash, $_ becomes a reference to that hash. If the value is an array, then the block is repeated for each item in the array with $_ becoming a reference to each item in turn.
- In addition to the symbolic '$_' key, there's also a symbolic '$i' key which holds the value of the current array index (of an array block).
- keys are searched first at the top most level, then at the block level (if your keys are unique, you can skip the '$_.' prefix inside blocks)
- Any value (block) not found or defined is simply left out


This is the short version. I also have several other macros in my template to do other things:
[%value:template%] - include another template named 'value'
(anyplace you can put a 'value' in a macro, you can also use 'key.var' to use the value of a key instead)
[%key:ift%] something [%key:else%] something else [%:key] - if 'true' else conditions (else is optional)
[%key:iff%] - Same as 'ift', only if 'false'
[%key:ifeq:value%],[%key:iflt:value%],[%key:ifgt:value%] - comparison tests, same as 'ift' (string)
[%key:if.eq:value%],[%key:if.lt:value%],[%key:if.gt:value%] - comparison tests, same as 'ift' (numeric)
[%key:table:cols][%key:row%][%key:col%][%key:cell%][%:key%] - given an array, turn it into a table with 'cols' columns. row, col and cell are all optional (the <table> tag itself is supplied by the template)

I've tried to keep the template substitution as close to the source Perl data as possible and streamlined for most common usage. It's not very pretty to look at, but it's logical and precise (imho) for a Perl developer. I have a school admin application I'm working on that neatly displays a very complex schedule table with a very minimal template.

I guess I should also add that this is part of a larger 'web application framework' I'm working on, so I've also built in support for template stylesheet themes, icon/image paths, javascript libraries, template view levels, and multi-language directories.

So, does it warrent further discussion or should I just keep it to myself?

In reply to Re^2: Yet Another Templating System by ruzam
in thread Yet Another Templating System by ruzam

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-04-19 01:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found