Build.PL100644000765000024 341713224611140 15036 0ustar00skajistaff000000000000Text-Xslate-v3.5.6# ========================================================================= # THIS FILE IS AUTOMATICALLY GENERATED BY MINILLA. # DO NOT EDIT DIRECTLY. # ========================================================================= use 5.008_001; use strict; use warnings; use utf8; BEGIN { push @INC, '.' } use builder::MyBuilder; use File::Basename; use File::Spec; my %args = ( license => 'perl_5', dynamic_config => 0, configure_requires => { 'Module::Build' => '0.4005', }, requires => { 'Data::MessagePack' => '0.38', 'Encode' => '2.26', 'Mouse' => 'v2.5.0', 'Scalar::Util' => '1.14', 'Storable' => '2.15', 'parent' => '0.221', 'perl' => '5.008001', }, recommends => { }, suggests => { }, build_requires => { }, test_requires => { 'File::Copy::Recursive' => '0', 'File::Path' => '2.07', 'Test::More' => '0.98', 'Test::Requires' => '0', }, name => 'Text-Xslate', module_name => 'Text::Xslate', allow_pureperl => 1, script_files => [glob('script/*'), glob('bin/*')], c_source => [qw()], PL_files => {}, test_files => ((-d '.git' || $ENV{RELEASE_TESTING}) && -d 'xt') ? 't/ xt/' : 't/', recursive_test_files => 1, ); if (-d 'share') { $args{share_dir} = 'share'; } my $builder = builder::MyBuilder->subclass( class => 'MyBuilder', code => q{ sub ACTION_distmeta { die "Do not run distmeta. Install Minilla and `minil install` instead.\n"; } sub ACTION_installdeps { die "Do not run installdeps. Run `cpanm --installdeps .` instead.\n"; } } )->new(%args); $builder->create_build_script(); Changes100644000765000024 12175013224611140 15076 0ustar00skajistaff000000000000Text-Xslate-v3.5.6Revision history for Perl extension Text::Xslate v3.5.6 2018-01-08T06:39:38Z - Fix build on perl 5.8.8 (wyoung #192, #193) v3.5.5 2018-01-05T02:53:17Z - Ensure that test cleans up after itself (jkeenan #190) v3.5.4 2017-12-19T14:06:41Z - Guarantee that test cleans up after itself (jkeenan #189) v3.5.3 2017-12-03T05:18:51Z - Fix tests for windows again (#188) v3.5.2 2017-12-02T08:19:33Z - Fix tests for windows (zdm #186, #187) v3.5.1 2017-11-30T16:09:33Z - Fix packaging issue; explicitly declare version for Text::Xslate::Engine v3.5.0 2017-11-30T15:57:50Z - Migrate to using minil (#179) - Improve perl 5.8 support (#182) - Use version->declare() to declare $VERSION (#182) - Make `prove -br t` work with dot-not-in-INC perls (#184) - Run tests against both XS and pureperl (#185) - Fix typo (anirvan #181) 3.4.0 2017-01-20 15:00:00+0900 - Fix tied hash issue(#173) - Fix encoding issue(#160) - Fix segmentation fault issue by accessing uninitialized array element(#159) 3.3.9 2015-12-18 22:15:00+0900 - Fix test for Windows 3.3.8 change breaks Windows 3.3.8 2015-12-18 16:20:00+0900 - Fix test for DragonflyBSD - Update document 3.3.7 2015-08-28 13:45:00+0900 - Fix for older Perl 5.8.8 or lower(#145) - Enable 5.8 tests again 3.3.6 2015-08-25 13:50:00+0900 - Fix issue 'include' makes stack pointer incorrect(#130) 3.3.5 2015-08-05 18:50:00+0900 - Update Mouse version for Perl 5.22 or higher 3.3.4 2015-03-24 23:21:57+0900 - Fix typos in document - Introduce $Text::Xslate::DEFAULT_CACHE_DIR 3.3.3 2014-08-04 15:50:00+0900 - No code changes from 3.3.2, just re-packaging. 3.3.2 2014-08-04 12:40:00+0900 [IMPROVEMENT] - #127 Improve generating temporary file name 3.3.1 2014-08-03 11:45:40+0900 [ANNOUNCE] - Now Xslate has new co-maintainers (those who can maintain and release Xslate): lestrrat, syohex, and tokuhirom [BUG FIXES] - #126 Fix a typo in naming tempfiles (Hugmeir) [DOCMENT] - #125 Update document on Text::Xslate->bridge() and Builtin.pod (Mike Raynham) 3.3.0 2014-08-03 11:54:02+0900 (mis-packaging release) 3.2.5 2014-07-15 08:18:31+0900 [TEST FIXES] - No CGI.pm, which is no longer a standard module 3.2.4 2014-04-27 17:18:15+0900 [TEST FIXES] - Fix #122, #120 testing issue on windows (syohex) [FEATURES] - Add $array.first() and $array.last() methods (#116, #118 / shyohex) 3.2.3 2014-04-23 07:32:39+0900 - Made a mistake in the release engineering, re-packaged on the correct status. 3.2.2 2014-04-23 07:29:42+0900 [BUG FIXES] - Fix #105 SEGV on blead (reported by tokuhirom, fixed by syohex in #117) 3.2.1 2014-04-17 07:55:38+0900 [BUG FIXES] - Fix #111 (by syohex in #113) inputting "0" made a wrong result 3.2.0 2014-04-04 07:39:59+0900 [BUG FIXES] - Fix #107, #109 HashWithDefault should use "exists" (yappo, tokuhirom) 3.1.2 2014-02-20 21:09:47+0900 [TEST] - Add a test for github issue #105, which will fail on Perl 5.19.x 3.1.1 2014-01-24 07:50:52+0900 [DOCUMENTS] - Fix some typos (#102) - Add an explanation of `validate()` (#101) [BUG FIXES] - Fix a race condition on making cache dirs (#103) 3.1.0 2013-11-16 16:46:35+0900 [BUG FIXES] - Close #96; $/ affected the parse() method [FEATURES] - Add $xslate->validate($file) method to check template syntax 3.0.2 2013-11-15 21:56:53+0900 [BUG FIXES] - Fix a mojibake issue where utf8::upgrade() was always called when loading caches (hanabukuro++) 3.0.1 2013-11-04 12:27:51+0900 [TEST FIXES] - Fix a test that might fail on a slow machine like Raspberry Pi (Getty++) 3.0.0 2013-10-18 08:59:22+0900 - No code changes from 2.1.0, just re-packaging for package managers 2.1.0 2013-10-17 22:18:21+0900 [BUG FIXES] - Fix an issue that multi-bytes string literals used for a hash key was not dealt as a text string (@Niratama++) WARNING: this change could break your code if you use multi-byte text string as a hash key. 2.0010 2013-10-07 21:56:12+0900 [BUG FIXES] - Fix an issue that vpath with text-strings raised errors on newer perls due to specification changes in PerlIO::scalar (#90) - Documentation tweaks (#84, #86) 2.0009 2013-07-08 10:49:47-0700 [BUG FIXES] - Fix a tied hash issue on string concat, thanks to zxchris (#81) 2.0008 2013-07-06 00:09:43-0700 [BUG FIXES] - Fix a chache issue that UTF8 flags were not turned on as expected (#82) - Fix Metakolon doc (#83) 2.0007 2013-06-21 13:16:16-0700 [DOCUMENTS] - Add doc about chomping newlines (<:- ... -:>) [NEW FEATURES] - Add pre_process_handler to pre-process template content (bluescreen) 2.0006 2013-06-02 22:58:27 [BUG FIXES] - Fix an issue that the state of VM broke on exception reported by nihen 2.0005 2013-06-02 12:23:15 [BUG FIXES] - Fix a Multiplexed WRAPPER issue reportedy by @kawamuray (#79) Those who use WRAPPER, template cascading, or anonymous functions (lambdas) are strongly recommended to upgrade Xslate. 2.0004 2013-05-29 20:27:07 [TEST FIXES] - Template string must be bytes (#78) 2.0003 2013-05-10 12:59:11 [BUG FIXES] - Fix a crash on compiling templates (#77) 2.0002 2013-04-26 12:51:47 [BUG FIXES] - Support perl-blead (5.17.11) 2.0001 2013-04-24 16:24:22 [FEATURES] - Support PUREPERL_ONLY build See the Lancaster Consensu: https://github.com/sjn/toolchain-site/blob/219db464af9b2f19b04fec05547ac10180a469f3/lancaster-consensus.md#specifying-pure-perl-builds 2.0000 2013-02-20 09:21:08 - No code change from 1.9999_01 1.9999_01 2013-02-16 15:44:31 [CHANGES] - Migrate from Any::Moose to Mouse because Any::Moose is deprecated 1.6002 2012-12-19 22:54:55 [BUG FIXES] - Fix a bug where TTerse created no variable scopes (thanks to Yappo) 1.6001 2012-12-05 10:03:13 [BUG FIXES] - Resolve issue #71: SV leaks in VM frames 1.6000_01 2012-11-04 09:56:45 - The bytecode version is now 1.6. So all the cache will be discarded. [FEATURES] - Add opcodes: find_file, suffix, is_code_ref, merge_file in order to enhance template syntaxes (doy) 1.5025 2012-10-20 21:45:27 [BUG FIXES] - Fix a bug that constants with unary operators might result in wrong values (thanks to @doy) 1.5024 2012-10-15 18:02:29 [BUG FIXES] - Fix false assertion failure (This change affects only to -DDEBUGGING enabled perl) 1.5023 2012-10-15 08:22:14 [TEST] - Apply issue #66 again - 1.5022 was identical to 1.5021 (thanks to @doy) 1.5022 2012-10-15 00:15:18 [TEST] - Do not depend on extra modules in tests (issue #66, @nihen). 1.5021 2012-10-15 00:07:54 [BUG FIXES] - Fix an issue that recursive call of render() may cause SEGV thanks to doy for reporting this issue (isseu #65). 1.5020 2012-10-14 23:06:49 [BUG FIXES] - Fix deploying issues reported at 1.5017, again. thanks to @woremacx for reporting it. - Fix a bug that calling macro which encloses outer variables, may clobber other variables, thanks to @ktat for reporting it. 1.5019 2012-10-03 12:28:20 [BUG FIXES] - Revert 1.5016's bugfix which introduced a more serious problem. The complete bufix will be applied to 1.5020. 1.5018 2012-09-30 13:41:13 [FEATURES] - "html_builder_module" option to import HTML builders; functions imported with this option are wrapped by html_builder() 1.5017 2012-08-04 19:31:59 [BUG FIXES] - Fix a problem on Win32 1.5016 2012-08-04 19:19:15 [BUG FIXES] - Fix a bug that reloading templates could fail on deploying - Fix a problem on 5.17 1.5015 2012-07-13 19:31:53 [IMPROVEMENT] - Enhance extensibility for custom parsers (shmorimo) 1.5014 2012-06-26 19:41:20 [IMPROVEMENT] - Add scalar::split() to Bridge::Star (tokuhirom) 1.5013 2012-06-12 23:46:44 [IMPROVEMENT] - Add "macro" option to Text::Xslate->new() (gunyoki) 1.5012 2012-05-21 15:52:59 [IMPROVEMENT] - imporve error messages when the parser reaches EOF 1.5011 2012-05-21 15:45:00 [BUG FIXES] - add warning about https://github.com/xslate/p5-Text-Xslate/issues/55 For backword compatibility, we don't change its behavior, but it is likely to a problem so we warnn about it. 1.5010 2012-05-04 01:04:47 [TEST FIXES] - Make `HANRESS_OPTIONS=j9 make test` work (@punytan) 1.5009 2012-03-30 09:19:18 [IMPROVEMENT] - Documentation improvement 1.5008 2012-03-28 09:39:45 [BUG FIXES] - Fix a typo in an error messages (issues/53, thanks to wchristian) - Fix an undefined behavior that giving utf8-encoded *bytes* as params made mojibake in use of caches 1.5007 2011-11-17 19:43:10 [BUG FIXES] * SWITCH without an END made infinate loops (reorted by ryochin) * "01" was parsed as 1, not "01" (reported by ryochin) 1.5006 2011-11-12 12:54:39 [META] - Move the repository from github.com/gfx/* to github.com/xslate/ [FEATURES] - Add Text::Xslate::Bridge::Star, utilities for templates 1.5005 2011-10-27 13:36:03 [IMPROVEMENT] - Update documentations 1.5004 2011-10-13 10:24:38 [BUG FIXES] - Small doc changes regarding escaping of HTML metacharacters (oalders) - Fix a missing current_vars() method in PP - Fix an error handling in Bridge.pm 1.5003 2011-10-05 11:23:56 [BUG FIXES] - Fix typos in docs - Resolve issue/45: nested macro modifiers caused errors (thanks to tokuhirom) 1.5002 2011-08-30 21:48:49 [FEATURES] * Add Text::Xslate->current_vars to get the parameters of render() (requested by cho45 and others) 1.5001 2011-08-30 19:37:24 [BUG FIXES] * Calling macros could break lexical vars; Thanks to tomyhero and tokuhirom. 1.5000 2011-08-29 17:37:10 [BUG FIXES] * Purge caches when input_layer has chagned. This fix forces to purge all the caches, so the version is now 1.5000, not 1.4003. 1.4002 2011-08-29 16:24:13 [FEATURES] * Support FOR-ELSE syntax in TTerse * Support file input hook by overriding slurp_template() (See the cookbook) 1.4001 2011-07-29 09:13:00 [CHANGES] * Forbid blessed HASH references as template parameters, which could break encapsulation 1.4000 2011-07-24 19:26:31 * No code changes from 1.3999_04 * Note that all the cache created before 1.4 will be purged 1.3999_04 2011-07-24 13:07:28 [BUG FIXES] * render() for %vpath did compile template sources at the first time of the running process, but it was not required 1.3999_03 2011-07-23 17:51:28 [BUG FIXES] * [% FOR x IN ... %] no longer throws errors Using reserved words as variables is allowed if it's not ambiguous [OTHER] * Files and directories have been cleaned up 1.3999_02 2011-07-23 13:31:09 [DOCUMENT] * Improve FAQ and Cookbook * Mention to Text::Xslate::Syntax::HTMLTemplate and HTML::Template::Parser (thnaks to @shmorimo) 1.3999_01 2011-07-13 23:14:05 The bytecode version is now 1.5. [NEW FEATURES] * New keyword: __ROOT__ for the root parameter (the parameter of render()) * New methods: $array.merge(...) and $hash.merge(...) which return a merged array / hash respectively 1.3001 2011-07-11 00:41:48 [BUG FIXES] * Constants (and my pseudo-vars) didn't work in foreach-loops (thanks to @toritori0318) 1.3000 2011-06-11 18:20:02 [CHANGES] * html_builder(\&f) passes @_ as-is to &f [BUG FIXES] * Comments broke line numers (thanks to ktat) * <: "10" x 100 :> was broken (thanks to ktat) 1.2004 2011-06-06 08:54:50 [BUG FIXES] * Overriding builtins (introduced in 1.1005) didn't work 1.2003 2011-06-03 00:41:03 [BUG FIXES] * Fix a miss-format in docs * Suppress a compiler warnings 1.2002 2011-05-18 23:53:31 [BUG FIXES] * Fix the overriding of the default escaping routine (rep. by @shmorimo) 1.2001 2011-05-16 23:39:16 * No code chages * Just updated Module::Install::XSUtil for PERL_ONLY configuration support 1.2000 2011-05-14 14:32:46 See the changes for 1.1005_01 1.1005_01 2011-05-12 00:13:48 [CHANGES] * The bytecode version is 1.4 [FEATURES] * Allow the default escaping function html_escape() overridden * Allow all the builtin functions overridden * Add html_escape() and uri_escape() builtin functions, which are the same as html() and uri() respectively 1.1005 2011-04-30 11:56:35 [BUG FIXES] * Fix a bug which caused the performance to suffer severly under large template files 1.1004 2011-04-11 22:55:59 [BUG FIXES] * Fix a test which failed on Windows 1.1003 2011-04-08 09:51:47 [BUG FIXES] * render_string(), to which you must pass a text string, died when wide characters were passed (reported by @kazeburo) 1.1002 2011-04-05 00:41:09 [CHANGES] * Remove the dependency on MX::Getopt 1.1001 2011-04-02 00:00:16 [BUG FIXES] * A quote in comments caused parse errors (reported by @lestrrat) 1.1000 2011-03-17 22:18:07 This is a major update with the bytecode version 1.3 See the 1.0099_* for details [NEW FEATURES] * Loop control statements (next and last) * for-else syntax in Kolon 1.0099_03 2011-03-13 13:22:21 [BUG FIXES] * Fix tests [CHANGES] * Remove PP::Booster stuff 1.0099_02 2011-03-10 16:21:18 [NEW FEATURES] * Add loop control statements (last and next) in both Kolon and TTerse 1.0099_01 2011-03-10 12:42:28 [CHANGES] * The bytecode version is now 1.3, which means all the compiled codes will be purged on render() * Remove PP::Booster because of its high maintainance cost * <: for nil -> $i { } :> no longer produces warnings [NEW FEATURES] * Add for-else syntax in Kolon 1.0012 2011-03-04 12:18:19 [BUG FIXES] * Fix a bug that <: include foo() :> and <: my $var = ...; include $var :> were wrongly parsed in Kolon (thanks to @shmorimo) 1.0011 2011-03-01 18:08:16 [CHANGES] * Internet Explorer (<= 8) doesn't support ' in title, so we must escape ' (apostrophe) into ', not ' (thanks to @tokuhirom) 1.0010 2011-02-28 18:09:28 [BUG FIXES] * Fix a bug in import_from(), which failed to import optimized constant introduced in 5.10 (thanks to @kane46taka) 1.0009 2011-02-28 13:00:50 [BUG FIXES] * Lock cache file operations with flock(2) * Fix doc issues [CHANGES] * Switch PP backend from PP::Booster to PP::Opcode. PP::Booster will be removed from the core because its maintainance cost is too high. 1.0008 2011-02-14 12:46:45 [BUG FIXES] * Fix docs 1.0007 2011-02-13 23:10:03 [BUG FIXES] * Suppress irrational uuv warnings in relational operators (github issue/28, reported by @tokuhirom) 1.0006 2011-02-11 16:23:32 [BUG FIXES] * Complex templates which include too many string literals (e.g. large JSON) could cause fatal errors on 5.10+, or SEGV on 5.8 (github issue/27; thanks to @cho45 for reporting it) [NEW FEATURES] * You can inject customized messages into the output with the 'warn_handler' option and Text::Xslate->print() method. See the Cookbook for details. 1.0005 2011-02-09 14:33:57 ANNOUNCE: If you are interested in xslate, join #xslate @ irc.perl.org! [BUG FIXES] * The INCLUDE recursion bug (see the NOTE at 1.0004) has been fixed. (thanks to @kane46taka for reporting it) 1.0004 2011-02-08 12:36:21 NOTE: All the versions including this version has a bug that INCLUDE recursion doesn't work. It will be fixed in the next release. [BUG FIXES] * Fix a critical bug that warnings in templates could break the Perl stack (thanks to @tokuhirom for reporting it) * Fix a bug that method calls didn't work in PP version (thanks to @tokuhirom for reporting it) 1.0003 2011-02-05 11:54:45 [NEW FEATURES] * For-loops allow overloaded objects. i.e. you can use Scalar::Defer to defer to create large arrays. 1.0002 2011-02-02 12:02:40 [BUG FIXES] * A tiny doc fix 1.0001 2011-02-02 11:50:43 [BUG FIXES] * Template caches was not purged correctly when functions were added (thanks to @tokuhirom for reporting it) * The 'super' keyword didn't work in template components (thanks to @shiba_yu36 for reporting it) 1.0000 2011-01-07 16:08:44 This is the version 1.0, which means "very stable". Although some features are planned to impement in the near future, the basic features are unlikely to be changed. [BUG FIXES] * Resolve github issue/23: html_builder() doesn't work with functions which accepts multiple arguments [DOCUMENTS] * Add an entry about I18N to the cookbook (c9s) 0.3002 2010-12-16 16:17:48 [BUG FIXES] * hash_with_default() didn't work with `include with vars` syntax (thanks to hirose31 for reporting this issue) 0.3001 2010-12-09 17:18:14 [BUG FIXES] * Fix `module => \@bridges` that importing of bridge modules incorrectly cleared the function mapping (reported by lestrrat) 0.3000 2010-11-23 15:19:04 [CHANGES] * `option => undef` passes the option as is, which allows Text::Xslate->new( line_start => undef ) (issue/21, reported by @tomita). Note that this is an IMCOMPATIBLE CHANGE. [DOCUMENTS] * Update Cookbook and FAQ 0.2015 2010-11-17 22:27:34 [NEW FEATURES] * The 'include' command allows barewords as 'cascade' does 0.2014 2010-11-06 09:24:00 [BUF FIXES] * Error messages did not respect input_layer 0.2013 2010-10-30 15:17:40 [BUG FIXES] * Magic handlings for 'print' opcode [NEW FEATURES] * hash_with_default(\%vars, $default) in Text::Xslate::Util see Text::Xslate::Manual::Debugging [OTHERS] * Switch from M::I::ExtendsMakeTest to M::I::TestTarget 0.2012 Mon Oct 18 23:25:38 2010 * No code changes * Update Module::Install::ExtendsMakeTest (to HEAD of the repo) to avoid problems with non-author environments 0.2011 Sun Oct 17 18:38:01 2010 [CHANGES] * The bytecode version is now 1.2 * Remove builtin ref(); Add is_array_ref() and is_hash_ref() instead. I'm sorry to change APIs, but use of ref() would confuse people. 0.2010 Sat Oct 16 10:00:00 2010 This is the commemorative release for YAPC::Asia Tokyo 2010! [CHANGES] * The bytecode version is now 1.1 [NEW FEATURES] * Add a builtin function ref(), which is the same as Perl's ref() [BUG FIXES] * Resolve RT #62028 (Kaare Rasmussen): Test failed on old URI::Find 0.2009 Wed Oct 6 18:50:45 2010 [BUG FIXES] * Large template files could cause SEGV (reported by id:peppon) [ENHANCEMENT] * The first call of render() has been significantly faster than 0.2008 0.2008_02 Tue Sep 28 16:42:21 2010 [BUG FIXES] * Cache mechanism was affected by the special variables $/ and $\ * Developpers' releases might produced warnings about versions [CHANGES] * Upgrading Text::Xslate no longer forces to purge cached templates. Instead, the internal bytecode version (1.0, currentl) is used. 0.2008_01 Wed Sep 22 17:18:53 2010 [CHANGES] * Use Data::MessagePack as the bytecode serializer, which make the first call of render() much faster 0.2008 Sun Sep 19 18:17:51 2010 [CHANGES] * The obsolete feature that render(undef) is the same as render('') has been removed. render(undef) always throws the error. [FEATURES] * Range operator (e.g. <: for [1 .. 10] -> $i { } :>) 0.2007 Fri Sep 17 12:12:50 2010 [BUG FIXES] * Resolve RT #61359 (Sam Graham): Taint flag broke templates 0.2006 Tue Sep 14 11:46:33 2010 [BUF FIXES] * Single-quote literals parsed wrong, when contain paired double q (Mons Anderson) * Infinite recursion during _fold_constants in case of warnings (Mons Anderson) 0.2005 Mon Sep 13 14:44:22 2010 [BUG FIXES] * Workaround a new deprecated warnings for qw(...) (See perl.git/master/ea25a9b2cf73948b1e8c5675de027e0ad13277bd) 0.2004 Fri Sep 10 13:50:08 2010 [BUG FIXES] * Workaround test failure about 'too long arguments for exec()' 0.2003 Thu Sep 9 19:25:08 2010 [BUG FIXES] * Fix a misuse of test functions. This problem is revealed by Test::Builder2. * Workaround MAGIC problems with html_escape($1) 0.2002 Tue Sep 7 15:23:49 2010 [FEATURES] * Performance improvement (thanks to @kazuho) This version is 10% faster than the previous version! * Update meta spec. 0.2001 Tue Aug 31 13:48:29 2010 [BUG FIXES] * Resolve github issue/16: header/footer was applied recursively, which caused deep recursions (reported by egor) * Dies in macros could make inconsistent data * Optimization of if statements could make wrong results [FEATURES] * Statement modifiers (a.k.a. post-if statements) for Kolon and TTerse 0.2000 Fri Aug 27 11:44:26 2010 Version 0.2000 is stable but has some incompatible changes. Please check the [CHANGES] section of this file before upgrading. [CHANGES] * Remove deprecated .defined() method. Use defined(expr) instead. 0.1999_06 Thu Aug 26 14:50:46 2010 [BUG FIXES] * Fix a test. IPC::Cmd seems broken. 0.1999_05 Wed Aug 25 18:35:15 2010 [BUG FIXES] * Fix another build problem on Win32 0.1999_04 Wed Aug 25 11:34:09 2010 [BUG FIXES] * Fix a build problem on Win32 0.1999_03 Tue Aug 24 17:20:16 2010 [BUG FIXES] * t/300_examples/100_eg_pl.t could hung up on Win32 (@turugina) 0.1999_02 Tue Aug 24 12:08:03 2010 [CHANGES] * For Text::Xslate::Runner, remove --input_layer option, and add --input_encoding and --output_encoding [BUG FIXES] * uri_escape() in PP didn't work for UTF-8-flagged string 0.1999_01 Sun Aug 22 17:45:17 2010 [CHANGES] * The "escape" option is changed to "type", which accepts "html", "xml", and "text" * The default pure Perl backend is now PP::Booster, which is about 2 times faster than PP::Opcode (according to benchmark/x-poor-env.pl) [BUG FIXES] * Modulus zero ($foo % 0) could throw uncatchable errors [FEATURES] * Repeat operator (infix:) is added (so "x" is now an invalid variable name in TTerse) * Now html_builder() can be applied to dynamic filters (e.g. to the HTML::FillInForm::fillinform() function) 0.1058 Tue Aug 17 17:59:53 2010 [CHANGES] - Deprecate defined() method, which is provided only for compatibility with TT, but the behaviour might not be exceptable. That is, $object.defined() returns false unless the $object has its own defined() method. Use defined(expr) function instead, which return false if and only if the expr is undef (nil). [FEATURES] - Add html_builder() to make it easy to import HTML builders. See Text::Xslate::Cookbook for example. 0.1057 Sun Aug 15 18:28:32 2010 [BUG FIXES] - Subroutines that localize $SIG{__WARN__} or $SIG{__DIE__} could make Perl interpreter panic (reported by tokuhirom) - Invalid expressions could produce insane errors including infinite loop (issue/13, reported by y) - A Win32 problem in tests might be fixed [FEATURES] - Experimental support for PP::Compiler which make PP::Booster faster (makamaka) 0.1056 Tue Aug 10 14:28:55 2010 [BUG FIXES] - The rendering methods ignored signals - 'path' option could not deal with overloaded strings (e.g. Path::Class::Dir) correctly (chiba) - Die in macros/blocks caused segfaults (reported by chiba) [OTHERS] - Benchmarks to compare other template engines have been refactored and improved (lestrrat, tokuhirom). See http://xslate.org/benchmark.html for details. 0.1055 Sat Aug 7 17:33:56 2010 [BUG FIXES] - Make xslate(1) print the result to stdout when both --suffix and --dest are omitted - Add HTML escaping in benchmarks correctly, updating the result of benchmarks in documents 0.1054 Mon Aug 2 17:26:21 2010 [BUG FIXES] - The print routine for raw stirings was significantly slower than that with automatic HTML escaping 0.1053 Sun Aug 1 18:14:52 2010 [BUG FIXES] - Fix incorrect titles of manuals 0.1052 Sun Aug 1 15:42:16 2010 http://xslate.org is out! Thanks to Shibuya.pm, esp. @tokuhirom and @lestrrat. [BUG FIXES] - Forbid '..' in file names - "<: $foo :>:<: $bar :>" caused parse errors [CHANGES] - The algorithm of building cache paths has been changed, which requires to re-compile templates. [NEW FEATURES] - Documents: Text::Xslate::Manual for table of contents, Text::Xslate::Builtin for builtin methods and filters - Exportable functions: uri_escape() - Builtin filters: uri 0.1051 Thu Jul 29 17:41:43 2010 [BUG FIXES] - Fix cache issues enbugged in 0.1049 0.1050 Tue Jul 27 19:36:39 2010 [BUG FIXES] - Fix another keyword problem 0.1049 Tue Jul 27 19:03:04 2010 [BUG FIXES] - Compliant with Moose 1.09 (warns about coerce => 1 without coercion) - Lower cased keywords were incorrectly parsed as an upper cased keyword in TTerse (thanks to chiba) - Complex expression problems in PP::Booster, again (@maka2_donzoko) [CHANGES] - Now chache file names include tha path they are 0.1048 Mon Jul 26 16:17:43 2010 [BUG FIXES] - Virtual paths were not cached when cache => 1 - The explanation of 'tag_end' were incorrect - AUTOLOAD were ignored in methodcall - Complex expression problems in PP::Booster (@maka2_donzoko) [CHANGES] - Internal refactoring to make parsers more robust - Rename Text::Xslate::Cookbook to Text::Xslate::Manual::Cookbook - Now string concatination (infix:<~>) respects raw strings [NEW FEATURES] - Add GET statement to TTerse - Add prefix:, infix: and infix: to TTerse (@clouder) [NEW DOCUMENTS] - Text::Xslate::Manual::FAQ to answer a few questions 0.1047 Mon Jul 19 17:04:51 2010 [BUG FIXES] - $foo.nil did not work. - "+10" was wongly converted into "10" [CHANGES] - Rename Text::Xslate->engine to Text::Xslate->current_engine - Remove deprecated Text::Xslate::EscapedString->new [NEW FEATURES] - New methods: Text::Xslate->current_file and current_line 0.1046 Sat Jul 17 18:48:14 2010 [NEW FEATURES] - Add Perl6-like bitwise operators: infix:<+|> for bitwise or infix:<+&> for bitwise and infix:<+^> for bitwise xor prefix:<+^> for bitwise negate 0.1045 Tue Jul 13 20:05:10 2010 [BUG FIXES] - prechomp/postchomp ([%- ... -%]) was not completly comptible with TT2 - Line numbers were wrong if templates used prechomp/postchomp - TTerse could not parse dynamic filters with FILTER blocks correctly [NEW FEATURES] - Text::Xslate::Runner as the guts of xslate(1) - The __FILE__ and __LINE__ keywords for testing and debugging - Now parsers can has its own identity pattern 0.1044 Mon Jul 12 17:50:35 2010 [BUG FIXES] - Underscores in bare words (i.e. left-hand side of the operator '=>') were accidentally removed. - There were several issues on path => \%vpath [NEW FESTURES] - $array.reduce(-> $x, $y { ... }) method 0.1043 Sat Jul 10 14:26:57 2010 [BUG FIXES] - What Makefile.PL wrote for additional tests did not work on Win32 (thanks to Taro, Nishino) [DOC FIXES] - Fix typos for Changes: s/ware/were/g (thanks to @ryochin) [NEW FEATURES] - Extend 'path' option for in-memory file mapping, inspired by Text::MicorTemplate::DataSection (@typester++), requested by @kazeburo 0.1042 Tue Jul 6 13:28:43 2010 [BUG FIXES] - Makefile.PL did not work on some environments - block -> {} and FILTER BLOCK were not consistent with normal macros [CHANGES] - Internal refactoring 0.1041 Sat Jul 3 14:52:00 2010 [BUG FIXES] - Tests for filenames did not work on Win32 [CHANGES] - Refactor internal function registration APIs [NEW FEATURES] - For App::xslate + New option --version to show versions + New option --engine (or -E) to change the engine class 0.1040 Thu Jul 1 15:33:14 2010 [BUG FIXES] - UTF8 flags was not respected in some cases [CHANGES] - Error messages contain source lines 0.1039 Mon Jun 28 20:31:54 2010 [DOCUMENTS] - Applying the raw filter in templates is considered harmful. Remove the use of it from the cookbook. Thanks to @typester. 0.1038 Mon Jun 28 17:44:52 2010 [BUG FIXES] - Extra white spaces caused syntax errors in given blocks - Original error handlers (i.e. $SIG{__WARN__} and $SIG{__DIE__}) were ignored. This problem affected PSGI applications with the StackTrace middlewere. [NEW FEATURES] - New document Text::Xslate::Cookbook - Block filter syntax in Kolon. See Text::Xslate::Cookbook. - SWITCH-CASE directives in TTerse 0.1037 Sun Jun 27 17:37:57 2010 [BUG FIXES] - Template cascading broke the file name of error messages [OTHERS] - Internal refactoring 0.1036 Wed Jun 23 20:05:44 2010 [CHANGES] - Change line_start, tag_start and tag_end to take string tokens, not regexps [NEW FEATURES] - Improve performance (about 10%+) by direct threaded code, although it's enabled only on gcc - Text::Xslate->engine() method to access the executing engine from functions and methods 0.1035 Sun Jun 20 15:03:12 2010 [BUG FIXES] - Macros with args could not refer to outer variables [NEW FEATURES] - "while defined expr -> $item" as a syntactic sugar to "while defined(my $item = expr)" - New iterator element: $~iter.cycle(...) 0.1034 Wed Jun 16 17:27:44 2010 [CHANGES] - Rename $~iter.max to $~iter.max_index in Kolon [BUG FIXES] - The cache reloader was broken from 0.1032 (thanks to @fujiwara) [NEW FEATURES] - For TTerse + Support header/footer options curresponding to TT's PRE_PROCESS/POST_PROCESS + Support DEFAULT and FILTER syntax 0.1033 Sun Jun 13 17:14:36 2010 [BUG FIXES] - Workaround a Win32 filesystem issue [NEW FEATURES] - Anonymous macro: <: -> $x, $y { $x + $y }(10, 20) # => 30 :> - The sort method accepts an anonymous macro - New methods: map - New options for Text::Xslate: line_start, tag_start and tag_end 0.1032 Thu Jun 10 18:00:25 2010 [CHANGES] - Rename the term "escaped string" to "raw string": escaped_string() -> mark_raw() Text::Xslate::EscapedString -> Text::Xslate::Type::Raw (old names remain for compatibility) [BUG FIXES] - App::Xslate created result files even if render() dies [NEW FEATURES] - New builtin filters: + mark_raw as an alias to 'raw' + unmark_raw as the opposite of 'mark_raw' 0.1031 Wed Jun 9 21:55:57 2010 [BUG FIXES] - Issues on older perls [NEW FEATURES] - New defined() named operator/builtin method: expr.defined() and defined(expr) is the same. 0.1030 Wed Jun 9 15:33:43 2010 [CHANGES] - Unknown options to new() will produce warnings [BUG FIXES] - Resolve issue #10: utf8 flags break macros (reported by nihen) - The auto semicolon insertion was broken - Loops could waste memory [NEW FEATURES] - The interface of bridge mecahnism has been improved; now you can do "module => ['Text::Xslate::Bridge::TT2']" 0.1029 Tue Jun 8 16:30:46 2010 Macros and autoboxing have been refactored. [CHANGES] - A few undecoumented features have been removed [BUG FIXES] - Tied array/hash could cause segv by builtin methods [NEW FEATURES] - User-defined autoboxing methods; see Text::Xslate::Bridge::TT2 on CPAN - Macros become first objects; i.e. <: macro foo -> { ... }; my $foo = [foo]; $foo[0]() :> works. 0.1028 Sun Jun 6 17:21:18 2010 This release introduces variable definition and mutation, which might be unstable. Please report any bugs you'd run into. [CHANGES] - Make Kolon's while statement the same as Perl's [BUG FIXES] - Resolve various issues [NEW FEATURES] - Improve App::Xslate - Implement constant folding - For Kolon + constant statement (e.g. constant FOO = 42) - For TTerse + CALL statement not to print expressions + WHILE statement + SET statement and the "=" operator to assign values 0.1027 Fri Jun 4 15:09:47 2010 [CHANGES] - s/peep/peek/, which is really what I want [BUG FIXES] - Ternary operators could cause problems in PP::Booster, again (makamaka) - "or" and "and" operators could cause problems in given-when 0.1026 Thu Jun 3 22:04:02 2010 [CHANGES] - Metakolon's line code has been changed to %% like TT3 and TTerse - The default cache_dir is chaned to "$HOME/.xslate_cache" - Error messages are improved [BUG FIXES] - Empty hash/array literals were not allowed - There were several edge-case issues in string literals - The precedence of the ternary operator was wrong - Resolve issue #5: [% "foo' %] was silently accepted - Ternary operators could cause problems in PP::Booster (makamaka) [NEW FEATURES] - Macros can be called with the filter operator (e.g. expr | my_macro) - For Kolon + Loop iterators as "$~LOOP_VAR" (e.g. $~item) + Loop iterator elements: index, count, size, max, body, is_first, is_last, peep_next, and peep_prev - For TTerse + Loop iterators as "loop" + Loop iterator elements: index, count, size, max, body is_first/first, is_last/last, peep_next/next, and peep_prev/prev. + MACRO foo(...) BLOCK ... END syntax + WRAPPER "foo.tt" ... END syntax 0.1025 Mon May 31 20:29:50 2010 - Support 5.8.1 0.1024 Sun May 30 19:00:56 2010 [BUG FIXES] - 'module' option wiped away builtin functions - Array/hash literals were invalid in TTerse - Calling undefined functions produced unreadable messages in TTerse - The parser could not parse <: f({ not => 42 }) :> [NEW FEATURES] - For TTerse + Support TT3-like single line code with '%%' + Support INCLUDE-WITH syntax - New PP engine: Text::Xslate::PP::Booster (makamaka) Now PP is much faster than Template-Toolkit 2.22 0.1023 Fri May 28 15:00:38 2010 [BUG FIXES] - Fix variable localization for include command - Correct warning location from render_string() - More robust cache checking [NEW FEATURES] - For General + Array literal syntax: [ "foo", "bar", "baz" ] + Hash literal syntax: { foo => 1, baz => 2 } - For TTerse + TT2 like comment tag [%# ... %] + "FOR" and "for" for "FOREACH" + The _ operator for concatination - For App::xslate + --cache accepts an integer, not a bool 0.1022 Wed May 26 17:29:09 2010 [BUG FIXES] - Fix variable localization (used for cascade-with-vars syntax) [CHANGES] - Use {} in cascade-with-vars syntax, instead of () [NEW FEATURES] - Support include-with-vars syntax: : include "foo.tx" { var => 42 } - Support --escape and --verbose options in xslate(1) - Support --eval (like perl's -e) option in xslate(1) 0.1021 Tue May 25 18:18:06 2010 [BUG FIXES] - Fix a bug about for-loops on PP (makamaka) [CHANGES] - "'" will be escaped into "'", not "'" [NEW FEATURES] - Resolve issue#2: Improve cascade statement: : cascade base ( foo => 42, bar => "baz" ) - Add html() and dump() builtins: <: $var | html # explicit html-espace :> <: $var | dump # print $var using Data::Dumper :> 0.1020 Fri May 21 17:21:03 2010 [NEW FEATURES] - Resolve issue#1: make semicolon/{} block unnecessary in block foo -> { ; } - New "raw" builtin filter: <: $value | raw :> 0.1019 Wed May 19 15:48:53 2010 [BUG FIXES] - Workaround Win32 CRLF issues on tests 0.1018 Wed May 19 15:34:47 2010 [CHANGES] - Use Any::Moose (lestrrat) [BUG FIXES] - There was several issues on Mouse::PurePerl 0.1017 Tue May 18 14:35:30 2010 [NEW FEATURES] - Support hex/oct/binary literals (e.g. 0xCAFE) - Support lower-cased keywords in TTerse [CHANGES] - Rename 'import' option to 'module' because of the confliction with Perl's import() method in App::Xslate 0.1016 Sun May 16 13:59:08 2010 [NEW FEATURES] - Support --pp (and --xs) option in Makefile.PL - Support autoboxing; currently supported methods are: For array: size(), join(), reverse() For hash: keys(), values(), kv() (and all the array methods) 0.1015 Fri May 14 14:52:52 2010 [BUG FIXES] - Fix literal_to_value(), which could break values (reported by xaicron) - Missing prerequisites: MouseX::Getopt (reported by xaicron) 0.1014 Fri May 14 13:05:17 2010 [NEW FEATURES] - Now Xslate works without XS (makamaka) - New xlsate(1) utility, which is like ttree(1) (lestrrat) 0.1013 Thu May 13 15:00:41 2010 [CHANGES] - The warning policy has been changed. See the document for details. - Allow calling render without any variables (lestrrat) 0.1012 Mon May 10 13:56:28 2010 [BUG FIXES] - Cascaded templates were not reloaded correctly (thanks to tokuhirom) 0.1011 Fri May 7 12:29:45 2010 [NEW FEATURES] - New escape => 'none' mode for non-HTML templates 0.1010 Thu May 6 13:25:47 2010 [BUG FIXES] - There were various parsing issues [NEW FEATURES] - Switch statement like Perl6 - Arrows in pointy blocks can be omitted if not necessary 0.1009 Wed May 5 13:59:13 2010 [NEW FEATURES] - Extend cascade statement: cascade myapp::base with component1, component2 cascade with component1, component2 - Function import mechanism, which needs no plugin modules: Text::Xslate->new(import => [qw(Data::Dumper)]) - Support "elsif" in Kolon for compatibility with Perl - Support "UNLESS" in TTerse for compatibility with TT - Support function and method call in TTerse [CHANGES] - Internal APIs and tests have been refactored 0.1008 Mon May 3 18:36:52 2010 [CHANGES] - Deprecate "string" option for new() and render(\%vars). Use render_string() instead. [NEW FEATURES] - render_string($str, \%vars), which is provided mainly for testing 0.1007 Sun May 2 22:26:09 2010 [BUG FIXES] - Nested function call could cause problems. - Blessed references were not printable. - The "file" option to new() was confusing. Now it has been removed. [NEW FEATURES] - New operators: "and", "or", "not", "min", "max" - New method call syntax: $obj.method(...) - New while statement: while $obj.fetch() -> $row { print $row; } - New "cache_dir" option to new() - INCLUDE command in TTerse 0.1006 Sat May 1 13:36:06 2010 - Workaround MSVC problems 0.1005 Sat May 1 13:21:24 2010 - Introduce TTerse syntax, a Template-Toolkit-like template parser - Introduce Metakolon syntax to produce Xslate templates by itself - Change print command (<:= ... :>) to be implicitly enabled i.e. you need not to put =; <: $foo :> is enough - Add TT-like chomp command ("<:-" for prechomp, "-:>" for postchomp) 0.1004 Fri Apr 30 14:32:47 2010 - Fix an over-optimizing issue (revealed by Template::Benchmark) 0.1003 Fri Apr 30 12:30:21 2010 - Disable leaktrace testing temporarily 0.1002 Fri Apr 30 11:17:15 2010 - Fix template reloading issues 0.1001 Thu Apr 29 17:58:33 2010 - Fix macrocall issues, again - Allow a literal string for cascade() - Allow underbars in literal numbers - Macros now returns a value, not output it directly 0.1000 Wed Apr 28 21:50:29 2010 - First non-dev release! - Change the default path to ["."] - Fix a macrocall issue 0.001_09 Wed Apr 28 18:01:42 2010 - New keywords: cascade, macro, block, before, around and after - Add template cascading - Add macro statement - Add "cache => 2" mode (or release mode) 0.001_08 Fri Apr 23 13:33:14 2010 - Add escaped_string() to tell the engine that strings are escaped 0.001_07 Thu Apr 22 12:59:03 2010 - Fix a bug that for-loops for an empty array did not work 0.001_06 Wed Apr 21 13:39:50 2010 - Workaround multi-thread related problems 0.001_05 Tue Apr 20 18:27:33 2010 - Add "include" command 0.001_04 Tue Apr 20 17:08:49 2010 - The "file => [...]" option is no longer required - Fix file auto reloading 0.001_03 Tue Apr 20 15:28:13 2010 [IMCOMPATIBLE CHANGE] - Template tags are now <: ... :>, not . This is because looks too like Text::MicroTemplate - render() requires a file name: my $tx = Text::Xslate->new( file => [qw(foo.tx bar.tx)] ); print $tx->render('foo.tx', \%vars); print $tx->render('bar.tx', \%vars); 0.001_02 Mon Apr 19 15:07:43 2010 - Fix a bug that program branches could be broken by the optimizer 0.001_01 Mon Apr 5 18:52:06 2010 - The first preview release for OSDC.TW 2010 (5/24-25) 0.001 Mon Apr 5 18:52:06 2010 - original version; created by Module::Setup HACKING100644000765000024 226713224611140 14533 0ustar00skajistaff000000000000Text-Xslate-v3.5.6NOTES FOR HACKERS Easy evaluation: $ xslate -e 'Hello, <: $ARGV[0] :> world!' Xslate Debugging options ($ENV{XSLATE}; or --debug for xslate(1)): dump=proto Output preprocessed proto templates dump=token Output token sequence dump=denote Output code denotation dump=gen Output code generation dump=ast Output abstract syntax tree dump=asm Output xslate assembly dump=asm:ix Output xslate assembly with indexes dump=pp Output Perl code PP::Booster generates optimize=0 Suppress optimization pp=verbose Make error messages verbose (by Carp->import('verbose')) Parser's terminology: arity Symbol class; used while compiling bp Binding power; or operator precedence nud Null denotation; processing values and prefix operators led Left denotation; processing infix and postfix operators std Statement denotation; processing statements Callbacks: functios, methods, and macros tx_call_sv() is a thin wrapper to Perl_call_sv() tx_funcall() tries to call Perl fuctions tx_proccall() tries to call macros, or fallback to tx_funcall() tx_methodcall() tries to call Perl methods, or fallback to tx_proccall() LICENSE100644000765000024 4377013224611140 14575 0ustar00skajistaff000000000000Text-Xslate-v3.5.6This software is copyright (c) 2010-2013 by Fuji, Goro (gfx) . This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2010-2013 by Fuji, Goro (gfx) . This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2010-2013 by Fuji, Goro (gfx) . This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End META.json100644000765000024 1410013224611140 15172 0ustar00skajistaff000000000000Text-Xslate-v3.5.6{ "abstract" : "Scalable template engine for Perl5", "author" : [ "Fuji, Goro (gfx) ." ], "dynamic_config" : 0, "generated_by" : "Minilla/v3.0.14", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Text-Xslate", "no_index" : { "directory" : [ "t", "xt", "inc", "share", "eg", "examples", "author", "builder" ] }, "prereqs" : { "configure" : { "requires" : { "Devel::PPPort" : "3.33", "Module::Build" : "0.4005", "Module::Build::XSUtil" : "0", "version" : "0.9913" } }, "develop" : { "requires" : { "Data::Section::Simple" : "0", "Devel::StackTrace" : "0", "Test::CPAN::Meta" : "0", "Test::LeakTrace" : "0", "Test::MinimumVersion::Fast" : "0.04", "Test::PAUSE::Permissions" : "0.04", "Test::Pod" : "1.41", "Test::Spellunker" : "v0.2.7" } }, "runtime" : { "requires" : { "Data::MessagePack" : "0.38", "Encode" : "2.26", "Mouse" : "v2.5.0", "Scalar::Util" : "1.14", "Storable" : "2.15", "parent" : "0.221", "perl" : "5.008001" } }, "test" : { "requires" : { "File::Copy::Recursive" : "0", "File::Path" : "2.07", "Test::More" : "0.98", "Test::Requires" : "0" } } }, "provides" : { "Text::Xslate" : { "file" : "lib/Text/Xslate.pm", "version" : "v3.5.6" }, "Text::Xslate::Bridge" : { "file" : "lib/Text/Xslate/Bridge.pm" }, "Text::Xslate::Bridge::Star" : { "file" : "lib/Text/Xslate/Bridge/Star.pm" }, "Text::Xslate::Compiler" : { "file" : "lib/Text/Xslate/Compiler.pm" }, "Text::Xslate::Engine" : { "file" : "lib/Text/Xslate.pm", "version" : "v3.5.6" }, "Text::Xslate::HashWithDefault" : { "file" : "lib/Text/Xslate/HashWithDefault.pm" }, "Text::Xslate::PP" : { "file" : "lib/Text/Xslate/PP.pm", "version" : "v3.5.6" }, "Text::Xslate::PP::Method" : { "file" : "lib/Text/Xslate/PP/Method.pm" }, "Text::Xslate::PP::Opcode" : { "file" : "lib/Text/Xslate/PP/Opcode.pm", "version" : "v3.5.6" }, "Text::Xslate::PP::State" : { "file" : "lib/Text/Xslate/PP/State.pm" }, "Text::Xslate::PP::Type::Macro" : { "file" : "lib/Text/Xslate/PP/Type/Macro.pm" }, "Text::Xslate::PP::Type::Pair" : { "file" : "lib/Text/Xslate/PP/Type/Pair.pm" }, "Text::Xslate::PP::Type::Raw" : { "file" : "lib/Text/Xslate/PP/Type/Raw.pm" }, "Text::Xslate::Parser" : { "file" : "lib/Text/Xslate/Parser.pm" }, "Text::Xslate::Runner" : { "file" : "lib/Text/Xslate/Runner.pm" }, "Text::Xslate::Symbol" : { "file" : "lib/Text/Xslate/Symbol.pm" }, "Text::Xslate::Syntax::Kolon" : { "file" : "lib/Text/Xslate/Syntax/Kolon.pm" }, "Text::Xslate::Syntax::Metakolon" : { "file" : "lib/Text/Xslate/Syntax/Metakolon.pm" }, "Text::Xslate::Syntax::TTerse" : { "file" : "lib/Text/Xslate/Syntax/TTerse.pm" }, "Text::Xslate::Type::Raw" : { "file" : "lib/Text/Xslate/Type/Raw.pm" }, "Text::Xslate::Util" : { "file" : "lib/Text/Xslate/Util.pm" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/xslate/p5-Text-Xslate/issues" }, "homepage" : "https://github.com/xslate/p5-Text-Xslate", "repository" : { "url" : "git://github.com/xslate/p5-Text-Xslate.git", "web" : "https://github.com/xslate/p5-Text-Xslate" } }, "version" : "v3.5.6", "x_contributors" : [ "Andrテゥ Walker ", "Anirvan Chatterjee ", "Anirvan Chatterjee ", "Brian Fraser ", "Christian Walde ", "David Steinbrunner ", "Fuji, Goro (gfx) ", "Fuji, Goro ", "Fuji, Goro ", "Hao Wu ", "James E Keenan ", "Jesse Luehrs ", "Justin Cook ", "Kazuhiro Osawa ", "Kenichi Ishigaki ", "Kevin M. Goess ", "Konstantin S. Uvarin ", "Mariano Wahlmann ", "Masahiro Chiba ", "Michael Krテカll ", "Mike Raynham ", "Mons Anderson ", "Nick Morrott ", "Olaf Alders ", "Shigeki Morimoto ", "Shigeki Morimoto ", "Shoichi Kaji ", "Shoichi Kaji ", "Syohei YOSHIDA ", "Tasuku SUENAGA a.k.a. gunyarakun ", "Tokuhiro Matsuno ", "Ueda Satoshi ", "Ueda Satoshi ", "Yoshiki Kurihara ", "c9s ", "hiratara ", "hitode909 ", "lestrrat ", "makamaka ", "moznion ", "punytan " ], "x_serialization_backend" : "JSON::PP version 2.97001" } README.md100644000765000024 4712413224611140 15044 0ustar00skajistaff000000000000Text-Xslate-v3.5.6[![Build Status](https://travis-ci.org/xslate/p5-Text-Xslate.svg?branch=master)](https://travis-ci.org/xslate/p5-Text-Xslate) # NAME Text::Xslate - Scalable template engine for Perl5 # VERSION This document describes Text::Xslate version v3.5.6. # SYNOPSIS use Text::Xslate qw(mark_raw); my $tx = Text::Xslate->new(); my %vars = ( title => 'A list of books', books => [ { title => 'Islands in the stream' }, { title => 'Programming Perl' }, # ... ], # mark HTML components as raw not to escape its HTML tags gadget => mark_raw('
...
'), ); # for files print $tx->render('hello.tx', \%vars); # for strings (easy but slow) my $template = q{

