Permalink
Browse files

Flower works again. Many changes. See log.

 * Updated to work with latest Rakudo and Perl 6 XML library.
 * Added a template Provider interface, used by process() and METAL.
 * New File Provider works like Template6. Updated METAL test.
 * Lots of minor fixes and changes.
  • Loading branch information...
1 parent 10724e5 commit 64e5bc51cdc1564483b0786ffccb6c857a34b6a7 Timothy Totten committed Nov 10, 2012
Showing with 101 additions and 77 deletions.
  1. +16 −13 README.md
  2. +0 −12 doc/TODO.txt
  3. +22 −7 lib/Flower.pm6
  4. +46 −0 lib/Flower/Provider/File.pm6
  5. +5 −21 lib/Flower/TAL/METAL.pm6
  6. +4 −20 lib/Flower/TAL/TAL.pm6
  7. +4 −2 lib/Flower/TAL/TALES.pm6
  8. +4 −2 t/07-metal.t
View
@@ -1,12 +1,5 @@
# Flower: XML Application Languages
-## BIG IMPORTANT NOTE
-
-Flower is currently horribly broken and does not work, like at all.
-It's been unmaintained for a while and has suffered some bitrot.
-
-I am planning to get it back into a working shape again soon.
-
## Introduction
Flower is a library for building and using XML Application Languages.
@@ -29,16 +22,18 @@ loads the Flower::TAL::TAL, Flower::TAL::METAL application languages
by default, and offers the ability to easily load plugins for the
Flower::TAL::TALES attribute parser (used by Flower::TAL::TAL)
-### Differences from Petal (also PHPTAL and Zope)
+### Differences from Petal (and Template::TAL, PHPTAL and Zope)
* The default local namespace is 'tal', and to override it, you must
declare http://xml.zope.org/namespaces/tal instead of the Petal namespace.
* Flower can use template strings instead of requiring files.
+ * In addition to strings, it can use a custom provider class.
+ Currently a File provider is included.
* Flower does not support the multiple template files based on language.
+ But that can be added easily by defining a custom Provider class.
* Adding custom modifiers is completely different in Flower.
* There is NO support for anything but well-formed XML.
There is no equivelant to the Petal::Parser::HTB, and no plans for one.
- Use well-formed XML, it's just better.
* Flower supports tal:block elements, as per the PHPTAL project.
* While you can use the 'structure' keyword, it's not really needed.
If you want an unescaped XML structure for a replacement, send an
@@ -65,10 +60,10 @@ The above list will be updated as this project is developed, as I'm sure
other changes will be introduced that will be a gotchya for users of Petal,
Zope or PHPTAL.
-### Flower::TAL Plugins
+### Flower::TAL::TALES Plugins
Inspired by Petal::Utils, Flower includes a bunch of libraries in the
-Flower::TAL::TALES:: namespace. These are also available using Flower::TAL's
+Flower::TAL::TALES:: namespace. These are available using Flower::TAL's
add-tales() method.
* Text, same as the :text set from Petal::Utils
@@ -102,7 +97,7 @@ add-tales() method.
* dump: modifier spits out the .perl representation of the object.
* what: modifier spits out the class name of the object.
-In addition, the following sets are planned for inclusion very soon:
+In addition, the following sets are planned for inclusion at some point:
* Logic, similar to the :logic set from Petal::Utils
* Hash, same as the :hash set from Petal::Utils
@@ -122,9 +117,17 @@ The URI set from Petal::Utils is not planned for inclusion,
feel free to write it if you need it.
I'm sure new exciting libraries will be made adding onto these.
+## TODO
+
+ * Add Logic and Hash TALES plugins.
+ * Implement optional query caching.
+ * Implement multiple paths (/test/path1 | /test/path2) support.
+ * Implement on-error.
+ * Add Flower::Provider::Multiple for querying providers by prefix.
+
## Requirements
- * [Exemel](http://github.com/supernovus/exemel/)
+ * [XML](http://github.com/supernovus/exemel/)
* [DateTime::Utils](http://github.com/supernovus/temporal-utils/)
## Author
View
@@ -1,12 +0,0 @@
-Things yet to do (in the order they will likely be done in):
-
- - Clean up the alpha-isms that are still hanging about.
- - Finish implementing Flower::TAL::TALES::* plugins, as per the README.
- - Implement query caching (it will be optional)
- - Implement multiple paths (/test/path1 | /test/path2) support.
- - Implement on-error.
-
-Things not likely to be done by me (feel free to do them):
-
- - The I18N sub-lang.
-
View
@@ -2,10 +2,19 @@ class Flower;
use XML;
-## Override find with a subroutine that can find templates based off
-## of whatever your needs are (multiple roots, extensions, etc.)
-has $.find = sub ($file) {
- if $file.IO ~~ :f { return $file }
+has $.provider handles <fetch store>;
+
+submethod BUILD (:$provider)
+{
+ if $provider
+ {
+ $!provider = $provider;
+ }
+ else
+ {
+ require Flower::Provider::File;
+ $!provider = ::('Flower::Provider::File').new;
+ }
}
## Data, is used to store the replacement data. Is available for modifiers.
@@ -18,6 +27,12 @@ has @.elements;
## The XML application languages we support.
has @.plugins;
+## This belongs in Provider.
+method add-path ($path)
+{
+ @.paths.push: $path;
+}
+
## Add an XML application language plugin.
method add-plugin ($plugin) {
my $object = self!get-plugin($plugin);
@@ -76,9 +91,9 @@ multi method parse (Stringy $template, *%data) {
}
}
-## Parse a template using a filename. The filename is passed to find().
-method parse-file ($filename, *%data) {
- my $file = $.find.($filename);
+## Process a template using our Provider class.
+method process ($name, *%data) {
+ my $file = self.fetch($name);
if $file {
my $template = XML::Document.load($file);
if $template {
@@ -0,0 +1,46 @@
+use v6;
+
+class Flower::Provider::File;
+
+has @.include-path;
+has %.templates;
+has $.ext is rw = '.xml';
+
+## TODO: Implement 'absolute', 'relative', etc. options.
+
+submethod BUILD (:@path, *%args)
+{
+ if @path
+ {
+ @!include-path.splice(@!include-path.elems, 0, @path);
+ }
+}
+
+method add-path ($path)
+{
+ @!include-path.push: $path;
+}
+
+method fetch ($name)
+{
+ if %.templates.exists($name)
+ {
+ return %.templates{$name};
+ }
+ for @.include-path -> $path
+ {
+ my $file = "$path/$name"~$.ext;
+ if $file.IO ~~ :f
+ {
+ my $template = slurp $file;
+ %.templates{$name} = $template;
+ return $template;
+ }
+ }
+ return;
+}
+
+method store ($name, $template)
+{
+ %.templates{$name} = $template;
+}
View
@@ -1,5 +1,5 @@
-#use Flower::Lang;
-class Flower::TAL::METAL; # does Flower::Lang;
+use Flower::Lang;
+class Flower::TAL::METAL does Flower::Lang;
## The METAL XML Application Language.
@@ -20,32 +20,16 @@ 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) {
if %.file.exists($filename) {
return %.file{$filename};
}
- my $file = $.flower.find.($filename);
- if ($file) {
- my $xml = XML::Document.load($file);
+ my $xmltext = $.flower.fetch($filename);
+ if $xmltext {
+ my $xml = XML::Document.new($xmltext);
%.file{$filename} = $xml;
return $xml;
}
View
@@ -1,5 +1,5 @@
-#use Flower::Lang;
-class Flower::TAL::TAL; #does Flower::Lang;
+use Flower::Lang;
+class Flower::TAL::TAL does Flower::Lang;
## The TAL XML Application Language
@@ -26,22 +26,6 @@ has @.handlers =
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;
-
-method tag {
- if $.custom-tag.defined {
- return $.custom-tag;
- }
- return $.default-tag;
-}
-
## 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.
@@ -110,7 +94,7 @@ method parse-attrs ($xml is rw, $tag) {
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 $array.defined && $array ~~ Array {
if (! $.flower.data.exists('repeat') || $.flower.data<repeat> !~~ Hash) {
$.flower.data<repeat> = {}; # Initialize the repeat hash.
}
@@ -122,7 +106,7 @@ method parse-repeat ($xml is rw, $tag) {
$.flower.data{$attrib} = $item;
my $repeat = Flower::TAL::Repeat.new(:index($count), :length($array.elems));
$.flower.data<repeat>{$attrib} = $repeat;
- my $wrapper = XML::Element.new(:nodes(($newxml)));
+ my $wrapper = XML::Element.new(:name<wrapper>, :nodes(($newxml)));
$.flower.parse-elements($wrapper);
@elements.push: @($wrapper.nodes);
$count++;
View
@@ -88,9 +88,11 @@ method query ($query is copy, :$noxml, :$forcexml, :$bool, :$noescape is copy) {
}
## Enforce processing rules for query().
-method process-query($data is copy, :$forcexml, :$noxml, :$noescape, :$bool) {
+method process-query($data is copy, :$forcexml, :$noxml, :$noescape, :$bool)
+{
## First off, let's escape text, unless noescape is set.
- if (!defined $noescape && $data ~~ Str) {
+ if (! $noescape && $data ~~ Str)
+ {
$data.=subst(/'&' [<!before \w+ ';'>]/, '&amp;', :g);
$data.=subst('<', '&lt;', :g);
$data.=subst('>', '&gt;', :g);
View
@@ -13,15 +13,17 @@ my $xml = '<?xml version="1.0"?>';
my $template = '<test><zool metal:define-macro="hello">Hello World</zool><zed metal:use-macro="hello">Goodbye Universe</zed></test>';
my $tal = Flower::TAL.new();
+$tal.provider.add-path: './t/metal';
+
is ~$tal.parse($template), $xml~'<test><zool>Hello World</zool><zool>Hello World</zool></test>', 'metal:define-macro and metal:use-macro';
## test 2, using from an external file.
-$template = '<test><zed metal:use-macro="./t/metal/common.xml#hello">Say Hi</zed></test>';
+$template = '<test><zed metal:use-macro="common#hello">Say Hi</zed></test>';
is ~$tal.parse($template), $xml~'<test><zool>Hello, World.</zool></test>', 'metal:use-macro with external reference.';
## test 3, slots.
-$template = '<test><zed metal:use-macro="./t/metal/common.xml#slotty">A slotty test, <orb metal:fill-slot="booya">Yippie Kai Yay!</orb>.</zed></test>';
+$template = '<test><zed metal:use-macro="common#slotty">A slotty test, <orb metal:fill-slot="booya">Yippie Kai Yay!</orb>.</zed></test>';
is ~$tal.parse($template), $xml~'<test><zarf>It is known, <orb>Yippie Kai Yay!</orb> What do you think?</zarf></test>', 'metal:define-slot and metal:fill-slot';

0 comments on commit 64e5bc5

Please sign in to comment.