summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2017-12-27 10:16:22 +0100
committerYorhel <git@yorhel.nl>2017-12-27 10:17:22 +0100
commit35776908b286b3f31a7d14f745f5ec6641c97fd6 (patch)
tree2b8b4c53992cf3a78a56295374d635b7bc03c981
parent60273e1e79ed06840530450b2888cfa5c8933cce (diff)
TUWF::XML: Support multiple function naming flavors
Read: "I've no clue which style is best and everyone has their own opinions, so let's just support everything!" This is a breaking change for the :html5 group, but that group was only added recently and did not yet make it into a stable TUWF release, so there's little actual breakage.
-rwxr-xr-xexamples/singlefile.pl8
-rw-r--r--lib/TUWF/XML.pm60
-rw-r--r--lib/TUWF/XML.pod163
3 files changed, 148 insertions, 83 deletions
diff --git a/examples/singlefile.pl b/examples/singlefile.pl
index 0a9445a..88f8d09 100755
--- a/examples/singlefile.pl
+++ b/examples/singlefile.pl
@@ -19,7 +19,7 @@ use lib $ROOT.'/lib';
# load TUWF and import all html functions
-use TUWF ':html5', 'mkclass';
+use TUWF ':Html5', 'mkclass';
TUWF::set debug => 1;
@@ -46,9 +46,9 @@ TUWF::get '/' => sub {
TUWF::get qr{/sub/(?<capturename>.*)} => sub {
# output a plain text file containing $uri
tuwf->resHeader('Content-Type' => 'text/plain; charset=UTF-8');
- lit tuwf->capture(1);
- lit "\n";
- lit tuwf->capture('capturename');
+ Lit tuwf->capture(1);
+ Lit "\n";
+ Lit tuwf->capture('capturename');
};
diff --git a/lib/TUWF/XML.pm b/lib/TUWF/XML.pm
index 77a3857..b4be372 100644
--- a/lib/TUWF/XML.pm
+++ b/lib/TUWF/XML.pm
@@ -23,19 +23,24 @@ BEGIN {
a abbr acronym address area b base bdo big blockquote body br button caption
cite code col colgroup dd del dfn div dl dt em fieldset form h1 h2 h3 h4 h5 h6
head i img input ins kbd label legend li Link Map meta noscript object ol
- optgroup option p param pre q samp script Select small span strong style Sub
+ optgroup option p param pre Q samp script Select small span strong style Sub
sup table tbody td textarea tfoot th thead title Tr tt ul var
|;
my @html5tags = qw|
- A Abbr Address Area Article Aside Audio B Base Bb Bdo Blockquote Body Br
- Button Canvas Caption Cite Code Col Colgroup Command Datagrid Datalist Dd
- Del Details Dfn Dialog Div Dl Dt Em Embed Fieldset Figure Footer Form H1 H2
- H3 H4 H5 H6 Head Header Hr I Iframe Img Input Ins Kbd Label Legend Li Link
- Map Mark Menu Meta Meter Nav Noscript Object Ol Optgroup Option Output P
- Param Pre Progress Q Rp Rt Ruby Samp Script Section Select Small Source
- Span Strong Style Sub Sup Table Tbody Td Textarea Tfoot Th Thead Time Title
- Tr Ul Var Video
+ a abbr address area article aside audio b base bb bdo blockquote body br
+ button canvas caption cite code col colgroup command datagrid datalist dd
+ del details dfn dialog div dl dt em embed fieldset figure footer form h1 h2
+ h3 h4 h5 h6 head header hr i iframe img input ins kbd label legend li Link
+ Map mark menu meta meter nav noscript object ol optgroup option output p
+ param pre progress Q rp rt ruby samp script section Select small source
+ span strong style Sub sup table tbody td textarea tfoot th thead Time title
+ Tr ul var video
|;
+ my @Htmltags = map ucfirst, @htmltags;
+ my @Html5tags = map ucfirst, @html5tags;
+ my @html_tags = map lc($_).'_', @htmltags;
+ my @html5_tags = map lc($_).'_', @html5tags;
+ my @all = uniq @htmltags, @html5tags, @Htmltags, @Html5tags, @html_tags, @html5_tags;
# boolean/empty/self-closing tags
my %htmlbool = map +($_,1), qw{
@@ -44,8 +49,8 @@ BEGIN {
# create the subroutines to map to the html tags
no strict 'refs';
- for my $e (uniq @html5tags, @htmltags) {
- my $le = lc $e;
+ for my $e (@all) {
+ (my $le = lc $e) =~ s/_$//;
*{__PACKAGE__."::$e"} = sub {
my $s = ref($_[0]) eq __PACKAGE__ ? shift : $OBJ;
$s->tag($le, @_, $htmlbool{$le} && $#_%2 ? undef : ());
@@ -53,14 +58,20 @@ BEGIN {
}
# functions to export
- my @htmlexport = (qw| html Html lit txt tag end |);
- my @xmlexport = qw| xml lit txt tag end |;
-
- @EXPORT_OK = uniq @htmlexport, @html5tags, @htmltags, @xmlexport, 'mkclass', 'xml_escape', 'html_escape';
+ @EXPORT_OK = (@all, qw(
+ mkclass xml_escape html_escape
+ tag html lit txt end
+ Tag Html Lit Txt End
+ tag_ html_ lit_ txt_ end_
+ ));
%EXPORT_TAGS = (
- html => [ @htmlexport, @htmltags ],
- html5 => [ @htmlexport, @html5tags ],
- xml => \@xmlexport,
+ html => [ @htmltags, qw(tag html lit txt end ) ],
+ html5 => [ @html5tags, qw(tag html lit txt end ) ],
+ Html => [ @Htmltags, qw(Tag Html Lit Txt End ) ],
+ Html5 => [ @Html5tags, qw(Tag Html Lit Txt End ) ],
+ html_ => [ @html_tags, qw(tag_ html_ lit_ txt_ end_) ],
+ html5_=> [ @html5_tags, qw(tag_ html_ lit_ txt_ end_) ],
+ xml => [ qw(xml tag lit txt end) ],
);
};
@@ -133,6 +144,9 @@ sub lit {
$s->{write}->($_) for @_;
}
+*Lit = \&lit;
+*lit_ = \&lit;
+
# output text (HTML escaped)
sub txt {
@@ -140,6 +154,9 @@ sub txt {
$s->lit(xml_escape $_) for @_;
}
+*Txt = \&txt;
+*txt_ = \&txt;
+
# Output any XML or HTML tag.
# Arguments Output
@@ -178,6 +195,9 @@ sub tag {
}
}
+*Tag = \&tag;
+*tag_ = \&tag;
+
# Ends the last opened tag
sub end {
@@ -190,6 +210,9 @@ sub end {
$s->lit('</'.$l.'>');
}
+*End = \&end;
+*end_ = \&end;
+
sub html {
my $s = ref($_[0]) eq __PACKAGE__ ? shift : $OBJ;
@@ -215,6 +238,7 @@ sub html {
}
*Html = \&html;
+*html_ = \&html;
# Writes an xml header, doesn't open an <xml> tag, and doesn't need an
diff --git a/lib/TUWF/XML.pod b/lib/TUWF/XML.pod
index b022b3d..e86dda4 100644
--- a/lib/TUWF/XML.pod
+++ b/lib/TUWF/XML.pod
@@ -21,29 +21,27 @@ can be expressed in proper XML, extending it to write XML was a small step. In
fact, this module is basically an XML generator with convenience functions for
HTML.
-This module provides two interfaces: a functional interface and an object
+This module provides two interfaces: a function interface and an object
interface. Both can be used, even at the same time. The object interface is
required in threaded environments or when you want to generate multiple
-documents simultaneously, while the functional interface is far more
+documents simultaneously, while the function interface is far more
convenient, but has some limitations and contributes to namespace pollution.
-The functional interface looks like this:
+The function interface looks like this:
use TUWF::XML ':html5';
- # -- or, from within a TUWF website:
- use TUWF ':html5';
TUWF::XML->new(default => 1);
- Html sub {
- Head sub {
- Title 'Document title!';
+ html sub {
+ head sub {
+ title 'Document title!';
};
};
-
+
# -- or, in more imperative style:
- Html;
- Head;
- Title 'Document title!';
+ html;
+ head;
+ title 'Document title!';
end;
end 'html';
@@ -53,16 +51,16 @@ And the equivalent, using the object interface:
use TUWF::XML;
my $xml = TUWF::XML->new();
- $xml->Html(sub {
- $xml->Head(sub {
- $xml->Title('Document title!');
+ $xml->html(sub {
+ $xml->head(sub {
+ $xml->title('Document title!');
});
});
-
+
# -- or, again in more imperative style:
- $xml->Html;
- $xml->Head;
- $xml->Title('Document title!');
+ $xml->html;
+ $xml->head;
+ $xml->title('Document title!');
$xml->end;
$xml->end('html');
@@ -70,11 +68,11 @@ You may also combine the two interfaces by setting the I<default> option in
C<new()> and mixing method calls and function calls, but that is rather
inconsistent and messy.
-TUWF automatically calls C<TUWF::XML-E<gt>new(default =E<gt> 1, ..)> at the start of
-each request, so you can start generating XML or HTML using the functional
-interface without having to initialize this module. Of course, if you wish to
-generate an other XML document while processing a request, you should use the
-object interface for that, otherwise this may cause problems with other
+TUWF automatically calls C<TUWF::XML-E<gt>new(default =E<gt> 1, ..)> at the
+start of each request, so you can start generating XML or HTML using the
+function interface without having to initialize this module. Of course, if you
+wish to generate an other XML document while processing a request, you should
+use the object interface for that, otherwise this may cause problems with other
functions within the TUWF framework that assume that the default C<TUWF::XML>
object has been set to output to TUWF.
@@ -260,31 +258,8 @@ Is more safely written as:
=head2 <html-tag>(attribute => value, .., contents)
For convenience, all HTML5 and XHTML 1.0 tags have their own function that acts
-as a shorthand for calling C<tag()>. The following XHTML 1.0 functions are
-defined (exported by C<:html>):
-
- a abbr acronym address area b base bdo big blockquote body br button caption
- cite code col colgroup dd del dfn div dl dt em fieldset form h1 h2 h3 h4 h5
- h6 head i img input ins kbd label legend li Link Map meta noscript object ol
- optgroup option p param pre q samp script Select small span strong style Sub
- sup table tbody td textarea tfoot th thead title Tr tt ul var
-
-Note that some functions start with an upper-case character. This is to avoid
-problems with reserved words or overriding Perl core functions with the same
-name.
-
-The following HTML5 tags are exported with C<:html5>. For consistency, and to
-soften the effects of namespace pollution to some extend, all of these start
-with an upper-case character:
-
- A Abbr Address Area Article Aside Audio B Base Bb Bdo Blockquote Body Br
- Button Canvas Caption Cite Code Col Colgroup Command Datagrid Datalist Dd Del
- Details Dfn Dialog Div Dl Dt Em Embed Fieldset Figure Footer Form H1 H2 H3 H4
- H5 H6 Head Header Hr I Iframe Img Input Ins Kbd Label Legend Li Link Map Mark
- Menu Meta Meter Nav Noscript Object Ol Optgroup Option Output P Param Pre
- Progress Q Rp Rt Ruby Samp Script Section Select Small Source Span Strong
- Style Sub Sup Table Tbody Td Textarea Tfoot Th Thead Time Title Tr Ul Var
- Video
+as a shorthand for calling C<tag()>. For the function naming flavors, see
+L</IMPORT OPTIONS> below.
Some tags are I<boolean>, meaning that they should always be self-closing and
not have any contents. To generate these tags with C<tag()>, you have to
@@ -296,16 +271,16 @@ following tags:
Again, some examples:
- Br; # tag 'br', undef;
- Div; # tag 'div';
+ br; # tag 'br', undef;
+ div; # tag 'div';
- Title 'Page title';
+ title 'Page title';
# tag 'title', 'Page title';
Link rel => 'shortcut icon', href => '/favicon.ico';
# tag 'link', rel => 'shortcut icon', href => '/favicon.ico', undef;
- Textarea rows => 10, cols => 50, $content;
+ textarea rows => 10, cols => 50, $content;
# tag 'textarea', rows => 10, cols => 50, $content;
@@ -320,16 +295,82 @@ function (except C<new()>) by specifying it on the C<use> line:
lit html_escape $content;
br;
-Or you can import an entire group of functions by adding C<:xml>, C<:html> or
-C<:html5> to the list. The C<:xml> group consists of the functions C<xml()>,
-C<lit()>, C<txt()>, C<tag()>, and C<end()>. The C<:html> group consists of all
-(mostly lowercase) xhtml-tag functions, and the C<:html5> group consists of all
-the HTML5 tags starting with an upper-case character. The C<:html> and
-C<:html5> groups also export the following functions: C<html()>, C<lit()>,
-C<txt()>, C<tag()> and C<end()>.
+Or you can import an entire group of functions by adding the C<:xml> group or
+any of the HTML flavors to the list:
+
+=over
+
+=item B<:xml>
+
+This group exports the functions C<xml()>, C<lit()>, C<txt()>, C<tag()>, and
+C<end()>. All lower-case.
+
+=item B<:html>
+
+This group exports the following functions:
+
+ tag html lit txt end
+
+And the following XHTML 1.0 functions:
+
+ a abbr acronym address area b base bdo big blockquote body br button caption
+ cite code col colgroup dd del dfn div dl dt em fieldset form h1 h2 h3 h4 h5
+ h6 head i img input ins kbd label legend li Link Map meta noscript object ol
+ optgroup option p param pre Q samp script Select small span strong style Sub
+ sup table tbody td textarea tfoot th thead title Tr tt ul var
+
+Note that some functions start with an upper-case character. This is to avoid
+problems with reserved keywords or overriding Perl core functions with the same
+name.
+
+=item B<:html5>
+
+Same as C<:html>, except that instead of XHTML 1.0, this exports all HTML 5
+functions:
+
+ a abbr address area article aside audio b base bb bdo blockquote body br
+ button canvas caption cite code col colgroup command datagrid datalist dd
+ del details dfn dialog div dl dt em embed fieldset figure footer form h1 h2
+ h3 h4 h5 h6 head header hr i iframe img input ins kbd label legend li Link
+ Map mark menu meta meter nav noscript object ol optgroup option output p
+ param pre progress Q rp rt ruby samp script section Select small source
+ span strong style Sub sup table tbody td textarea tfoot th thead Time title
+ Tr ul var video
+
+=item B<:Html> and B<:Html5>
+
+These are equivalent to C<:html> and C<html5>, respectively, except that all
+functions start with an upper case character for consistency. This flavor
+looks like:
+
+ use TUWF:XML ':Html5';
+ Html sub {
+ Head sub {
+ Title 'Document title!';
+ Tag 'a', href => '/', 'Home';
+ Lit '&nbsp;';
+ };
+ };
+
+=item B<:html_> and B<:html5_>
+
+These are equivalent to C<:html> and C<html5>, respectively, except that all
+functions are lower-case and are suffixed with an underscore. This flavor is
+similar to Haskell's L<Lucid|https://hackage.haskell.org/package/lucid>:
+
+ use TUWF::XML ':html5_';
+ html_ sub {
+ head_ sub {
+ title_ 'Document title!';
+ tag_ 'a', href => '/', 'Home';
+ lit_ '&nbsp;';
+ };
+ };
+
+=back
When using this module in a TUWF website, you can substitute C<TUWF::XML> with
-C<TUWF>. The main TUWF module will then redirect its import argments to this
+C<TUWF>. The main TUWF module will then redirect its import arguments to this
module. This saves some typing, and allows you to import functions from other
TUWF modules on the same C<use> line.