<: $title :>

    : for $books -> $book {
  • <: $book.title :>
  • : } # for
}; print $tx->render_string($template, \%vars); # DESCRIPTION **Xslate** is a template engine, tuned for persistent applications, safe as an HTML generator, and with rich features. There are a lot of template engines in CPAN, for example Template-Toolkit, Text::MicroTemplate, HTML::Template, and so on, but all of them have some weak points: a full-featured template engine may be slow, while a fast template engine may be too simple to use. This is why Xslate is developed, which is the best template engine for web applications. The concept of Xslate is strongly influenced by Text::MicroTemplate and Template-Toolkit 2, but the central philosophy of Xslate is different from them. That is, the philosophy is **sandboxing** that the template logic should not have no access outside the template beyond your permission. Other remarkable features are as follows: ## Features ### High performance This engine introduces the virtual machine paradigm. Templates are compiled into intermediate code, and then executed by the virtual machine, which is highly optimized for rendering templates. Thus, Xslate is much faster than any other template engines. The template roundup project by Sam Graham shows Text::Xslate got amazingly high scores in _instance\_reuse_ condition (i.e. for persistent applications). - The template roundup project [http://illusori.co.uk/projects/Template-Roundup/](http://illusori.co.uk/projects/Template-Roundup/) - Perl Template Roundup October 2010 Performance vs Variant Report: instance\_reuse [http://illusori.co.uk/projects/Template-Roundup/201010/performance\_vs\_variant\_by\_feature\_for\_instance\_reuse.html](http://illusori.co.uk/projects/Template-Roundup/201010/performance_vs_variant_by_feature_for_instance_reuse.html) There are also benchmarks in `benchmark/` directory in the Xslate distribution. ### Smart escaping for HTML metacharacters Xslate employs the **smart escaping strategy**, where a template engine escapes all the HTML metacharacters in template expressions unless users mark values as **raw**. That is, the output is unlikely to prone to XSS. ### Template cascading Xslate supports the **template cascading**, which allows you to extend templates with block modifiers. It is like a traditional template inclusion, but is more powerful. This mechanism is also called as template inheritance. ### Easiness to enhance Xslate is ready to enhance. You can add functions and methods to the template engine and even add a new syntax via extending the parser. # INTERFACE ## Methods ### **Text::Xslate->new(%options)** Creates a new Xslate template engine with options. You can reuse this instance for multiple calls to `render()`. Possible options are: - `path => \@path // ['.']` Specifies the include paths, which may be directory names or virtual paths, i.e. HASH references which contain `$file_name => $content` pairs. Note that if you use taint mode (`-T`), you have to give absolute paths to `path` and `cache_dir`. Otherwise you'll get errors because they depend on the current working directory which might not be secure. - `cache => $level // 1` Sets the cache level. If `$level == 1` (default), Xslate caches compiled templates on the disk, and checks the freshness of the original templates every time. If `$level >= 2`, caches will be created but the freshness will not be checked. `$level == 0` uses no caches, which is provided for testing. - `cache_dir => $dir // "$ENV{HOME}/.xslate_cache"` Specifies the directory used for caches. If `$ENV{HOME}` doesn't exist, `File::Spec->tmpdir` will be used. You **should** specify this option for productions to avoid conflicts of template names. - `function => \%functions` Specifies a function map which contains name-coderef pairs. A function `f` may be called as `f($arg)` or `$arg | f` in templates. Note that these registered functions have to return a **text string**, not a binary string unless you want to handle bytes in whole templates. Make sure what you want to use returns either a text string or a binary string. For example, some methods of `Time::Piece` might return a binary string which is encoded in UTF-8, so you'll want to decode their values. # under LANG=ja_JP.UTF-8 on MacOSX (Darwin 11.2.0) use Time::Piece; use Encode qw(decode); sub ctime { my $ctime = Time::Piece->new->strftime; # UTF-8 encoded bytes return decode "UTF-8", $ctime; } my $tx = Text::Xslate->new( function => { ctime => \&ctime, }, ..., ); Built-in functions are described in [Text::Xslate::Manual::Builtin](https://metacpan.org/pod/Text::Xslate::Manual::Builtin). - `module => [$module => ?\@import_args, ...]` Imports functions from _$module_, which may be a function-based or bridge module. Optional _@import\_args_ are passed to `import` as `$module->import(@import_args)`. For example: # for function-based modules my $tx = Text::Xslate->new( module => ['Digest::SHA1' => [qw(sha1_hex)]], ); print $tx->render_string( '<: sha1_hex($x).substr(0, 6) :>', { x => foo() }, ); # => 0beec7 # for bridge modules my $tx = Text::Xslate->new( module => ['Text::Xslate::Bridge::Star'], ); print $tx->render_string( '<: $x.uc() :>', { x => 'foo' }, ); # => 'FOO' Because you can use function-based modules with the `module` option, and also can invoke any object methods in templates, Xslate doesn't require specific namespaces for plugins. - `html_builder_module => [$module => ?\@import_args, ...]` Imports functions from _$module_, wrapping each function with `html_builder()`. - `input_layer => $perliolayers // ':utf8'` Specifies PerlIO layers to open template files. - `verbose => $level // 1` Specifies the verbose level. If `$level == 0`, all the possible errors will be ignored. If `$level >= 1` (default), trivial errors (e.g. to print nil) will be ignored, but severe errors (e.g. for a method to throw the error) will be warned. If `$level >= 2`, all the possible errors will be warned. - `suffix => $ext // '.tx'` Specify the template suffix, which is used for `cascade` and `include` in Kolon. Note that this is used for static name resolution. That is, the compiler uses it but the runtime engine doesn't. - `syntax => $name // 'Kolon'` Specifies the template syntax you want to use. _$name_ may be a short name (e.g. `Kolon`), or a fully qualified name (e.g. `Text::Xslate::Syntax::Kolon`). This option is passed to the compiler directly. - `type => $type // 'html'` Specifies the output content type. If _$type_ is `html` or `xml`, smart escaping is applied to template expressions. That is, they are interpolated via the `html_escape` filter. If _$type_ is `text` smart escaping is not applied so that it is suitable for plain texts like e-mails. _$type_ may be **html**, **xml** (identical to `html`), and **text**. This option is passed to the compiler directly. - `line_start => $token // $parser_defined_str` Specify the token to start line code as a string, which `quotemeta` will be applied to. If you give `undef`, the line code style is disabled. This option is passed to the parser via the compiler. - `tag_start => $str // $parser_defined_str` Specify the token to start inline code as a string, which `quotemeta` will be applied to. This option is passed to the parser via the compiler. - `tag_end => $str // $parser_defined_str` Specify the token to end inline code as a string, which `quotemeta` will be applied to. This option is passed to the parser via the compiler. - `header => \@template_files` Specify the header template files, which are inserted to the head of each template. This option is passed to the compiler. - `footer => \@template_files` Specify the footer template files, which are inserted to the foot of each template. This option is passed to the compiler. - `warn_handler => \&cb` Specify the callback _&cb_ which is called on warnings. - `die_handler => \&cb` Specify the callback _&cb_ which is called on fatal errors. - `pre_process_handler => \&cb` Specify the callback _&cb_ which is called after templates are loaded from the disk in order to pre-process template. For example: # Remove whitespace from templates my $tx = Text::Xslate->new( pre_process_handler => sub { my $text = shift; $text=~s/\s+//g; return $text; } ); The first argument is the template text string, which can be both **text strings** and `byte strings`. This filter is applied only to files, not a string template for `render_string`. ### **$tx->render($file, \\%vars) :Str** Renders a template file with given variables, and returns the result. _\\%vars_ is optional. Note that _$file_ may be cached according to the cache level. ### **$tx->render\_string($string, \\%vars) :Str** Renders a template string with given variables, and returns the result. _\\%vars_ is optional. Note that _$string_ is never cached, so this method should be avoided in production environment. If you want in-memory templates, consider the _path_ option for HASH references which are cached as you expect: my %vpath = ( 'hello.tx' => 'Hello, <: $lang :> world!', ); my $tx = Text::Xslate->new( path => \%vpath ); print $tx->render('hello.tx', { lang => 'Xslate' }); Note that _$string_ must be a text string, not a binary string. ### **$tx->load\_file($file) :Void** Loads _$file_ into memory for following `render()`. Compiles and saves it as disk caches if needed. ### **Text::Xslate->current\_engine :XslateEngine** Returns the current Xslate engine while executing. Otherwise returns `undef`. This method is significant when it is called by template functions and methods. ### **Text::Xslate->current\_vars :HashRef** Returns the current variable table, namely the second argument of `render()` while executing. Otherwise returns `undef`. ### **Text::Xslate->current\_file :Str** Returns the current file name while executing. Otherwise returns `undef`. This method is significant when it is called by template functions and methods. ### **Text::Xslate->current\_line :Int** Returns the current line number while executing. Otherwise returns `undef`. This method is significant when it is called by template functions and methods. ### **Text::Xslate->print(...) :Void** Adds the argument into the output buffer. This method is available on executing. ### **$tx->validate($file) :Void** Checks whether the syntax of _$file_ is valid or invalid as Xslate. If it detects the invalid factor, this method throws the exception. ## Exportable functions ### `mark_raw($str :Str) :RawStr` Marks _$str_ as raw, so that the content of _$str_ will be rendered as is, so you have to escape these strings by yourself. For example: use Text::Xslate qw( mark_raw ); my $tx = Text::Xslate->new(); my $tmpl = 'Mailaddress: <: $email :>'; my %vars = ( email => mark_raw('Foo <foo at example.com>'), ); print $tx->render_string($tmpl, \%email); # => Mailaddress: Foo <foo@example.com> This function is available in templates as the `mark_raw` filter, although the use of it is strongly discouraged. ### `unmark_raw($str :Str) :Str` Clears the raw marker from _$str_, so that the content of _$str_ will be escaped before rendered. This function is available in templates as the `unmark_raw` filter. ### `html_escape($str :Str) :RawStr` Escapes HTML meta characters in _$str_, and returns it as a raw string (see above). If _$str_ is already a raw string, it returns _$str_ as is. By default, this function will automatically be applied to all template expressions. This function is available in templates as the `html` filter, but you're better off using `unmark_raw` to ensure that expressions are html-escaped. ### `uri_escape($str :Str) :Str` Escapes URI unsafe characters in _$str_, and returns it. This function is available in templates as the `uri` filter. ### `html_builder { block } | \&function :CodeRef` Wraps a block or _&function_ with `mark_raw` so that the new subroutine will return a raw string. This function is used to tell the xslate engine that _&function_ is an HTML builder that returns HTML sources. For example: sub some_html_builder { my @args = @_; my $html; # build HTML ... return $html; } my $tx = Text::Xslate->new( function => { some_html_builder => html_builder(\&some_html_builder), }, ); See also [Text::Xslate::Manual::Cookbook](https://metacpan.org/pod/Text::Xslate::Manual::Cookbook). ## Command line interface The `xslate(1)` command is provided as a CLI to the Text::Xslate module, which is used to process directory trees or to evaluate one liners. For example: $ xslate -Dname=value -o dest_path src_path $ xslate -e 'Hello, <: $ARGV[0] :> wolrd!' Xslate $ xslate -s TTerse -e 'Hello, [% ARGV.0 %] world!' TTerse See [xslate(1)](http://man.he.net/man1/xslate) for details. # TEMPLATE SYNTAX There are multiple template syntaxes available in Xslate. - Kolon **Kolon** is the default syntax, using `<: ... :>` inline code and `: ...` line code, which is explained in [Text::Xslate::Syntax::Kolon](https://metacpan.org/pod/Text::Xslate::Syntax::Kolon). - Metakolon **Metakolon** is the same as Kolon except for using `[% ... %]` inline code and `%% ...` line code, instead of `<: ... :>` and `: ...`. - TTerse **TTerse** is a syntax that is a subset of Template-Toolkit 2 (and partially TT3), which is explained in [Text::Xslate::Syntax::TTerse](https://metacpan.org/pod/Text::Xslate::Syntax::TTerse). - HTMLTemplate There's HTML::Template compatible layers in CPAN. [Text::Xslate::Syntax::HTMLTemplate](https://metacpan.org/pod/Text::Xslate::Syntax::HTMLTemplate) is a syntax for HTML::Template. [HTML::Template::Parser](https://metacpan.org/pod/HTML::Template::Parser) is a converter from HTML::Template to Text::Xslate. # NOTES There are common notes in Xslate. ## Nil/undef handling Note that nil (i.e. `undef` in Perl) handling is different from Perl's. Basically it does nothing, but `verbose => 2` will produce warnings on it. - to print Prints nothing. - to access fields Returns nil. That is, `nil.foo.bar.baz` produces nil. - to invoke methods Returns nil. That is, `nil.foo().bar().baz()` produces nil. - to iterate Dealt as an empty array. - equality `$var == nil` returns true if and only if _$var_ is nil. # DEPENDENCIES Perl 5.8.1 or later. If you have a C compiler, the XS backend will be used. Otherwise the pure Perl backend will be used. # TODO - Context controls. e.g. `<: [ $foo->bar @list ] :>`. - Augment modifiers. - Default arguments and named arguments for macros. - External macros. Just idea: in the new macro concept, macros and external templates will be the same in internals: : macro foo($lang) { "Hello, " ~ $lang ~ " world!" } : include foo { lang => 'Xslate' } : # => 'Hello, Xslate world!' : extern bar 'my/bar.tx'; # 'extern bar $file' is ok : bar( value => 42 ); # calls an external template : include bar { value => 42 } # ditto - A "too-safe" HTML escaping filter which escape all the symbolic characters # RESOURCES PROJECT HOME: [https://github.com/xslate/](https://github.com/xslate/) REPOSITORY: [https://github.com/xslate/p5-Text-Xslate/](https://github.com/xslate/p5-Text-Xslate/) # BUGS Please report issues at [https://github.com/xslate/p5-Text-Xslate/issues](https://github.com/xslate/p5-Text-Xslate/issues). Patches are always welcome. # SEE ALSO Documents: [Text::Xslate::Manual](https://metacpan.org/pod/Text::Xslate::Manual) Xslate template syntaxes: [Text::Xslate::Syntax::Kolon](https://metacpan.org/pod/Text::Xslate::Syntax::Kolon) [Text::Xslate::Syntax::Metakolon](https://metacpan.org/pod/Text::Xslate::Syntax::Metakolon) [Text::Xslate::Syntax::TTerse](https://metacpan.org/pod/Text::Xslate::Syntax::TTerse) Xslate command: [xslate](https://metacpan.org/pod/xslate) Other template modules that Xslate has been influenced by: [Text::MicroTemplate](https://metacpan.org/pod/Text::MicroTemplate) [Text::MicroTemplate::Extended](https://metacpan.org/pod/Text::MicroTemplate::Extended) [Text::ClearSilver](https://metacpan.org/pod/Text::ClearSilver) [Template](https://metacpan.org/pod/Template) (Template::Toolkit) [HTML::Template](https://metacpan.org/pod/HTML::Template) [HTML::Template::Pro](https://metacpan.org/pod/HTML::Template::Pro) [Template::Alloy](https://metacpan.org/pod/Template::Alloy) [Template::Sandbox](https://metacpan.org/pod/Template::Sandbox) Benchmarks: [Template::Benchmark](https://metacpan.org/pod/Template::Benchmark) Papers: [http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf](http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf) - Enforcing Strict Model-View Separation in Template Engines # ACKNOWLEDGEMENT Thanks to lestrrat for the suggestion to the interface of `render()`, the contribution of Text::Xslate::Runner (was App::Xslate), and a lot of suggestions. Thanks to tokuhirom for the ideas, feature requests, encouragement, and bug finding. Thanks to gardejo for the proposal to the name **template cascading**. Thanks to makamaka for the contribution of Text::Xslate::PP. Thanks to jjn1056 to the concept of template overlay (now implemented as `cascade with ...`). Thanks to typester for the various inspirations. Thanks to clouder for the patch of adding `AND` and `OR` to TTerse. Thanks to punytan for the documentation improvement. Thanks to chiba for the bug reports and patches. Thanks to turugina for the patch to fix Win32 problems Thanks to Sam Graham for the bug reports. Thanks to Mons Anderson for the bug reports and patches. Thanks to hirose31 for the feature requests and bug reports. Thanks to c9s for the contribution of the documents. Thanks to shiba\_yu36 for the bug reports. Thanks to kane46taka for the bug reports. Thanks to cho45 for the bug reports. Thanks to shmorimo for the bug reports. Thanks to ueda for the suggestions. # AUTHOR Fuji, Goro (gfx) . Makamaka Hannyaharamitu (makamaka) (Text::Xslate::PP) Maki, Daisuke (lestrrat) (Text::Xslate::Runner) # LICENSE AND COPYRIGHT Copyright (c) 2010-2013, Fuji, Goro (gfx). All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 040_signals_on_loading.t100644000765000024 55413224611140 21424 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Test::More; use Text::Xslate; use Time::HiRes qw(sleep alarm); note $$; for (1..10) { my $tx = Text::Xslate->new(); eval { local $SIG{ALRM} = sub { die "TIMEOUT" }; alarm(0.010); $tx->render_string(q{: while true {} }); }; $@ =~ /TIMEOUT/ or note $@; } pass "program finished"; done_testing; augment.pl100644000765000024 46213224611140 17016 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Text::Xslate; my %template = ( 'base' => <<'T', : block hello -> { Hello, <: inner :>! : } T 'child' => <<'T', : cascade 'base' : augment hello -> { "Augment" } T ); my $tx = Text::Xslate->new( path => \%template, cache => 0, ); print $tx->render('child'); bench_compile.pl100644000765000024 103213224611140 20157 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Benchmark qw(:all); use Text::Xslate; my $tx = Text::Xslate->new(); my $tt = Text::Xslate->new(syntax => 'TTerse'); my $x = <<'T'; List: : for $data ->($item) { * <:= $item.title :> * <:= $item.title :> * <:= $item.title :> : } T my $y = <<'T'; List: [% FOREACH item IN data -%] * [% item.title %] * [% item.title %] * [% item.title %] [% END -%] T print "Parser: Kolon v.s. TTerse\n"; cmpthese 0, { kolon => sub { $tx->compile($x) }, tterse => sub { $tt->compile($y) }, }; bench_deserialize.pl100644000765000024 162713224611140 21041 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl use strict; use Benchmark qw(:all); BEGIN{ $ENV{PERL_JSON_BACKEND} = 'JSON::PP' } use Data::Serializer::JSON; use Data::Serializer::Storable; use Data::Serializer::Data::Dumper; use Test::More tests => 3; my $asm = [ map { [$_ => 42, undef, undef] } ('aa' .. 'zz') ]; print scalar @{$asm}, "\n"; my $j = Data::Serializer::JSON->serialize($asm); my $s = Data::Serializer::Storable->serialize($asm); my $d = Data::Serializer::Data::Dumper->serialize($asm); { is_deeply(Data::Serializer::JSON->deserialize($j), $asm); is_deeply(Data::Serializer::Storable->deserialize($s), $asm); is_deeply(Data::Serializer::Data::Dumper->deserialize($d), $asm); } cmpthese timethese -1 => { json => sub { Data::Serializer::JSON->deserialize($j) }, storable => sub { Data::Serializer::Storable->deserialize($s) }, datadumper => sub { Data::Serializer::Data::Dumper->deserialize($d) }, }; cache.pl100644000765000024 54513224611140 16423 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/authoruse strict; use Text::Xslate; use Benchmark qw/ :all /; use Path::Class qw/ file /; END{ unlink "test.tx" } file("test.tx")->openw->print(q{[% FOR i IN list %] [% i %] [% END %]}); my $tx = Text::Xslate->new( syntax => "TTerse" ); print $tx->VERSION, "\n"; timethese 0, { tx => sub { $tx->render("test.tx", { list => [ 1 .. 100 ] }); }, }; chtags.pl100644000765000024 73113224611140 16626 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use File::Find; use Fatal qw(open close); sub wanted { return if not -f $_; print "$_\n"; my $name = $_; open my $in, '<', $name; open my $out, '>', $name . ".tmp"; while(<$in>) { s/^([ \t]*) \Q?/$1:/xms; s/\Q/:>/xmsg; print $out $_; } close $in; close $out; rename "$name.tmp" => $name; } find({ wanted => \&wanted, }, qw(t lib example benchmark)); gen-graph.pl100644000765000024 535713224611140 17256 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use 5.010_000; use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use HTML::Template::Pro; use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate HTML::Template::Pro)){ say $mod, '/', $mod->VERSION; } my($n, $m) = @ARGV; $n //= 100; $m //= 10; my $x = Text::Xslate->new(string => <<'TX_END' x 4);
    : for $books ->($item) {
  • <:= $item.title :>
  • <:= $item.title :>
  • <:= $item.title :>
  • <:= $item.title :>
  • <:= $item.title :>
  • : }
