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;
  
  
  
  


Reply via email to