cvsuser 02/03/21 20:29:35
Modified: P5EEx/Blue/P5EEx/Blue TemplateEngine.pm
Added: P5EEx/Blue/P5EEx/Blue/Widget Template.pm
P5EEx/Blue/P5EEx/Blue/Widget/HTML Template.pm
Log:
added template support
Revision Changes Path
1.2 +178 -13 p5ee/P5EEx/Blue/P5EEx/Blue/TemplateEngine.pm
Index: TemplateEngine.pm
===================================================================
RCS file: /cvs/public/p5ee/P5EEx/Blue/P5EEx/Blue/TemplateEngine.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- TemplateEngine.pm 5 Feb 2002 22:23:29 -0000 1.1
+++ TemplateEngine.pm 22 Mar 2002 04:29:35 -0000 1.2
@@ -1,6 +1,6 @@
#############################################################################
-## $Id: TemplateEngine.pm,v 1.1 2002/02/05 22:23:29 spadkins Exp $
+## $Id: TemplateEngine.pm,v 1.2 2002/03/22 04:29:35 spadkins Exp $
#############################################################################
package P5EEx::Blue::TemplateEngine;
@@ -20,10 +20,11 @@
use P5EEx::Blue::P5EE;
$context = P5EEx::Blue::P5EE->context();
- $template = $context->service("TemplateEngine"); # or ...
- $template = $context->template();
+ $template_engine = $context->service("TemplateEngine"); # or ...
+ $template_engine = $context->template_engine();
- ... TBD ...
+ $template = "index.html";
+ $text = $template_engine->render($template);
=head1 DESCRIPTION
@@ -110,25 +111,31 @@
=cut
#############################################################################
-# TBD()
+# render()
#############################################################################
-=head2 TBD()
+=head2 render()
- * Signature: $tbd_return = $repository->tbd($tbd_param);
- * Param: $tbd_param integer
- * Return: $tbd_return integer
- * Throws: P5EEx::Blue::Exception::Repository
+ * Signature: $text = $template_engine->render($template);
+ * Param: $template string
+ * Return: $text text
+ * Throws: P5EEx::Blue::Exception::TemplateEngine
* Since: 0.01
Sample Usage:
- $tbd_return = $repository->tbd($tbd_param);
+ $text = $template_engine->render($template);
=cut
-sub tbd {
- my ($self) = @_;
+sub render {
+ my ($self, $template) = @_;
+
+ my ($template_text, $values, $text);
+ $template_text = $self->read_template($template);
+ $values = $self->prepare_values();
+ $text = $self->substitute($template_text, $values);
+ $text;
}
#############################################################################
@@ -157,6 +164,164 @@
=cut
sub service_type () { 'TemplateEngine'; }
+
+#############################################################################
+# read_template()
+#############################################################################
+
+=head2 read_template()
+
+ * Signature: $template_text = $template_engine->read_template($template);
+ * Param: $template string
+ * Return: $template_text text
+ * Throws: P5EEx::Blue::Exception::TemplateEngine
+ * Since: 0.01
+
+ Sample Usage:
+
+ $template_text = $template_engine->read_template($template);
+
+=cut
+
+sub read_template {
+ my ($self, $template) = @_;
+
+ my ($template_dir, $template_text);
+ local(*FILE);
+ $template_dir = $self->{templateDir};
+ $template_dir = "templates" if (!$template_dir);
+
+ if (open(main::FILE,"< $template_dir/$template")) {
+ $template_text = join("",<main::FILE>);
+ }
+ else {
+ # maybe we should throw an exception here
+ $template_text = "Template [$template_dir/$template] not found.";
+ }
+
+ return($template_text);
+}
+
+#############################################################################
+# prepare_values()
+#############################################################################
+
+=head2 prepare_values()
+
+ * Signature: $values = $template_engine->prepare_values();
+ * Param: void
+ * Return: $values {}
+ * Throws: P5EEx::Blue::Exception::TemplateEngine
+ * Since: 0.01
+
+ Sample Usage:
+
+ $values = $template_engine->prepare_values();
+
+=cut
+
+sub prepare_values {
+ my ($self) = @_;
+
+ my ($session, %values);
+ $session = $self->{context}->session();
+
+ # OK. I'm breaking some of the encapsulation.
+ # They say Perl is post-modern. ;-)
+
+ if (defined $session->{cache}{Widget}{session} &&
+ ref($session->{cache}{Widget}{session}) eq "HASH") {
+ %values = %{$session->{cache}{Widget}{session}}; # make a copy
+ }
+ if (defined $session->{cache}{Widget} && ref($session->{cache}{Widget}) eq
"HASH") {
+ $values{WIDGET} = $session->{cache}{Widget}; # add ref to higher level
+ }
+ if (defined $session->{cache} && ref($session->{cache}) eq "HASH") {
+ $values{SESSION} = $session->{cache}; # add ref to higher level
+ }
+
+ return(\%values);
+}
+
+#############################################################################
+# substitute()
+#############################################################################
+
+=head2 substitute()
+
+ * Signature: $text = $template_engine->substitute($template_text, $values);
+ * Param: $template_text string
+ * Param: $values {}
+ * Return: $text text
+ * Throws: P5EEx::Blue::Exception::TemplateEngine
+ * Since: 0.01
+
+ Sample Usage:
+
+ $text = $template_engine->substitute($template_text, $values);
+
+This method substitutes
+(No subclass of this class need be used if the
+
+=cut
+
+sub substitute {
+ my ($self, $template_text, $values) = @_;
+
+ $self->{context}->dbgprint("DataTable->substitute()")
+ if ($P5EEx::Blue::DEBUG && $self->{context}->dbg());
+
+ my ($phrase, $var, $value, $context);
+ $context = $self->{context};
+ $values = {} if (! defined $values);
+
+ while ( $template_text =~ /\[([^\[\]]+)\]/ ) {
+ $phrase = $1;
+ while ( $phrase =~ /\{([^\{\}]+)\}/ ) {
+ $var = $1;
+ if (defined $values->{$var}) {
+ $value = $values->{$var};
+ $phrase =~ s/\{$var\}/$value/g;
+ }
+ else {
+ if ($var =~ /^(.+)\.([^.]+)$/) {
+ $value = $context->wget($1, $2);
+ if (defined $value) {
+ $phrase =~ s/\{$var\}/$value/g;
+ }
+ else {
+ $phrase = "";
+ }
+ }
+ else {
+ $phrase = "";
+ }
+ }
+ }
+ if ($phrase eq "") {
+ $template_text =~ s/\[[^\[\]]+\]\n?//; # zap it including (optional)
ending newline
+ }
+ else {
+ $template_text =~ s/\[[^\[\]]+\]/$phrase/;
+ }
+ }
+ while ( $template_text =~ /\{([^\{\}]+)\}/ ) { # vars of the form {var}
+ $var = $1;
+ if (defined $values->{$var}) {
+ $value = $values->{$var};
+ $template_text =~ s/\{$var\}/$value/g;
+ }
+ else {
+ $value = "";
+ if ($var =~ /^(.+)\.([^.]+)$/) {
+ $value = $context->wget($1, $2);
+ }
+ }
+ $value = "" if (!defined $value);
+ $template_text =~ s/\{$var\}/$value/g;
+ }
+ $template_text;
+}
=head1 ACKNOWLEDGEMENTS
1.1 p5ee/P5EEx/Blue/P5EEx/Blue/Widget/Template.pm
Index: Template.pm
===================================================================
######################################################################
## $Id: Template.pm,v 1.1 2002/03/22 04:29:35 spadkins Exp $
######################################################################
package P5EEx::Blue::Widget::Template;
$VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
use P5EEx::Blue::Widget;
@ISA = ( "P5EEx::Blue::Widget" );
use strict;
=head1 NAME
P5EEx::Blue::Widget::Template - A widget built from a template, rendered by a
TemplateEngine
=head1 SYNOPSIS
use P5EEx::Blue::Widget::Template;
=cut
#############################################################################
# PUBLIC METHODS
#############################################################################
=head1 Public Methods:
=cut
#############################################################################
# display()
#############################################################################
=head2 display()
* Signature: $text = $widget->display();
* Param: void
* Return: $text text
* Throws: P5EEx::Blue::Exception::Widget
* Since: 0.01
Sample Usage:
$text = $widget->display();
Note: By using the P5EEx::Blue::Widget::Template class, the developer or
deployer is not making any guarantee about what type of text will be emitted
when the template is rendered. If the output were known to be HTML,
perhaps the P5EEx::Blue::Widget::HTML::Template would be a better choice
of widget class to use instead.
=cut
sub display {
my $self = shift;
my ($name, $msg);
my ($text, $template_name, $template_engine, $session, %vars);
$self->{context}->dbgprint("P5EEx::Blue::Widget::Template(",
$self->{name}, ")->display()")
if ($P5EEx::Blue::DEBUG && $self->{context}->dbg(1));
$name = $self->{name};
$template_name = $self->{templateName};
return "[$name] No template specified (templateName attribute)";
$session = $self->{context}->session();
# OK. I'm breaking some of the encapsulation.
# They say Perl is post-modern. ;-)
if (defined $session->{cache}{Widget} &&
ref($session->{cache}{Widget}) eq "HASH") {
%vars = %{$session->{cache}{Widget}}; # make a shallow copy
}
if (defined $session->{cache} && ref($session->{cache}) eq "HASH") {
$vars{SESSION} = $session->{cache}; # add ref to higher level
}
eval {
$template_engine =
$self->{context}->template_engine($self->{templateEngine});
$text = $template_engine->render($template_name, \%vars);
};
if ($@) {
if (ref($@) eq "") { # i.e. a string thrown with "die"
$msg = $@;
}
elsif ($@->isa("P5EEx::Blue::Exception")) {
$msg = $@->error . "\n" . $@->trace->as_string . "\n";
}
else {
$@->rethrow();
}
$text = <<EOF;
Template Display Error: $name
$msg
EOF
}
return $text;
}
1;
1.1 p5ee/P5EEx/Blue/P5EEx/Blue/Widget/HTML/Template.pm
Index: Template.pm
===================================================================
######################################################################
## $Id: Template.pm,v 1.1 2002/03/22 04:29:35 spadkins Exp $
######################################################################
package P5EEx::Blue::Widget::HTML::Template;
$VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
use P5EEx::Blue::Widget::HTML;
@ISA = ( "P5EEx::Blue::Widget::HTML" );
use strict;
=head1 NAME
P5EEx::Blue::Widget::HTML::Template - An HTML widget built from a template, rendered
by a TemplateEngine
=head1 SYNOPSIS
use P5EEx::Blue::Widget::HTML::Template;
=cut
#############################################################################
# ATTRIBUTES
#############################################################################
=head1 Attributes
templateEngine - The name of the TemplateEngine service that will do the
rendering. If not given, the name "default" will be used.
templateName - The name of the template that should be rendered.
If not given, the widget name is changed to a template
name by changing dots (".") to slashes ("/") and
appending ".html".
=cut
#############################################################################
# PUBLIC METHODS
#############################################################################
=head1 Public Methods
=cut
#############################################################################
# html()
#############################################################################
=head2 html()
* Signature: $html = $w->html();
* Param: void
* Return: $html text
* Throws: P5EE::Blue::Exception
* Since: 0.01
Sample Usage:
print $w->html();
The html() method returns the HTML output of the Template as rendered through
its TemplateEngine.
Note: By using the P5EEx::Blue::Widget::HTML::Template, the developer or
deployer is guaranteeing that the output of the template will be valid HTML.
If this is not the case, perhaps the P5EEx::Blue::Widget::Template is the
correct widget class to use instead.
=cut
sub html {
my $self = shift;
my ($name);
my ($html, $template_name, $template_engine);
$self->{context}->dbgprint("P5EEx::Blue::Widget::Template(",
$self->{name}, ")->display()")
if ($P5EEx::Blue::DEBUG && $self->{context}->dbg(1));
$name = $self->{name};
$template_name = $self->{templateName};
if (!$template_name) {
$template_name = $name;
$template_name =~ s/\./\//g
$template_name .= ".html";
}
$template_engine = $self->{context}->template_engine($self->{templateEngine});
$html = $template_engine->render($template_name);
return $html;
}
1;