TX_END my $mt = build_mt(<<'MT_END' x 4);
    ? for my $item(@{$_[0]->{books}}) {
  • {title} ?>
  • {title} ?>
  • {title} ?>
  • {title} ?>
  • {title} ?>
  • ? }
MT_END my $ht = HTML::Template->new(scalarref => \(<<'HT_END' x 4), case_sensitive => 1);
HT_END my @x_labels; my %data; for(my $i = 20; $i <= $n; $i += $m) { push @x_labels, $i; my %vars = ( books => [( { title => 'Islands in the stream' }, ) x $i], ); $x->render(\%vars) eq $mt->(\%vars) or die $x->render(\%vars); #$ht->param(\%vars);die $ht->output(); # suppose PSGI response body print "data x $i\n"; my $r = timethese -1 => { xs => sub { my $body = [$x->render(\%vars)]; return; }, mt => sub { my $body = [$mt->(\%vars)]; return; }, ht => sub{ $ht->param(\%vars); my $body = [$ht->output()]; return; }, }; push @{ $data{ht} }, int($r->{ht}->iters / $r->{mt}->cpu_a); push @{ $data{mt} }, int($r->{mt}->iters / $r->{mt}->cpu_a); push @{ $data{xs} }, int($r->{xs}->iters / $r->{xs}->cpu_a); } # draw use Imager; use Imager::Font; use Imager::Graph::Line; my $g = Imager::Graph::Line->new(); $g->set_image_width(800); $g->set_image_height(600); $g->set_font(Imager::Font->new(file => "/usr/share/fonts/ja/TrueType/ipag.ttf")); $g->set_title('Xslate vs. HTML::Template::Pro vs. Text::MicroTemplate'); $g->set_labels(\@x_labels); $g->add_data_series($data{ht}, 'HTML::Template::Pro'); $g->add_data_series($data{mt}, 'Text::MicroTemplate'); $g->add_data_series($data{xs}, 'Text::Xslate'); my $image = $g->draw() or die Imager->errstr; $image->write(file => 'xslate-vs-mt-vs-ht.png'); large.pl100644000765000024 30013224611140 16437 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Text::Xslate; my $file = shift(@ARGV) or die "No templae file supplied"; my $tx = Text::Xslate->new( path => 'author', cache => 0, ); $tx->render($file); list_builtins.pl100644000765000024 20113224611140 20231 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Text::Xslate; my $tx = Text::Xslate->new(); print join("\n", sort keys %{ $tx->{function} }), "\n"; modifiers.pl100644000765000024 67013224611140 17340 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use 5.010; use strict; { package Base; use Any::Moose; sub foo { say "Base::foo" } package Role; use Any::Moose '::Role'; before foo => sub { say "Role::before" }; after foo => sub { say "Role::after" }; package Derived; use Any::Moose; extends 'Base'; with 'Role'; before foo => sub { say "Derived::before" }; after foo => sub { say "Derived::after" }; } Derived->foo; pptest.pl100644000765000024 34113224611140 16671 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w BEGIN{ $ENV{XSLATE} ||= 'pp=booster;dump=pp;' } use strict; use Text::Xslate; my $tx = Text::Xslate->new(); $tx->render_string( <<'CODE', {} ); : macro foo -> $arg { Hello <:= $arg :>! : } : foo($value) CODE prof-large-file.pl100644000765000024 112613224611140 20347 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use File::Temp; use File::Basename; my $N = 500; my $tmp = File::Temp->new( UNLINK => 0, DIR => 'author', SUFFIX => '.tt', ); $tmp->unlink_on_destroy(1); my $tmpl = <<'XML'; [% aaa %] [% bbb %] XML print $tmp "\n"; for my $i(1 .. $N) { print $tmp $tmpl; } print $tmp "\n"; close $tmp; system($^X, 'author/large.pl', basename($tmp)) == 0 or die "Failed to exec"; # wake up system($^X, '-d:NYTProf', 'author/large.pl', basename($tmp)) == 0 or die "Failed to exec"; profile.pl100644000765000024 133313224611140 17034 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Text::Xslate; use UNIVERSAL(); # makes NYTProf happy { package BlogEntry; use Mouse; has title => (is => 'rw'); has body => (is => 'rw'); } my($cache, $n) = @ARGV; $cache //= 1; $n //= 100; my @blog_entries = map{ BlogEntry->new($_) } ( { title => 'Entry one', body => 'This is my first entry.', }, { title => 'Entry two', body => 'This is my second entry.', }, ) x 10; for(1 .. $n) { my $tx = Text::Xslate->new( path => ["./benchmark/template"], cache => $cache, ); $tx->render('child.tx', { blog_entries => \@blog_entries }); } print $INC{'Text/Xslate/Compiler.pm'} ? "compiled.\n" : "cached.\n"; requires.cpanm100644000765000024 112013224611140 17710 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author# for configure Module::Install Module::Install::XSUtil Module::Install::AuthorTests Module::Install::TestTarget Module::Install::Repository # for testing Test::Vars Test::Synopsis Test::Spellunker Test::LeakTrace Plack IPC::Run # for benchmarks Text::MicroTemplate::Extended Text::ClearSilver HTML::Template HTML::Template::Pro Template # for examples Data::Section::Simple HTML::FillInForm HTML::FillInForm::Lite HTML::Shakan URI::Find Mojolicious MojoX::Renderer::Xslate JavaScript::Value::Escape Locale::Maketext::Lexicon Data::Localize File::Which Amon2::Lite Catalyst::View::Xslate t_renumber.pl100644000765000024 106713224611140 17542 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w # re-number test files use strict; my $dir = shift(@ARGV) or die "Usage: $0 test-dir\n"; $dir =~ s{/$}{}; -d $dir or die "No such directory: $dir\n"; my $i = 0; foreach my $dir (sort { ($a =~ /(\d+)_\w+\.t$/)[0] <=> ($b =~ /(\d+)_\w+\.t$/)[0] } <$dir/*.t>) { my $n = ($dir =~ /(\d+)_\w+\.t$/)[0]; last if $n >= 100; (my $newdir = $dir) =~ s/(\d+)(_\w+\.t)$/ sprintf '%03d%s', ++$i, $2 /xmse; next if $dir eq $newdir; printf "%-36s => %-36s\n", $dir, $newdir; rename $dir => $newdir or die "Cannot rename $dir to $newdir: $!"; } tt.pl100644000765000024 26713224611140 16010 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w use strict; use Template; use Smart::Comments; my $t = Template->new(); $t->process(\<<'T', {}, \my $x) or die $t->error, "\n"; A [%- component -%] B T ### $x while-loop.pl100644000765000024 43713224611140 17437 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/author#!perl -w BEGIN{ $ENV{XSLATE} ||= 'dump=asm;' } use strict; use Text::Xslate; my $tx = Text::Xslate->new( function => { f => sub { undef } }, ); print $tx->render_string(<<'TX', { x => shift }); : macro add -> $x, $y { $x + $y } : while(true) { : if(add(1, 2) > 0) { } : } TX cascade.pl100644000765000024 343413224611140 17413 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate::Extended; use Benchmark qw(:all); use FindBin qw($Bin); use Test::More; use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate Text::MicroTemplate::Extended)){ print $mod, '/', $mod->VERSION, "\n"; } my %args = @ARGV; my $cache = defined($args{'--cache'}) ? $args{'--cache'} : 2; { package BlogEntry; use Mouse; has title => (is => 'rw'); has body => (is => 'rw'); } my $n = $args{'--size'} || 2; my @blog_entries = map{ BlogEntry->new($_) } ( { title => 'Entry one', body => "This is my first entry.\n" x $n, }, { title => 'Entry two', body => "This is my second entry.\n" x $n, }, { title => 'Entry three', body => "This is my thrid entry.\n" x $n, }, { title => 'Entry four', body => "This is my forth entry.\n" x $n, }, { title => 'Entry five', body => "This is my fifth entry.\n" x $n, }, ); my $path = "$Bin/template"; my $tx = Text::Xslate->new( path => [$path], cache_dir => '.xslate_cache', cache => $cache, ); my $mt = Text::MicroTemplate::Extended->new( include_path => [$path], template_args => { blog_entries => \@blog_entries }, use_cache => $cache, ); { plan tests => 1; my $x = $tx->render('child.tx', { blog_entries => \@blog_entries }); my $y = $mt->render('child'); $x =~ s/\n//g; $y =~ s/\n//g; is $x, $y, "Xslate eq T::MT::Ex" or exit 1; } print "Benchmarks for template cascading\n"; cmpthese -1 => { MTEx => sub{ my $body = [ $mt->render('child') ] }, TX => sub{ my $body = [ $tx->render('child.tx', { blog_entries => \@blog_entries }) ] }, }; data_section.pl100644000765000024 327213224611140 20465 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Data::Section::Simple qw(get_data_section); use FindBin qw($Bin); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my $tx1 = Text::Xslate->new( path => [ get_data_section(), "$Bin/template" ], cache_dir => ".xslate_cache", cache => 1, ); my $tx2 = Text::Xslate->new( path => [ get_data_section(), "$Bin/template" ], cache_dir => ".xslate_cache", cache => 2, ); my $vars = { books => [( { title => 'Islands in the stream' }, { title => 'Beautiful code' }, { title => 'Introduction to Psychology' }, { title => 'Programming Perl' }, { title => 'Compilers: Principles, Techniques, and Tools' }, ) x $n], }; { use Test::More; plan tests => 2; is $tx1->render('list_ds.tx', $vars), $tx1->render('list.tx', $vars) or die; is $tx2->render('list_ds.tx', $vars), $tx2->render('list.tx', $vars) or die; } print "Files v.s. __DATA__ with cache => 1 or 2\n"; cmpthese -1 => { 'file/1' => sub { my $body = [$tx1->render('list.tx', $vars)]; return; }, 'file/2' => sub { my $body = [$tx2->render('list.tx', $vars)]; return; }, 'vpath/1' => sub { my $body = [$tx1->render('list_ds.tx', $vars)]; return; }, 'vpath/2' => sub { my $body = [$tx2->render('list_ds.tx', $vars)]; return; }, }; __DATA__ @@ list_ds.tx List: : for $data ->($item) { * <:= $item.title :> * <:= $item.title :> * <:= $item.title :> : } demo-mt.pl100644000765000024 245313224611140 17372 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate::File; use Time::HiRes qw(time); use FindBin qw($Bin); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $path = "$Bin/template"; my $mt = Text::MicroTemplate::File->new( include_path => [$path], use_cache => 2, ); my $tx = Text::Xslate->new( path => [$path], cache_dir => '.xslate_cache', cache => 2, ); my %vars = ( data => [ ({ title => 'Programming Perl'}) x 100, ] ); { my $out = $mt->render_file('list.mt', \%vars); $tx->render('list.tx', \%vars) eq $out or die $out; } $| = 1; print "Text::MicrTemplate's render_file() x 1000\n"; my $start = time(); foreach (1 .. 1000) { print $_, "\r"; my $out = $mt->render_file('list.mt', \%vars); } print "\n"; my $mt_used = time() - $start; printf "Used: %.03f sec.\n", $mt_used; print "Text::Xslate's render() x 1000\n"; $start = time(); foreach (1 .. 1000) { print $_, "\r"; my $out = $tx->render('list.tx', \%vars); } print "\n"; my $tx_used = time() - $start; printf "Used: %.03f sec.\n", $tx_used; printf "In this benchmark, Xslate is about %.01f times faster than Text::MicroTemplate.\n", $mt_used / $tx_used; demo-tt.pl100644000765000024 247713224611140 17407 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Template; use Time::HiRes qw(time); use FindBin qw($Bin); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Template)){ print $mod, '/', $mod->VERSION, "\n"; } my $file = 'list.tt'; my $tt = Template->new( INCLUDE_PATH => ["$Bin/template"], COMPILE_EXT => '.out', ); my $tx = Text::Xslate->new( syntax => 'TTerse', path => ["$Bin/template"], cache_dir => '.xslate_cache', cache => 2, ); my %vars = ( data => [ ({ title => 'Programming Perl'}) x 100, ] ); { my $out; $tt->process($file, \%vars, \$out); $tx->render($file, \%vars) eq $out or die $tx->render($file, \%vars), "\n", $out; } $| = 1; print "Template-Toolkit's process() x 1000\n"; my $start = time(); foreach (1 .. 1000) { print $_, "\r"; $tt->process($file, \%vars, \my $out); } print "\n"; my $tt_used = time() - $start; printf "Used: %.03f sec.\n", $tt_used; print "Text::Xslate's render() x 1000\n"; $start = time(); foreach (1 .. 1000) { print $_, "\r"; my $out = $tx->render($file, \%vars); } print "\n"; my $tx_used = time() - $start; printf "Used: %.03f sec.\n", $tx_used; printf "In this benchmark, Xslate is about %.01f times faster than Template-Tookit.\n", $tt_used / $tx_used; expr.pl100644000765000024 232513224611140 17004 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 100; my %vpath = ( expr => "Hello, <:= \$value + 1 :> world!\n" x $n, ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(qq{Hello, {value} + 1 ?> world!\n} x $n); my $subst_tmpl = qq{Hello, %value% world!\n} x $n; my $vars = { value => '41', }; { plan tests => 2; my $expected = $tx->render(expr => $vars); is $mt->($vars), $expected, 'MT'; my $body = [$subst_tmpl]; $body->[0] =~ s/%(\w+)%/ $vars->{$1} + 1 /eg; is $body->[0], $expected, 's///g'; } # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(expr => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, 's///g' => sub { my $body = [$subst_tmpl]; $body->[0] =~ s/%(\w+)%/ $vars->{$1} + 1 /eg; return; }, }; expr_eq.pl100644000765000024 245413224611140 17474 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 100; my %vpath = ( expr_eq => "Hello, <:= \$value == 42 ? 'Xslate' : 'unlikely' :> world!\n" x $n, ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(qq{Hello, {value} == 42 ? 'Xslate' : 'unlikely' ?> world!\n} x $n); my $subst_tmpl = qq{Hello, %value% world!\n} x $n; my $vars = { value => '41', }; { plan tests => 2; my $expected = $tx->render(expr_eq => $vars); is $mt->($vars), $expected, 'MT'; my $body = [$subst_tmpl]; $body->[0] =~ s/%(\w+)%/ $vars->{$1} == 42 ? 'Xslate' : 'unlikely' /eg; is $body->[0], $expected, 's///g'; } # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(expr_eq => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, 's///g' => sub { my $body = [$subst_tmpl]; $body->[0] =~ s/%(\w+)%/ $vars->{$1} + 1 /eg; return; }, }; for.pl100644000765000024 404213224611140 16612 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use HTML::Template::Pro; use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate HTML::Template::Pro)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( for => <<'TX',
    : for $books ->($item) {
  • <:= $item.title :>
  • <:= $item.title :>
  • <:= $item.title :>
  • <:= $item.title :>
  • <:= $item.title :>
  • : }
TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'MT_END');
    ? for my $item(@{$_[0]->{books}}) {
  • {title} ?>
  • {title} ?>
  • {title} ?>
  • {title} ?>
  • {title} ?>
  • ? }
