[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