.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Text::Xslate::Syntax::Kolon 3pm" .TH Text::Xslate::Syntax::Kolon 3pm "2018-11-02" "perl v5.28.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Text::Xslate::Syntax::Kolon \- The default template syntax .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& use Text::Xslate; \& my $tx = Text::Xslate\->new( \& syntax => \*(AqKolon\*(Aq, # optional \& ); \& \& print $tx\->render_string( \& \*(AqHello, <: $dialect :> world!\*(Aq, \& { dialect => \*(AqKolon\*(Aq } \& ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Kolon is the default syntax, using \f(CW\*(C`<: ... :>\*(C'\fR tags and \f(CW\*(C`: ...\*(C'\fR line code. In this syntax all the features in Xslate are available. .SH "SYNTAX" .IX Header "SYNTAX" .SS "Variable access" .IX Subsection "Variable access" Variable access: .PP .Vb 1 \& <: $var :> .Ve .PP Field access: .PP .Vb 3 \& <: $var.0 :> \& <: $var.field :> \& <: $var.accessor :> \& \& <: $var["field"] :> \& <: $var[0] :> .Ve .PP Variables may be \s-1HASH\s0 references, \s-1ARRAY\s0 references, or objects. Because \f(CW\*(C`$var.field\*(C'\fR and \f(CW$var["field"]\fR are the same semantics, \&\f(CW$obj["accessor"]\fR syntax may be call object methods. .SS "Literals" .IX Subsection "Literals" Special: .PP .Vb 3 \& : nil # as undef, indicating "nothing" \& : true # as the integer 1 \& : false # as the integer 0 .Ve .PP String: .PP .Vb 2 \& : "foo\en" # the same as perl \& : \*(Aqfoo\en\*(Aq # the same as perl .Ve .PP Number: .PP .Vb 5 \& : 42 \& : 3.14 \& : 0xFF # hex \& : 0777 # octal \& : 0b1010 # binary .Ve .PP Array: .PP .Vb 1 \& : for [1, 2, 3] \-> $i { ... } .Ve .PP Hash: .PP .Vb 1 \& : foo({ foo => "bar" }) .Ve .PP Note that \f(CW\*(C`{ ... }\*(C'\fR is always parsed as hash literals, so you don't need to use the <+> prefix as Perl sometimes requires: .PP .Vb 2 \& : {}.kv(); # ok \& : +{}.kv(); # also ok .Ve .SS "Expressions" .IX Subsection "Expressions" Conditional operator (\f(CW\*(C`?:\*(C'\fR): .PP .Vb 1 \& : $var.value == nil ? "nil" : $var.value .Ve .PP Relational operators (\f(CW\*(C`== != < <= > >=\*(C'\fR): .PP .Vb 2 \& : $var == 10 ? "10" : "not 10" \& : $var != 10 ? "not 10" : "10" .Ve .PP Note that \f(CW\*(C`==\*(C'\fR and \f(CW\*(C`!=\*(C'\fR are similar to Perl's \f(CW\*(C`eq\*(C'\fR and \f(CW\*(C`ne\*(C'\fR except that \&\f(CW\*(C`$var == nil\*(C'\fR is true \fBiff\fR \fI\f(CI$var\fI\fR is uninitialized, while other relational operators are numerical. .PP Arithmetic operators (\f(CW\*(C`+ \- * / % min max\*(C'\fR): .PP .Vb 4 \& : $var * 10_000 \& : ($var % 10) == 0 \& : 10 min 20 min 30 # 10 \& : 10 max 20 max 30 # 30 .Ve .PP Bitwise operators (\f(CW\*(C`prefix:<+^> +& +| +^\*(C'\fR) .PP .Vb 4 \& : 0x1010 +| 0x3200 # bitwise or: 0x3210 \& : 0x1010 +& 0x3200 # bitwise and: 0x1000 \& : 0x1010 +^ 0x3200 # bitwise xor: 0x0210 \& : +^0x1010 # bitwise neg: 0xFFFFEFEF (on 32 bit system) .Ve .PP Logical operators (\f(CW\*(C`! && || // not and or\*(C'\fR) .PP .Vb 2 \& : $var >= 0 && $var <= 10 ? "ok" : "too smaller or too larger" \& : $var // "foo" # as a default value .Ve .PP String operators (\f(CW\*(C`~\*(C'\fR) .PP .Vb 1 \& : "[" ~ $var ~ "]" # concatenation .Ve .PP The operator precedence is very like Perl's: .PP .Vb 10 \& . () [] \& prefix: prefix:<+> prefix:<\-> prefix:<+^> \& * / % x +& \& + \- ~ +| +^ \& prefix: \& < <= > >= \& == != \& | \& && \& || // min max \& ?: \& not \& and \& or .Ve .SS "Constants (or binding)" .IX Subsection "Constants (or binding)" You can define lexical constants with \f(CW\*(C`constant\*(C'\fR, which requires a bare word, and \f(CW\*(C`my\*(C'\fR, which requires a variable name. .PP .Vb 2 \& : constant FOO = 42; \& : my $foo = 42; .Ve .PP These two statements has the same semantics, so you cannot modify \f(CW$foo\fR. .PP .Vb 1 \& : my $foo = 42; $foo = 3.14; # compile error! .Ve .SS "Loops" .IX Subsection "Loops" There are \f(CW\*(C`for\*(C'\fR loops that are like Perl's \f(CW\*(C`foreach\*(C'\fR. .PP .Vb 4 \& : # iterate over an ARRAY reference \& : for $data \-> $item { \& [<: $item.field :>] \& : } \& \& : # iterate over a HASH reference \& : # You must specify how to iterate it (.keys(), .values() or .kv()) \& : for $data.keys() \-> $key { \& <: $key :>=<: $data[$key] :> \& : } .Ve .PP And the \f(CW\*(C`for\*(C'\fR statement can take an \f(CW\*(C`else\*(C'\fR block: .PP .Vb 6 \& : for $data \-> $item { \& [<: $item.field :>] \& : } \& : else { \& Nothing in data \& : } .Ve .PP The \f(CW\*(C`else\*(C'\fR block is executed if \fI\f(CI$data\fI\fR is an empty array or nil. .PP You can get the iterator index in \f(CW\*(C`for\*(C'\fR statements as \f(CW\*(C`$~ITERATOR_VAR\*(C'\fR: .PP .Vb 8 \& : for $data \-> $item { \& : if ($~item % 2) == 0 { \& Even (0, 2, 4, ...) \& : } \& : else { \& Odd (1, 3, 5, ...) \& : } \& : } .Ve .PP \&\f(CW\*(C`$~ITERATOR_VAR\*(C'\fR is a pseudo object, so you can access its elements via the dot-name syntax. .PP .Vb 4 \& : for $data \-> $i { \& : $~i # 0\-origin iterator index (0, 1, 2, ...) \& : $~i.index # the same as $~i \& : $~i.count # the same as $~i + 1 \& \& : if ($~i.index % 2) == 0 { \& even \& : } \& : else { \& odd \& : } \& : $~i.cycle("even", "odd") # => "even" \-> "odd" \-> "even" \-> "odd" ... \& : } .Ve .PP Supported iterator elements are \f(CW\*(C`index :Int\*(C'\fR, \f(CW\*(C`count :Int\*(C'\fR, \&\f(CW\*(C`body : ArrayRef\*(C'\fR, \f(CW\*(C`size : Int\*(C'\fR, \f(CW\*(C`max_index :Int\*(C'\fR, \f(CW\*(C`is_first :Bool\*(C'\fR, \&\f(CW\*(C`is_last :Bool\*(C'\fR, \f(CW\*(C`peek_next :Any\*(C'\fR, \f(CW\*(C`peek_prev :Any\*(C'\fR, \f(CW\*(C`cycle(...) :Any\*(C'\fR. .PP \&\f(CW\*(C`while\*(C'\fR loops are also supported in the same semantics as Perl's: .PP .Vb 4 \& : # $obj might be an iteratable object \& : while $dbh.fetch() \-> $item { \& [<: $item.field :>] \& : } .Ve .PP \&\f(CW\*(C`while defined expr \-> $item\*(C'\fR is interpreted as \&\f(CW\*(C`while defined(my $item = expr)\*(C'\fR for convenience. .PP .Vb 3 \& : while defined $dbh.fetch() \-> $item { \& [<: $item # $item can be false\-but\-defined :>] \& : } .Ve .PP Loop control statements, namely \f(CW\*(C`next\*(C'\fR and \f(CW\*(C`last\*(C'\fR, are also supported in both \f(CW\*(C`for\*(C'\fR and \f(CW\*(C`while\*(C'\fR loops. .PP .Vb 4 \& : for $data \-> $item { \& : last if $item == 42 \& ... \& : } .Ve .SS "Conditional statements" .IX Subsection "Conditional statements" There are \f(CW\*(C`if\-else\*(C'\fR and \f(CW\*(C`given\-when\*(C'\fR conditional statements. .PP \&\f(CW\*(C`if\-else\*(C'\fR: .PP .Vb 9 \& : if $var == nil { \& $var is nil. \& : } \& : else if $var != "foo" { # elsif is okay \& $var is not nil nor "foo". \& : } \& : else { \& $var is "foo". \& : } \& \& : if( $var >= 1 && $var <= 10 ) { \& $var is 1 .. 10 \& : } .Ve .PP Note that \f(CW\*(C`if\*(C'\fR doesn't require parens, so the following code is okay: .PP .Vb 1 \& : if ($var + 10) == 20 { } # OK .Ve .PP \&\f(CW\*(C`given\-when\*(C'\fR(also known as \fBswitch statement\fR): .PP .Vb 11 \& : given $var { \& : when "foo" { \& it is foo. \& : } \& : when ["bar", "baz" ] { \& it is either bar or baz. \& : } \& : default { \& it is not foo nor bar. \& } \& : } .Ve .PP You can specify the topic variable. .PP .Vb 8 \& : given $var \-> $it { \& : when "foo" { \& it is foo. \& : } \& : when $it == "bar" or $it == "baz" { \& it is either bar or baz. \& : } \& : } .Ve .SS "Functions and filters" .IX Subsection "Functions and filters" You can register functions via \f(CW\*(C`function\*(C'\fR or \f(CW\*(C`module\*(C'\fR options for \&\f(CW\*(C`Text::Xslate\->new()\*(C'\fR. .PP Once you have registered functions, you can call them with the \f(CW\*(C`()\*(C'\fR operator. \&\f(CW\*(C`infix:<|>\*(C'\fR is also supported as a syntactic sugar to \f(CW\*(C`()\*(C'\fR. .PP .Vb 3 \& : f() # without args \& : f(1, 2, 3) # with args \& : 42 | f # the same as f(42) .Ve .PP Functions are just Perl's subroutines, so you can define dynamic functions (a.k.a. dynamic filters), which is a subroutine that returns another subroutine: .PP .Vb 10 \& # code \& sub mk_indent { \& my($prefix) = @_; \& return sub { \& my($str) = @_; \& $str =~ s/^/$prefix/xmsg; \& return $str; \& } \& } \& my $tx = Text::Xslate\->new( \& function => { \& indent => \e&mk_indent, \& }, \& ); \& \& :# template \& : $value | indent("> ") # Template\-Toolkit like \& : indent("> ")($value) # This is also valid .Ve .PP \&\f(CW\*(C`example/dynamic_functions.tx\*(C'\fR has examples of dynamic functions being used with block, function and filter syntax, and with scalar, hash and array objects. .PP There are several builtin functions, which you cannot redefine: .PP .Vb 5 \& : $var | mark_raw # marks it as a raw string \& : $var | raw # synonym to mark_raw \& : $var | unmark_raw # removes "raw" marker from it \& : $var | html # does html\-escape to it and marks it as raw \& : $var | dump # dumps it with Data::Dumper .Ve .PP Note that you should not use \f(CW\*(C`mark_raw\*(C'\fR in templates because it can make security hole easily just like as type casts in C. If you want to generate \s-1HTML\s0 components dynamically, e.g. by \s-1HTML\s0 form builders, application code should be responsible to make strings as marked \f(CW\*(C`raw\*(C'\fR. .SS "Methods" .IX Subsection "Methods" When \fI\f(CI$var\fI\fR is an object instance, you can call its methods with the dot operator. .PP .Vb 3 \& <: $var.method() :> \& <: $var.method(1, 2, 3) :> \& <: $var.method( foo => [ 1, 2, 3 ] ) :> .Ve .PP There is an autoboxing mechanism that provides primitive types with builtin methods. See Text::Xslate::Manual::Builtin for details. .PP You can define more primitive methods with the \f(CW\*(C`function\*(C'\fR option. See Text::Xslate. .SS "Template inclusion" .IX Subsection "Template inclusion" Template inclusion is a traditional way to extend templates. .PP .Vb 3 \& : include "foo.tx"; \& : include "foo.tx" { var1 => value1, var2 => value2, ... }; \& : include "foo.tx" {$vars}; # use $vars as the params .Ve .PP if a var exist in the {$vars} and _\|_ROOT_\|_, the one in {$vars} will win. .PP also, be careful about the order of vars. .PP .Vb 1 \& : include "foo.tx" { var1 => $id, id => $var, var2 => $id } .Ve .PP var1 and var2 will be replaced by \f(CW$id\fR, var2 will be replaced by \f(CW$var\fR, because the value of id is changed .PP As \f(CW\*(C`cascade\*(C'\fR does, \f(CW\*(C`include\*(C'\fR allows barewords: .PP .Vb 2 \& : include foo # the same as \*(Aqfoo.tx\*(Aq \& : include foo::bar # the same as \*(Aqfoo/bar.tx\*(Aq .Ve .PP Xslate templates may be recursively included, but the including depth is limited to 100. .SS "Template cascading" .IX Subsection "Template cascading" Template cascading is another way to extend templates other than \f(CW\*(C`include\*(C'\fR. .PP First, make base templates \fImyapp/base.tx\fR: .PP .Vb 3 \& : block title \-> { # with default \& [My Template!] \& : } \& \& : block body \-> { } # without default .Ve .PP Then extend from base templates with the \f(CW\*(C`cascade\*(C'\fR keyword: .PP .Vb 4 \& : cascade myapp::base \& : cascade myapp::base { var1 => value1, var2 => value2, ...} \& : cascade myapp::base with myapp::role1, myapp::role2 \& : cascade with myapp::role1, myapp::role2 .Ve .PP In derived templates, you may extend templates (e.g. \fImyapp/foo.tx\fR) with block modifiers \f(CW\*(C`before\*(C'\fR, \f(CW\*(C`around\*(C'\fR (or \f(CW\*(C`override\*(C'\fR) and \f(CW\*(C`after\*(C'\fR. .PP .Vb 6 \& : # cascade "myapp/base.tx" is also okay \& : cascade myapp::base \& : # use default title \& : around body \-> { \& My template body! \& : } .Ve .PP And, make yet another derived template \fImyapp/bar.tx\fR: .PP .Vb 12 \& : cascade myapp::foo \& : around title \-> { \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& : super \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& : } \& : before body \-> { \& Before body! \& : } \& : after body \-> { \& After body! \& : } .Ve .PP Then render it as usual. .PP .Vb 2 \& my $tx = Text::Xslate\->new( file => \*(Aqmyapp/bar.tx\*(Aq ); \& $tx\->render({}); .Ve .PP The result is something like this: .PP .Vb 3 \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& [My Template!] \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& \& Before body! \& My template body! \& After body! .Ve .PP You can also cascade templates just like Moose's roles: .PP .Vb 1 \& : cascade myapp::base with myapp::role1, myapp::role2 .Ve .PP You can omit the base template. .PP Given a file \fImyapp/hello.tx\fR: .PP .Vb 5 \& : around hello \-> { \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& : super \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& : } .Ve .PP Then the main template: .PP .Vb 1 \& : cascade with myapp::hello \& \& : block hello \-> { \& Hello, world! \& : } .Ve .PP Output: .PP .Vb 3 \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Hello, world! \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- .Ve .PP In fact, you can omit the base template, and components can include any macros. .PP Given a file \fIcommon.tx\fR .PP .Vb 3 \& : macro hello \-> $lang { \& Hello, <: $lang :> world! \& : } \& \& : around title \-> { \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& : super \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& : } .Ve .PP The main template: .PP .Vb 1 \& : cascade with common \& \& : block title \-> { \& Hello, world! \& : } \& : hello("Xslate") .Ve .PP Output: .PP .Vb 4 \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Hello, world! \& \-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Hello, Xslate world! .Ve .PP There is a limitation that you cannot pass variables to the \f(CW\*(C`cascade\*(C'\fR keyword, because template cascading is statically processed. .SS "Macro blocks" .IX Subsection "Macro blocks" Macros are supported, which are called in the same way as functions and return a \f(CW\*(C`raw\*(C'\fR string. Macros return what their bodies render, so they cannot return references or objects, including other macros. .PP .Vb 4 \& : macro add \->($x, $y) { \& : $x + $y; \& : } \& : add(10, 20) \& \& : macro signature \-> { \& This is foo version <: $VERSION :> \& : } \& : signature() \& \& : macro factorial \-> $x { \& : $x == 0 ? 1 : $x * factorial($x\-1) \& : } \& : factorial(1) # as a function \& : 1 | factorial # as a filter .Ve .PP If you want to html-escape the return values of macros, you can use \&\f(CW\*(C`unmark_raw\*(C'\fR to remove \f(CW\*(C`raw\-ness\*(C'\fR from the values. .PP .Vb 5 \& : macro em \-> $s { \& <: $s :> \& : } \& : em("foo") # renders "foo" \& : em("foo") | unmark_raw # renders "<em>foo<em>" .Ve .PP Because macros are first-class objects, you can bind them to symbols. .PP .Vb 7 \& <: macro foo \-> { "foo" } \& macro bar \-> { "bar" } \& my $dispatcher = { \& foo => foo, \& bar => bar, \& }; \-:> \& : $dispatcher{$key}() .Ve .PP Anonymous macros are also supported, although they can return only strings. They might be useful for callbacks to high-level functions or methods. .PP .Vb 1 \& <: \-> $x, $y { $x + $y }(1, 2) # => 3 :> .Ve .PP The \f(CW\*(C`block\*(C'\fR keyword is used to make a group of template code, and you can apply filters to that block with \f(CW\*(C`infix:<|>\*(C'\fR. Here is an example to embed \s-1HTML\s0 source code into templates. .PP Template: .PP .Vb 3 \& : block source | unmark_raw \-> { \& Hello, world! \& : } .Ve .PP Output: .PP .Vb 1 \& <em>Hello, world!</em> .Ve .PP See also \*(L"Using FillInForm\*(R" in Text::Xslate::Manual::Cookbook for another example to use this block filter syntax. .PP Note that closures are not supported. .SS "Chomping newlines" .IX Subsection "Chomping newlines" You can add \f(CW\*(C`\-\*(C'\fR to the immediate start or end of a directive tag to control the newline chomping options to keep the output clean. The starting \f(CW\*(C`\-\*(C'\fR removes leading newlines and the ending \f(CW\*(C`\-\*(C'\fR removes trailing ones. .SS "Special keywords" .IX Subsection "Special keywords" There are special keywords: .IP "_\|_FILE_\|_" 4 .IX Item "__FILE__" Indicates the current file name. Equivalent to \f(CW\*(C`Text::Xslate\->current_file\*(C'\fR. .IP "_\|_LINE_\|_" 4 .IX Item "__LINE__" Indicates the current line number. Equivalent to \f(CW\*(C`Text::Xslate\->current_line\*(C'\fR. .IP "_\|_ROOT_\|_" 4 .IX Item "__ROOT__" Means the root of the parameters. Equivalent to \f(CW\*(C`Text::Xslate\->current_vars\*(C'\fR. .SS "Comments" .IX Subsection "Comments" Comments start from \f(CW\*(C`#\*(C'\fR to a new line or semicolon. .PP .Vb 5 \& :# this is a comment \& <: \& # this is also a comment \& $foo # $foo is rendered \& :> \& \& <: $bar # this is ok :> \& <: # this is comment; $baz # $baz is rendered :> .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Text::Xslate