[Jifty-commit] r2167 - in Template-Declare: . lib lib/Template
lib/Template/Declare lib/Wifty t
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Wed Nov 15 21:42:11 EST 2006
Author: jesse
Date: Wed Nov 15 21:42:11 2006
New Revision: 2167
Added:
Template-Declare/Makefile.PL
Template-Declare/lib/
Template-Declare/lib/MyApp/
Template-Declare/lib/Template/
Template-Declare/lib/Template/Declare/
Template-Declare/lib/Template/Declare.pm
Template-Declare/lib/Template/Declare/Tags.pm
Template-Declare/lib/Wifty/
Template-Declare/mycode
Template-Declare/pl
Template-Declare/t/
Template-Declare/t/trivial.t
Modified:
Template-Declare/ (props changed)
Log:
* Initial version of Template::Declare
Added: Template-Declare/Makefile.PL
==============================================================================
--- (empty file)
+++ Template-Declare/Makefile.PL Wed Nov 15 21:42:11 2006
@@ -0,0 +1,6 @@
+use inc::Module::Install;
+name('Template-Declare');
+license('Pelr');
+author('Jesse Vincent <jesse at bestpractical.com>');
+version_from('lib/Template/Declare.pm');
+WriteAll;
Added: Template-Declare/lib/Template/Declare.pm
==============================================================================
--- (empty file)
+++ Template-Declare/lib/Template/Declare.pm Wed Nov 15 21:42:11 2006
@@ -0,0 +1,41 @@
+use warnings;
+use strict;
+
+package Template::Declare;
+
+$Template::Declare::VERSION = "-1.00_01";
+
+=head1 NAME
+
+Template::Declare
+
+=head1 DESCRIPTION
+
+C<Template::Declare> is a prototype declarative code-based HTML
+templating system. Yes. Another one. There are many others like it,
+but this one is ours. It's designed to allow template libraries to be
+composed, mixed in and inherited. The code isn't (yet) pretty nor is
+it in any way optimized. It's not well enough tested, either.
+
+In the coming weeks, months and years, Template::Declare we will extend it
+to support all the things we've designed it to do.
+
+=head1 BUGS
+
+Crawling all over, baby. Be very, very careful. This code is so cutting edge, it can only be fashioned from carbon nanotubes.
+
+The only real documentation is in t/trivial.t
+
+=cut
+
+
+sub has_template {
+ my $pkg = shift;
+ my $templatename = shift;
+
+ my $callable = "_jifty_template_".$templatename;
+ return $pkg->can($callable);
+
+}
+
+1;
Added: Template-Declare/lib/Template/Declare/Tags.pm
==============================================================================
--- (empty file)
+++ Template-Declare/lib/Template/Declare/Tags.pm Wed Nov 15 21:42:11 2006
@@ -0,0 +1,114 @@
+use warnings;
+use strict;
+
+package Template::Declare::Tags;
+use vars qw/@EXPORT @EXPORT_OK $self/;
+use base 'Exporter';
+ at EXPORT_OK = (qw(with));
+ at EXPORT = (qw(with template private show outs outs in_isolation));
+
+our $DEPTH = 0;
+our %ATTRIBUTES = ();
+our $BUFFER = '';
+
+sub outs { $BUFFER .= join('',grep { defined } @_); return ''; }
+sub template ($$) {
+ my $templatename = shift;
+ my $coderef = shift;
+ no strict 'refs';
+ *{(caller(0))[0]."::_jifty_template_$templatename"} = sub { my $self = shift; $coderef->(@_) } ;
+
+}
+sub private ($){}
+
+sub install_tag {
+ my $tag = shift;
+ { no strict 'refs';
+ *{$tag} = sub (&) {local *__ANON__ = $tag; _tag(@_)};
+ }
+ push @EXPORT_OK, $tag;
+ push @EXPORT, $tag;
+}
+
+
+our %TAGS = ( html => {}, head => {}, title => {}, meta => {}, body => {}, p => {}, hr => {}, br => {}, ul => {}, dl => {}, dt=> {}, dd => {}, ol => {}, li => {}, b => {}, i => {}, em => {}, div => {}, span => {}, form => {}, input => {}, textarea => {}, select => {}, option => {}, a => {}, pre => {}, code => {}, address => {}, iframe => {}, script => {}, h1 => {}, h2=> {}, h3 => {}, h4 => {}, h5 => {}, ); install_tag($_) for(keys %TAGS);
+
+
+
+
+sub with (@) {
+ %ATTRIBUTES = ();
+ while (@_) {
+ my $key = shift || '';
+ my $val = shift || '';
+ $ATTRIBUTES{$key} = $val;
+ }
+}
+
+sub _tag {
+ my $code = shift;
+ my ($package, $filename, $line, $subroutine, $hasargs,
+ $wantarray, $evaltext, $is_require, $hints, $bitmask
+ )
+ = caller(1);
+
+ # This is the hash of attributes filled in by attr() calls in the code;
+
+ my $tag = $subroutine;
+ $tag =~ s/^.*\:\://;
+ $BUFFER .= "\n" . ( " " x $DEPTH ) . "<$tag"
+ . join( '',
+ map { qq{ $_="} . ( $ATTRIBUTES{$_} || '' ) . qq{"} }
+ keys %ATTRIBUTES );
+ %ATTRIBUTES = ();
+
+ my $buf;
+ {
+ local $BUFFER = '';
+ local $DEPTH = $DEPTH + 1;
+ my $last = $code->() || '';
+
+ $buf = $BUFFER;
+
+# We concatenate "" to force scalarization when $last or $BUFFER is solely a Jifty::Web::Link
+ $buf .= $last unless ($BUFFER); # HACK WRONG;
+ }
+
+ # default to <tag/> rather than <tag></tag> if there's no content
+ if ($buf) {
+ $BUFFER .= ( ">" . $buf );
+ $BUFFER .= "\n" . ( " " x $DEPTH ) if ( $buf =~ /\n/ );
+ $BUFFER .= "</$tag>";
+ } else {
+ $BUFFER .= "/>";
+ }
+ return '';
+}
+
+=head2 show [$class or $object] templatename
+
+show can either be called with a template name or a package/object and
+a template. (It's both functional and OO.)
+
+Displays that template, if it exists.
+
+
+=cut
+
+sub show {
+ $self = shift if ( $_[0]->isa('Template::Declare') );
+ my $templatename = shift;
+ my $buf;
+ {
+ local $BUFFER = '';
+ my $callable = "_jifty_template_" . $templatename;
+
+ # may want to just use the return value of has_template eventuall
+ my $ret = $self->$callable(@_) if $self->has_template($templatename);
+ $buf = $BUFFER;
+ }
+ $BUFFER .= $buf;
+ return $buf;
+}
+
+1;
Added: Template-Declare/mycode
==============================================================================
--- (empty file)
+++ Template-Declare/mycode Wed Nov 15 21:42:11 2006
@@ -0,0 +1,24 @@
+use warnings;
+use strict;
+
+use Wifty::Widgets;
+use Template::Declare::Tags;
+
+
+print html {
+
+ head {
+ attr id => 5;
+ attr name => "I hate you";
+ };
+ body {
+ for ( 1 .. 5 ) {
+ span { attr class => "bozo"; 'yyy' };
+ }
+ attr bgcolor => "#ffffff";
+ p {'xxx'};
+ Wifty::Widgets->login_widget();
+ }
+};
+
+1;
Added: Template-Declare/pl
==============================================================================
--- (empty file)
+++ Template-Declare/pl Wed Nov 15 21:42:11 2006
@@ -0,0 +1,63 @@
+use warnings; use strict;
+use vars qw'%ATTRIBUTES $BUFFER $DEPTH';
+sub html (&) { _element(@_); }
+sub head (&) { _element(@_); }
+sub body (&) { _element(@_); }
+sub p (&) { _element(@_); }
+sub br (&) { _element(@_); }
+sub ul (&) { _element(@_); }
+sub li (&) { _element(@_); }
+sub dl (&) { _element(@_); }
+sub ol (&) { _element(@_); }
+sub b (&) { _element(@_); }
+sub i (&) { _element(@_); }
+sub em (&) { _element(@_); }
+sub div (&) { _element(@_); }
+sub span (&) { _element(@_); }
+sub attr ($$) {my ($key,$val)=(@_); $ATTRIBUTES{$key} = $val; }
+
+sub _element {
+ my $code = shift;
+ my ($package, $filename, $line, $subroutine, $hasargs,
+ $wantarray, $evaltext, $is_require, $hints, $bitmask
+ )
+ = caller(1);
+
+ local %ATTRIBUTES = ();
+
+ my $tag = $subroutine;
+ $tag =~ s/^$package\:\://;
+
+my $buf;
+ {
+ local $BUFFER = '';
+ local $DEPTH = $DEPTH +1;
+
+ $code->();
+ $buf = $BUFFER;
+}
+ $BUFFER .= "\n".(" " x $DEPTH). "<$tag"
+ . join( '', map {qq{ $_="$ATTRIBUTES{$_}"}} keys %ATTRIBUTES ) . ">"
+ . ($buf ? ($buf . "\n" . (" " x $DEPTH) ) : '')
+ ."</$tag>";
+
+ return $BUFFER;
+}
+
+
+print html {
+
+ head {
+ attr id => 5;
+ attr name => "I hate you";
+ };
+ body {
+ for ( 1 .. 5 ) {
+ span { attr class => "bozo"; 'yyy' };
+ }
+ attr bgcolor => "#ffffff";
+ p {'xxx'};
+ }
+};
+
+
Added: Template-Declare/t/trivial.t
==============================================================================
--- (empty file)
+++ Template-Declare/t/trivial.t Wed Nov 15 21:42:11 2006
@@ -0,0 +1,184 @@
+use warnings;
+use strict;
+
+
+package Wifty::UI;
+use base qw/Template::Declare/;
+use Template::Declare::Tags;
+use Test::More;
+
+template simple => sub {
+
+html {
+ head { };
+ body {
+ show 'content';
+ }
+}
+
+};
+
+template content => sub {
+ with( id => 'body' ), div {
+ outs('This is my content');
+ };
+
+};
+
+
+template wrapper => sub {
+ my ( $title, $coderef) = (@_);
+ outs('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
+ with ( xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => "en"),
+ html {
+ head {
+ with ( 'http-equiv' => "content-type", 'content' => "text/html; charset=utf-8"),
+ meta { };
+ with ( name => "robots", content => "all"), meta { };
+ title { outs($title) };
+ };
+ body {
+ $coderef->();
+ }
+
+ }
+};
+
+template markup => sub {
+ my $self = shift;
+
+ show(
+ 'wrapper',
+ 'My page!',
+ sub {
+
+ with( id => 'syntax' ), div {
+ div {
+ with(
+ href => "#",
+ onclick =>
+ "Element.toggle('syntax_content');return(false);"
+ ),
+ a {
+ b {'Wiki Syntax Help'};
+ }
+ };
+ with( id => 'syntax_content' ), div {
+ h3 {'Phrase Emphasis'};
+ code {
+ b { '**bold**'; };
+ i {'_italic_'};
+ };
+
+ h3 {'Links'};
+
+ code {'Show me a [wiki page](WikiPage)'};
+ code {'An [example](http://url.com/ "Title")'};
+ h3 {'Headers'};
+ pre {
+ code {
+ join( "\n",
+ '# Header 1',
+ '## Header 2',
+ '###### Header 6' );
+ }
+ };
+ h3 {'Lists'};
+ p {'Ordered, without paragraphs:'};
+ pre {
+ code { join( "\n", '1. Foo', '2. Bar' ); };
+ };
+ p {' Unordered, with paragraphs:'};
+ pre {
+ code {
+ join( "\n",
+ '* A list item.',
+ 'With multiple paragraphs.',
+ '* Bar' );
+ }
+ };
+ h3 {'Code Spans'};
+
+ p {
+ code {'`<code>`'}
+ . 'spans are delimited by backticks.';
+ };
+
+ h3 {'Preformatted Code Blocks'};
+
+ p {
+ 'Indent every line of a code block by at least 4 spaces.';
+ };
+
+ pre {
+ code {
+ 'This is a normal paragraph.' . "\n\n" . "\n"
+ . ' This is a preformatted' . "\n"
+ . ' code block.';
+ };
+ };
+
+ h3 {'Horizontal Rules'};
+
+ p {
+ 'Three or more dashes: ' . code {'---'};
+ };
+
+ address {
+ '(Thanks to <a href="http://daringfireball.net/projects/markdown/dingus">Daring Fireball</a>)';
+ }
+ }
+ };
+ script {
+ qq{
+ // javascript flyout by Eric Wilhelm
+ // TODO use images for minimize/maximize button
+ // Is there a way to add a callback?
+ Element.toggle('syntax_content');
+ };
+ };
+ }
+ );
+};
+
+package Template::Declare::Tags;
+
+use Test::More qw/no_plan/;
+use HTML::Lint;
+
+our $self;
+local $self = {};
+bless $self, 'Wifty::UI';
+{
+local $Template::Declare::Tags::BUFFER;
+my $simple =(show('simple'));
+ok($simple =~ 'This is my content');
+#diag ($simple);
+ok_lint($simple);
+}
+{local $Template::Declare::Tags::BUFFER;
+my $out = (show('markup'));
+#diag($out);
+my @lines = split("\n",$out);
+
+ok($out =~ /Fireball/, "We found fireball in the output");
+my $count = grep { /Fireball/} @lines;
+is($count, 1, "Only found one");
+ok_lint($out);
+
+}
+sub ok_lint {
+ my $html = shift;
+
+ my $lint = HTML::Lint->new;
+
+ $lint->parse($html);
+ is( $lint->errors, 0, "Lint checked clean" );
+ foreach my $error ( $lint->errors ) {
+ diag( $error->as_string );
+ }
+
+}
+
+
+1;
More information about the Jifty-commit
mailing list