Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Text::Xslate::Manual::UserbContributed Perl DText::Xslate::Manual::Cookbook(3)

NAME
       Text::Xslate::Manual::Cookbook -	How to cook Xslate templates

DESCRIPTION
       The Xslate cookbook is a	set of recipes showing Xslate features.

RECIPES
   How to manage HTML forms
       Managing	HTML forms is an important issue for web applications.	You're
       better off using	modules	that manage HTML forms rather than managing
       this yourself in	your templates.	 This section proposes two basic
       solutions: using	FillInForm and HTML form builders.

       In both solutions, you should not use the "mark_raw" filter in
       templates, which	easily creates security	holes. Instead,	application
       code should be responsible for calling the "mark_raw" function that
       "Text::Xslate" can export.

       Using FillInForm

       One solution to manage HTML forms is to use FillInForm modules with the
       block filter syntax.

       Example code using "HTML::FillInForm":

	   #!perl -w
	   use strict;
	   use Text::Xslate qw(html_builder);

	   use HTML::FillInForm; # HTML::FillInForm::Lite is okay

	   sub fillinform {
	       my($q) =	@_;
	       my $fif = HTML::FillInForm->new();
	       return html_builder {
		   my($html) = @_;
		   return $fif->fill(\$html, $q);
	       };
	   }

	   my $tx = Text::Xslate->new(
	       function	=> {
		   fillinform => \&fillinform,
	       },
	   );

	   my %vars = (
	       q => { foo => "<filled value>" },
	   );
	   print $tx->render_string(<<'T', \%vars);
	   FillInForm:
	   : block form	| fillinform($q) -> {
	   <form>
	   <input type="text" name="foo" />
	   </form>
	   : }
	   T

       Output:

	   FillInForm:
	   <form>
	   <input type="text" name="foo" value="&lt;filled value&gt;" />
	   </form>

       Because HTML::FillInForm::Lite provides a "fillinform" function,	it
       becomes even simpler:

	   use HTML::FillInForm::Lite qw(fillinform);

	   my $tx = Text::Xslate->new(
	       function	=> { fillinform	=> html_builder(\&fillinform) },
	   );

       From 1.5018 on, "html_builder_module" is	supported for HTML builder
       modules like "HTML::FillInForm".	Just import HTML builder functions
       with "html_builder_module" option.

	   my $tx = Text::Xslate->new(
	       html_builder_module => [	'HTML::FillInForm::Lite' => [qw(fillinform)] ],
	   );

       See also	HTML::FillInForm or HTML::FillInForm::Lite for details.

       Using HTML form builders

       Another solution	to manage HTML forms is	to use form builders.  In such
       cases, all you have to do is to apply "mark_raw()" to HTML parts.

       Here is a PSGI application that uses "HTML::Shakan":

	   #!psgi
	   use strict;
	   use warnings;
	   use Text::Xslate qw(mark_raw);
	   use HTML::Shakan;
	   use Plack::Request;

	   my $tx = Text::Xslate->new();

	   sub app {
	       my($env)	= @_;
	       my $req	= Plack::Request->new($env);

	       my $shakan = HTML::Shakan->new(
		   request => $req,
		   fields  => [	TextField(name => 'name', label	=> 'Your name: ') ],
	       );

	       my $res = $req->new_response(200);

	       # do mark_raw here, not in templates
	       my $form	= mark_raw($shakan->render());
	       $res->body( $tx->render_string(<<'T', { form => $form })	);
	   <!doctype html>
	   <html>
	   <head><title>Building form</title></head>
	   <body>
	   <form>
	   <p>
	   Form:<br />
	   <: $form :>
	   </p>
	   </body>
	   </html>
	   T
	       return $res->finalize();

	   }

	   return \&app;

       Output:

	   <!doctype html>
	   <html>
	   <head><title>Building form</title></head>
	   <body>
	   <form>
	   <p>
	   Form:<br />
	   <label for="id_name">Your name</label>
	   <input id="id_name" name="name" type="text" value="&lt;Xslate&gt;" />
	   </p>
	   </body>
	   </html>

       See also	HTML::Shakan for details.

   How to use Template Toolkit's WRAPPER feature in Kolon
       Use template cascading, which is	a super-set of the "WRAPPER"
       directive.

       wrapper.tx:

	   <div	class="wrapper">
	   block content -> { }
	   </div>

       content.tx

	   : cascade wrapper

	   : override content -> {
	       Hello, world!
	   : }

       Output:

	   <div	class="wrapper">
	       Hello, world!
	   </div>

       Template	cascading

       Xslate supports template	cascading, which allows	you to extend
       templates with block modifiers. It is like traditional template
       inclusion, but is more powerful.

       This mechanism is also called as	template inheritance.

       See also	"Template cascading" in	Text::Xslate.

   How to map __DATA__ sections	to the include path
       Use "Data::Section::Simple", and	the "path" option of "new()", which
       accepts HASH references which contain "$file_name => $content" mapping.

	   use Text::Xslate;
	   use Data::Section::Simple;

	   my $vpath = Data::Section::Simple->new()->get_data_section();
	   my $tx = Text::Xslate->new(
	       path => [$vpath],
	   );

	   print $tx->render('child.tx');

	   __DATA__
	   @@ base.tx
	   <html>
	   <body><: block body -> { :>default body<: } :></body>
	   </html>
	   @@ child.tx
	   : cascade base;
	   : override body -> {
	   child body
	   : } # endblock body

       This feature is directly	inspired by Text::MicroTemplate::DataSection,
       and originated from Mojolicious.

       See also	Data::Section::Simple, Text::MicroTemplate::DataSection, and
       Mojolicious.

   How to interpolate data into	JavaScript sections without XSS
       Because Xslate escapes only HTML	meta characters, you must escape
       JavaScript meta characters by yourself when you put data	into "<script>
       ... </script>" sections.

       The "JSON" module is not	suitable because it doesn't escape some	meta
       characters such as "</script>".

       It is better to use utilities proven to be secure for JavaScript
       escaping	to avoid XSS.  JavaScript::Value::Escape helps you in this
       regard.

	   my $tx = Text::Xslate->new(
	       module => ['JavaScript::Value::Escape' => [qw(js)]],
	       );

	   my %params =	(
	       user_input => '</script><script>alert("XSS")</script>',
	       );

	   print $tx->render_string(<<'T', \%params);
	   <script>
	   document.write('<: $user_input | html | js :>');
	   var user_input = '<:	$user_input | js :>';
	   </script>
	   T

       You'd better to consult the security experts on more complex cases.

   How to interpolate structured texts into HTML without XSS
       There's no silver bullet	to parse structured texts in secure ways.
       You'd better to consult the security experts to do so.

       Some CPAN module	might help you.	See String::Filter for example.

   How to manage localization in templates
       You can register	any functions including	"_()", so no specific
       techniques are required.

       For example:

	   use I18N::Handle;
	   # I18N::Handle installs the locale function "_" to the global namespace.
	   # (remember the symbol *_ is	global)
	   I18N::Handle->new( ... )->speak('zh_tw');

	   my $tx = Text::Xslate->new(
	       function	=> {
		   _ =>	\&_,
	       },
	   );

       Then in your templates:

	   <: _('Hello %1', $john ) :>

       See also: I18N::Handle, App::I18N.

   How to load templates before	"fork()"ing?
       It is a good idea to load templates in preforking-model applications.
       Here is an example to load all the templates which is in	a given	path:

	   use File::Find;

	   my $path = ...;
	   my $tx = Text::Xslate->new(
	       path	 => [$path],
	       cache_dir =>  $path,
	   );

	   # pre-load files
	   find	sub {
	       if(/\.tx$/) {
		   my $file = $File::Find::name;
		   $file =~ s/\Q$path\E	.//xsm;	# fix path names
		   $tx->load_file($file);
	       }
	   }, $path;

	   # fork and render ...

SEE ALSO
       Text::Xslate

       Text::Xslate::Manual

       Text::Xslate::Manual::FAQ

perl v5.32.1			  2017-01-19 Text::Xslate::Manual::Cookbook(3)

NAME | DESCRIPTION | RECIPES | SEE ALSO

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Text::Xslate::Manual::Cookbook&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help