@@ -1,5 +1,13 @@
Revision history for Template-Mustache
+v0.5.2 2015-06-12
+
+ don't use length(@arr) when scalar(@arr) is meant!
+
+ use tr/// for counting, not split
+
+ don't die if provided context object is a non-object ref
+
v0.5.1 2011-02-13
Updating dependency on Test::Mini::Unit. Solves build problems on Perl
5.13+.
@@ -1,14 +1,5 @@
benchmark.pl
Changes
-ext/spec/README.md
-ext/spec/specs/comments.yml
-ext/spec/specs/delimiters.yml
-ext/spec/specs/interpolation.yml
-ext/spec/specs/inverted.yml
-ext/spec/specs/partials.yml
-ext/spec/specs/sections.yml
-ext/spec/specs/~lambdas.yml
-ext/spec/TESTING.md
lib/Template/Mustache.pm
Makefile.PL
MANIFEST This list of files
@@ -27,5 +18,5 @@ t/read_partials_from_subs.t
t/read_templates_from_file_system.t
t/read_templates_from_file_system_with_namespacing.t
t/read_templates_from_subclass.t
-META.yml Module meta-data (added by MakeMaker)
-lib/Template/Mustache.pod
+META.yml Module YAML meta-data (added by MakeMaker)
+META.json Module JSON meta-data (added by MakeMaker)
@@ -0,0 +1,52 @@
+{
+ "abstract" : "Drawing Mustaches on Perl for fun and profit",
+ "author" : [
+ "Pieter van de Bruggen <pvande@cpan.org>"
+ ],
+ "dynamic_config" : 1,
+ "generated_by" : "ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.150001",
+ "license" : [
+ "perl_5"
+ ],
+ "meta-spec" : {
+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+ "version" : "2"
+ },
+ "name" : "Template-Mustache",
+ "no_index" : {
+ "directory" : [
+ "t",
+ "inc"
+ ]
+ },
+ "prereqs" : {
+ "build" : {
+ "requires" : {
+ "Test::Mini::Unit" : "v1.0.3",
+ "YAML::Syck" : "1.15"
+ }
+ },
+ "configure" : {
+ "requires" : {
+ "ExtUtils::MakeMaker" : "6.31",
+ "ExtUtils::Manifest" : "1.56"
+ }
+ },
+ "runtime" : {
+ "requires" : {
+ "version" : "0.77"
+ }
+ }
+ },
+ "release_status" : "stable",
+ "resources" : {
+ "bugtracker" : {
+ "web" : "https://github.com/pvande/Template-Mustache/issues"
+ },
+ "homepage" : "https://github.com/pvande/Template-Mustache",
+ "repository" : {
+ "url" : "git://github.com/pvande/Template-Mustache.git"
+ }
+ },
+ "version" : "v0.5.2"
+}
@@ -1,29 +1,28 @@
---- #YAML:1.0
-name: Template-Mustache
-version: v0.5.1
-abstract: Drawing Mustaches on Perl for fun and profit
+---
+abstract: 'Drawing Mustaches on Perl for fun and profit'
author:
- - Pieter van de Bruggen <pvande@cpan.org>
-license: perl
-distribution_type: module
-configure_requires:
- ExtUtils::MakeMaker: 6.31
- ExtUtils::Manifest: 1.56
+ - 'Pieter van de Bruggen <pvande@cpan.org>'
build_requires:
- ExtUtils::MakeMaker: 0
+ Test::Mini::Unit: v1.0.3
+ YAML::Syck: '1.15'
+configure_requires:
+ ExtUtils::MakeMaker: '6.31'
+ ExtUtils::Manifest: '1.56'
+dynamic_config: 1
+generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.150001'
+license: perl
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
+ version: '1.4'
+name: Template-Mustache
+no_index:
+ directory:
+ - t
+ - inc
requires:
- Test::Mini::Unit: v1.0.3
- version: 0.77
- YAML::Syck: 1.15
+ version: '0.77'
resources:
- bugtracker: https://github.com/pvande/Template-Mustache/issues
- homepage: https://github.com/pvande/Template-Mustache
- repository: git://github.com/pvande/Template-Mustache.git
-no_index:
- directory:
- - t
- - inc
-generated_by: ExtUtils::MakeMaker version 6.55_02
-meta-spec:
- url: http://module-build.sourceforge.net/META-spec-v1.4.html
- version: 1.4
+ bugtracker: https://github.com/pvande/Template-Mustache/issues
+ homepage: https://github.com/pvande/Template-Mustache
+ repository: git://github.com/pvande/Template-Mustache.git
+version: v0.5.2
@@ -12,7 +12,7 @@ SKIP
my %WriteMakefileArgs = (
'NAME' => 'Template::Mustache',
'ABSTRACT' => 'Drawing Mustaches on Perl for fun and profit',
- 'VERSION' => 'v0.5.1',
+ 'VERSION' => 'v0.5.2',
'AUTHOR' => 'Pieter van de Bruggen <pvande@cpan.org>',
'LICENSE' => 'perl',
'META_MERGE' => {
@@ -1,30 +0,0 @@
-This repository acts as an attempt at specifying both standard- and edge-case
-behavior for libraries parsing Mustache (or a superset thereof). Early
-development will focus on describing idealized output, with later work being
-done to normalize expectations. *It is not expected that any implementation
-support any draft prior to v1.0.0.*
-
-Optional Modules
-----------------
-
-Specification files beginning with a tilde (~) describe optional modules. At
-present, the only module being described as optional is regarding support for
-lambdas. As a guideline, a module may be a candidate for optionality when:
-
- * It does not affect the core syntax of the language.
- * It does not significantly affect the output of rendered templates.
- * It concerns implementation language features or data types that are not
- common to or core in every targeted language.
- * The lack of support by an implementation does not diminish the usage of
- Mustache in the target language.
-
-As an example, the lambda module is primarily concerned with the handling of a
-particular data type (code). This is a type of data that may be difficult to
-support in some languages, and users of those languages will not see the lack
-as an 'inconsistency' between implementations.
-
-Support for specific pragmas or syntax extensions, however, are best managed
-outside this core specification, as adjunct specifications.
-
-Implementors are strongly encouraged to support any and all modules they are
-reasonably capable of supporting.
@@ -1,43 +0,0 @@
-Testing your Mustache implementation against this specification should be
-relatively simple. If you have a readily available testing framework on your
-platform, your task may be even simpler.
-
-In general, the process for each `.yml` file is as follows:
-
-1. Use a YAML parser to load the file.
-
-2. For each test in the 'tests' array:
-
- 1. Ensure that each element of the 'partials' hash (if it exists) is
- stored in a place where the interpreter will look for it.
-
- 2. If your implementation will not support lambdas, feel free to skip over
- the optional '~lambdas.yml' file.
-
- 2.1. If your implementation will support lambdas, ensure that each member of
- 'data' tagged with '!code' is properly processed into a language-
- specific lambda reference.
-
- * e.g. Given this YAML data hash:
-
- `{ x: !code { ruby: 'proc { "x" }', perl: 'sub { "x" }' } }`
-
- a Ruby-based Mustache implementation would process it such that it
- was equivalent to this Ruby hash:
-
- `{ 'x' => proc { "x" } }`
-
- * If your implementation language does not currently have lambda
- examples in the spec, feel free to implement them and send a pull
- request.
-
- 3. Render the template (stored in the 'template' key) with the given 'data'
- hash.
-
- 4. Compare the results of your rendering against the 'expected' value; any
- differences should be reported, along with any useful debugging
- information.
-
- * Of note, the 'desc' key contains a rough one-line description of the
- behavior being tested -- this is most useful in conjunction with the
- file name and test 'name'.
@@ -1,77 +0,0 @@
-tests:
- - name: Inline
- desc: Comment blocks should be removed from the template.
- data: { }
- template: '12345{{! Comment Block! }}67890'
- expected: '1234567890'
-
- - name: Multiline
- desc: Multiline comments should be permitted.
- data: { }
- template: |
- 12345{{!
- This is a
- multi-line comment...
- }}67890
- expected: |
- 1234567890
-
- - name: Standalone
- desc: All standalone comment lines should be removed.
- data: { }
- template: |
- Begin.
- {{! Comment Block! }}
- End.
- expected: |
- Begin.
- End.
-
- - name: Indented Standalone
- desc: All standalone comment lines should be removed.
- data: { }
- template: |
- Begin.
- {{! Indented Comment Block! }}
- End.
- expected: |
- Begin.
- End.
-
- - name: Multiline Standalone
- desc: All standalone comment lines should be removed.
- data: { }
- template: |
- Begin.
- {{!
- Something's going on here...
- }}
- End.
- expected: |
- Begin.
- End.
-
- - name: Indented Multiline Standalone
- desc: All standalone comment lines should be removed.
- data: { }
- template: |
- Begin.
- {{!
- Something's going on here...
- }}
- End.
- expected: |
- Begin.
- End.
-
- - name: Indented Inline
- desc: Inline comments should not strip whitespace
- data: { }
- template: " 12 {{! 34 }}\n"
- expected: " 12 \n"
-
- - name: Surrounding Whitespace
- desc: Comment removal should preserve surrounding whitespace.
- data: { }
- template: '12345 {{! Comment Block! }} 67890'
- expected: '12345 67890'
@@ -1,131 +0,0 @@
-tests:
- - name: Pair Behavior
- desc: The equals sign (used on both sides) should permit delimiter changes.
- data: { text: 'Hey!' }
- template: '{{=<% %>=}}(<%text%>)'
- expected: '(Hey!)'
-
- - name: Special Characters
- desc: Characters with special meaning regexen should be valid delimiters.
- data: { text: 'It worked!' }
- template: '({{=[ ]=}}[text])'
- expected: '(It worked!)'
-
- - name: Sections
- desc: Delimiters set outside sections should persist.
- data: { section: true, data: 'I got interpolated.' }
- template: |
- [
- {{#section}}
- {{data}}
- |data|
- {{/section}}
-
- {{= | | =}}
- |#section|
- {{data}}
- |data|
- |/section|
- ]
- expected: |
- [
- I got interpolated.
- |data|
-
- {{data}}
- I got interpolated.
- ]
-
- - name: Inverted Sections
- desc: Delimiters set outside inverted sections should persist.
- data: { section: false, data: 'I got interpolated.' }
- template: |
- [
- {{^section}}
- {{data}}
- |data|
- {{/section}}
-
- {{= | | =}}
- |^section|
- {{data}}
- |data|
- |/section|
- ]
- expected: |
- [
- I got interpolated.
- |data|
-
- {{data}}
- I got interpolated.
- ]
-
- - name: Partial Inheritence
- desc: Delimiters set in a parent template should not affect a partial.
- data: { value: 'yes' }
- partials:
- include: '.{{value}}.'
- template: |
- [ {{>include}} ]
- {{= | | =}}
- [ |>include| ]
- expected: |
- [ .yes. ]
- [ .yes. ]
-
- - name: Post-Partial Behavior
- desc: Delimiters set in a partial should not affect the parent template.
- data: { value: 'yes' }
- partials:
- include: '.{{value}}. {{= | | =}} .|value|.'
- template: |
- [ {{>include}} ]
- [ .{{value}}. .|value|. ]
- expected: |
- [ .yes. .yes. ]
- [ .yes. .|value|. ]
-
- # Whitespace Sensitivity
-
- - name: Surrounding Whitespace
- desc: Surrounding whitespace should be left untouched.
- data: { }
- template: '| {{=@ @=}} |'
- expected: '| |'
-
- - name: Outlying Whitespace (Inline)
- desc: Whitespace should be left untouched.
- data: { }
- template: " | {{=@ @=}}\n"
- expected: " | \n"
-
- - name: Standalone Tag
- desc: Standalone lines should be removed from the template.
- data: { }
- template: |
- Begin.
- {{=@ @=}}
- End.
- expected: |
- Begin.
- End.
-
- - name: Indented Standalone Tag
- desc: Indented standalone lines should be removed from the template.
- data: { }
- template: |
- Begin.
- {{=@ @=}}
- End.
- expected: |
- Begin.
- End.
-
- # Whitespace Insensitivity
-
- - name: Pair with Padding
- desc: Superfluous in-tag whitespace should be ignored.
- data: { }
- template: '|{{= @ @ =}}|'
- expected: '||'
@@ -1,134 +0,0 @@
-tests:
- - name: No Interpolation
- desc: Mustache-free templates should render as-is.
- data: { }
- template: |
- Hello from {Mustache}!
- expected: |
- Hello from {Mustache}!
-
- - name: Basic Interpolation
- desc: Unadorned tags should interpolate content into the template.
- data: { subject: "world" }
- template: |
- Hello, {{subject}}!
- expected: |
- Hello, world!
-
- - name: HTML Escaping
- desc: Basic interpolation should be HTML escaped.
- data: { forbidden: '& " < >' }
- template: |
- These characters should be HTML escaped: {{forbidden}}
- expected: |
- These characters should be HTML escaped: & " < >
-
- - name: Triple Mustache
- desc: Triple mustaches should interpolate without HTML escaping.
- data: { forbidden: '& " < >' }
- template: |
- These characters should not be HTML escaped: {{{forbidden}}}
- expected: |
- These characters should not be HTML escaped: & " < >
-
- - name: Ampersand
- desc: Ampersand should interpolate without HTML escaping.
- data: { forbidden: '& " < >' }
- template: |
- These characters should not be HTML escaped: {{&forbidden}}
- expected: |
- These characters should not be HTML escaped: & " < >
-
- - name: Basic Integer Interpolation
- desc: Integers should interpolate seamlessly.
- data: { mph: 85 }
- template: '"{{mph}} miles an hour!"'
- expected: '"85 miles an hour!"'
-
- - name: Triple Mustache Integer Interpolation
- desc: Integers should interpolate seamlessly.
- data: { mph: 85 }
- template: '"{{{mph}}} miles an hour!"'
- expected: '"85 miles an hour!"'
-
- - name: Ampersand Integer Interpolation
- desc: Integers should interpolate seamlessly.
- data: { mph: 85 }
- template: '"{{&mph}} miles an hour!"'
- expected: '"85 miles an hour!"'
-
- - name: Basic Decimal Interpolation
- desc: Decimals should interpolate seamlessly with proper significance.
- data: { power: 1.210 }
- template: '"{{power}} jiggawatts!"'
- expected: '"1.21 jiggawatts!"'
-
- - name: Triple Mustache Decimal Interpolation
- desc: Decimals should interpolate seamlessly with proper significance.
- data: { power: 1.210 }
- template: '"{{{power}}} jiggawatts!"'
- expected: '"1.21 jiggawatts!"'
-
- - name: Ampersand Decimal Interpolation
- desc: Decimals should interpolate seamlessly with proper significance.
- data: { power: 1.210 }
- template: '"{{&power}} jiggawatts!"'
- expected: '"1.21 jiggawatts!"'
-
- # Whitespace Sensitivity
-
- - name: Interpolation - Surrounding Whitespace
- desc: Interpolation should not alter surrounding whitespace.
- data: { string: '---' }
- template: '| {{string}} |'
- expected: '| --- |'
-
- - name: Triple Mustache - Surrounding Whitespace
- desc: Interpolation should not alter surrounding whitespace.
- data: { string: '---' }
- template: '| {{{string}}} |'
- expected: '| --- |'
-
- - name: Ampersand - Surrounding Whitespace
- desc: Interpolation should not alter surrounding whitespace.
- data: { string: '---' }
- template: '| {{&string}} |'
- expected: '| --- |'
-
- - name: Interpolation - Standalone
- desc: Standalone interpolation should not alter surrounding whitespace.
- data: { string: '---' }
- template: " {{string}}\n"
- expected: " ---\n"
-
- - name: Triple Mustache - Standalone
- desc: Standalone interpolation should not alter surrounding whitespace.
- data: { string: '---' }
- template: " {{{string}}}\n"
- expected: " ---\n"
-
- - name: Ampersand - Standalone
- desc: Standalone interpolation should not alter surrounding whitespace.
- data: { string: '---' }
- template: " {{&string}}\n"
- expected: " ---\n"
-
- # Whitespace Insensitivity
-
- - name: Interpolation With Padding
- desc: Superfluous in-tag whitespace should be ignored.
- data: { string: "---" }
- template: '|{{ string }}|'
- expected: '|---|'
-
- - name: Triple Mustache With Padding
- desc: Superfluous in-tag whitespace should be ignored.
- data: { string: "---" }
- template: '|{{{ string }}}|'
- expected: '|---|'
-
- - name: Ampersand With Padding
- desc: Superfluous in-tag whitespace should be ignored.
- data: { string: "---" }
- template: '|{{& string }}|'
- expected: '|---|'
@@ -1,108 +0,0 @@
-tests:
- - name: Falsey
- desc: Falsey sections should have their contents rendered.
- data: { boolean: false }
- template: '"{{^boolean}}This should be rendered.{{/boolean}}"'
- expected: '"This should be rendered."'
-
- - name: Truthy
- desc: Truthy sections should have their contents omitted.
- data: { boolean: true }
- template: '"{{^boolean}}This should not be rendered.{{/boolean}}"'
- expected: '""'
-
- - name: Context
- desc: Objects and hashes should behave like truthy values.
- data: { context: { name: 'Joe' } }
- template: '"{{^context}}Hi {{name}}.{{/context}}"'
- expected: '""'
-
- - name: List
- desc: Lists should behave like truthy values.
- data: { list: [ { n: 1 }, { n: 2 }, { n: 3 } ] }
- template: '"{{^list}}{{n}}{{/list}}"'
- expected: '""'
-
- - name: Empty List
- desc: Empty lists should behave like falsey values.
- data: { list: [ ] }
- template: '"{{^list}}Yay lists!{{/list}}"'
- expected: '"Yay lists!"'
-
- - name: Doubled
- desc: Multiple inverted sections per template should be permitted.
- data: { t: false, two: 'second' }
- template: |
- {{^t}}
- * first
- {{/t}}
- * {{two}}
- {{^t}}
- * third
- {{/t}}
- expected: |
- * first
- * second
- * third
-
- - name: Nested (Falsey)
- desc: Nested falsey sections should have their contents rendered.
- data: { t: false }
- template: "| A {{^t}}B {{^t}}C{{/t}} D{{/t}} E |"
- expected: "| A B C D E |"
-
- - name: Nested (Truthy)
- desc: Nested truthy sections should be omitted.
- data: { t: true }
- template: "| A {{^t}}B {{^t}}C{{/t}} D{{/t}} E |"
- expected: "| A E |"
-
- # Whitespace Sensitivity
-
- - name: Surrounding Whitespace
- desc: Inverted sections should not alter surrounding whitespace.
- data: { boolean: false }
- template: " | {{^boolean}}\t|\t{{/boolean}} | \n"
- expected: " | \t|\t | \n"
-
- - name: Internal Whitespace
- desc: Inverted should not alter internal whitespace.
- data: { boolean: false }
- template: " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
- expected: " | \n | \n"
-
- - name: Standalone Lines
- desc: Standalone lines should be removed from the template.
- data: { boolean: false }
- template: |
- | This Is
- {{^boolean}}
- |
- {{/boolean}}
- | A Line
- expected: |
- | This Is
- |
- | A Line
-
- - name: Standalone Indented Lines
- desc: Standalone indented lines should be removed from the template.
- data: { boolean: false }
- template: |
- | This Is
- {{^boolean}}
- |
- {{/boolean}}
- | A Line
- expected: |
- | This Is
- |
- | A Line
-
- # Whitespace Insensitivity
-
- - name: Padding
- desc: Superfluous in-tag whitespace should be ignored.
- data: { boolean: false }
- template: '|{{^ boolean }}={{/ boolean }}|'
- expected: '|=|'
@@ -1,66 +0,0 @@
-tests:
- - name: Basic Behavior
- desc: The greater-than operator should expand to the named partial.
- data: { }
- template: '"{{>text}}"'
- partials: { text: 'from partial' }
- expected: '"from partial"'
-
- - name: Context
- desc: The greater-than operator should operate within the current context.
- data: { text: 'content' }
- template: '"{{>partial}}"'
- partials: { partial: '*{{text}}*' }
- expected: '"*content*"'
-
- - name: Recursion
- desc: The greater-than operator should properly recurse.
- data: { content: "X", nodes: [ { content: "Y", nodes: [] } ] }
- template: '{{>node}}'
- partials: { node: '{{content}}<{{#nodes}}{{>node}}{{/nodes}}>' }
- expected: 'X<Y<>>'
-
- # Whitespace Sensitivity
-
- - name: Surrounding Whitespace
- desc: The greater-than operator should not alter surrounding whitespace.
- data: { }
- template: '| {{>partial}} |'
- partials: { partial: "\t|\t" }
- expected: "| \t|\t |"
-
- - name: Inline Indentation
- desc: Whitespace should be left untouched.
- data: { data: '|' }
- template: " {{data}} {{> partial}}\n"
- partials: { partial: ">\n>" }
- expected: " | >\n>\n"
-
- - name: Standalone Indentation
- desc: Each line of the partial should be indented before rendering.
- data: { content: "<\n->" }
- template: |
- \
- {{>partial}}
- /
- partials:
- partial: |
- |
- {{{content}}}
- |
- expected: |
- \
- |
- <
- ->
- |
- /
-
- # Whitespace Insensitivity
-
- - name: Padding Whitespace
- desc: Superfluous in-tag whitespace should be ignored.
- data: { boolean: true }
- template: "|{{> partial }}|"
- partials: { partial: "[]" }
- expected: '|[]|'
@@ -1,147 +0,0 @@
-tests:
- - name: Truthy
- desc: Truthy sections should have their contents rendered.
- data: { boolean: true }
- template: '"{{#boolean}}This should be rendered.{{/boolean}}"'
- expected: '"This should be rendered."'
-
- - name: Falsey
- desc: Falsey sections should have their contents omitted.
- data: { boolean: false }
- template: '"{{#boolean}}This should not be rendered.{{/boolean}}"'
- expected: '""'
-
- - name: Context
- desc: Objects and hashes should be pushed onto the context stack.
- data: { context: { name: 'Joe' } }
- template: '"{{#context}}Hi {{name}}.{{/context}}"'
- expected: '"Hi Joe."'
-
- - name: Deeply Nested Contexts
- desc: All elements on the context stack should be accessible.
- data:
- a: { one: 1 }
- b: { two: 2 }
- c: { three: 3 }
- d: { four: 4 }
- e: { five: 5 }
- template: |
- {{#a}}
- {{one}}
- {{#b}}
- {{one}}{{two}}{{one}}
- {{#c}}
- {{one}}{{two}}{{three}}{{two}}{{one}}
- {{#d}}
- {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
- {{#e}}
- {{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}
- {{/e}}
- {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
- {{/d}}
- {{one}}{{two}}{{three}}{{two}}{{one}}
- {{/c}}
- {{one}}{{two}}{{one}}
- {{/b}}
- {{one}}
- {{/a}}
- expected: |
- 1
- 121
- 12321
- 1234321
- 123454321
- 1234321
- 12321
- 121
- 1
-
- - name: List
- desc: Lists should be iterated; list items should visit the context stack.
- data: { list: [ { item: 1 }, { item: 2 }, { item: 3 } ] }
- template: '"{{#list}}{{item}}{{/list}}"'
- expected: '"123"'
-
- - name: Empty List
- desc: Empty lists should behave like falsey values.
- data: { list: [ ] }
- template: '"{{#list}}Yay lists!{{/list}}"'
- expected: '""'
-
- - name: Doubled
- desc: Multiple sections per template should be permitted.
- data: { t: true, two: 'second' }
- template: |
- {{#t}}
- * first
- {{/t}}
- * {{two}}
- {{#t}}
- * third
- {{/t}}
- expected: |
- * first
- * second
- * third
-
- - name: Nested (Truthy)
- desc: Nested truthy sections should have their contents rendered.
- data: { t: true }
- template: "| A {{#t}}B {{#t}}C{{/t}} D{{/t}} E |"
- expected: "| A B C D E |"
-
- - name: Nested (Falsey)
- desc: Nested falsey sections should be omitted.
- data: { t: false }
- template: "| A {{#t}}B {{#t}}C{{/t}} D{{/t}} E |"
- expected: "| A E |"
-
- # Whitespace Sensitivity
-
- - name: Surrounding Whitespace
- desc: Sections should not alter surrounding whitespace.
- data: { boolean: true }
- template: " | {{#boolean}}\t|\t{{/boolean}} | \n"
- expected: " | \t|\t | \n"
-
- - name: Internal Whitespace
- desc: Sections should not alter internal whitespace.
- data: { boolean: true }
- template: " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
- expected: " | \n | \n"
-
- - name: Standalone Lines
- desc: Standalone lines should be removed from the template.
- data: { boolean: true }
- template: |
- | This Is
- {{#boolean}}
- |
- {{/boolean}}
- | A Line
- expected: |
- | This Is
- |
- | A Line
-
- - name: Indented Standalone Lines
- desc: Indented standalone lines should be removed from the template.
- data: { boolean: true }
- template: |
- | This Is
- {{#boolean}}
- |
- {{/boolean}}
- | A Line
- expected: |
- | This Is
- |
- | A Line
-
- # Whitespace Insensitivity
-
- - name: Padding
- desc: Superfluous in-tag whitespace should be ignored.
- data: { boolean: true }
- template: '|{{# boolean }}={{/ boolean }}|'
- expected: '|=|'
@@ -1,106 +0,0 @@
-tests:
- - name: Interpolation
- desc: A lambda's return value should be interpolated.
- data:
- lambda: !code
- ruby: 'proc { "world" }'
- perl: 'sub { "world" }'
- js: 'function() { return "world" }'
- php: 'return "world";'
- template: "Hello, {{lambda}}!"
- expected: "Hello, world!"
-
- - name: Interpolation - Expansion
- desc: A lambda's return value should be parsed.
- data:
- planet: "world"
- lambda: !code
- ruby: 'proc { "{{planet}}" }'
- perl: 'sub { "{{planet}}" }'
- js: 'function() { return "{{planet}}" }'
- php: 'return "{{planet}}";'
- template: "Hello, {{lambda}}!"
- expected: "Hello, world!"
-
- - name: Interpolation - Multiple Calls
- desc: Interpolated lambdas should only be called once.
- data:
- lambda: !code
- ruby: 'proc { $calls ||= 0; $calls += 1 }'
- perl: 'sub { no strict; $calls += 1 }'
- js: 'function() { f = arguments.callee; return f.calls = (f.calls || 0) + 1 }'
- php: 'global $calls; return ++$calls;'
- template: '{{lambda}} == {{{lambda}}} == {{lambda}}'
- expected: '1 == 1 == 1'
-
- - name: Interpolation - Caches
- desc: Lambda caches should not disrupt normal context operations.
- data:
- key: Top
- context:
- key: Under
- lambda: !code
- ruby: 'proc { "Big" }'
- perl: 'sub { "Big" }'
- js: 'function() { return "Big" }'
- php: 'return "Big";'
- template: "{{#context}}{{key}} the {{lambda}}{{/context}} {{key}}"
- expected: "Under the Big Top"
-
- - name: Escaping
- desc: Lambda results should be appropriately escaped.
- data:
- lambda: !code
- ruby: 'proc { ">" }'
- perl: 'sub { ">" }'
- js: 'function() { return ">" }'
- php: 'return ">";'
- template: "<{{lambda}}{{{lambda}}}"
- expected: "<>>"
-
- - name: Section
- desc: Lambdas used for sections should receive the raw section string.
- data:
- x: 'Error!'
- lambda: !code
- ruby: 'proc { |text| text == "{{x}}" ? "yes" : "no" }'
- perl: 'sub { $_[0] eq "{{x}}" ? "yes" : "no" }'
- js: 'function(txt) { return (txt == "{{x}}" ? "yes" : "no") }'
- php: 'return ($text == "{{x}}") ? "yes" : "no";'
- template: "<{{#lambda}}{{x}}{{/lambda}}>"
- expected: "<yes>"
-
- - name: Section - Expansion
- desc: Lambdas used for sections should have their results parsed.
- data:
- planet: "Earth"
- lambda: !code
- ruby: 'proc { |text| "#{text}{{planet}}#{text}" }'
- perl: 'sub { $_[0] . "{{planet}}" . $_[0] }'
- js: 'function(txt) { return txt + "{{planet}}" + txt }'
- php: 'return $text . "{{planet}}" . $text;'
- template: "<{{#lambda}}-{{/lambda}}>"
- expected: "<-Earth->"
-
- - name: Section - Multiple Calls
- desc: Lambdas used for sections should not simply cache the first response.
- data:
- lambda: !code
- ruby: 'proc { |text| "__#{text}__" }'
- perl: 'sub { "__" . $_[0] . "__" }'
- js: 'function(txt) { return "__" + txt + "__" }'
- php: 'return "__" . $text . "__";'
- template: '{{#lambda}}FILE{{/lambda}} != {{#lambda}}LINE{{/lambda}}'
- expected: '__FILE__ != __LINE__'
-
- - name: Inverted Section
- desc: Lambdas used for inverted sections should be considered truthy.
- data:
- static: 'static'
- lambda: !code
- ruby: 'proc { |text| text }'
- perl: 'sub { shift }'
- js: 'function(txt) { return txt }'
- php: 'return $text;'
- template: "<{{^lambda}}{{static}}{{/lambda}}>"
- expected: "<>"
@@ -9,8 +9,9 @@ use warnings;
use CGI ();
use File::Spec;
+use Scalar::Util 'blessed';
-use version 0.77; our $VERSION = qv("v0.5.1");
+use version 0.77; our $VERSION = qv("v0.5.2");
my %TemplateCache;
@@ -84,9 +85,9 @@ sub parse {
my $error = sub {
my ($message, $errorPos) = @_;
- my @lineCount = split("\n", substr($tmpl, 0, $errorPos));
+ my $lineCount = substr($tmpl, 0, $errorPos) =~ tr/\n/\n/;
- die $message . "\nLine " . length(@lineCount);
+ die $message . "\nLine " . $lineCount
};
# Build the pattern, and instruct the regex engine to begin at `$start`.
@@ -275,8 +276,9 @@ sub lookup {
next unless exists $ctx->{$field};
$value = $ctx->{$field};
last;
- } else {
- next unless UNIVERSAL::can($ctx, $field);
+ } elsif ($ctx && (blessed($ctx) || ! ref $ctx) && $ctx->can($field)) {;
+ # We want to accept class names and objects, but not unblessed refs
+ # or undef. -- rjbs, 2015-06-12
$value = $ctx->$field();
last;
}
@@ -1,588 +0,0 @@
-=for comment Documentation generated by YARD v0.6.4 and yard-pod-plugin v0.1.
-
-=head1 NAME
-
-Template::Mustache - Template::Mustache is an implementation of the fabulous Mustache templating
-language for Perl 5.8 and later
-
-=head1 METHODS
-
-=head2 Class Methods
-
-=over
-
-=item B<<<< new >>>>
-
- new($class, %args) # => Template::Mustache
-
-
-Standard hash constructor.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-B<<<<< C<<<< %args >>>> >>>>> -- Initialization data.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< Template::Mustache >>>>) -- A new instance.
-
-
-=back
-
-=item B<<<< partial >>>>
-
- partial($receiver, $name) # => String
-
-
-Reads a named partial off disk.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) B<<<<< C<<<< $name >>>> >>>>> -- The name of the
-partial to lookup.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The contents of the partial (in L<<<< S<<<<<
-template_path >>>>>|template_path >>>>, of type L<<<< S<<<<<
-template_extension >>>>>|template_extension >>>>), or the empty
-string, if the partial does not exist.
-
-
-=back
-
-=item B<<<< render >>>>
-
- render # => String
- render($tmpl) # => String
- render($data) # => String
- render($tmpl, $data) # => String
- render($tmpl, $data, $partials) # => String
- render($tmpl, $data, $partials) # => String
- render($tmpl, $data, $partials) # => String
-
-
-
-
-
-Overloads:
-
-
- render # => String
-
-=over
-
-
-Renders a class or instance's template with data from the receiver. The
-template will be retrieved by calling the L<<<< S<<<<< template
->>>>>|template >>>> method. Partials will be fetched by L<<<< S<<<<<
-partial >>>>>|partial >>>>.
-
-
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
- render($tmpl) # => String
-
-=over
-
-
-Renders the given template with data from the receiver. Partials will
-be fetched by L<<<< S<<<<< partial >>>>>|partial >>>>.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) B<<<<< C<<<< $tmpl >>>> >>>>> -- The template to
-render.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
- render($data) # => String
-
-=over
-
-
-Renders a class or instance's template with data from the receiver. The
-template will be retrieved by calling the L<<<< S<<<<< template
->>>>>|template >>>> method. Partials will be fetched by L<<<< S<<<<<
-partial >>>>>|partial >>>>.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< Hash, Object >>>>) B<<<<< C<<<< $data >>>> >>>>> -- Data to
-be interpolated into the template.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
- render($tmpl, $data) # => String
-
-=over
-
-
-Renders the given template with the given data. Partials will be
-fetched by L<<<< S<<<<< partial >>>>>|partial >>>>.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) B<<<<< C<<<< $tmpl >>>> >>>>> -- The template to
-render.
-
-
-=item *
-
-(I<<<< Hash, Class, Object >>>>) B<<<<< C<<<< $data >>>> >>>>> --
-Data to be interpolated into the template.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
- render($tmpl, $data, $partials) # => String
-
-=over
-
-
-Renders the given template with the given data. Partials will be looked
-up by calling the given code reference with the partial's name.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) B<<<<< C<<<< $tmpl >>>> >>>>> -- The template to
-render.
-
-
-=item *
-
-(I<<<< Hash, Class, Object >>>>) B<<<<< C<<<< $data >>>> >>>>> --
-Data to be interpolated into the template.
-
-
-=item *
-
-(I<<<< Code >>>>) B<<<<< C<<<< $partials >>>> >>>>> -- A function
-used to lookup partials.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
- render($tmpl, $data, $partials) # => String
-
-=over
-
-
-Renders the given template with the given data. Partials will be looked
-up by calling the partial's name as a method on the given class or
-object.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) B<<<<< C<<<< $tmpl >>>> >>>>> -- The template to
-render.
-
-
-=item *
-
-(I<<<< Hash, Class, Object >>>>) B<<<<< C<<<< $data >>>> >>>>> --
-Data to be interpolated into the template.
-
-
-=item *
-
-(I<<<< Class, Object >>>>) B<<<<< C<<<< $partials >>>> >>>>> -- A
-thing that responds to partial names.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
- render($tmpl, $data, $partials) # => String
-
-=over
-
-
-Renders the given template with the given data. Partials will be looked
-up in the given hash.
-
-
-
-Parameters:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) B<<<<< C<<<< $tmpl >>>> >>>>> -- The template to
-render.
-
-
-=item *
-
-(I<<<< Hash, Class, Object >>>>) B<<<<< C<<<< $data >>>> >>>>> --
-Data to be interpolated into the template.
-
-
-=item *
-
-(I<<<< Hash >>>>) B<<<<< C<<<< $partials >>>> >>>>> -- A hash
-containing partials.
-
-
-=back
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The fully rendered template.
-
-
-=back
-
-
-
-
-=back
-
-=item B<<<< template >>>>
-
- template($receiver) # => String
-
-
-Reads the template off disk.
-
-
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The contents of the L<<<< S<<<<<
-template_file >>>>>|template_file >>>> under L<<<< S<<<<<
-template_path >>>>>|template_path >>>>.
-
-
-=back
-
-=item B<<<< template_extension >>>>
-
- template_extension # => String
-
-
-File extension for templates and partials.
-
-
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- C<<<< $Template::Mustache::template_extension
->>>> (defaults to 'mustache').
-
-
-=back
-
-=item B<<<< template_file >>>>
-
- template_file($receiver) # => String
-
-
-The template filename to read. The filename follows standard Perl
-module lookup practices (e.g. My::Module becomes My/Module.pm) with the
-following differences:
-
-
-=over
-
-=item *
-
-Templates have the extension given by L<<<< S<<<<< template_extension
->>>>>|template_extension >>>> ('mustache' by default).
-
-
-=item *
-
-Templates will have L<<<< S<<<<< template_namespace
->>>>>|template_namespace >>>> removed, if it appears at the beginning of
-the package name.
-
-
-=item *
-
-Template filename resolution will short circuit if C<<<<
-$Template::Mustache::template_file >>>> is set.
-
-
-=item *
-
-Template filename resolution may be overriden in subclasses.
-
-
-=item *
-
-Template files will be resolved against L<<<< S<<<<< template_path
->>>>>|template_path >>>>, not C<<<< $PERL5LIB >>>>.
-
-
-=back
-
-
-
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The path to the template file, relative to
-L<<<< S<<<<< template_path >>>>>|template_path >>>>.
-
-
-=back
-
-See Also:
-
-=over
-
-=item *
-
-L<<<< S<<<<< template >>>>>|template >>>>
-
-
-=back
-
-=item B<<<< template_namespace >>>>
-
- template_namespace # => String
-
-
-Package namespace to ignore during template lookups.
-
-As an example, if you subclass C<<<< Template::Mustache >>>> as the
-class C<<<< My::Heavily::Namepaced::Views::SomeView >>>>, calls to L<<<<
-S<<<<< render >>>>>|render >>>> will automatically try to load the
-template C<<<< ./My/Heavily/Namespaced/Views/SomeView.mustache >>>>
-under the L<<<< S<<<<< template_path >>>>>|template_path >>>>. Since
-views will very frequently all live in a common namespace, you can
-override this method in your subclass, and save yourself some headaches.
-
- Setting template_namespace to: yields template name:
- My::Heavily::Namespaced::Views => SomeView.mustache
- My::Heavily::Namespaced => Views/SomeView.mustache
- Heavily::Namespaced =>
-My/Heavily/Namespaced/Views/SomeView.mustache
-
-As noted by the last example, namespaces will only be removed from the
-beginning of the package name.
-
-
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- The empty string.
-
-
-=back
-
-=item B<<<< template_path >>>>
-
- template_path # => String
-
-
-Filesystem path for template and partial lookups.
-
-
-
-
-Returns:
-
-=over
-
-=item *
-
-(I<<<< String >>>>) -- C<<<< $Template::Mustache::template_path >>>>
-(defaults to '.').
-
-
-=back
-
-=back
-
-=head1 AUTHOR
-
-Pieter van de Bruggen
-