Permalink
Browse files

Work in progress, nearly there!

  • Loading branch information...
1 parent 0f62e14 commit 85d83073b201482e4dd77b0f76e651b45436142c @supernovus committed Oct 13, 2011
View
@@ -40,6 +40,9 @@ method !get-plugin ($plugin) {
my $object = $plugin;
if ! $plugin.defined {
$object = $plugin.new(:flower(self));
+ if $object.can('init') {
+ $object.init();
+ }
}
return $object;
}
@@ -55,10 +58,11 @@ multi method parse (Exemel::Document $template, *%data) {
%rootattrs{$val} = $key; ## Yeah, we're reversing it.
}
for @.plugins -> $plugin {
+ $plugin.custom-tag = Nil;
if %rootattrs.exists($plugin.ns) {
my $tag = %rootattrs{$plugin.ns};
$tag ~~ s/^xmlns\://;
- $plugin.tag = $tag;
+ $plugin.custom-tag = $tag;
}
}
@@ -169,6 +173,7 @@ method parse-element($element is rw, :$safe) {
}
if ! $meth { next; } ## Undefined method, we can't handle that.
my $fullname = $plugin.tag ~ ':' ~ $name;
+# $*ERR.say: "-- Parsing $fullname tags";
if $isel {
if $element.name eq $fullname {
$plugin."$meth"($element, $fullname);
View
@@ -0,0 +1,15 @@
+role Flower::Lang;
+
+## Common methods for Flower Languages.
+
+has $.flower;
+has $.custom-tag is rw;
+has %.options;
+
+method tag {
+ if $.custom-tag.defined {
+ return $.custom-tag;
+ }
+ return $.default-tag;
+}
+
View
@@ -0,0 +1,23 @@
+use Flower;
+class Flower::TAL is Flower;
+
+## Extend Flower into a TAL/METAL engine.
+
+use Flower::TAL::TAL;
+use Flower::TAL::METAL;
+
+our submethod BUILD () {
+ self.add-plugin(Flower::TAL::METAL); ## We parse METAL first.
+ self.add-plugin(Flower::TAL::TAL); ## Then we parse TAL.
+}
+
+## Add a TALES plugin.
+method add-tales ($tale) {
+ for @.plugins -> $plugin {
+ if $plugin ~~ Flower::TAL::TAL {
+ $plugin.tales.add-plugin($tale);
+ last;
+ }
+ }
+}
+
View
@@ -1,9 +1,11 @@
-class Flower::TAL::METAL; ## The METAL XML Application Language.
+#use Flower::Lang;
+class Flower::TAL::METAL; # does Flower::Lang;
+
+## The METAL XML Application Language.
use Exemel;
-has $.flower;
-has $.tag is rw = 'metal';
+has $.default-tag = 'metal';
has $.ns = 'http://xml.zope.org/namespaces/metal';
## The tags for METAL macro processing.
@@ -12,15 +14,28 @@ has @.handlers =
'define-macro' => 'parse-define',
'use-macro' => 'parse-use';
-## Needed by the spec, but unused here.
-has %.options;
-
## The cache for METAL macros.
has %.metal is rw;
## The cache for included XML templates.
has %.file is rw;
+## Common methods for Flower Languages.
+## This is in Flower::Lang role, but due to bugs with having
+## multiple classes using the same roles in Rakudo ng, I've simply
+## copied and pasted it. Oh, I can't wait until this works on "nom".
+
+has $.flower;
+has $.custom-tag is rw;
+has %.options;
+
+method tag {
+ if $.custom-tag.defined {
+ return $.custom-tag;
+ }
+ return $.default-tag;
+}
+
## Loading more XML documents.
## Now caches results, for easy re-use.
method load-xml-file ($filename) {
View
@@ -1,12 +1,14 @@
-class Flower::TAL::TAL; ## The TAL XML Application Language
+#use Flower::Lang;
+class Flower::TAL::TAL; #does Flower::Lang;
+
+## The TAL XML Application Language
use Exemel;
use Flower::TAL::TALES; ## The TALES attribute sub-language.
use Flower::TAL::Repeat; ## A class representing our repeat object.
-has $.flower;
-has $.tag is rw = 'tal';
+has $.default-tag = 'tal'; ## What to use if nothing is set.
has $.ns = 'http://xml.zope.org/namespaces/tal';
## The full set of TAL attributes.
@@ -22,28 +24,43 @@ has @.handlers =
'omit-tag' => 'parse-omit',
'block' => { :element }; ## lazy <tal:block> extension from PHPTAL.
-## Needed by the spec, but unused here.
+has $.tales;
+
+## Common methods for Flower Languages.
+## This is in Flower::Lang role, but due to bugs with having
+## multiple classes using the same roles in Rakudo ng, I've simply
+## copied and pasted it. Oh, I can't wait until this works on "nom".
+
+has $.flower;
+has $.custom-tag is rw;
has %.options;
-has $.tales;
+method tag {
+ if $.custom-tag.defined {
+ return $.custom-tag;
+ }
+ return $.default-tag;
+}
-our submethod BUILD (:$flower) {
- $!flower = $flower;
+## Normally we'd use submethod BUILD but in "ng" at least, it
+## completely wipes out our defaults in the "has" statements.
+## Boo, hiss. So now we have this lovely bit of magic instead.
+method init () {
$!tales = Flower::TAL::TALES.new(:parent(self));
}
## This is super simple, as a <tal:block> acts the
## same as a normal element with a tal:omit-tag="" rule.
-method parse_block ($element is rw, $name) {
+method parse-block ($element is rw, $name) {
$element = $element.nodes;
}
method parse-define ($xml is rw, $tag) {
my @statements = $xml.attribs{$tag}.split(/\;\s+/);
for @statements -> $statement {
my ($attrib, $query) = $statement.split(/\s+/, 2);
- my $val = self.query($query);
- if defined $val { %.data{$attrib} = $val; }
+ my $val = $.tales.query($query);
+ if defined $val { $.flower.data{$attrib} = $val; }
}
$xml.unset($tag);
}
@@ -94,24 +111,24 @@ method parse-repeat ($xml is rw, $tag) {
my ($attrib, $query) = $xml.attribs{$tag}.split(/\s+/, 2);
my $array = $.tales.query($query);
if (defined $array && $array ~~ Array) {
- if (! %.data.exists('repeat') || %.data<repeat> !~~ Hash) {
- %.data<repeat> = {}; # Initialize the repeat hash.
+ if (! $.flower.data.exists('repeat') || $.flower.data<repeat> !~~ Hash) {
+ $.flower.data<repeat> = {}; # Initialize the repeat hash.
}
$xml.unset($tag);
my @elements;
my $count = 0;
for @($array) -> $item {
my $newxml = $xml.deep-clone;
- %.data{$attrib} = $item;
+ $.flower.data{$attrib} = $item;
my $repeat = Flower::TAL::Repeat.new(:index($count), :length($array.elems));
- %.data<repeat>{$attrib} = $repeat;
+ $.flower.data<repeat>{$attrib} = $repeat;
my $wrapper = Exemel::Element.new(:nodes(($newxml)));
- self.parse-elements($wrapper);
+ $.flower.parse-elements($wrapper);
@elements.push: @($wrapper.nodes);
$count++;
}
- %.data<repeat>.delete($attrib);
- %.data.delete($attrib);
+ $.flower.data<repeat>.delete($attrib);
+ $.flower.data.delete($attrib);
$xml = @elements;
}
else {
View
@@ -5,7 +5,7 @@ BEGIN { @*INC.unshift: './lib' }
use Test;
use Flower::TAL;
-plan 10;
+plan 9; ## from outer space.
sub attrmake (*@opts) { @opts.join(' ') | @opts.reverse.join(' ') }
@@ -61,17 +61,3 @@ is ~$tal.parse($template, test=>'Hello World'), $xml~'<test xmlns:petal="http://
$template = '<test tal:attributes="id id">Test document</test>';
is ~$tal.parse($template, id=>'first'), $xml~'<test id="first">Test document</test>', 'attributes on root document';
-## test 10
-
-my @options = (
- { value => 'a', label => 'Option 1' },
- { value => 'b', label => 'Option 2', selected => 'selected' },
- { value => 'c', label => 'Option 3' },
-);
-
-$template = '<select><option tal:repeat="option options" tal:attributes="value option/value; selected option/selected" tal:content="option/label"/></select>';
-
-$attrpos = attrmake 'value="b"', 'selected="selected"';
-
-is ~$tal.parse($template, options => @options), $xml~'<select><option value="a">Option 1</option><option '~$attrpos~'>Option 2</option><option value="c">Option 3</option></select>', 'attributes with undefined value';
-
View
@@ -3,35 +3,33 @@
BEGIN { @*INC.unshift: './lib' }
use Test;
-use Flower;
+use Flower::TAL;
-plan 8;
+plan 9; ## also from outer space.
my $xml = '<?xml version="1.0"?>';
## test 1
my $template = '<test><item tal:repeat="item items" tal:attributes="alt item/alt" tal:content="item/content"/></test>';
-my $flower = Flower.new(:template($template));
+my $tal = Flower::TAL.new();
my @items = (
{ :alt<One>, :content<First> },
{ :alt<Two>, :content<Second> },
{ :alt<Three>, :content<Third> },
);
-is $flower.parse(:items(@items)), $xml~'<test><item alt="One">First</item><item alt="Two">Second</item><item alt="Three">Third</item></test>', 'tal:repeat';
+is ~$tal.parse($template, :items(@items)), $xml~'<test><item alt="One">First</item><item alt="Two">Second</item><item alt="Three">Third</item></test>', 'tal:repeat';
## test 2
$template = '<test><div tal:repeat="item items" tal:omit-tag=""><tr><td tal:content="item/alt"/><td tal:content="item/content"/></tr></div></test>';
-$flower.=another(:template($template));
-is $flower.parse(:items(@items)), $xml~'<test><tr><td>One</td><td>First</td></tr><tr><td>Two</td><td>Second</td></tr><tr><td>Three</td><td>Third</td></tr></test>', 'tal:repeat with nested elements and omit-tag';
+is ~$tal.parse($template, :items(@items)), $xml~'<test><tr><td>One</td><td>First</td></tr><tr><td>Two</td><td>Second</td></tr><tr><td>Three</td><td>Third</td></tr></test>', 'tal:repeat with nested elements and omit-tag';
## test 3, Here we test tal:block as well.
$template = '<test><tal:block tal:repeat="item items"><tr><td tal:content="item/alt"/><td tal:content="item/content"/></tr></tal:block></test>';
-$flower.=another(:template($template));
-is $flower.parse(:items(@items)), $xml~'<test><tr><td>One</td><td>First</td></tr><tr><td>Two</td><td>Second</td></tr><tr><td>Three</td><td>Third</td></tr></test>', 'tal:block used in repeat';
+is ~$tal.parse($template, :items(@items)), $xml~'<test><tr><td>One</td><td>First</td></tr><tr><td>Two</td><td>Second</td></tr><tr><td>Three</td><td>Third</td></tr></test>', 'tal:block used in repeat';
## test 4, Now we're going to test the repeat object.
@@ -43,38 +41,45 @@ my @rows = (
[ '3.1', '3.2', '3.3' ],
);
-$flower.=another(:template($template));
-is $flower.parse(:rows(@rows)), $xml~'<table><tr><td>1 / 1 = 1.1</td><td>1 / 2 = 1.2</td><td>1 / 3 = 1.3</td></tr><tr><td>2 / 1 = 2.1</td><td>2 / 2 = 2.2</td><td>2 / 3 = 2.3</td></tr><tr><td>3 / 1 = 3.1</td><td>3 / 2 = 3.2</td><td>3 / 3 = 3.3</td></tr></table>', 'nested repeat numbers';
+is ~$tal.parse($template, :rows(@rows)), $xml~'<table><tr><td>1 / 1 = 1.1</td><td>1 / 2 = 1.2</td><td>1 / 3 = 1.3</td></tr><tr><td>2 / 1 = 2.1</td><td>2 / 2 = 2.2</td><td>2 / 3 = 2.3</td></tr><tr><td>3 / 1 = 3.1</td><td>3 / 2 = 3.2</td><td>3 / 3 = 3.3</td></tr></table>', 'nested repeat numbers';
## test 5
$template = '<test><tal:block tal:repeat="item items"><item tal:condition="repeat/item/odd" tal:attributes="id repeat/item/index">Odd</item><item tal:condition="repeat/item/even" tal:attributes="id repeat/item/index">Even</item></tal:block></test>';
-$flower.=another(:template($template));
-
-is $flower.parse(:items([1..4])), $xml~'<test><item id="0">Odd</item><item id="1">Even</item><item id="2">Odd</item><item id="3">Even</item></test>', 'repeat with odd and even conditionals';
+is ~$tal.parse($template, :items([1..4])), $xml~'<test><item id="0">Odd</item><item id="1">Even</item><item id="2">Odd</item><item id="3">Even</item></test>', 'repeat with odd and even conditionals';
## test 6
$template = '<test><tal:block tal:repeat="item items"><item tal:condition="repeat/item/start">First</item><item tal:condition="repeat/item/inner">Inner</item><item tal:condition="repeat/item/end" tal:attributes="length repeat/item/length">Last</item></tal:block></test>';
-$flower.=another(:template($template));
-
-is $flower.parse(:items([1..4])), $xml~'<test><item>First</item><item>Inner</item><item>Inner</item><item length="4">Last</item></test>', 'repeat with start, end, inner and length.';
+is ~$tal.parse($template, :items([1..4])), $xml~'<test><item>First</item><item>Inner</item><item>Inner</item><item length="4">Last</item></test>', 'repeat with start, end, inner and length.';
## test 7
$template = '<test><tal:block tal:repeat="item items"><item tal:condition="repeat/item/every \'3\'">Every third</item><item tal:condition="repeat/item/skip \'3\'">Normal item</item></tal:block></test>';
-$flower.=another(:template($template));
-
-is $flower.parse(:items([1..7])), $xml~'<test><item>Normal item</item><item>Normal item</item><item>Every third</item><item>Normal item</item><item>Normal item</item><item>Every third</item><item>Normal item</item></test>', 'repeat with every and skip';
+is ~$tal.parse($template, :items([1..7])), $xml~'<test><item>Normal item</item><item>Normal item</item><item>Every third</item><item>Normal item</item><item>Normal item</item><item>Every third</item><item>Normal item</item></test>', 'repeat with every and skip';
## test 8
$template = '<test><tal:block tal:repeat="item items"><item tal:condition="repeat/item/lt \'3\'">lt 3</item><item tal:condition="repeat/item/gt \'3\'">gt 3</item><item tal:condition="repeat/item/eq \'3\'">the third</item></tal:block></test>';
-$flower.=another(:template($template));
+is ~$tal.parse($template, :items([1..5])), $xml~'<test><item>lt 3</item><item>lt 3</item><item>the third</item><item>gt 3</item><item>gt 3</item></test>', 'repeat with gt, lt and eq';
+
+## test 9
+
+sub attrmake (*@opts) { @opts.join(' ') | @opts.reverse.join(' ') }
+
+my @options = (
+ { value => 'a', label => 'Option 1' },
+ { value => 'b', label => 'Option 2', selected => 'selected' },
+ { value => 'c', label => 'Option 3' },
+);
+
+$template = '<select><option tal:repeat="option options" tal:attributes="value option/value; selected option/selected" tal:content="option/label"/></select>';
+
+my $attrpos = attrmake 'value="b"', 'selected="selected"';
-is $flower.parse(:items([1..5])), $xml~'<test><item>lt 3</item><item>lt 3</item><item>the third</item><item>gt 3</item><item>gt 3</item></test>', 'repeat with gt, lt and eq';
+is ~$tal.parse($template, options => @options), $xml~'<select><option value="a">Option 1</option><option '~$attrpos~'>Option 2</option><option value="c">Option 3</option></select>', 'attributes with undefined value';
View
@@ -3,7 +3,7 @@
BEGIN { @*INC.unshift: './lib' }
use Test;
-use Flower;
+use Flower::TAL;
plan 2;
@@ -12,15 +12,14 @@ my $xml = '<?xml version="1.0"?>';
## test 1
my $template = '<test><i tal:content="default">The default text</i></test>';
-my $flower = Flower.new(:template($template));
+my $tal = Flower::TAL.new();
-is $flower.parse(), $xml~'<test><i>The default text</i></test>', 'tal:content with default';
+is ~$tal.parse($template), $xml~'<test><i>The default text</i></test>', 'tal:content with default';
## test 2
$template = '<test><i tal:replace="default">The default text</i></test>';
-$flower.=another(:template($template));
-is $flower.parse(), $xml~'<test>The default text</test>', 'tal:replace with default';
+is ~$tal.parse($template), $xml~'<test>The default text</test>', 'tal:replace with default';
View
@@ -3,14 +3,14 @@
BEGIN { @*INC.unshift: './lib' }
use Test;
-use Flower;
+use Flower::TAL;
plan 1;
my $xml = '<?xml version="1.0"?>';
my $template = '<test><escaped tal:content="string"/><unescaped tal:content="structure string"/></test>';
-my $flower = Flower.new(:template($template));
+my $tal = Flower::TAL.new();
-is $flower.parse(string=>'hello to you & your friend, "how are you?"'), $xml~'<test><escaped>hello to you &amp; your friend, &quot;how are you?&quot;</escaped><unescaped>hello to you & your friend, "how are you?"</unescaped></test>', 'XML escapes and structure keyword';
+is ~$tal.parse($template, string=>'hello to you & your friend, "how are you?"'), $xml~'<test><escaped>hello to you &amp; your friend, &quot;how are you?&quot;</escaped><unescaped>hello to you & your friend, "how are you?"</unescaped></test>', 'XML escapes and structure keyword';
Oops, something went wrong.

0 comments on commit 85d8307

Please sign in to comment.