package Maypole::View::Base; use File::Spec; use UNIVERSAL::moniker; use strict; use Maypole::Constants; use Carp; sub new { bless {}, shift } # By default, do nothing. sub paths { my ( $self, $r ) = @_; my $root = $r->config->template_root || $r->get_template_root; if(ref($root) ne 'ARRAY') { $root = [ $root ]; } my @output = (); my $i = 0; foreach my $path (@$root) { push(@output, ( $r->model_class && File::Spec->catdir( $path, $r->model_class->table ) ) ); push(@output, File::Spec->catdir( $path, "custom" )) unless ($i); push(@output, $path); push(@output, File::Spec->catdir( $path, "factory" )) unless ($i); $i = 1; } return grep( $_, @output); } sub vars { my ( $self, $r ) = @_; my $class = $r->model_class; my $base = $r->config->uri_base; $base =~ s/\/+$//; my %args = ( request => $r, objects => $r->objects, base => $base, config => $r->config, ); $args{object} = $r->object if ($r->can('object')); if ($class) { my $classmeta = $r->template_args->{classmetadata} ||= {}; $classmeta->{name} ||= $class; $classmeta->{table} ||= $class->table; $classmeta->{columns} ||= [ $class->display_columns ] if ($class->can('display_columns')); $classmeta->{list_columns} ||= [ $class->list_columns ] if ($class->can('list_columns')); $classmeta->{colnames} ||= { $class->column_names } if ($class->can('column_names')); $classmeta->{related_accessors} ||= [ $class->related($r) ]; $classmeta->{moniker} ||= $class->moniker; $classmeta->{plural} ||= $class->plural_moniker; $classmeta->{cgi} ||= { $class->to_cgi } if ($r->build_form_elements && $class->can('to_cgi')); $classmeta->{stringify_column} ||= $class->stringify_column if ($class->can('stringify_column')); # User-friendliness facility for custom template writers. if ( @{ $r->objects || [] } > 1 ) { $args{ $r->model_class->plural_moniker } = $r->objects; } else { ( $args{ $r->model_class->moniker } ) = @{ $r->objects || [] }; } } # Overrides %args = ( %args, %{ $r->template_args || {} } ); %args; } sub process { my ( $self, $r ) = @_; my $status = $self->template($r); return $self->error($r) if $status != OK; return OK; } sub error { my ( $self, $r, $desc ) = @_; $desc = $desc ? "$desc: " : ""; if ( $r->{error} =~ /not found$/ ) { warn "template not found error : ", $r->{error}; # This is a rough test to see whether or not we're a template or # a static page return -1 unless @{ $r->{objects} || [] }; my $template_error = $r->{error}; $r->{error} = < Template not found A template was not found while processing the following request: @{[$r->{action}]} on table @{[ $r->{table} ]} with objects:
@{[join "\n", @{$r->{objects}}]}
The main template is @{[$r->{template}]}. The template subsystem's error message was
$template_error
We looked in paths:
@{[ join "\n", $self->paths($r) ]}
EOF $r->{content_type} = "text/html"; $r->{output} = $r->{error}; return OK; } return ERROR; } sub template { die shift() . " didn't define a decent template method!" } 1; =head1 NAME Maypole::View::Base - Base class for view classes =head1 DESCRIPTION This is the base class for Maypole view classes. This is an abstract class that defines the interface, and can't be used directly. =head2 process This is the entry point for the view. It templates the request and returns a C indicate success or failure for the view phase. Anyone subclassing this for a different rendering mechanism needs to provide the following methods: =head2 template In this method you do the actual processing of your template. it should use L to search for components, and provide the templates with easy access to the contents of L. It should put the result in C<$r-Eoutput> and return C if processing was sucessfull, or populate C<$r-Eerror> and return C if it fails. =head1 Other overrides Additionally, individual derived model classes may want to override the =head2 new The default constructor does nothing. You can override this to perform actions during view initialization. =head2 paths Returns search paths for templates. the default method returns folders for the model class's C, factory, custom under the configured template root. =head2 vars returns a hash of data the template should have access to. The default one populates classmetadata if there is a table class, as well as setting the data objects by name if there is one or more objects available. =head2 error =cut