[Jifty-commit] r3827 - in Template-Declare: lib/HTML
lib/Template/Declare lib/XUL t
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Thu Aug 9 00:13:16 EDT 2007
Author: agentz
Date: Thu Aug 9 00:13:11 2007
New Revision: 3827
Added:
Template-Declare/MANIFEST.SKIP
Template-Declare/lib/HTML/
Template-Declare/lib/HTML/TagSet.pm
Template-Declare/lib/Template/Declare/TagSet.pm
Template-Declare/lib/XUL/
Template-Declare/lib/XUL/TagSet.pm
Template-Declare/t/alternative.t
Template-Declare/t/tagset_html.t
Template-Declare/t/tagset_mix.t
Template-Declare/t/tagset_xul.t
Modified:
Template-Declare/MANIFEST
Template-Declare/META.yml
Template-Declare/lib/Template/Declare/Tags.pm
Template-Declare/t/forms.t
Log:
[TD]
* refactored Template::Decalre::Tags to make the tagset configurable.
* added HTML::TagSet, XUL::TagSet, and their common base class, Template::Declare::TagSet.
* added t/tagset_*.t to test these features.
* added some POD for these new classes.
* should be backward-compatible and no regressions observed.
Modified: Template-Declare/MANIFEST
==============================================================================
--- Template-Declare/MANIFEST (original)
+++ Template-Declare/MANIFEST Thu Aug 9 00:13:11 2007
@@ -7,27 +7,41 @@
inc/Module/Install/Metadata.pm
inc/Module/Install/Win32.pm
inc/Module/Install/WriteAll.pm
+lib/HTML/TagSet.pm
lib/Template/Declare.pm
lib/Template/Declare/Buffer.pm
lib/Template/Declare/Tags.pm
+lib/Template/Declare/TagSet.pm
+lib/XUL/TagSet.pm
Makefile.PL
MANIFEST This list of files
+MANIFEST.SKIP
META.yml
README
SIGNATURE
t/99-pod.t
t/aliasing.t
+t/alternative.t
t/arg-declaration-styles.t
+t/arg-passing.t
t/attributes.t
t/closures.t
+t/deep_aliasing.t
+t/deep_importing.t
t/duplicate_element_ids.t
+t/forms.t
t/importing.t
t/indexhtml.t
t/private.t
+t/relative-pathing.t
t/self.t
t/smart_tag_wrapper.t
t/subclassing.t
t/subtemplates.t
+t/tagset_html.t
+t/tagset_mix.t
+t/tagset_xul.t
t/trivial.t
+t/utf8.t
t/utils.pl
t/xss.t
Added: Template-Declare/MANIFEST.SKIP
==============================================================================
--- (empty file)
+++ Template-Declare/MANIFEST.SKIP Thu Aug 9 00:13:11 2007
@@ -0,0 +1,43 @@
+^a$
+^Template-Declare-\d+\.\d+
+^.*ref.*\.xml
+^t\.sh$
+^\w+\.pm
+^t.sh$
+^temp/
+^lrep/
+precedence.pl
+RuleInline-more.pl
+benchmark.pl
+t6/iterator_engine.pl
+lib/pcr.txt
+lib/print.sh
+tmp.txt
+lib/Pugs/Grammar/Rule2.pmc
+trans.pl
+trans2.pl
+tmp
+^blib/
+^Makefile$
+^Makefile\.[a-z]+$
+\.swp$
+Pugs-Compiler-Rule-\d+
+^pm_to_blib$
+CVS/.*
+,v$
+^tmp/
+\.old$
+\.bak$
+~$
+^#
+\.shar$
+\.tar$
+\.tgz$
+\.tar\.gz$
+\.zip$
+_uu$
+t/zz.*
+test\.[co]
+benchmarks/.*
+\.svn
+\.t_$
Modified: Template-Declare/META.yml
==============================================================================
--- Template-Declare/META.yml (original)
+++ Template-Declare/META.yml Thu Aug 9 00:13:11 2007
@@ -1,22 +1,22 @@
----
+---
abstract: Perlish declarative templates
-author: Jesse Vincent <jesse at bestpractical.com>
-build_requires:
+author: 'Jesse Vincent <jesse at bestpractical.com>'
+build_requires:
HTML::Lint: 0
Test::More: 0
Test::Warn: 0
distribution_type: module
generated_by: Module::Install version 0.67
license: perl
-meta-spec:
+meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.3.html
version: 1.3
name: Template-Declare
-no_index:
- directory:
+no_index:
+ directory:
- inc
- t
-requires:
+requires:
Class::Accessor: 0
Class::Data::Inheritable: 0
perl: 5.6.0
Added: Template-Declare/lib/HTML/TagSet.pm
==============================================================================
--- (empty file)
+++ Template-Declare/lib/HTML/TagSet.pm Thu Aug 9 00:13:11 2007
@@ -0,0 +1,102 @@
+package HTML::TagSet;
+
+use strict;
+use warnings;
+use base 'Template::Declare::TagSet';
+#use Smart::Comments;
+
+use CGI ();
+
+our %AlternateSpelling = (
+ tr => 'row',
+ td => 'cell',
+ base => '', # Currently 'base' has no alternate spellings; simply ignore it;
+);
+
+sub get_alternate_spelling {
+ my ($self, $tag) = @_;
+ $AlternateSpelling{$tag};
+}
+
+sub get_tag_list {
+ my @tags = map {@{$_||[]}}
+ @CGI::EXPORT_TAGS{
+ qw/:html2 :html3 :html4 :netscape :form/
+ };
+ return [ @tags, qw/form/ ];
+}
+
+sub can_combine_empty_tags {
+ my ($self, $tag) = @_;
+ $tag
+ =~ m{\A(?: base | meta | link | hr | br | param | img | area | input | col )\z}x;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+HTML::TagSet - Tag set for HTML
+
+=head1 SYNOPSIS
+
+ use HTML::TagSet;
+ my $list = HTML::TagSet->get_tag_list();
+ print "@$list";
+
+ my $altern = HTML::TagSet->get_alternate_spelling('tr');
+ if ( defined $altern ) {
+ print $altern;
+ }
+
+ if ( HTML::TagSet->can_combine_empty_tags('img') ) {
+ print "<img src='blah.gif' />";
+ }
+
+ # normal use
+ package MyApp::Templates;
+ use Template::Declare::Tags qw/ HTML::TagSet /;
+ use base 'Template::Declare';
+ # ...
+
+
+=head1 INHERITANCE
+
+ HTML::TagSet
+ isa Template::Declare::TagSet
+
+=head1 METHODS
+
+=over
+
+=item C<< $list = __PACKAGE__->get_tag_list() >>
+
+Returns an array ref for the tag names.
+
+Out of the box, C<HTML::TagSet> returns the
+C<:html2 :html3 :html4 :netscape> and C<:form>
+tagsets from CGI.pm.
+
+=item C<< $bool = __PACKAGE__->get_alternate_spelling($tag) >>
+
+Returns the alternative spelling for a given tag if any or
+undef otherwise. Currently, C<tr> is mapped to C<row>
+and C<td> is mapped to C<cell>.
+
+Because C<tr> is reserved by the perl interpreter for
+the operator of that name. We can't override it. And
+we override C<td> as well so as to keep consistent.
+
+=item C<< $bool = __PACKAGE__->can_combine_empty_tags($tag) >>
+
+=back
+
+=head1 AUTHOR
+
+Agent Zhang E<lt>agentzh at gmail.comE<gt>
+
+=head1 SEE ALSO
+
+L<Template::Declare::TagSet>, L<XUL::TagSet>, L<Template::Declare::Tags>, L<Template::Declare>.
+
Added: Template-Declare/lib/Template/Declare/TagSet.pm
==============================================================================
--- (empty file)
+++ Template-Declare/lib/Template/Declare/TagSet.pm Thu Aug 9 00:13:11 2007
@@ -0,0 +1,90 @@
+package Template::Declare::TagSet;
+
+use strict;
+use warnings;
+
+sub get_alternate_spelling {
+ undef;
+}
+
+sub get_tag_list {
+ [];
+}
+
+# specify whether "<tag></tag>" can be combined to "<tag />"
+sub can_combine_empty_tags {
+ 1;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Template::Declare::TagSet - Base class for tag set classes used by Template::Declare::Tags
+
+=head1 SYNOPSIS
+
+ package My::TagSet;
+ use base 'Template::Declare::TagSet';
+
+ # returns an array ref for the tag names
+ sub get_tag_list {
+ [ qw/ html body tr td table
+ base meta link hr
+ / ]
+ }
+
+ # prevents potential naming conflicts:
+ sub get_alternate_spelling {
+ my ($self, $tag) = @_;
+ return 'row' if $tag eq 'tr';
+ return 'cell' if $tag eq 'td';
+ }
+
+ # Specifies whether "<tag></tag>" can be
+ # combined to "<tag />":
+ sub can_combine_empty_tags {
+ my ($self, $tag) = @_;
+ $tag =~ /^ base | meta | link | hr $/x;
+ }
+
+=head1 METHODS
+
+=over
+
+=item C<< $list = __PACKAGE__->get_tag_list() >>
+
+Returns an array ref for the tag names.
+
+=item C<< $bool = __PACKAGE__->get_alternate_spelling($tag) >>
+
+Returns whether a tag has an alternative spelling. Basically
+it provides a way to work around naming conflicts, for
+examples, the C<tr> tag in HTML conflicts with the C<tr>
+operator in Perl and the C<template> tag in XUL conflicts
+with the C<template> sub exported by C<Template::Declare::Tags>.
+
+=item C<< $bool = __PACKAGE__->can_combine_empty_tags($tag) >>
+
+Specifies whether "<tag></tag>" can be combined into a single
+token "<tag />".
+
+Always returns true (value 1) in this base class.
+
+But there's some cases where you want to override the
+deafault implementation. For example,
+C<< HTML::TagSet->can_combine_empty_tags('img') >> returns true (1) since C<< <img src="..." /> >> is always
+required for HTML pages.
+
+=back
+
+=head1 AUTHOR
+
+Agent Zhang E<lt>agentzh at gmail.comE<gt>.
+
+=head1 SEE ALSO
+
+L<HTML::TagSet>, L<XUL::TagSet>, L<Template::Declare::Tags>,
+L<Template::Declare>.
+
Modified: Template-Declare/lib/Template/Declare/Tags.pm
==============================================================================
--- Template-Declare/lib/Template/Declare/Tags.pm (original)
+++ Template-Declare/lib/Template/Declare/Tags.pm Thu Aug 9 00:13:11 2007
@@ -1,26 +1,104 @@
use 5.006;
use warnings;
use strict;
+#use Smart::Comments '####';
package Template::Declare::Tags;
+
use Template::Declare;
-use vars qw/@EXPORT @EXPORT_OK $PRIVATE $self/;
+use vars qw( @EXPORT @EXPORT_OK $PRIVATE $self );
use base 'Exporter';
-use Carp;
+use Carp qw(carp croak);
+use Symbol 'qualify_to_ref';
@EXPORT
= qw( with template private show show_page attr outs outs_raw in_isolation $self under get_current_attr smart_tag_wrapper current_template );
-push @EXPORT, qw(Tr td ); # these two warns the user to use row/cell instead
our %ATTRIBUTES = ();
our %ELEMENT_ID_CACHE = ();
our $TAG_NEST_DEPTH = 0;
our @TEMPLATE_STACK;
+sub import {
+ ### caller: caller(0)
+ ### @_
+ my $self = shift;
+ my @set_modules;
+ if (!@_) {
+ push @_, 'HTML::TagSet';
+ }
+ for my $module (@_) {
+ eval "use $module";
+ if ($@) {
+ warn $@;
+ croak "Failed to load tagset module $module";
+ }
+ my $tags = $module->get_tag_list;
+ Template::Declare::Tags::install_tag($_, $module)
+ for @$tags;
+ }
+ __PACKAGE__->export_to_level(1, $self);
+}
+
+sub _install {
+ my ($no_override, $package, $subname, $coderef) = @_;
+
+ my $name = $package . '::' . $subname;
+ my $slot = qualify_to_ref($name);
+ return if $no_override and *$slot{CODE};
+
+ no warnings 'redefine';
+ *$slot = $coderef;
+}
+
=head1 NAME
Template::Declare::Tags
+=head1 SYNOPSIS
+
+ package MyApp::Templates;
+ use base 'Template::Declare';
+ use Template::Declare::Tags qw/ HTML::TagSet XUL::TagSet /;
+
+=head1 DESCRIPTION
+
+Template::Declare::Tags is used to generate and export
+subroutines for tags into the user's namespace.
+
+You can specify the tag sets used by providing a list of
+module list in the C<use> statement:
+
+ use Template::Declare::Tags qw/ HTML::TagSet XUL::TagSet/;
+
+By default, it uses the tag set provided by C<HTML::TagSet>. So
+
+ use Template::Declare::Tags;
+
+is equivalent to
+
+ use Template::Declare::Tags 'HTML::TagSet';
+
+Currently C<Template::Declare> bundles C<HTML::TagSet>
+for HTML tags and C<XUL::TagSet> for XUL tags. You can
+certainly specify your own tag set classes, as long
+as they implement a C<tags> method which returns
+a hash ref. The keys of the hash ref are the names
+for your custom tags and the values are also hash refs,
+which are the options for the corresponding tag.
+An example is as follows:
+
+ {
+ html => {},
+ body => {},
+ tr => { alternate => 'row' },
+ td => { alternate => 'cell' },
+ }
+
+The 'alternate' option is used to specify an
+alternative spelling for the correspondig tag
+if there's a naming conflict.
+
=head1 METHODS
=head2 template TEMPLATENAME => sub { 'Implementation' };
@@ -164,29 +242,31 @@
$ATTRIBUTES{ $_[0] };
}
-our %TagAlternateSpelling = (
- tr => 'row',
- td => 'cell',
- base =>
- '', # Currently 'base' has no alternate spellings; simply ignore it
-);
=head2 install_tag TAGNAME
Sets up TAGNAME as a tag that can be used in user templates.
-Out of the box, C<Template::Declare> installs the :html2 :html3 :html4 :netscape and
-:form tagsets from CGI.pm. Patches to make this configurable or use HTML::TagSet would be great.
-
-
=cut
sub install_tag {
my $tag = lc( $_[0] );
my $name = $tag;
+ my $tagset = $_[1];
- if ( exists( $TagAlternateSpelling{$tag} ) ) {
- $name = $TagAlternateSpelling{$tag} or return;
+ ### caller: (caller(0))[0]
+ my $alternative = $tagset->get_alternate_spelling($tag);
+ if ( defined $alternative ) {
+ _install(
+ 1, # do not override
+ scalar(caller), $tag,
+ sub (&;$) {
+ die "$tag {...} is invalid; use $alternative {...} instead.\n";
+ }
+ );
+ #### Exporting place-holder sub: $name
+ push @EXPORT, $name;
+ $name = $alternative or return;
}
push @EXPORT, $name;
@@ -213,12 +293,6 @@
};
}
-use CGI ();
-our %TAGS = (
- map { $_ => +{} }
- map {@{$_||[]}} @CGI::EXPORT_TAGS{qw/:html2 :html3 :html4 :netscape :form/}
-);
-install_tag($_) for ((keys %TAGS), 'form') ;
=head2 with
@@ -318,9 +392,11 @@
= caller(1);
# This is the hash of attributes filled in by attr() calls in the code;
+ ### Caller: (caller(1))[0]
my $tag = $subroutine;
$tag =~ s/^.*\:\://;
+ #$tag = "html:$tag";
my $buf = "\n" . ( " " x $TAG_NEST_DEPTH ) . "<$tag"
. join( '',
@@ -336,6 +412,7 @@
shift;
my $field = our $AUTOLOAD;
+ ### $field
$field =~ s/.*:://;
$field =~ s/__/:/g; # xml__lang is 'foo' ====> xml:lang="foo"
@@ -551,33 +628,9 @@
sub under ($) { return shift }
-=head2 Tr
-
-Template::Declare::Tags uses C<row> and C<cell> for table definitions rather than C<tr> and C<td>.
-(C<tr> is reserved by the perl interpreter for the operator of that name. We can't override it.)
-
-=cut
-
-sub Tr (&) {
- die
- "Tr {...} and td {...} are invalid; use row {...} and cell {...} instead.";
-}
-
-=head2 td
-
-Template::Declare::Tags uses C<row> and C<cell> for table definitions rather than C<tr> and C<td>.
-(C<tr> is reserved by the perl interpreter for the operator of that name. We can't override it.)
-
-=cut
-
-sub td (&) {
- die
- "Tr {...} and td {...} are invalid; use row {...} and cell {...} instead.";
-}
-
=head1 SEE ALSO
-L<Template::Declare>
+L<HTML::TagSet>, L<XUL::TagSet>, L<Template::Declare>.
=head1 AUTHOR
Added: Template-Declare/lib/XUL/TagSet.pm
==============================================================================
--- (empty file)
+++ Template-Declare/lib/XUL/TagSet.pm Thu Aug 9 00:13:11 2007
@@ -0,0 +1,117 @@
+package XUL::TagSet;
+
+use strict;
+use warnings;
+#use Smart::Comments;
+use base 'Template::Declare::TagSet';
+
+use CGI ();
+
+our %AlternateSpelling = (
+ template => 'xul_tempalte',
+);
+
+sub get_alternate_spelling {
+ my ($self, $tag) = @_;
+ $AlternateSpelling{$tag};
+}
+
+sub get_tag_list {
+ return [ qw{
+ action arrowscrollbox bbox binding
+ bindings body box broadcaster
+ broadcasterset browser button caption
+ checkbox children colorpicker column
+ columns command commandset conditions
+ constructor content deck description
+ destructor dialog dialogheader editor
+ field getter grid grippy
+ groupbox handler handlers hbox
+ iframe image implementation key
+ keyset label listbox listcell
+ listcol listcols listhead listheader
+ listitem member menu menubar
+ menuitem menulist menupopup menuseparator
+ method observes overlay page
+ parameter popup popupset progressmeter
+ property radio radiogroup rdf
+ resizer resources row rows
+ rule script scrollbar scrollbox
+ separator setter spacer splitter
+ stack statusbar statusbarpanel stringbundle
+ stringbundleset stylesheet tab tabbox
+ tabbrowser tabpanel tabpanels tabs
+ template textbox textnode titlebar
+ toolbar toolbarbutton toolbargrippy toolbaritem
+ toolbarpalette toolbarseparator toolbarset toolbarspacer
+ toolbarspring toolbox tooltip tree
+ treecell treechildren treecol treecols
+ treeitem treerow treeseparator triple
+ vbox window wizard wizardpage
+ } ];
+}
+
+1;
+__END__
+
+=head1 NAME
+
+XUL::TagSet - Tag set for XUL
+
+=head1 SYNOPSIS
+
+ use XUL::TagSet;
+ my $list = XUL::TagSet->get_tag_list();
+ print "@$list";
+
+ my $altern = XUL::TagSet->get_alternate_spelling('template');
+ if ( defined $altern ) {
+ print $altern;
+ }
+
+ if ( XUL::TagSet->can_combine_empty_tags('button') ) {
+ print "<button label='OK' />";
+ }
+
+ # normal use
+ package MyApp::Templates;
+ use Template::Declare::Tags qw/ XUL::TagSet /;
+ use base 'Template::Declare';
+ # ...
+
+=head1 INHERITANCE
+
+ XUL::TagSet
+ isa Template::Declare::TagSet
+
+=head1 METHODS
+
+=over
+
+=item C<< $list = __PACKAGE__->get_tag_list() >>
+
+Returns an array ref for the tag names.
+
+The tag list was extracted from L<http://www.xulplanet.com/references/elemref/refall_elemref.xml> (only C<< <element name='...'> >> were recognized).
+
+=item C<< $bool = __PACKAGE__->get_alternate_spelling($tag) >>
+
+Returns the alternative spelling for a given tag if any or
+undef otherwise. Currently, C<template> is mapped to C<xul_template> because there is already a C<template> sub exported
+by L<Template::Declare::Tags>.
+
+=item C<< $bool = __PACKAGE__->can_combine_empty_tags($tag) >>
+
+Always returns true (inherited directly from the base class,
+L<Template::Declare::TagSet>.
+
+=back
+
+=head1 AUTHOR
+
+Agent Zhang E<lt>agentzh at gmail.comE<gt>
+
+=head1 SEE ALSO
+
+L<Template::Declare::TagSet>, L<HTML::TagSet>, L<Template::Declare::Tags>, L<Template::Declare>.
+
Added: Template-Declare/t/alternative.t
==============================================================================
--- (empty file)
+++ Template-Declare/t/alternative.t Thu Aug 9 00:13:11 2007
@@ -0,0 +1,32 @@
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+package MyApp::Templates;
+
+use Template::Declare::Tags 'HTML::TagSet';
+
+eval "td { 'hi' }";
+::ok $@, 'td is invalid';
+::is $@, "td {...} is invalid; use cell {...} instead.\n";
+
+eval "tr { 'hi' }";
+::ok $@, 'tr is invalid';
+::like $@, qr/Transliteration replacement not terminated/;
+
+package MyApp::Templates2;
+
+use base 'Template::Declare';
+use Template::Declare::Tags 'XUL::TagSet';
+
+template main => sub {
+ xul_tempalte {}
+};
+
+Template::Declare->init( roots => ['MyApp::Templates2']);
+my $out = Template::Declare->show('main') . "\n";
+::is $out, <<_EOC_;
+
+<template></template>
+_EOC_
+
Modified: Template-Declare/t/forms.t
==============================================================================
--- Template-Declare/t/forms.t (original)
+++ Template-Declare/t/forms.t Thu Aug 9 00:13:11 2007
@@ -35,7 +35,7 @@
Template::Declare->buffer->clear;
my $simple =(show('simple'));
ok($simple =~ '<form', "we have a form");
-diag ($simple);
+#diag ($simple);
ok_lint($simple);
}
Added: Template-Declare/t/tagset_html.t
==============================================================================
--- (empty file)
+++ Template-Declare/t/tagset_html.t Thu Aug 9 00:13:11 2007
@@ -0,0 +1,29 @@
+use strict;
+use warnings;
+
+package MyApp::Templates;
+
+use base 'Template::Declare';
+use Template::Declare::Tags qw/ HTML::TagSet /;
+
+template main => sub {
+ table {
+ row {
+ cell { "Hello, world!" }
+ }
+ }
+};
+
+package main;
+use Test::More tests => 1;
+Template::Declare->init( roots => ['MyApp::Templates']);
+my $out = Template::Declare->show('main') . "\n";
+is $out, <<_EOC_;
+
+<table>
+ <tr>
+ <td>Hello, world!</td>
+ </tr>
+</table>
+_EOC_
+
Added: Template-Declare/t/tagset_mix.t
==============================================================================
--- (empty file)
+++ Template-Declare/t/tagset_mix.t Thu Aug 9 00:13:11 2007
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+
+package MyApp::Templates;
+
+use base 'Template::Declare';
+use Template::Declare::Tags qw/ XUL::TagSet /;
+
+template main => sub {
+ groupbox {
+ caption { attr { label => 'Colors' } }
+ radiogroup {
+ for my $id ( qw< orange violet yellow > ) {
+ radio { attr { id => $id, label => ucfirst($id), $id eq 'violet' ? (selected => 'true') : () } }
+ }
+ }
+ }
+};
+
+package main;
+use Test::More tests => 1;
+Template::Declare->init( roots => ['MyApp::Templates']);
+my $out = Template::Declare->show('main') . "\n";
+is $out, <<_EOC_;
+
+<groupbox>
+ <caption label="Colors"></caption>
+ <radiogroup>
+ <radio id="orange" label="Orange"></radio>
+ <radio id="violet" label="Violet" selected="true"></radio>
+ <radio id="yellow" label="Yellow"></radio>
+ </radiogroup>
+</groupbox>
+_EOC_
+
Added: Template-Declare/t/tagset_xul.t
==============================================================================
--- (empty file)
+++ Template-Declare/t/tagset_xul.t Thu Aug 9 00:13:11 2007
@@ -0,0 +1,43 @@
+use strict;
+use warnings;
+
+package MyApp::Templates;
+
+use base 'Template::Declare';
+use Template::Declare::Tags qw/ HTML::TagSet XUL::TagSet /;
+
+template main => sub {
+ groupbox {
+ caption { attr { label => 'Colors' } }
+ radiogroup {
+ for my $id ( qw< orange violet yellow > ) {
+ radio { attr { id => $id, label => ucfirst($id), $id eq 'violet' ? (selected => 'true') : () } }
+ }
+ }
+ html {
+ body { p { 'hi' } }
+ }
+ }
+};
+
+package main;
+use Test::More tests => 1;
+Template::Declare->init( roots => ['MyApp::Templates']);
+my $out = Template::Declare->show('main') . "\n";
+is $out, <<_EOC_;
+
+<groupbox>
+ <caption label="Colors"></caption>
+ <radiogroup>
+ <radio id="orange" label="Orange"></radio>
+ <radio id="violet" label="Violet" selected="true"></radio>
+ <radio id="yellow" label="Yellow"></radio>
+ </radiogroup>
+ <html>
+ <body>
+ <p>hi</p>
+ </body>
+ </html>
+</groupbox>
+_EOC_
+
More information about the Jifty-commit
mailing list