[Templates-cvs] cvs commit: TT3/lib/Template Context.pm
cvs@template-toolkit.org
cvs@template-toolkit.org
Fri, 17 Dec 2004 15:34:51 +0000
cvs 04/12/17 15:34:50
Modified: lib/Template Context.pm
Log:
* new implementation of template() and component()
Revision Changes Path
1.15 +105 -147 TT3/lib/Template/Context.pm
Index: Context.pm
===================================================================
RCS file: /template-toolkit/TT3/lib/Template/Context.pm,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Context.pm 2004/12/17 14:20:49 1.14
+++ Context.pm 2004/12/17 15:34:50 1.15
@@ -16,7 +16,7 @@
# modify it under the same terms as Perl itself.
#
# REVISION
-# $Id: Context.pm,v 1.14 2004/12/17 14:20:49 abw Exp $
+# $Id: Context.pm,v 1.15 2004/12/17 15:34:50 abw Exp $
#
#========================================================================
@@ -39,7 +39,7 @@
use constant FETCH => 'fetch';
use constant GET => 'get';
-our $VERSION = sprintf("%d.%02d", q$Revision: 1.14 $ =~ /(\d+)\.(\d+)/);
+our $VERSION = sprintf("%d.%02d", q$Revision: 1.15 $ =~ /(\d+)\.(\d+)/);
our $DEBUG = 0 unless defined $DEBUG;
our $ERROR = '';
our $THROW = 'context';
@@ -176,10 +176,10 @@
# create a path object for manipulating the path and cache it
my $pathclass = $self->pkgvar( PATH => $PATH );
$pathclass->new($self->{ path } || $self->path())
- || return $self->error($pathclass->error());
+ || $self->throw( path => $pathclass->error() );
};
my $paths = $path->paths(@_)
- || $self->error($path->error());
+ || $self->throw( path => $path->error() );
return wantarray ? @$paths : $paths;
}
@@ -227,73 +227,27 @@
$self->debug("component($name)\n") if $debug;
+ # $name may already be a component object
+ if (UNIVERSAL::isa($name, $cclass)) {
+ $self->debug(" - already a component: ", $name->id()) if $debug;
+ return $name;
+ }
+
+ # fetch template for this component $name
+ my $template = $self->template($name);
+
# TODO: check local component cache
my $global = $self->{ global } || $self->global();
- my $paths = $global->{ paths }; # id map for static paths
my $cache = $global->{ cache }; # in-memory component cache
my $store = $global->{ store }; # on-disk component store
- my ($component, $template, $id, $path, $names, $static);
-
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Identify
- # First we need to figure out exactly which template is wanted,
- # resolving ambiguous names (e.g. '.../foo') which can have
- # multiple possible locations. We're looking for a template id,
- # to uniquely identify the template.
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- if (ref $name) {
- # $name may already be a component
- return $name if UNIVERSAL::isa($name, $cclass);
-
- # let template() handle a reference to something else,
- $template = $self->template($name) || return;
- $id = $template->id();
- $path = $template->path();
- }
- else {
- # expand $name template name into full path name(s) computed
- # relative to the current context path
- my $names = $self->paths($name) || return;
- $self->debug("paths: ", join(', ', @$names), "\n"), if $debug;
-
-
- foreach $path (@$names) {
- $self->debug(" - path: $path\n") if $debug;
+ my ($component, $id, $path, $names, $static);
- # If there is a global paths cache and the requested path
- # is an absolute one then it is static. We can cache the
- # id returned for it so we don't have to look for the
- # template again next time we use it
- $static = $paths && $path =~ m[^(\w+:)?/];
+ # get template's unique id suitable for cache/store indexing
+ $id = $template->id();
- if ($static && ($id = $paths->{ $path })) {
- $self->debug(" - mapped static path '$path' to id '$id'\n")
- if $debug;
- last;
- }
- elsif ($template = $self->template($path)) {
- $id = $template->id();
- $self->debug(" - sourced template '$path' with id '$id'\n")
- if $debug;
- # save static path for next time
- $paths->{ $path } = $id if $static;
- last;
- }
- }
- # we should have a valid template id, or we can't find it
- return $self->error("template not found: $name")
- unless $id;
- }
- $self->debug("template path : $path\n") if $debug;
-
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Cache
- # now we've got a template id we can look in the memory cache to
- # see if we already have a compiled component for this template,
- # If we do we check that it's fresh compared to its source template
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ # look first in the in-memory cache for a compiled component, and
+ # if found, check that it's fresh wrt to its template source
if ($cache && ($component = $cache->get($id))) {
if ($component->fresh()) {
@@ -306,21 +260,11 @@
}
}
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Store
- # If we didn't find the component in the cache then we look for
- # it in the store. If we find it then we restore its link to a
- # source template so that it can subsequently check its
- # freshness. If we haven't got a source template (e.g. if we used
- # an id fetched from the global cache for static paths) then we
- # need to go and fetch the complete template first.
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- if ($store && ($component = $store->get($id))) {
- # fetch source object if we need to
- $template ||= $self->template($path) || return;
+ # next try the persistant store (if in use) and if found, restore
+ # its link to the template source object so that it can check its
+ # freshness. If it is fresh then we cache it in memory.
- # notify component of its source object
+ if ($store && ($component = $store->get($id))) {
$component->source($template);
if ($component->fresh()) {
@@ -333,125 +277,139 @@
if $debug;
}
}
-
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Compile
- # If we haven't got a cached/stored component then we have to
- # create one from the template. If we haven't got a complete
- # template yet (e.g. we used a static path to get the template id)
- # then we need to get fetch it now.
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- # TODO: $path may be undefined?
- $template ||= $self->template($path) || do {
- # this should probably never happen, but never say never....
- # we could get an id for a template one minute, cache it in
- # the static paths, but then some time later, the provider
- # could withdraw it. But if that happens then there shouldn't
- # be a global paths cache for static paths in the first place
- delete $paths->{ $path } if $static;
- return $self->error("template not found (cached id error): $path");
- };
- # cache the template id for a static path
- # TODO: warning ($path undefined)
- $self->debug("setting path [$path]\n") if $debug;
- $paths->{ $path } = $template->id() if $static;
-
- # now we should have a valid source ready to be compiled
+ # if we haven't got a component from the cache or store then we
+ # compile it from the template source
$component = $template->component(context => $self)
- || return $self->error($template->error());
+ || return $self->throw( component => $template->error() );
# give the component a chance to cache/store itself
$component->cache($cache) if $cache;
$component->store($store) if $store;
+ # TODO: $template->strip() to remove any dead wood before caching
+
return $component;
}
-sub template {
- my ($self, $path) = @_;
- my $debug = $self->{ DEBUG };
- my $source;
+# TODO: may have a context local hash for mapping any names (including
+# relative ones) to a template
- $self->debug("template($path)\n") if $debug;
+sub template {
+ my ($self, $name) = @_;
my $tclass = $self->pkgvar( TEMPLATE => $TEMPLATE );
+ my $debug = $self->{ DEBUG };
+ my $template;
- if (ref $path) {
- # $path can be a reference to something
- $source = $path;
+ $self->debug("template($name)\n") if $debug;
+
+ if (ref $name) {
+ # $name can be a reference to something already
+ $template = $name;
}
else {
- # otherwise it's the name of a template which we look for
- # in the templates for the context and any parents
- $source = $self->find( templates => $path )
- || return $self->decline("template not found: $path");
+ # get list of one or more paths to try for $name and a reference to
+ # any global_paths cache mapping explicit paths to template objects
+ my $paths = $self->paths($name);
+ my $global = $self->{ global } || $self->global();
+ my $gpaths = $global->{ paths };
+ my $gpath;
+
+ $self->debug("- trying paths: ", join(', ', @$paths), "\n") if $debug;
+
+ foreach my $path (@$paths) {
+ $self->debug(" - path: $path\n") if $debug;
+
+ # $gpath flag indicates global_paths are in use ($gpaths)
+ # and the path is explicit, suitable for global caching
+ $gpath = $gpaths && $path =~ m[^(\w+:)?/];
+
+ if ($gpath && ($template = $gpaths->{ $path })) {
+ $self->debug(" - found template in global paths cache: $path\n")
+ if $debug;
+ $name = $path;
+ last;
+ }
+ elsif ($template = $self->find( templates => $path )) {
+ $self->debug(" - found template in context templates: $path\n")
+ if $debug;
+ # cache template in global_path if $gpath set
+ $gpaths->{ $path } = $template if $gpath;
+ $name = $path;
+ last;
+ }
+ }
+ return $self->throw( template => "not found: $name")
+ unless $template;
}
- # $source should be a Template::Template object (or whatever
- # the current value of $tclass is), a code reference, or a
- # text string or reference to one, all of which get upgraded
- # to Template::Template objects if necessary.
+ # $template can be a Template::Template object (or whatever the
+ # current value of $tclass is), a code reference, a text string or
+ # reference to one, all of which get upgraded to
+ # Template::Template objects if necessary.
- if (UNIVERSAL::isa($source, $tclass)) {
- $self->debug(" - template source is already a template object\n")
+ if (UNIVERSAL::isa($template, $tclass)) {
+ $self->debug(" - template is already a template object: $name\n")
if $debug;
- return $source;
+ return $template;
}
- elsif (UNIVERSAL::isa($source, 'HASH')) {
- # $source is a hash reference
- $self->debug(" - constructing template object from hash reference\n")
+ elsif (UNIVERSAL::isa($template, 'HASH')) {
+ $self->debug(" - constructing template from hash reference: $name\n")
if $debug;
- $source->{ path } = $path
- unless defined $source->{ path };
+ $template->{ path } = $name
+ unless defined $template->{ path };
+
+ $template->{ id } = "hash:$name"
+ unless defined $template->{ id };
- $source->{ id } = "hash:$path"
- unless defined $source->{ id };
+ $template->{ time } = CORE::time()
+ unless defined $template->{ time };
- return $tclass->new($source)
- || $self->error($tclass->error());
+ return $tclass->new($template)
+ || $self->throw( template => $tclass->error() );
}
- elsif (UNIVERSAL::isa($source, 'CODE')) {
- # $source is an anonymous subroutine reference
- $self->debug(" - constructing template object from code reference\n")
+ elsif (UNIVERSAL::isa($template, 'CODE')) {
+ $self->debug(" - constructing template object from code reference: $name\n")
if $debug;
return $tclass->new({
- id => "code:$path",
- path => $path,
+ id => "code:$name",
+ path => $name,
time => CORE::time(),
- code => $source,
+ code => $template,
text => '',
fresh => 1,
cache => 0,
store => 0,
- }) || $self->error($tclass->error());
+ }) || $self->throw( template => $tclass->error() );
}
- elsif (UNIVERSAL::isa($source, 'SCALAR') || ! ref $source) {
- # $source is plain text or a reference to a scalar
+ elsif (UNIVERSAL::isa($template, 'SCALAR') || ! ref $template) {
+ # $template is plain text or a reference to a scalar
$self->debug(" - constructing template object from template text\n")
if $debug;
return $tclass->new({
- id => "text:$path",
- path => $path,
+ id => "text:$name",
+ path => $name,
time => CORE::time(),
- text => $source,
+ text => $template,
fresh => 1,
cache => 0,
store => 0,
- }) || $self->error($tclass->error());
+ }) || $self->throw( template => $tclass->error() );
}
else {
- return $self->error("invalid template source: $source");
+ return $self->throw( template => "invalid template: $template" );
}
}
+
+
sub process {
my ($self, $paths, $params) = @_;
my $output = '';
@@ -551,7 +509,7 @@
=head1 VERSION
-$Revision: 1.14 $
+$Revision: 1.15 $
=head1 COPYRIGHT