| blib/lib/HTML/DynamicTemplate.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 61 | 63 | 96.8 |
| branch | 16 | 22 | 72.7 |
| condition | 6 | 6 | 100.0 |
| subroutine | 10 | 10 | 100.0 |
| pod | 5 | 5 | 100.0 |
| total | 98 | 106 | 92.4 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | #================================================================== | ||||||
| 2 | # DynamicTemplate.pm | ||||||
| 3 | |||||||
| 4 | package HTML::DynamicTemplate; | ||||||
| 5 | 2 | 2 | 14253 | use strict; | |||
| 2 | 4 | ||||||
| 2 | 75 | ||||||
| 6 | |||||||
| 7 | 2 | 2 | 10 | use vars qw($VERSION); | |||
| 2 | 5 | ||||||
| 2 | 3101 | ||||||
| 8 | $VERSION = "0.94"; | ||||||
| 9 | |||||||
| 10 | |||||||
| 11 | |||||||
| 12 | #================================================================== | ||||||
| 13 | |||||||
| 14 | =head1 NAME | ||||||
| 15 | |||||||
| 16 | HTML::DynamicTemplate - HTML template class. | ||||||
| 17 | |||||||
| 18 | =head1 SYNOPSIS | ||||||
| 19 | |||||||
| 20 | use HTML::DynamicTemplate; | ||||||
| 21 | my $template = new HTML::DynamicTemplate 'path/to/template'; | ||||||
| 22 | $template->set_recursion_limit($integer); | ||||||
| 23 | $template->set(NAME => $value); | ||||||
| 24 | $template->set(NAME_1 => $value_1, | ||||||
| 25 | NAME_2 => $value_2, | ||||||
| 26 | NAME_3 => $value_3); | ||||||
| 27 | |||||||
| 28 | $template->clear(); | ||||||
| 29 | $template->render(); | ||||||
| 30 | $template->render(@variables); | ||||||
| 31 | |||||||
| 32 | path/to/template | ||||||
| 33 | ---------------- | ||||||
| 34 | |||||||
| 35 | |||||||
| 36 | $HEADING |
||||||
| 37 | |||||||
| 38 | This is standard HTML with |
||||||
| 39 | arbitrary embedded variable references which are substituted | ||||||
| 40 | with actual values when the template is rendered. | ||||||
| 41 | |||||||
| 42 | Template variables may be set within the template itself |
||||||
| 43 | with the special $SET directive. This is useful when setting | ||||||
| 44 | variables for use by included templates. Example: | ||||||
| 45 | $SET(PAGE_TITLE, "What's New"). Note: Be sure to escape | ||||||
| 46 | quotes (") and closing parantheses ()) as HTML | ||||||
| 47 | entities. | ||||||
| 48 | |||||||
| 49 | Additionally, templates may be recursively included by |
||||||
| 50 | specifying a template with the special $INCLUDE directive. | ||||||
| 51 | Example: $INCLUDE(templates/example.tmpl). Template paths may | ||||||
| 52 | be variable references as in $INCLUDE($EXAMPLE_FILE). Note: | ||||||
| 53 | Any variable references found in included templates will be | ||||||
| 54 | substituted as in the original template. | ||||||
| 55 | |||||||
| 56 | Usage note: variable and directive names are always |
||||||
| 57 | specified in uppercase. | ||||||
| 58 | |||||||
| 59 | |||||||
| 60 | |||||||
| 61 | |||||||
| 62 | =head1 DESCRIPTION | ||||||
| 63 | |||||||
| 64 | The C |
||||||
| 65 | template in perl. Significant features include the ability to set | ||||||
| 66 | template variables from within the template itself, the ability to | ||||||
| 67 | recursively include other templates, and the ability to selectively | ||||||
| 68 | render a specified subset of variables. | ||||||
| 69 | |||||||
| 70 | =head1 METHODS | ||||||
| 71 | |||||||
| 72 | =over 4 | ||||||
| 73 | |||||||
| 74 | =cut | ||||||
| 75 | |||||||
| 76 | #================================================================== | ||||||
| 77 | |||||||
| 78 | =item $template = new HTML::DynamicTemplate $template_filename; | ||||||
| 79 | |||||||
| 80 | Constructor for the template. Returns a reference to a | ||||||
| 81 | HTML::DynamicTemplate object based on the specified template file. | ||||||
| 82 | |||||||
| 83 | =cut | ||||||
| 84 | |||||||
| 85 | sub new { | ||||||
| 86 | 2 | 2 | 1 | 58 | my($class, $template) = @_; | ||
| 87 | |||||||
| 88 | 2 | 6 | my $self = {}; | ||||
| 89 | 2 | 6 | bless $self, $class; | ||||
| 90 | |||||||
| 91 | 2 | 14 | $self->{'vars'} = {}; | ||||
| 92 | 2 | 6 | $self->{'source'} = ''; | ||||
| 93 | 2 | 6 | $self->{'recursion_level'} = 0; | ||||
| 94 | 2 | 4 | $self->{'recursion_limit'} = 10; | ||||
| 95 | 2 | 42 | $self->{'template'} = $template; | ||||
| 96 | |||||||
| 97 | 2 | 50 | 111 | open TEMPLATE, $template or die $!; | |||
| 98 | 2 | 48 | while() { $self->{'source'} .= $_ } | ||||
| 74 | 184 | ||||||
| 99 | 2 | 24 | close TEMPLATE; | ||||
| 100 | |||||||
| 101 | 2 | 9 | return $self; | ||||
| 102 | } | ||||||
| 103 | |||||||
| 104 | |||||||
| 105 | |||||||
| 106 | #================================================================== | ||||||
| 107 | |||||||
| 108 | =item $template->set_recursion_limit($integer); | ||||||
| 109 | |||||||
| 110 | A default recursion limit for template includes is implemented to | ||||||
| 111 | prevent infinite recursions. Use this method to override the | ||||||
| 112 | default value (10). | ||||||
| 113 | |||||||
| 114 | =cut | ||||||
| 115 | |||||||
| 116 | sub set_recursion_limit { | ||||||
| 117 | 2 | 2 | 1 | 13 | my($self, $limit) = @_; | ||
| 118 | |||||||
| 119 | 2 | 50 | 24 | $self->{'recursion_limit'} = $limit | |||
| 120 | unless $limit !~ m/^\d+$/; | ||||||
| 121 | |||||||
| 122 | 2 | 6 | return; | ||||
| 123 | } | ||||||
| 124 | |||||||
| 125 | #================================================================== | ||||||
| 126 | |||||||
| 127 | =item $template->set(NAME => $value); | ||||||
| 128 | |||||||
| 129 | Sets template variable to given value. | ||||||
| 130 | |||||||
| 131 | =cut | ||||||
| 132 | |||||||
| 133 | sub set { | ||||||
| 134 | 8 | 8 | 1 | 57 | my($self, @arguments) = @_; | ||
| 135 | |||||||
| 136 | 8 | 21 | while(my $name = shift @arguments) { | ||||
| 137 | 28 | 30 | my $value = shift @arguments; | ||||
| 138 | 28 | 50 | 57 | $value = '' unless defined $value; | |||
| 139 | 28 | 105 | $self->{'vars'}{uc $name} = $value; | ||||
| 140 | } | ||||||
| 141 | |||||||
| 142 | 8 | 19 | return; | ||||
| 143 | } | ||||||
| 144 | |||||||
| 145 | #================================================================== | ||||||
| 146 | |||||||
| 147 | =item $template->clear(); | ||||||
| 148 | |||||||
| 149 | Clears template variables. Useful when processing table row | ||||||
| 150 | templates. | ||||||
| 151 | |||||||
| 152 | =cut | ||||||
| 153 | |||||||
| 154 | sub clear { | ||||||
| 155 | 2 | 2 | 1 | 9 | my($self) = @_; | ||
| 156 | |||||||
| 157 | 2 | 5 | $self->{'vars'} = {}; | ||||
| 158 | |||||||
| 159 | 2 | 10 | return; | ||||
| 160 | } | ||||||
| 161 | |||||||
| 162 | #================================================================== | ||||||
| 163 | |||||||
| 164 | =item $template->render(); | ||||||
| 165 | |||||||
| 166 | Renders template by performing variable substitutions. | ||||||
| 167 | |||||||
| 168 | =cut | ||||||
| 169 | |||||||
| 170 | =item $template->render(@variables); | ||||||
| 171 | |||||||
| 172 | Renders template by performing variable substitutions on only those | ||||||
| 173 | variable names specified in @variables. | ||||||
| 174 | |||||||
| 175 | =cut | ||||||
| 176 | |||||||
| 177 | sub render { | ||||||
| 178 | 2 | 2 | 1 | 17 | my($self, @variables) = @_; | ||
| 179 | |||||||
| 180 | 2 | 5 | $self->{'recursion_level'} = 0; | ||||
| 181 | 2 | 11 | return $self->_substitute($self->{'source'}, @variables); | ||||
| 182 | } | ||||||
| 183 | |||||||
| 184 | |||||||
| 185 | |||||||
| 186 | #================================================================== | ||||||
| 187 | |||||||
| 188 | sub _substitute { | ||||||
| 189 | 218 | 218 | 662 | my($self, $source, @variables) = @_; | |||
| 190 | |||||||
| 191 | 218 | 1443 | $source =~ s/\$([0-9_A-Z]+)(\(([^)]+)\))?(\n?)/ | ||||
| 192 | 146 | 100 | 100 | 1894 | if($1 eq 'SET' and defined $2) { | ||
| 100 | 100 | ||||||
| 100 | |||||||
| 193 | 6 | 50 | 38 | if($3 =~ m%^([0-9_A-Z]+)\s*,\s*"([^"]+)"$%) { | |||
| 194 | 6 | 26 | $self->{'vars'}{$1} = $2 | ||||
| 195 | } | ||||||
| 196 | 6 | 33 | ""; | ||||
| 197 | } elsif($1 eq 'INCLUDE' and defined $2) { | ||||||
| 198 | 110 | 100 | 261 | if($self->{'recursion_level'} < $self->{'recursion_limit'}) { | |||
| 199 | 108 | 410 | $self->_include($self->_substitute($3), @variables).$4 | ||||
| 200 | } else { | ||||||
| 201 | 2 | 13 | "[ include recursion limit exceeded ]$4" | ||||
| 202 | } | ||||||
| 203 | } elsif($#variables > 0) { | ||||||
| 204 | 14 | 50 | 30 | if($self->_is_in_array($1, @variables)) { | |||
| 205 | 14 | 73 | $self->{'vars'}{$1}.$4 | ||||
| 206 | } else { | ||||||
| 207 | 0 | 0 | $4 | ||||
| 208 | } | ||||||
| 209 | } else { | ||||||
| 210 | 16 | 88 | $self->{'vars'}{$1}.$4 | ||||
| 211 | } | ||||||
| 212 | /egm; | ||||||
| 213 | |||||||
| 214 | 218 | 761 | return $source; | ||||
| 215 | } | ||||||
| 216 | |||||||
| 217 | #================================================================== | ||||||
| 218 | |||||||
| 219 | sub _include { | ||||||
| 220 | 108 | 108 | 253 | my($self, $template, @variables) = @_; | |||
| 221 | |||||||
| 222 | 108 | 115 | my $source; | ||||
| 223 | 108 | 50 | 3745 | open TEMPLATE, $template or return "[ $template: $! ]"; | |||
| 224 | 108 | 2370 | while() { $source .= $_ } | ||||
| 108 | 873 | ||||||
| 225 | 108 | 1307 | close TEMPLATE; | ||||
| 226 | 108 | 156 | chomp $source; | ||||
| 227 | |||||||
| 228 | 108 | 187 | $self->{'recursion_level'}++; | ||||
| 229 | 108 | 296 | $source = $self->_substitute($source, @variables); | ||||
| 230 | 108 | 144 | $self->{'recursion_level'}--; | ||||
| 231 | |||||||
| 232 | 108 | 424 | return $source; | ||||
| 233 | } | ||||||
| 234 | |||||||
| 235 | #================================================================== | ||||||
| 236 | |||||||
| 237 | sub _is_in_array { | ||||||
| 238 | 14 | 14 | 40 | my($self, $element, @array) = @_; | |||
| 239 | |||||||
| 240 | 14 | 34 | for my $index (0..$#array) { | ||||
| 241 | 65 | 100 | 143 | return 1 unless $element ne $array[$index]; | |||
| 242 | } | ||||||
| 243 | |||||||
| 244 | 0 | return 0; | |||||
| 245 | } | ||||||
| 246 | |||||||
| 247 | |||||||
| 248 | |||||||
| 249 | 1; | ||||||
| 250 | __END__ |