NAME
Dotiac::DTL::Core - Common functions for Dotiac::DTL and Dotiac::DTL::Reduced
SYNOPSIS
require Dotiac::DTL;
$t=Dotiac::DTL->new("file.html")
$t->print();
require Dotiac::DTL::Reduced;
$t=Dotiac::DTL->new("compiled.html") #Works only with compiled templates
$t->print();
DESCRIPTION
This module includes the detailed documentation on the functions used by Dotiac::DTL and Dotiac::DTL::Reduced.
Settings
These are Settings that modify the behavior of Dotiac::DTL and should be set to your preferences.
$Dotiac::DTL::TEMPLATE_STRING_IF_INVALID
Defines what value should be inserted if a variable is not found. Defaults to "";
require Dotiac::DTL;
my $data="Hello, {{ asfdsfsdfasdf }}"; #asfdsfsdfasdf won't be defined.
$t=Dotiac::DTL->new(\$data);
$t->print(); #prints "Hello, "
$Dotiac::DTL::TEMPLATE_STRING_IF_INVALID="[[Not found]]";
$t->print(); #prints "Hello, [[Not found]]";
$Dotiac::DTL::ALLOW_METHOD_CALLS
Setting this to "1" allows methods of objects in the given variables to be called (without parameters).
Setting this to "0" makes the template slightly safer if you can't trust your variables.
Defaults to "1".
$Dotiac::DTL::ALLOWED_INCLUDE_ROOTS
Setting this to "1" allows the unsafe ssi-tag to open any file on your filesystem.
Setting this to "2" also allows the tags include and extend to open files anywhere.
Defaults to "0", which allows only files to be opened in the current or subdirectories.
$Dotiac::DTL::AUTOESCAPING
Enables or disables HTML-autoescaping for all templates. Defaults to enabled(1)
require Dotiac::DTL;
my $data="Hello, {{ "<World>" }}";
$t=Dotiac::DTL->new(\$data);
$t->print(); #prints "Hello, <World>"
$Dotiac::DTL::AUTOESCAPING=0;
$t->print(); #prints "Hello, <World>";
You could also use the safe filter for a single variable Dotiac::DTL::Filter, or the autoescape tag Dotiac::DTL::Tag::autoescape for an area.
@Dotiac::DTL::TEMPLATE_DIRS
Defines a list of directories in which the exported Template() should look for the template. Defaults to an empty list.
$Dotiac::DTL::DATETIME_FORMAT
Default format for the {% now %}-tag if there is no format given. (Defaults to 'N j, Y, P')
$Dotiac::DTL::DATE_FORMAT
Default format for the date-filter if there is no format given. (Defaults to 'N j, Y')
$Dotiac::DTL::TIME_FORMAT
Default format for the time-filter if there is no format given. (Defaults to 'P')
$Dotiac::DTL::PARSER
Which parser Dotiac::DTL should use. Defaults to "Dotiac::DTL::Parser", the normal Dotiac parser.
You only should change this, if you know what you are doing.
Static internal variables
These are only important to people writing there own Tags. See Dotiac::DTL::Tag for details on that.
These variables are cleared every time print() or string() or similar on the main template is called.
$Dotiac::DTL::Max_Depth
This is used for output (during the string()-call of Dotiac::DTL::Value). This defines how deep datastructures are printed if rendered as a Variable. Defaults to 3, set this to 0 to make Arrays and Hashes print as a space.
%Dotiac::DTLs::blocks
Contains the content of the named blocks, either as a Dotiac::DTL::Tag like object or a reference to a code reference.
sub eval() {
$Dotiac::DTLs::blocks{"main"}=Dotiac::DTL->new("file.html")->{first};
my $sub={
return "Hello World";
};
$Dotiac::DTLs::blocks{"compiled"}=\$sub;
}
%Dotiac::DTLs::cycle
Used by the cycle tag to store state information, there should be no need to play around with this
%Dotiac::DTLs::globals
Storage space for other tags. You should never store any information that changes in the objects themselves, you should store it in here. The objects won't be resetted on every run.
#In your tag, lets call it counter
sub print {
$Dotiac::DTLs::globals{counter}->{$self}=1 unless $Dotiac::DTLs::globals{counter}->{$self}=1;
print $Dotiac::DTLs::globals{counter}->{$self}++;
#or named counters:
$Dotiac::DTLs::globals{counter}->{$self->{name}}=1 unless $Dotiac::DTLs::globals{counter}->{$self->{name}}=1;
print $Dotiac::DTLs::globals{counter}->{$self->{name}}++;
$self->{n}->print(@_);
}
#And for the compiled output
sub perlprint {
my ($fh,$id,$level,$digest)=(shift(),shift(),shift(),shift());
#...
my $name='"'.$digest."-".$id.'"'; #$digest will be unique in combination with $id.
print $fh "\t" x $level,"\$Dotiac::DTLs::globals{counter}->{$name}=1 unless \$Dotiac::DTLs::globals{counter}->{$name}=1;\n";
print $fh "\t" x $level,"print \$Dotiac::DTLs::globals{counter}->{$name}++;\n";
# or named templates, which are even easier here: Just define \$name$id in perl()
my ($fh,$id,$level,$digest)=(shift(),shift(),shift(),shift());
print $fh "\t" x $level,"\$Dotiac::DTLs::globals{counter}->{\$name$id}=1 unless \$Dotiac::DTLs::globals{counter}->{\$name$id}=1;\n";
print $fh "\t" x $level,"print \$Dotiac::DTLs::globals{counter}->{\$name$id}++;\n";
#...
}
#Same for string() of course.
See Dotiac::DTL::Tag for details on what those methods should do.
%Dotiac::DTLs::included
Stores information on which template is already included to detect cyclic includes. Used by the tags ssi and include. There shouldn't also be any need to change this.
Public methods
new(FILE) or new(FILE,COMPILE)
This one differs if you are using Dotiac::DTL or Dotiac::DTL::Reduced, since Dotiac::DTL::Reduced will die on uncompiled Templates and can't compile them. See their documentation for details.
safenew(FILE) or safenew(FILE,COMPILE)
Same as new(), mostly used internally by include and extends. Accepts only relative pathes without leading ".." .
By setting $ALLOWED_INCLUDE_ROOTS to "2" this will be disabeled.
Also depends on if you are using Dotiac::DTL or Dotiac::DTL::Reduced.
compiled(PACKAGENAME)
Treats PACKAGENAME as a compiled template. See Dotiac::DTL::Compiled.
This is useful to insert perl code into templates.
Returns a Dotiac::DTL object
package MyTemplate;
sub print {
my ($vars,$escape)=(shift(),shift());
print "There are ".keys(%$vars)." parameters registered and x is $vars->{x}\n";
}
sub string {
my ($vars,$escape)=(shift(),shift());
return "There are ".keys(%$vars)." parameters registered and x is $vars->{x}\n";
}
sub eval {
#nothing for now.
}
package main;
require Dotiac::DTL;
my $mytemplate=Dotiac::DTL->compiled("MyTemplate");
# now you can use $mytemplate as a normal template.
$mytemplate->print({x=>123});
# This doesn't seem quite useful you could easily just write the code here, until you do this:
my $templatedata="{% for x in array %}{% include template %}{% endfor %}";
my $t = Dotiac::DTL->new(\$templatedata); #File templates work just as well.
$t->print({array=>[1..100],template=>$mytemplate);
# This will now include and print the above package a hundert times and
# will be a lot faster, depending on the contents of that for loop.
param(NAME, VALUE)
Works like HTML::Templates param() method, will set a param that will be used for output generation.
my $t=Dotiac::DTL->new("file.html");
$t->param(FOO=>"bar");
$t->print();
#Its the same as:
my $t=Dotiac::DTL->new("file.html");
$t->print({FOO=>"bar"});
- NAME
-
Name of the parameter.
- VALUE
-
Value to set the parameter to.
Returns the value of the param NAME if VALUE is skipped.
string(HASHREF)
Returns the templates output.
- HASHREF
-
Parameters to give to the template. See Variables below.
output(HASHREF) and render(HASHREF)
Same as string(HASHREF) just for HTML::Template and Django syntax.
print(HASHREF)
You can think of these two being equal:
print $t->string(HASHREF);
$t->print(HASHREF);
But string() can cause a lot of memory to be used (on large templates), so print() will print to the default output handle as soon as it has some data, which uses a lot less memory.
- HASHREF
-
Parameters to give to the template. See Variables below.
Returns nothing.
Internal methods
These are used internally only, they should only be called by new() or tags.
parse(TEMPLATEREF,POSITIONREF, [FOUNDREF, List,of,endtags,to,look,for])
Parses the string referenced in TEMPLATEREF starting at the position referenced in POSITIONREF.
Returns the parsed templatedata if either one of the endtags is found (and sets FOUNDREF to the endtag) or the end of the string is reached.
This is used by tags to look for their endtag. For example the ifequal tag:
sub new {
my $class=shift;
my $self={p=>shift()}; #Text that came before the tag.
my $data=shift; #Content of the tag other than the name.
my $obj=shift;
my $data=shift; #Templatedataref
my $pos=shift; #and positionref from the parse() calling this tags new().
my $found=""; #Empty found
$self->{true}=$obj->parse($data,$pos,\$found,"else","endifequal"); #Search for either "else" or "endifequal" and set it to $found.
if ($found eq "else") {
$self->{false}=$obj->parse($data,$pos,\$found,"endifequal"); #If "else" was found, search for "endifequal"
}
($self->{var1},$self->{var2},undef)=Dotiac::DTL::get_variables($data);
bless $self,$class;
return $self;
}
#....
Note
Dotiac::DTL::Reduced doesn't support this, so it doesn't have to load all the tags or the parser.
unparsed(TEMPLATEREF,POSITIONREF, [FOUNDREF, STARTTAG, List,of,endtags,to,look,for])
Parses the string referenced in TEMPLATEREF starting at the position referenced in POSITIONREF.
Returns the unparsed templatedata if either one of the endtags is found (and sets FOUNDREF to the endtag) or the end of the string is reached.
Skips STARTTAG occurences and searches for additional endtags
This is used by tags to look for their endtag. For example an unparsed tag:
sub new {
my $class=shift;
my $self={p=>shift()}; #Text that came before the tag.
my $data=shift; #Content of the tag other than the name.
my $obj=shift;
my $data=shift; #Templatedataref
my $pos=shift; #and positionref from the parse() calling this tags new().
my $found=""; #Empty found
$self->{content}=$obj->unparsed($data,$pos,\$found,"unparsed","endunparsed");
bless $self,$class;
return $self;
}
#....
Note
There is no internal tag for now that needs this. But you might find some addons.
I planned this for a addon like Calypso DTL's {% ajax %} tag, that throws the unparsed template at DojoxDTL to render it in the browser.
Dotiac::DTL::Reduced doesn't support this either.
Internal static functions
escap(STRING)
Escapes a quoted string so it won't contain any special chars the parser might use.
The are for now: Space, tab, newline (Seperates variables in most tags), "," (spereates variables in for and filter arguments), "|" (seperates Filters), ":" (seperates filter and its arguments) and of course "+'.
This is used by Dotiac::DTL::get_variables() and doesn't need to be called anywhere else.
String literals in this implementation can contain:
\n #newline
\t #tab
\b #backspace
\f #formfeed
\r #carriage return
\" # "
\' # '
\{ # {
\} # }
\\ # \\
\xXX # character with hexadecimal charcode (00 - FF) \x20 = " "
\uXXXX # Unicode 16Bit \u0020 = " "
\UXXXXXXXX # Unicode 32Bit \u00000020 = " "
descap(STRING)
inversion of escap().
Called by devar() and apply_filters(), no need to call it anywhere else.
get_varibales(STRING, [SPLIT,BY])
Spilts a string, as given by the parser, into variables, which can be given to devar.
If there are additional arguments, it returns a two dimensional list splitted at the arguments.
Also escapes the quoted strings for safe processing using escap().
This is best explained with some examples:
my @list = Dotiac::DTL::get_varibales("var1 var2|Filter \"String with spaces\""); #@list is then ("var1", "var2|Filter", "`String%20with%spaces`")
my %list = Dotiac::DTL::get_varibales("foo|dictsort:'sort by some option' othervar by bar as newvar","as","by"); #%list is then (""=>["foo|dictsort:`sort%20by%20some%20option`","othervar"],as=>["bar"],by=>["newvar"])
#note the first " by " in the string is not being used for splitting
#And now without the arguments:
my @list = Dotiac::DTL::get_varibales("foo|dictsort:'sort by some option' othervar by bar as newvar"); #@list is then ("foo|dictsort:`sort%20by%20some%20option`","othervar","by","bar","as","newvar")
Escape(STRING,ESCAPE)
This is used in compiled templates for variables, it just escapes if ESCAPE is set or doesn't otherwise.
There should be no need to use this anywhere else.
urlencode(STRING)
About the same as CGI::escape(STRING), but doesn't work on EBCDIC
Conditional(OBJECT)
Returns a true Value if the object is true or filled (for array and hashrefs) and "" otherwise.
This is needed for the if, ifequal and ifnot equal tags to skip on a lot defineds().
It will return the size of the referenced container of an arrayref or hashref.
It will also try to run the count() method of an object, if available.
apply_filters(VALUE,VARS,ESCAPE,[FILTER1,FILTER2....])
Applies FILTER1, FILTER2, ... on a variable and escapes it if needed.
VARS is a hashref which holds all the parameters (The same you would give to string() or print())
ESACPE gives the starting point for the auto-escape (1: autoescape, 0:no autoescape)
print Dotiac::DTL::apply_filters("foo",{},0,"cut:`o`");# prints "f";
print Dotiac::DTL::apply_filters("foo",{var=>"0"},0,"cut:var"); #Also prints "f";
print Dotiac::DTL::apply_filters("<foo>",{},1); #Prints "<foo>";
print Dotiac::DTL::apply_filters("<foo>",{},0); #Prints "<foo>";
print Dotiac::DTL::apply_filters("<foo>",{},1,"safe"); #Prints "<foo>" even when autoescape is on
print Dotiac::DTL::apply_filters("<foo>",{},0,"escape"); #Prints "<foo>" # even when autoescape is off
devar(VARIABLE,VARS,ESCAPE, ...)
Replaces a string (as returned from get_variables()) with the variable from the part of VARS it references.
VARS is a hashref as given to string() or print()
ESCAPE controls the autoescape behavior (0: off, 1:on)
Returns the resolved variable with all the filters applied, or $Dotiac::DTL::TEMPLATE_STRING_IF_INVALID if the produkt is undef.
print Dotiac::DTL::devar("FOO|lower",{FOO=>"Hello"},1); #prints "hello"
print Dotiac::DTL::devar("FOO",{FOO=>"Hello"},1); #prints "Hello"
print Dotiac::DTL::devar("`FOO`",{FOO=>"Hello"},1); #prints "FOO"
print Dotiac::DTL::devar("`<FOO>`",{},1); #prints "<FOO>"
print Dotiac::DTL::devar("`<FOO>`",{},0); #prints "<FOO>"
print Dotiac::DTL::devar("`<FOO>|safe`",{},1); #prints "<FOO>"
print Dotiac::DTL::devar("`<FOO>|escape`",{},0); #prints "<FOO>"
devar_nodefault(VARIABLE,VARS,ESCAPE, ...)
Same as devar() (see above), but returns undef if the generated variable is undef.
devar_raw(VARIABLE,VARS,ESCAPE, ...)
Same as devar() but returns the Dotiac::DTL::Value object.
devar_content(VARIABLE,VARS,ESCAPE, ...)
Same as devar() but returns always the content and does no escaping or pretty printing.
devar_repr(VARIABLE,VARS,ESCAPE, ...)
Same as devar() but returns always the a representation without escaping. Use this, if the variable is not for printing or is going to be escaped some other way
devar_var(RAWVARIABLE,VARS,ESCAPE, ...)
Similar as devar(). But it won't accept filters in RAWVARIABLE and returns a Dotiac::DTL::Value object.
This is used by the Variable construct to cache filters and calling devar_var() and apply_filters() for increased performance.
This will return undef similar to devar_nodefault().
devar_var_default(RAWVARIABLE,VARS,ESCAPE, ...)
Similar as devar_var().
This will return $Dotiac::DTL::TEMPLATE_STRING_IF_INVALID if the result of devar_var() is undef.
SEE ALSO
http://www.djangoproject.com, Dotiac::DTL
BUGS
If you find a bug, please report it.
LEGAL
Dotiac::DTL was built according to http://docs.djangoproject.com/en/dev/ref/templates/builtins/.
AUTHOR
Marc-Sebastian Lucksch
perl@marc-s.de