MT_END my $ht = HTML::Template->new(scalarref => \<<'HT_END', case_sensitive => 1);
HT_END my %vars = ( books => [( { title => 'Islands in the stream' }, { title => 'Beautiful code' }, { title => 'Introduction to Psychology' }, { title => 'Programming Perl' }, { title => 'Compilers: Principles, Techniques, and Tools' }, ) x $n], ); $tx->render(for => \%vars) eq $mt->(\%vars) or die $tx->render(for => \%vars); #$ht->param(\%vars);die $ht->output(); # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(for => \%vars)]; return; }, mt => sub { my $body = [$mt->(\%vars)]; return; }, ht => sub{ $ht->param(\%vars); my $body = [$ht->output()]; return; }, }; include.pl100644000765000024 416213224611140 17452 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate::Extended; use HTML::Template::Pro; use Template; use Test::More; use Benchmark qw(:all); use FindBin qw($Bin); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate HTML::Template::Pro Template)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my @path = ("$Bin/template"); my $tx = Text::Xslate->new( path => \@path, cache_dir => '.xslate_cache', cache => 2, ); my $mt = Text::MicroTemplate::Extended->new( include_path => \@path, use_cache => 2, ); my $ht = HTML::Template->new( path => \@path, filename => "include.ht", case_sensitive => 1, ); my $tt = Template->new( INCLUDE_PATH => \@path, COMPILE_EXT => '.out', ); my %vars = ( data => [( { title => 'Islands in the stream' }, { title => 'Beautiful code' }, { title => 'Introduction to Psychology' }, { title => 'Programming Perl' }, { title => 'Compilers: Principles, Techniques, and Tools' }, ) x $n], ); { my $expected = $tx->render('include.tx', \%vars); $expected =~ s/\n+/\n/g; plan tests => 3; my $out = $mt->render('include', \%vars); $out =~ s/\n+/\n/g; is $out, $expected, 'MT - Text::MicroTemplate::Extended'; $ht->param(\%vars); $out = $ht->output(); $out =~ s/\n+/\n/g; is $out, $expected, 'HT - HTML::Template::Pro'; $out = ''; $tt->process('include.tt', \%vars, \$out) or die $tt->error; is $out, $expected, 'TT - Template-Toolkit'; } print "Benchmarks for include commands\n"; # suppose PSGI response body cmpthese -1 => { Xslate => sub { my $body = [$tx->render('include.tx', \%vars)]; return; }, MT => sub { my $body = [$mt->render('include', \%vars)]; return; }, HT => sub { $ht->param(\%vars); my $body = [$ht->output()]; return; }, TT => sub { my $body = ['']; $tt->process('include.tt', \%vars, \$body->[0]) or die $tt->error; return; }, }; interpolate.pl100644000765000024 345613224611140 20362 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my($n, $data) = @ARGV; $n ||= 100; $data ||= 10; my %vpath = ( interpolate => <<'TX' x $n, Hello, <:= $lang :> world! TX interpolate_raw => <<'TX' x $n, Hello, <:= $lang | raw :> world! TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt("Hello, {lang} ?> world!\n" x $n); my $subst_tmpl = qq{Hello, %lang% world!\n} x $n; my $sprintf_tmpl = qq{Hello, %1\$s world!\n} x $n; my $vars = { lang => 'Template' x $data, }; printf "template size: %d bytes; data size: %d bytes\n", length $vpath{interpolate}, length $vars->{lang}; { use Test::More; plan tests => 4; my $x = $tx->render(interpolate => $vars); is $tx->render(interpolate_raw => $vars), $x, 'xslate/raw (w/o escaping)'; is $mt->($vars), $x, 'Text::MicroTemplate'; (my $o = $subst_tmpl) =~ s/%(\w+)%/$vars->{$1}/g; is $o, $x, 's///g'; is sprintf($sprintf_tmpl, $vars->{lang}), $x, 'sprintf'; } # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(interpolate => $vars)]; return; }, 'xslate/raw' => sub { my $body = [$tx->render(interpolate_raw => $vars)]; return; }, TMT => sub { my $body = [$mt->($vars)]; return; }, 's///g' => sub { my $body = [$subst_tmpl]; $body->[0] =~ s/%(\w+)%/$vars->{$1}/g; return; }, 'sprintf' => sub { my $body = [ sprintf $sprintf_tmpl, $vars->{lang} ]; return; }, }; json.pl100644000765000024 255513224611140 17004 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl -w use strict; use Text::Xslate; use JSON::XS; use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate JSON::XS)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( json => <<'TX',
    : for $books ->($item) {
  • <:= $item.title :> (<: $item.author :>)
  • : }
TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $json = JSON::XS->new(); my %vars = ( books => [( { title => 'Islands in the stream', author => 'Ernest Hemingway' }, { title => 'Beautiful code', author => 'Brian Kernighan, Jon Bentley, et. al.' }, { title => q{Atkinson and Hilgard's Introduction to Psychology With Infotrac}, # ' author => 'Edward E. Smith, et. al.' }, { title => 'Programming Perl', author => 'Larry Wall, et.al.' }, { title => 'Compilers: Principles, Techniques, and Tools', author => 'Alfred V. Aho, et. al.' }, ) x $n], ); if(0) { print $tx->render(json => \%vars); print $json->encode(\%vars); } cmpthese -1 => { xslate => sub { my $body = $tx->render(json => \%vars); return; }, json => sub { my $body = $json->encode(\%vars); return; }, }; fib.pl100644000765000024 211713224611140 17713 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( fib => <<'TX', : macro fib -> $n { : $n <= 1 ? 1 : fib($n - 1) + fib($n - 2); : } : fib($x); TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'MT'); ? sub fib { ? my($n) = @_; ? $n <= 1 ? 1 : fib($n - 1) + fib($n - 2); ? } ?= fib($_[0]->{x}) MT my $vars = { x => $n, }; { plan tests => 1; my $out = $mt->($vars); chomp $out; is $out, $tx->render(fib => $vars), 'MT' or die; } # suppose PSGI response body print "fib($n) = ", $tx->render(fib => $vars), "\n"; cmpthese -1 => { xslate => sub { my $body = [$tx->render(fib => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, }; function.pl100644000765000024 216113224611140 20777 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 100; my %vpath = ( function => <<'TX' x $n, Hello, <:= $lang | uc :> world! TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, function => { uc => sub { uc $_[0] } }, ); my $mt = build_mt("Hello, {lang}) ?> world!\n" x $n); my $subst_tmpl = qq{Hello, %lang% world!\n} x $n; my $vars = { lang => 'Template', }; $tx->render(function => $vars) eq $mt->($vars) or die $tx->render(function => $vars); # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(function => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, 's///g' => sub { my $body = [$subst_tmpl]; $body->[0] =~ s/%(\w+)%/uc($vars->{$1})/eg; return; }, }; keys.pl100644000765000024 175213224611140 20132 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( keys => <<'TX' x $n, : for $h.keys() -> $k { [<: $k :>] : } TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'T' x $n); ? for my $k(sort keys %{ $_[0]->{h} }) { [] ? } T my $subst_tmpl = qq{Hello, %value% world!\n} x $n; my $vars = { h => { %ENV }, }; { plan tests => 1; is $mt->($vars), $tx->render(keys => $vars), 'MT' or exit(1); } # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(keys => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, }; map.pl100644000765000024 175413224611140 17736 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( map => <<'TX' x $n, : for $data.map(-> $x { $x + 1 }) -> $v { [<: $v :>] : } TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'T' x $n); ? { ? my $data = $_[0]->{data}; ? for my $v(map{ $_ + 1 } @{$data}) { [] ? } ? } T my $vars = { data => [ 1 .. 100 ], }; { plan tests => 1; is $mt->($vars), $tx->render(map => $vars), 'MT' or exit(1); } # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(map => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, }; method.pl100644000765000024 302213224611140 20427 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; { package Pair; use Mouse; has [qw(key value)] => ( is => 'rw', ); __PACKAGE__->meta->make_immutable(); } my %vpath = ( accessor => <<'TX' x $n, : for $data -> $v { [<: $v.key :>]=[<: $v.value :>] : } TX method => <<'TX' x $n, : for $data -> $v { [<: $v.key() :>]=[<: $v.value() :>] : } TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'T' x $n); ? { ? my $data = $_[0]->{data}; ? for my $v(@{$data}) { [key ?>]=[value ?>] ? } ? } T my $vars = { data => [ map { Pair->new(key => $_, value => $ENV{$_}) } keys %ENV ], #data => [ map { +{ key => $_, value => $ENV{$_} } } keys %ENV ], }; { plan tests => 1; is $mt->($vars), $tx->render(method => $vars), 'MT' or exit(1); } # suppose PSGI response body print "xslate/1 as field access, xslate/2 as method call, MT as method call\n"; cmpthese -1 => { 'xslate/1' => sub { my $body = [$tx->render(accessor => $vars)]; return; }, 'xslate/2' => sub { my $body = [$tx->render(method => $vars)]; return; }, MT => sub { my $body = [$mt->($vars)]; return; }, }; sort.pl100644000765000024 224713224611140 20146 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( sort => <<'TX' x $n, : for $data.sort(-> $a, $b { $a.value <=> $b.value }) -> $v { [<: $v.value :>] : } TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'T' x $n); ? { ? my $data = $_[0]->{data}; ? for my $v(sort { $a->{value} <=> $b->{value} } @{$data}) { [{value} ?>] ? } ? } T my $vars = { data => [ map { +{ value => $_ } } reverse 1 .. 100 ], }; { plan tests => 1; is $mt->($vars), $tx->render(sort => $vars), 'MT' or exit(1); } # suppose PSGI response body print q{Benchmark of sort-by-values ($a.sort( -> $a, $b { $a.value <=> $b.value })):}, "\n"; cmpthese -1 => { xslate => sub { my $body = [$tx->render(sort => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, }; uri_escape.pl100644000765000024 250613224611140 21274 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use URI::Escape; use URI::Escape::XS; use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; foreach my $mod(qw(Text::Xslate URI::Escape URI::Escape::XS)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 100; my %vpath = ( builtin_uri => <<'TX' x $n, Hello, <: $lang | uri :> world! TX uri_escape_pp => <<'TX' x $n, Hello, <: $lang | uri_pp :> world! TX uri_escape_xs => <<'TX' x $n, Hello, <: $lang | uri_xs :> world! TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, function => { uri_pp => \&uri_escape, uri_xs => \&encodeURIComponent, }, ); my $vars = { lang => '/Text::Xslate/', }; { use Test::More; plan tests => 2; is $tx->render(uri_escape_pp => $vars), $tx->render(builtin_uri => $vars), 'URI::Escape'; is $tx->render(uri_escape_xs => $vars), $tx->render(builtin_uri => $vars), 'URI::Escape:XS'; } # suppose PSGI response body cmpthese -1 => { builtin => sub { my $body = [$tx->render(builtin_uri => $vars)]; }, 'URI::Escape' => sub { my $body = [$tx->render(uri_escape_pp => $vars)]; }, 'URI::Escape::XS' => sub { my $body = [$tx->render(uri_escape_xs => $vars)]; }, }; values.pl100644000765000024 203013224611140 20444 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/procs#!perl -w use strict; use Text::Xslate; use Text::MicroTemplate qw(build_mt); use Benchmark qw(:all); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; use Test::More; foreach my $mod(qw(Text::Xslate Text::MicroTemplate)){ print $mod, '/', $mod->VERSION, "\n"; } my $n = shift(@ARGV) || 10; my %vpath = ( values => <<'TX' x $n, : for $h.values() -> $v { [<: $v :>] : } TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.xslate_cache', cache => 2, ); my $mt = build_mt(<<'T' x $n); ? { ? my $h = $_[0]->{h}; ? for my $v(map{ $h->{$_ } } sort keys %{ $h }) { [] ? } ? } T my $subst_tmpl = qq{Hello, %value% world!\n} x $n; my $vars = { h => { %ENV }, }; { plan tests => 1; is $mt->($vars), $tx->render(values => $vars), 'MT' or exit(1); } # suppose PSGI response body cmpthese -1 => { xslate => sub { my $body = [$tx->render(values => $vars)]; return; }, mt => sub { my $body = [$mt->($vars)]; return; }, }; base.mt100644000765000024 116213224611140 20556 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/template <? block title => sub { ?>My amazing site<? }; ?>
sub { } ?>
base.tx100644000765000024 114713224611140 20574 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/template <: block title -> { :>My amazing site<: } :>
<: block content -> { ; } :>
child.mt100644000765000024 31213224611140 20703 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/template? extends "base" sub { ?>My amazing blog ? block content => sub { ? for my $entry(@$blog_entries) {

title ?>

body ?>

? } ? }; child.tx100644000765000024 32513224611140 20722 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/template: cascade base <: around title ->{ :>My amazing blog<: } :> : around content -> { : for $blog_entries -> ($entry) {

<:= $entry.title :>

<:= $entry.body :>

: } # end for : } # end content include.cs100644000765000024 4213224611140 21210 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateInclude: include.ht100644000765000024 4713224611140 21223 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateInclude: include.mt100644000765000024 3713224611140 21227 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateInclude: ?= include "list", @_ include.tt100644000765000024 4213224611140 21232 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateInclude: [% INCLUDE "list.tt" -%] include.tx100644000765000024 3513224611140 21240 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateInclude: : include "list.tx" list.cs100644000765000024 20413224611140 20560 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: * * * list.ht100644000765000024 25713224611140 20576 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: * * * list.mst100644000765000024 12013224611140 20753 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: $ loop(data) { $ * $=h:title$ * $=h:title$ * $=h:title$ $ } $ list.mt100644000765000024 20313224611140 20572 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: ? for my $item(@{ $_[0]->{data} }) { * {title} ?> * {title} ?> * {title} ?> ? } list.tj100644000765000024 21413224611140 20571 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: {data} }) { ?> * [= $item->{title} =] * [= $item->{title} =] * [= $item->{title} =] list.tt100644000765000024 20713224611140 20605 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: [% FOREACH item IN data -%] * [% item.title | html %] * [% item.title | html %] * [% item.title | html %] [% END -%] list.tx100644000765000024 15513224611140 20613 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark/templateList: : for $data ->($item) { * <:= $item.title :> * <:= $item.title :> * <:= $item.title :> : } x-poor-env.pl100644000765000024 725313224611140 20045 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl # For poor environment, e.g. CGI applications without XS BEGIN { $ENV{PERL_ONLY}= 1 } use strict; use warnings; use Getopt::Long; use Test::More; use Benchmark qw(:all); use FindBin qw($Bin); use Template; use HTML::Template; use Text::MicroTemplate::Extended; use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; GetOptions( 'booster' => \my $pp_booster, 'opcode' => \my $pp_opcode, 'size=i' => \my $n, 'template=s' => \my $tmpl, 'help' => \my $help, ); die <<'HELP' if $help; perl -Mblib benchmark/x-poor-env.pl [--size N] [--template NAME] [--opcode|booster] This is a general benchmark utility for poor environment, assuming CGI applications using only pure Perl modules. See also benchmark/x-rich-env.pl. HELP $tmpl = 'include' if not defined $tmpl; $n = 100 if not defined $n; if(defined $pp_booster) { $ENV{XSLATE} = 'pp=booster'; } elsif(defined $pp_opcode) { $ENV{XSLATE} = 'pp=opcode'; } $ENV{MOUSE_PUREPERL} = 1; $Template::Config::STASH = 'Template::Stash'; # Instead of Stash::XS require Text::Xslate::PP; foreach my $mod(qw( Text::Xslate Template HTML::Template Text::MicroTemplate Text::MicroTemplate::Extended )){ print $mod, '/', $mod->VERSION, "\n" if $mod->VERSION; } my $path = "$Bin/template"; my $vars = { data => [ ({ title => "", author => "BAR", abstract => "BAZ", }) x $n ], }; TEST: { my $tx = Text::Xslate->new( path => [$path], cache_dir => '.xslate_cache', cache => 2, ); my $mt = Text::MicroTemplate::Extended->new( include_path => [$path], use_cache => 2, ); my $tt = Template->new( INCLUDE_PATH => [$path], COMPILE_EXT => '.out', ); my $ht = HTML::Template->new( path => [$path], filename => "$tmpl.ht", case_sensitive => 1, die_on_bad_params => 0, double_file_cache => 1, file_cache_dir => '.xslate_cache', ); my $expected = $tx->render("$tmpl.tx", $vars); $expected =~ s/\n+/\n/g; plan tests => 3; $tt->process("$tmpl.tt", $vars, \my $out) or die $tt->error; $out =~ s/\n+/\n/g; is $out, $expected, 'TT: Template-Toolkit'; $out = $mt->render_file($tmpl, $vars); $out =~ s/\n+/\n/g; is $out, $expected, 'MT: Text::MicroTemplate'; $ht->param($vars); $out = $ht->output(); $out =~ s/\n+/\n/g; is $out, $expected, 'HT: HTML::Template'; } print "Benchmarks with '$tmpl' (datasize=$n)\n"; cmpthese -1 => { Xslate => sub { my $tx = Text::Xslate->new( path => [$path], cache_dir => '.xslate_cache', cache => 2, ); my $body = $tx->render("$tmpl.tx", $vars); return; }, MT => sub { my $mt = Text::MicroTemplate::Extended->new( include_path => [$path], cache => 2, ); my $body = $mt->render_file($tmpl, $vars); return; }, TT => sub { my $tt = Template->new( INCLUDE_PATH => [$path], COMPILE_EXT => '.out', ); my $body; $tt->process("$tmpl.tt", $vars, \$body) or die $tt->error; return; }, HT => sub { my $ht = HTML::Template->new( path => [$path], filename => "$tmpl.ht", case_sensitive => 1, die_on_bad_params => 0, double_file_cache => 1, file_cache_dir => '.xslate_cache', ); $ht->param($vars); my $body = $ht->output(); return; }, }; x-rich-env.pl100644000765000024 1242513224611140 20030 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/benchmark#!perl # For rich environment, e.g. Persistent PSGI applications with XS use strict; use warnings; use Text::Xslate; use Text::MicroTemplate::Extended; use Template; use Getopt::Long; use Test::More; use Benchmark qw(:all); use FindBin qw($Bin); use Storable (); use Config; printf "Perl/%vd %s\n", $^V, $Config{archname}; GetOptions( 'mst' => \my $try_mst, 'tenjin' => \my $try_tenjin, 'clearsilver'=> \my $try_cs, 'size=i' => \my $n, 'template=s' => \my $tmpl, 'first-time' => \my $first_time, 'help' => \my $help, ); die <<'HELP' if $help; perl -Mblib benchmark/x-rich-env.pl [--size N] [--template NAME] This is a general benchmark utility for rich environment, assuming persisitent PSGI applications using XS modules. See also benchmark/x-poor-env.pl. HELP require Text::Xslate; $tmpl = 'include' if not defined $tmpl; $n = 100 if not defined $n; my $has_tcs = ($try_cs && eval q{ use Text::ClearSilver 0.10.5.4; 1 }); warn "Text::ClearSilver is not available ($@)\n" if $@; my $has_mst = ($tmpl eq 'list' && $try_mst && eval q{ use MobaSiF::Template; 1 }); warn "MobaSiF::Template is not available ($@)\n" if $try_mst && $@; my $has_htp = eval q{ use HTML::Template::Pro; 1 }; warn "HTML::Template::Pro is not available ($@)\n" if $@; my $has_tenjin = ($try_tenjin && eval q{ use Tenjin; 1 }); warn "Tenjin is not available ($@)\n" if $try_tenjin && $@; foreach my $mod(qw( Text::Xslate Text::MicroTemplate Text::MicroTemplate::Extended Template Text::ClearSilver MobaSiF::Template HTML::Template::Pro Tenjin )){ print $mod, '/', $mod->VERSION, "\n" if $mod->VERSION; } my $path = "$Bin/template"; sub xslate { return Text::Xslate->new( path => [$path], cache_dir => '.xslate_cache', cache => 2, ); } sub mt { return Text::MicroTemplate::Extended->new( include_path => [$path], use_cache => 2, ); } sub tt { return Template->new( INCLUDE_PATH => [$path], COMPILE_EXT => '.out', ); } sub htp { return HTML::Template::Pro->new( path => [$path], filename => "$tmpl.ht", case_sensitive => 1, ); } sub tcs { return Text::ClearSilver->new( VarEscapeMode => 'html', load_path => [$path], ); } sub tenjin { return Tenjin->new({ path => [$path], strict => 1, }); } my $tx = xslate(); my $mt = mt(); my $tt = tt(); my $htp; if($has_htp) { $htp = htp(); } my $tcs; if($has_tcs) { $tcs = tcs(); } my $mst_in = "$Bin/template/list.mst"; my $mst_bin = "$Bin/template/list.mst.out"; if($has_mst) { MobaSiF::Template::Compiler::compile($mst_in, $mst_bin); } my $tenjin; if($has_tenjin) { $tenjin = tenjin(); } my $vars = { data => [ ({ title => "", author => "BAR", abstract => "BAZ", }) x $n ], }; my $vars_tenjin = Storable::dclone($vars); { my $expected = $tx->render("$tmpl.tx", $vars); $expected =~ s/\n+/\n/g; my $tests = 2; $tests++ if $has_tcs; $tests++ if $has_mst; $tests++ if $has_htp; $tests++ if $has_tenjin; plan tests => $tests; $tt->process("$tmpl.tt", $vars, \my $out) or die $tt->error; $out =~ s/\n+/\n/g; is $out, $expected, 'TT: Template-Toolkit'; $out = $mt->render_file($tmpl, $vars); $out =~ s/\n+/\n/g; is $out, $expected, 'MT: Text::MicroTemplate'; if($has_tcs) { $tcs->process("$tmpl.cs", $vars, \$out); $out =~ s/\n+/\n/g; is $out, $expected, 'TCS: Text::ClearSilver'; } if($has_mst) { $out = MobaSiF::Template::insert($mst_bin, $vars); $out =~ s/\n+/\n/g; is $out, $expected, 'MST: MobaSiF::Template'; } if($has_htp) { $htp->param($vars); $out = $htp->output(); $out =~ s/\n+/\n/g; is $out, $expected, 'HTP: HTML::Template::Pro'; } if($has_tenjin) { $out = $tenjin->render("$tmpl.tj", $vars_tenjin); $out =~ s/\n+/\n/g; is $out, $expected, 'Tenjin'; } } print "Benchmarks with '$tmpl' (datasize=$n)\n"; cmpthese -1 => { Xslate => sub { $tx = xslate() if $first_time; my $body = $tx->render("$tmpl.tx", $vars); return; }, MT => sub { $mt = mt() if $first_time; my $body = $mt->render_file($tmpl, $vars); return; }, TT => sub { $tt = tt() if $first_time; my $body; $tt->process("$tmpl.tt", $vars, \$body) or die $tt->error; return; }, $has_tcs ? ( TCS => sub { $tcs = tcs() if $first_time; my $body; $tcs->process("$tmpl.cs", $vars, \$body); return; }, ) : (), $has_mst ? ( MST => sub { my $body = MobaSiF::Template::insert($mst_bin, $vars); return; }, ) : (), $has_htp ? ( HTP => sub { $htp = htp() if $first_time; $htp->param($vars); my $body = $htp->output(); return; }, ) : (), $has_tenjin ? ( Tenjin => sub { $tenjin = tenjin() if $first_time; my $body = $tenjin->render("$tmpl.tj", $vars_tenjin); return; }, ) : (), }; MyBuilder.pm100644000765000024 551013224611140 17416 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/builderpackage builder::MyBuilder; use strict; use warnings; use base 'Module::Build::XSUtil'; sub new { my ($class, %args) = @_; my $self = $class->SUPER::new( %args, c_source => ['src'], cc_warnings => 1, generate_ppport_h => 'src/ppport.h', generate_xshelper_h => 'src/xshelper.h', xs_files => { 'src/Text-Xslate.xs' => 'lib/Text/Xslate.xs' }, ); # src/xslate_ops.h uses special operators name in C++, # such as "and", "or", "not"; # so remove "-Wc++-compat" flags my $flags = $self->extra_compiler_flags; $self->extra_compiler_flags(grep { $_ ne "-Wc++-compat" } @$flags); $self; } sub _write_xs_version { my ($self, $file) = @_; open my $fh, ">", $file or die "$file: $!"; print {$fh} "#ifndef XS_VERSION\n"; printf {$fh} "# define XS_VERSION \"%s\"\n", $self->dist_version; print {$fh} "#endif\n"; } sub _derive_opcode { my ($self, $script, $source, $derived) = @_; my @cmd = ($self->{properties}{perl}, $script, $source); $self->log_info("@cmd > $derived\n"); open my $fh, ">", $derived or die "$derived: $!"; print {$fh} $self->_backticks(@cmd); } sub ACTION_code { my ($self, @args) = @_; if (!$self->pureperl_only) { $self->_write_xs_version("src/xs_version.h"); } my @derive = ( { xs => 0, source => "src/xslate_opcode.inc", derived => "lib/Text/Xslate/PP/Const.pm", code => sub { my ($self, $source, $derived) = @_; $self->_derive_opcode("tool/opcode_for_pp.PL", $source, $derived); }, }, { xs => 1, source => "src/xslate_opcode.inc", derived => "src/xslate_ops.h", code => sub { my ($self, $source, $derived) = @_; $self->_derive_opcode("tool/opcode.PL", $source, $derived); }, }, { xs => 1, source => "src/xslate_methods.xs", derived => "src/xslate_methods.c", code => sub { my ($self, $source, $derived) = @_; $self->compile_xs($source, outfile => $derived); }, } ); for my $derive (@derive) { next if $self->pureperl_only and $derive->{xs}; next if $self->up_to_date($derive->{source}, $derive->{derived}); $derive->{code}->($self, $derive->{source}, $derive->{derived}); } $self->SUPER::ACTION_code(@args); } sub ACTION_test { my ($self, @args) = @_; if (!$self->pureperl_only) { local $ENV{XSLATE} = 'xs'; $self->log_info("xs tests\n"); $self->SUPER::ACTION_test(@args); } { local $ENV{PERL_ONLY} = 1; $self->log_info("pureperl tests\n"); $self->SUPER::ACTION_test(@args); } } 1; cpanfile100644000765000024 124713224611140 15245 0ustar00skajistaff000000000000Text-Xslate-v3.5.6requires 'perl', '5.008001'; requires 'Mouse', 'v2.5.0'; requires 'Data::MessagePack', '0.38'; requires 'parent', '0.221'; requires 'Scalar::Util', '1.14'; # fix local $SIG{__DIE__} + eval problems requires 'Encode', '2.26'; requires 'Storable', '2.15'; on configure => sub { requires 'Devel::PPPort', '3.33'; requires 'Module::Build::XSUtil'; requires 'version', '0.9913'; }; on test => sub { requires 'Test::More', '0.98'; requires 'Test::Requires'; requires 'File::Copy::Recursive'; requires 'File::Path', '2.07'; }; on develop => sub { requires 'Test::LeakTrace'; requires 'Devel::StackTrace'; requires 'Data::Section::Simple'; }; amon2.psgi100644000765000024 64613224611140 17056 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl use strict; use warnings; use Amon2::Lite; get '/' => sub { my ($c) = @_; $c->render('index.tt'); }; get '/hello' => sub { my ($c) = @_; $c->render('index.tt', { name => 'Amon2' }); }; sub res_404 { my($c) = @_; use Data::Dumper; die Dumper($c); } __PACKAGE__->to_app(); __DATA__ @@ index.tt

Hello, [% name // 'Xslate' %] world! amon2.psgi.gold100644000765000024 11013224611140 17764 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example

Hello, Amon2 world! autolink.pl100644000765000024 112613224611140 17353 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate qw(html_builder html_escape); use URI::Find 20100505; my $text = <<'EOT'; EOT my $finder = URI::Find->new(sub { my($obj_uri, $orig_uri) = @_; my $safe_uri = html_escape($orig_uri); return qq|$safe_uri|; }); my $tx = Text::Xslate->new( function => { autolink => html_builder { my($text) = @_; $finder->find(\$text, \&html_escape); return $text; }, }, ); print $tx->render_string(<<'T', { text => $text }); : $text | autolink T autolink.pl.gold100644000765000024 13213224611140 20253 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example<http://example.com/?a=10&b=20> base.tx100644000765000024 113213224611140 16454 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example <: block title -> { :>My amazing site<: } :>
: block content -> { ; }
bridge.pl100644000765000024 171013224611140 16760 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use FindBin qw($Bin); { package MyBridge; use parent qw(Text::Xslate::Bridge); use Scalar::Util qw(looks_like_number); use List::Util qw(sum); __PACKAGE__->bridge( scalar => { looks_like_number => \&_scalar_looks_like_number, length => \&_scalar_length, }, array => { sum => \&_array_sum, }, hash => { delete_keys => \&_hash_delete_keys, }, ); sub _scalar_looks_like_number { looks_like_number($_[0]); } sub _scalar_length { defined $_[0] ? length $_[0] : 0; } sub _array_sum { defined $_[0] ? sum @{$_[0]} : 0; } sub _hash_delete_keys { my %hash = %{+shift}; delete $hash{$_} for @_; return \%hash; } } my $tx = Text::Xslate->new( module => [qw(MyBridge)], path => $Bin, ); print $tx->render('bridge.tx'); bridge.tx100644000765000024 76213224611140 16766 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example: my $num = 100; : my $str = 'abc'; : my $array = [1,2,4,8,16]; : my $hash = {a => 1, b => 2, c => 3, d => 4}; : $num ~ ' is a number' if $num.looks_like_number(); : $str ~ ' is a string' if !$str.looks_like_number(); : $str ~ ' length is ' ~ $str.length(); : 'sum of ' ~ $array.join(',') ~ ' is ' ~ $array.sum(); : my $reduced = $hash.delete_keys('b', 'd'); After keys b and d have been deleted, the hash is: : for $reduced.kv() -> $pair { <: $pair.key :> = <: $pair.value :> : }; cascade.pl100644000765000024 107113224611140 17107 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use FindBin qw($Bin); { package BlogEntry; use Mouse; has title => (is => 'rw'); has body => (is => 'rw'); } my @blog_entries = map{ BlogEntry->new($_) } ( { title => 'Entry one', body => 'This is my first entry.', }, { title => 'Entry two', body => 'This is my second entry.', }, ); my $path = $Bin; my $tx = Text::Xslate->new( path => [$path], cache_dir => '.eg_cache', ); print $tx->render('cascade.tx', { blog_entries => \@blog_entries }); cascade.pl.gold100644000765000024 115113224611140 20032 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example My amazing blog

Entry one

This is my first entry.

Entry two

This is my second entry.

cascade.tx100644000765000024 32513224611140 17110 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example: cascade base <: around title ->{ :>My amazing blog<: } :> : around content -> { : for $blog_entries -> ($entry) {

<:= $entry.title :>

<:= $entry.body :>

: } # end for : } # end content chained-scope.pl100644000765000024 47613224611140 20216 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl use strict; use warnings; use Text::Xslate; my %vpath = ( 'foo.tx' => 'Hello, <: $a ~ $b :> world!' . "\n", 'bar.tx' => ': include foo { __ROOT__.merge({ b => " with Kolon"}) }', ); my $tx = Text::Xslate->new( cache => 0, path => \%vpath, ); print $tx->render('bar.tx', { a => 'Xslate' }); chained-scope.pl.gold100644000765000024 4013224611140 21105 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleHello, Xslate with Kolon world! data_section.pl100644000765000024 62613224611140 20146 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use Data::Section::Simple; my $tx = Text::Xslate->new( path => [ Data::Section::Simple->new()->get_data_section() ], cache_dir => '.eg_cache', ); print $tx->render('child.tx'); __DATA__ @@ base.tx <: block body -> { :>default body<: } :> @@ child.tx : cascade base; : override body -> { child body : } # endblock body data_section.pl.gold100644000765000024 5213224611140 21043 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example child body dynamic_functions.pl100644000765000024 160713224611140 21245 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use FindBin qw($Bin); { package MyBridge; use parent qw(Text::Xslate::Bridge); __PACKAGE__->bridge( function => {my_func => \&_my_func}, scalar => {my_func => \&_scalar}, hash => {my_func => \&_hash}, array => {my_func => \&_array}, ); sub _scalar { my $obj = shift; _my_func(@_)->($obj); }; sub _hash { my $obj = shift; _my_func(@_)->(map {$_, $obj->{$_}} keys %$obj); }; sub _array { my $obj = shift; _my_func(@_)->(@$obj); }; sub _my_func { my @outer_args = @_; sub { my (@inner_args) = @_; join(', ', @outer_args, @inner_args) . "\n"; } } } my $tx = Text::Xslate->new( module => [qw(MyBridge)], path => $Bin, ); print $tx->render('dynamic_functions.tx'); dynamic_functions.tx100644000765000024 55013224611140 21241 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleBlock syntax: : block my_block | my_func(foo => 'bar') -> {'baz, qux'} Subroutine syntax: : my_func(foo => 'bar')('baz, qux'); Filter syntax: : 'baz, qux' | my_func(foo => 'bar') Scalar object syntax: : 'baz, qux'.my_func(foo => 'bar') Hash object syntax: : {baz => 'qux'}.my_func(foo => 'bar') Array object syntax: : ['baz', 'qux'].my_func(foo => 'bar') err_handler.pl100644000765000024 55213224611140 17774 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; my %vpath = ( hello => 'Hello, <: $lang :> world!' . "\n", ); my $tx = Text::Xslate->new( cache => 0, path => \%vpath, verbose => 2, warn_handler => sub { Text::Xslate->print('[[', @_, ']]') }, ); print $tx->render('hello', { lang => "Xslate" }); print $tx->render('hello', { }); fillinform.pl100644000765000024 63213224611140 17647 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use HTML::FillInForm::Lite 1.09; my $tx = Text::Xslate->new( html_builder_module => [ 'HTML::FillInForm::Lite' => [qw(fillinform)] ], cache_dir => '.eg_cache', ); my %vars = ( q => { foo => "" }, ); print $tx->render_string(<<'T', \%vars); FillInForm: : block form | fillinform($q) -> {
: } T fillinform.pl.gold100644000765000024 13113224611140 20565 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleFillInForm:
form.psgi100644000765000024 276213224611140 17026 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate qw(mark_raw); use HTML::Shakan 0.05; use Plack::Request; my %vpath = ( 'form.tx' => <<'T', Using Form Builder

Form:
<: $form :>

: if $errors.size() > 0 {

Errors (<: $errors.size() :>):
: for $errors -> $e { <: $e :>
: }

: }
T ); my $tx = Text::Xslate->new( path => \%vpath, verbose => 2, warn_handler => \&Carp::croak, cache => 0, ); { package My::Form; use HTML::Shakan::Declare; form 'add' => ( TextField( name => 'name', label => 'name: ', required => 1, ), EmailField( name => 'email', label => 'email: ', required => 1, ), ); } return sub { my($env) = @_; my $req = Plack::Request->new($env); my $shakan = My::Form->get( add => ( request => $req) ); my @errors; if($shakan->has_error) { $shakan->load_function_message('en'); @errors = $shakan->get_error_messages(); } my $res = $req->new_response( 200, [ content_type => 'text/html; charset=utf8' ], ); my $form = mark_raw( $shakan->render() ); my $body = $tx->render('form.tx', { form => $form, errors => \@errors }); utf8::encode($body); $res->body( $body ); return $res->finalize(); }; form.psgi.gold100644000765000024 54413224611140 17726 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example Using Form Builder

Form:

hello.pl100644000765000024 40213224611140 16604 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use FindBin qw($Bin); my $path = $Bin; my $tx = Text::Xslate->new( path => [$path], cache_dir => '.eg_cache', ); print $tx->render('hello.tx', { }); print $tx->render('hello.tx', { lang => "Xslate" }); hello.pl.gold100644000765000024 5013224611140 17507 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleHello, Perl world! Hello, Xslate world! hello.tmpl100644000765000024 4613224611140 17131 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleHello, world! hello.tx100644000765000024 4413224611140 16606 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleHello, <: $lang // "Perl" :> world! htmltemplate.pl100644000765000024 31013224611140 20177 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w # TODO use strict; use Text::Xslate; my $tx = Text::Xslate->new( syntax => 'HTMLTemplate', cache => 0, ); print $tx->render('example/hello.tmpl', { lang => 'HTML::Template' }); htparser.pl100644000765000024 102213224611140 17350 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w # TODO use strict; use Text::Xslate; use File::Slurp qw(slurp); use HTML::Template::Parser; use HTML::Template::Parser::TreeWriter::TextXslate::Metakolon; my $htparser = HTML::Template::Parser->new(); my $ast = $htparser->parse(slurp 'example/hello.tmpl'); my $writer = HTML::Template::Parser::TreeWriter::TextXslate::Metakolon->new; my $source = $writer->write($ast); my $tx = Text::Xslate->new( syntax => 'Metakolon', cache => 0, ); print $tx->render_string($source, { lang => 'HTML::Template' }); i18n-data-localize.pl100644000765000024 163513224611140 21020 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl use strict; use warnings; use utf8; use Text::Xslate; use Text::Xslate::Util qw(html_escape html_builder); use Data::Localize; use Data::Localize::Gettext; use FindBin qw($Bin); use Encode (); my $i18n = Data::Localize->new( auto => 1, languages => ['ja'], ); $i18n->add_localizer( class => 'Gettext', path => "$Bin/locale/*.po", ); my $xslate = Text::Xslate->new( syntax => 'TTerse', function => { l => sub { return $i18n->localize(@_); }, l_raw => html_builder { my $format = shift; my @args = map { html_escape($_) } @_; return $i18n->localize($format, @args); }, }, ); my %param = (location => ''); # user inputs my $body = $xslate->render_string(<<'TEMPLATE', \%param); [% l_raw('Hello!
') %] [% l_raw('I am in %1
', $location) %] TEMPLATE print Encode::encode_utf8($body); i18n-data-localize.pl.gold100644000765000024 10113224611140 21707 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example縺薙s縺ォ縺。縺ッシ
遘√ッ <Tokyo> 縺ォ縺縺セ縺
i18n.pl100644000765000024 174213224611140 16310 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl use strict; use warnings; use utf8; use Text::Xslate; use Text::Xslate::Util qw(html_escape html_builder); use Encode (); { package MyApp::I18N; use FindBin qw($Bin); use parent 'Locale::Maketext'; use Locale::Maketext::Lexicon { '*' => [Gettext => "$Bin/locale/*.po"], _auto => 1, _decode => 1, _style => 'gettext', }; } my $i18n = MyApp::I18N->get_handle('ja'); my $xslate = Text::Xslate->new( syntax => 'TTerse', function => { l => sub { return $i18n->maketext(@_); }, l_raw => html_builder { my $format = shift; my @args = map { html_escape($_) } @_; return $i18n->maketext($format, @args); }, }, ); my %param = (location => ''); # user inputs my $body = $xslate->render_string(<<'TEMPLATE', \%param); [% l_raw('Hello!
') %] [% l_raw('I am in %1
', $location) %] TEMPLATE print Encode::encode_utf8($body); i18n.pl.gold100644000765000024 10113224611140 17200 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example縺薙s縺ォ縺。縺ッシ
遘√ッ <Tokyo> 縺ォ縺縺セ縺
list.pl100644000765000024 107213224611140 16500 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; use FindBin qw($Bin); use File::Find; my $path = $Bin; my $tx = Text::Xslate->new( path => [$path], cache_dir => '.eg_cache', ); # preload templates find sub { if(/\.tx$/) { my $file = $File::Find::name; $file =~ s/\Q$path\E .//xsm; $tx->load_file($file); } }, $path; print $tx->render('list.tx', {data => [ { title => 'Islands in the stream' }, { title => 'Programming Perl' }, { title => 'River out of Eden' }, { title => 'Beautiful code' }, ]}); list.pl.gold100644000765000024 43613224611140 17407 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleList: ------------------------------- 1. Islands in the stream ------------------------------- 2. Programming Perl ------------------------------- 3. River out of Eden ------------------------------- 4. Beautiful code ------------------------------- list.tx100644000765000024 26713224611140 16505 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/exampleList: : for $data ->($item) { : if $~item.is_first { ------------------------------- : } <: $~item.count :>. <: $item.title :> ------------------------------- : } ja.po100644000765000024 71113224611140 17340 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example/locale# for example/i18n.pl msgid "" msgstr "" "Project-Id-Version: Xslate I18N example\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: 2011-11-02 12:00-0900\n" "Last-Translator: Fuji Goro\n" "Language-Team: Jaapanese\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Hello!
" msgstr "縺薙s縺ォ縺。縺ッシ
" msgid "I am in %1
" msgstr "遘√ッ %1 縺ォ縺縺セ縺
" mojo.psgi100644000765000024 55013224611140 17000 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl package HelloMojo; use strict; use warnings; use Mojolicious 1.0; use Mojolicious::Lite; #use MojoX::Renderer::Xslate; # this is automatically loaded plugin 'xslate_renderer'; get '/' => 'index'; get '/:name' => 'index'; app->start; __DATA__ @@ index.html.tx Hello, <: $c.req.param('lang') // "Xslate" :> world! mojo.psgi.gold100644000765000024 6413224611140 17704 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example Hello, Xslate world! put_js.pl100644000765000024 55613224611140 17017 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!perl -w use strict; use Text::Xslate; my $tx = Text::Xslate->new( module => ['JavaScript::Value::Escape' => [qw(js)]], ); my %params = ( user_input => '', ); print $tx->render_string(<<'T', \%params); T put_js.pl.gold100644000765000024 43413224611140 17736 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example simple.psgi100644000765000024 142413224611140 17346 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example#!psgi -w use strict; use Text::Xslate; use Plack::Request; my %vpath = ( 'hello.tx' => <<'TX', hello

Hello, <: $lang :> world!

TX ); my $tx = Text::Xslate->new( path => \%vpath, cache_dir => '.eg_cache', ); sub app { my($env) = @_; my $req = Plack::Request->new($env); my $res = $req->new_response( 200, [content_type => 'text/html; charset=utf-8'], ); my %vars = ( lang => $req->param('lang') || '', ); my $body = $tx->render('hello.tx', \%vars); utf8::encode($body); $res->body($body); return $res->finalize(); } return \&app; simple.psgi.gold100644000765000024 30613224611140 20250 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/example hello

Hello, <Xslate> world!

Xslate.pm100644000765000024 11164013224611140 17070 0ustar00skajistaff000000000000Text-Xslate-v3.5.6/lib/Textpackage Text::Xslate; # The Xslate engine class use 5.008_001; use strict; use warnings; use version; our $VERSION = version->declare('v3.5.6'); use Carp (); use File::Spec (); use Exporter (); use Data::MessagePack (); use Scalar::Util (); use Text::Xslate::Util (); BEGIN { # all the exportable functions are defined in ::Util our @EXPORT_OK = qw( mark_raw unmark_raw escaped_string html_escape uri_escape html_builder ); Text::Xslate::Util->import(@EXPORT_OK); } our @ISA = qw(Text::Xslate::Engine); my $BYTECODE_VERSION = '1.6'; # $bytecode_version + $fullpath + $compiler_and_parser_options my $XSLATE_MAGIC = qq{xslate;$BYTECODE_VERSION;%s;%s;}; our $DEFAULT_CACHE_DIR; # load backend (XS or PP) my $use_xs = 0; if(!exists $INC{'Text/Xslate/PP.pm'}) { my $pp = ($Text::Xslate::Util::DEBUG =~ /\b pp \b/xms or $ENV{PERL_ONLY}); if(!$pp) { eval { require XSLoader; XSLoader::load(__PACKAGE__, $VERSION); $use_xs = 1; }; die $@ if $@ && $Text::Xslate::Util::DEBUG =~ /\b xs \b/xms; # force XS } if(!__PACKAGE__->can('render')) { require 'Text/Xslate/PP.pm'; } } sub USE_XS() { $use_xs } # for error messages (see T::X::Util) sub input_layer { ref($_[0]) ? $_[0]->{input_layer} : ':utf8' } package Text::Xslate::Engine; # XS/PP common base class use version; our $VERSION = version->declare('v3.5.6'); use Text::Xslate::Util qw( make_error dump ); # constants BEGIN { our @ISA = qw(Exporter); my $dump_load = scalar($Text::Xslate::Util::DEBUG =~ /\b dump=load \b/xms); *_DUMP_LOAD = sub(){ $dump_load }; my $save_src = scalar($Text::Xslate::Util::DEBUG =~ /\b save_src \b/xms); *_SAVE_SRC = sub() { $save_src }; *_ST_MTIME = sub() { 9 }; # see perldoc -f stat } unless(defined $DEFAULT_CACHE_DIR) { my $cache_dir = '.xslate_cache'; foreach my $d($ENV{HOME}, File::Spec->tmpdir) { if(defined($d) and -d $d and -w _) { $cache_dir = File::Spec->catfile($d, '.xslate_cache'); last; } } $DEFAULT_CACHE_DIR = $cache_dir; } # the real defaults are defined in the parser my %parser_option = ( line_start => undef, tag_start => undef, tag_end => undef, ); # the real defaults are defined in the compiler my %compiler_option = ( syntax => undef, type => undef, header => undef, # template augment footer => undef, # template augment macro => undef, # template augment ); my %builtin = ( html_escape => \&Text::Xslate::Util::html_escape, mark_raw => \&Text::Xslate::Util::mark_raw, unmark_raw => \&Text::Xslate::Util::unmark_raw, uri_escape => \&Text::Xslate::Util::uri_escape, is_array_ref => \&Text::Xslate::Util::is_array_ref, is_hash_ref => \&Text::Xslate::Util::is_hash_ref, dump => \&Text::Xslate::Util::dump, # aliases raw => 'mark_raw', html => 'html_escape', uri => 'uri_escape', ); sub default_functions { +{} } # overridable sub parser_option { # overridable return \%parser_option; } sub compiler_option { # overridable return \%compiler_option; } sub replace_option_value_for_magic_token { # overridable #my($self, $name, $value) = @_; #$value; return $_[2]; } sub options { # overridable my($self) = @_; return { # name => default suffix => '.tx', path => ['.'], input_layer => $self->input_layer, cache => 1, # 0: not cached, 1: checks mtime, 2: always cached cache_dir => $DEFAULT_CACHE_DIR, module => undef, function => undef, html_builder_module => undef, compiler => 'Text::Xslate::Compiler', verbose => 1, warn_handler => undef, die_handler => undef, pre_process_handler => undef, %{ $self->parser_option }, %{ $self->compiler_option }, }; } sub new { my $class = shift; my %args = (@_ == 1 ? %{$_[0]} : @_); my $options = $class->options; my $used = 0; my $nargs = scalar keys %args; foreach my $key(keys %{$options}) { if(exists $args{$key}) { $used++; } elsif(defined($options->{$key})) { $args{$key} = $options->{$key}; } } if($used != $nargs) { my @unknowns = sort grep { !exists $options->{$_} } keys %args; warnings::warnif(misc => "$class: Unknown option(s): " . join ' ', @unknowns); } $args{path} = [ map { ref($_) ? $_ : File::Spec->rel2abs($_) } ref($args{path}) eq 'ARRAY' ? @{$args{path}} : $args{path} ]; my $arg_function= $args{function}; my %funcs; $args{function} = \%funcs; $args{template} = {}; # template structures my $self = bless \%args, $class; # definition of functions and methods # builtin functions %funcs = %builtin; $self->_register_builtin_methods(\%funcs); # per-class functions $self->_merge_hash(\%funcs, $class->default_functions()); # user-defined functions if(defined $args{module}) { $self->_merge_hash(\%funcs, Text::Xslate::Util::import_from(@{$args{module}})); } # user-defined html builder functions if(defined $args{html_builder_module}) { my $raw = Text::Xslate::Util::import_from(@{$args{html_builder_module}}); my $html_builders = +{ map { ($_ => &Text::Xslate::Util::html_builder($raw->{$_})) } keys %$raw }; $self->_merge_hash(\%funcs, $html_builders); } $self->_merge_hash(\%funcs, $arg_function); $self->_resolve_function_aliases(\%funcs); return $self; } sub _merge_hash { my($self, $base, $add) = @_; foreach my $name(keys %{$add}) { $base->{$name} = $add->{$name}; } return; } sub _resolve_function_aliases { my($self, $funcs) = @_; foreach my $f(values %{$funcs}) { my %seen; # to avoid infinite loops while(!( ref($f) or Scalar::Util::looks_like_number($f) )) { my $v = $funcs->{$f} or $self->_error( "Cannot resolve a function alias '$f'," . " which refers nothing", ); if( ref($v) or Scalar::Util::looks_like_number($v) ) { $f = $v; last; } else { $seen{$v}++ and $self->_error( "Cannot resolve a function alias '$f'," . " which makes circular references", ); } } } return; } sub load_string { # called in render_string() my($self, $string) = @_; if(not defined $string) { $self->_error("LoadError: Template string is not given"); } $self->note(' _load_string: %s', join '\n', split /\n/, $string) if _DUMP_LOAD; $self->{source}{''} = $string if _SAVE_SRC; $self->{string_buffer} = $string; my $asm = $self->compile($string); $self->_assemble($asm, '', \$string, undef, undef); return $asm; } my $updir = File::Spec->updir; sub find_file { my($self, $file) = @_; if($file =~ /\Q$updir\E/xmso) { $self->_error("LoadError: Forbidden component (updir: '$updir') found in file name '$file'"); } my $fullpath; my $cachepath; my $orig_mtime; my $cache_mtime; foreach my $p(@{$self->{path}}) { $self->note(" find_file: %s in %s ...\n", $file, $p) if _DUMP_LOAD; my $cache_prefix; if(ref $p eq 'HASH') { # virtual path defined(my $content = $p->{$file}) or next; $fullpath = \$content; # NOTE: # Because contents of virtual paths include their digest, # time-dependent cache verifier makes no sense. $orig_mtime = 0; $cache_mtime = 0; $cache_prefix = 'HASH'; } else { $fullpath = File::Spec->catfile($p, $file); defined($orig_mtime = (stat($fullpath))[_ST_MTIME]) or next; $cache_prefix = Text::Xslate::uri_escape($p); if (length $cache_prefix > 127) { # some filesystems refuse a path part with length > 127 $cache_prefix = $self->_digest($cache_prefix); } } # $file is found $cachepath = File::Spec->catfile( $self->{cache_dir}, $cache_prefix, $file . 'c', ); # stat() will be failed if the cache doesn't exist $cache_mtime = (stat($cachepath))[_ST_MTIME]; last; } if(not defined $orig_mtime) { $self->_error("LoadError: Cannot find '$file' (path: @{$self->{path}})"); } $self->note(" find_file: %s (mtime=%d)\n", $fullpath, $cache_mtime || 0) if _DUMP_LOAD; return { name => ref($fullpath) ? $file : $fullpath, fullpath => $fullpath, cachepath => $cachepath, orig_mtime => $orig_mtime, cache_mtime => $cache_mtime, }; } sub load_file { my($self, $file, $mtime, $omit_augment) = @_; local $self->{omit_augment} = $omit_augment; $self->note("%s->load_file(%s)\n", $self, $file) if _DUMP_LOAD; if($file eq '') { # simply reload it return $self->load_string($self->{string_buffer}); } my $fi = $self->find_file($file); my $asm = $self->_load_compiled($fi, $mtime) || $self->_load_source($fi, $mtime); # $cache_mtime is undef : uses caches without any checks # $cache_mtime > 0 : uses caches with mtime checks # $cache_mtime == 0 : doesn't use caches my $cache_mtime; if($self->{cache} < 2) { $cache_mtime = $fi->{cache_mtime} || 0; } $self->_assemble($asm, $file, $fi->{fullpath}, $fi->{cachepath}, $cache_mtime); return $asm; } sub slurp_template { my($self, $input_layer, $fullpath) = @_; if (ref $fullpath eq 'SCALAR') { return $$fullpath; } else { open my($source), '<' . $input_layer, $fullpath or $self->_error("LoadError: Cannot open $fullpath for reading: $!"); local $/; return scalar <$source>; } } sub _load_source { my($self, $fi) = @_; my $fullpath = $fi->{fullpath}; my $cachepath = $fi->{cachepath}; $self->note(" _load_source: try %s ...\n", $fullpath) if _DUMP_LOAD; # This routine is called when the cache is no longer valid (or not created yet) # so it should be ensured that the cache, if exists, does not exist if(-e $cachepath) { unlink $cachepath or Carp::carp("Xslate: cannot unlink $cachepath (ignored): $!"); } my $source = $self->slurp_template($self->input_layer, $fullpath); $source = $self->{pre_process_handler}->($source) if $self->{pre_process_handler}; $self->{source}{$fi->{name}} = $source if _SAVE_SRC; my $asm = $self->compile($source, file => $fullpath, name => $fi->{name}, ); if($self->{cache} >= 1) { my($volume, $dir) = File::Spec->splitpath($fi->{cachepath}); my $cachedir = File::Spec->catpath($volume, $dir, ''); if(not -e $cachedir) { require File::Path; File::Path::mkpath($cachedir); if (! -e $cachedir) { Carp::croak("Xslate: Cannot prepare cache directory $cachepath (ignored): $@"); } } my $tmpfile = sprintf('%s.%d.%d', $cachepath, $$, Scalar::Util::refaddr($self)); if (open my($out), ">:raw", $tmpfile) { my $mtime = $self->_save_compiled($out, $asm, $fullpath, utf8::is_utf8($source)); if(!close $out) { Carp::carp("Xslate: Cannot close $cachepath (ignored): $!"); unlink $tmpfile; } elsif (rename($tmpfile => $cachepath)) { # set the newest mtime of all the related files to cache mtime if (not ref $fullpath) { my $main_mtime = (stat $fullpath)[_ST_MTIME]; if (defined($main_mtime) && $main_mtime > $mtime) { $mtime = $main_mtime; } utime $mtime, $mtime, $cachepath; $fi->{cache_mtime} = $mtime; } else { $fi->{cache_mtime} = (stat $cachepath)[_ST_MTIME]; } } else { Carp::carp("Xslate: Cannot rename cache file $cachepath (ignored): $!"); unlink $tmpfile; } } else { Carp::carp("Xslate: Cannot open $cachepath for writing (ignored): $!"); } } if(_DUMP_LOAD) { $self->note(" _load_source: cache(mtime=%s)\n", defined $fi->{cache_mtime} ? $fi->{cache_mtime} : 'undef'); } return $asm; } # load compiled templates if they are fresh enough sub _load_compiled { my($self, $fi, $threshold) = @_; if($self->{cache} >= 2) { # threshold is the most latest modified time of all the related caches, # so if the cache level >= 2, they seems always fresh. $threshold = 9**9**9; # force to purge the cache } else { $threshold ||= $fi->{cache_mtime}; } # see also tx_load_template() in xs/Text-Xslate.xs if(!( defined($fi->{cache_mtime}) and $self->{cache} >= 1 and $threshold >= $fi->{orig_mtime} )) { $self->note( " _load_compiled: no fresh cache: %s, %s", $threshold || 0, Text::Xslate::Util::p($fi) ) if _DUMP_LOAD; $fi->{cache_mtime} = undef; return undef; } my $cachepath = $fi->{cachepath}; open my($in), '<:raw', $cachepath or $self->_error("LoadError: Cannot open $cachepath for reading: $!"); my $magic = $self->_magic_token($fi->{fullpath}); my $data; read $in, $data, length($magic); if($data ne $magic) { return undef; } else { local $/; $data = <$in>; close $in; } my $unpacker = Data::MessagePack::Unpacker->new(); my $offset = $unpacker->execute($data); my $is_utf8 = $unpacker->data(); $unpacker->reset(); $unpacker->utf8($is_utf8); my @asm; if($is_utf8) { # TODO: move to XS? my $seed = ""; utf8::upgrade($seed); push @asm, ['print_raw_s', $seed, __LINE__, __FILE__]; } while($offset < length($data)) { $offset = $unpacker->execute($data, $offset); my $c = $unpacker->data(); $unpacker->reset(); # my($name, $arg, $line, $file, $symbol) = @{$c}; if($c->[0] eq 'depend') { my $dep_mtime = (stat $c->[1])[_ST_MTIME]; if(!defined $dep_mtime) { Carp::carp("Xslate: Failed to stat $c->[1] (ignored): $!"); return undef; # purge the cache } if($dep_mtime > $threshold){ $self->note(" _load_compiled: %s(%s) is newer than %s(%s)\n", $c->[1], scalar localtime($dep_mtime), $cachepath, scalar localtime($threshold) ) if _DUMP_LOAD; return undef; # purge the cache } } elsif($c->[0] eq 'literal') { # force upgrade to avoid UTF-8 key issues utf8::upgrade($c->[1]) if($is_utf8); } push @asm, $c; } if(_DUMP_LOAD) { $self->note(" _load_compiled: cache(mtime=%s)\n", defined $fi->{cache_mtime} ? $fi->{cache_mtime} : 'undef'); } return \@asm; } sub _save_compiled { my($self, $out, $asm, $fullpath, $is_utf8) = @_; my $mp = Data::MessagePack->new(); local $\; print $out $self->_magic_token($fullpath); print $out $mp->pack($is_utf8 ? 1 : 0); my $newest_mtime = 0; foreach my $c(@{$asm}) { print $out $mp->pack($c); if ($c->[0] eq 'depend') { my $dep_mtime = (stat $c->[1])[_ST_MTIME]; if ($newest_mtime < $dep_mtime) { $newest_mtime = $dep_mtime; } } } return $newest_mtime; } sub _magic_token { my($self, $fullpath) = @_; $self->{serial_opt} ||= Data::MessagePack->pack([ ref($self->{compiler}) || $self->{compiler}, $self->_filter_options_for_magic_token($self->_extract_options($self->parser_option)), $self->_filter_options_for_magic_token($self->_extract_options($self->compiler_option)), $self->input_layer, [sort keys %{ $self->{function} }], ]); if(ref $fullpath) { # ref to content string $fullpath = join ':', ref($fullpath), $self->_digest(${$fullpath}); } return sprintf $XSLATE_MAGIC, $fullpath, $self->{serial_opt}; } sub _digest { my($self, $content) = @_; require 'Digest/MD5.pm'; # we don't want to create its namespace my $md5 = Digest::MD5->new(); utf8::encode($content); $md5->add($content); return $md5->hexdigest(); } sub _extract_options { my($self, $opt_ref) = @_; my @options; foreach my $name(sort keys %{$opt_ref}) { if(exists $self->{$name}) { push @options, $name => $self->{$name}; } } return @options; } sub _filter_options_for_magic_token { my($self, @options) = @_; my @filterd_options; while (@options) { my $name = shift @options; my $value = $self->replace_option_value_for_magic_token($name, shift @options); push(@filterd_options, $name => $value); } @filterd_options; } sub _compiler { my($self) = @_; my $compiler = $self->{compiler}; if(!ref $compiler){ require Mouse; Mouse::load_class($compiler); my $input_layer = $self->input_layer; $compiler = $compiler->new( engine => $self, input_layer => $input_layer, $self->_extract_options($self->compiler_option), parser_option => { input_layer => $input_layer, $self->_extract_options($self->parser_option), }, ); $compiler->define_function(keys %{ $self->{function} }); $self->{compiler} = $compiler; } return $compiler; } sub compile { my $self = shift; return $self->_compiler->compile(@_, omit_augment => $self->{omit_augment}); } sub _error { die make_error(@_); } sub note { my($self, @args) = @_; printf STDERR @args; } package Text::Xslate; 1; __END__ =for stopwords sandboxing vs metacharacters name-coderef html xml cb tx TTerse HTML xslate HTMLTemplate gardejo jjn1056 clouder chiba turugina cho45 shmorimo ueda punytan =head1 NAME Text::Xslate - Scalable template engine for Perl5 =head1 VERSION This document describes Text::Xslate version v3.5.6. =head1 SYNOPSIS use Text::Xslate qw(mark_raw); my $tx = Text::Xslate->new(); my %vars = ( title => 'A list of books', books => [ { title => 'Islands in the stream' }, { title => 'Programming Perl' }, # ... ], # mark HTML components as raw not to escape its HTML tags gadget => mark_raw('
...
'), ); # for files print $tx->render('hello.tx', \%vars); # for strings (easy but slow) my $template = q{

<: $title :>

    : for $books -> $book {
  • <: $book.title :>
  • : } # for
}; print $tx->render_string($template, \%vars); =head1 DESCRIPTION B is a template engine, tuned for persistent applications, safe as an HTML generator, and with rich features. There are a lot of template engines in CPAN, for example Template-Toolkit, Text::MicroTemplate, HTML::Template, and so on, but all of them have some weak points: a full-featured template engine may be slow, while a fast template engine may be too simple to use. This is why Xslate is developed, which is the best template engine for web applications. The concept of Xslate is strongly influenced by Text::MicroTemplate and Template-Toolkit 2, but the central philosophy of Xslate is different from them. That is, the philosophy is B that the template logic should not have no access outside the template beyond your permission. Other remarkable features are as follows: =head2 Features =head3 High performance This engine introduces the virtual machine paradigm. Templates are compiled into intermediate code, and then executed by the virtual machine, which is highly optimized for rendering templates. Thus, Xslate is much faster than any other template engines. The template roundup project by Sam Graham shows Text::Xslate got amazingly high scores in I condition (i.e. for persistent applications). =over =item The template roundup project L =item Perl Template Roundup October 2010 Performance vs Variant Report: instance_reuse L =back There are also benchmarks in F directory in the Xslate distribution. =head3 Smart escaping for HTML metacharacters Xslate employs the B, where a template engine escapes all the HTML metacharacters in template expressions unless users mark values as B. That is, the output is unlikely to prone to XSS. =head3 Template cascading Xslate supports the B