1 package Maypole::View::Base;
3 use UNIVERSAL::moniker;
5 use Maypole::Constants;
8 sub new { bless {}, shift } # By default, do nothing.
11 my ( $self, $r ) = @_;
12 my $root = $r->config->template_root || $r->get_template_root;
17 && File::Spec->catdir( $root, $r->model_class->moniker )
19 File::Spec->catdir( $root, "custom" ),
20 File::Spec->catdir( $root, "factory" )
25 my ( $self, $r ) = @_;
26 my $class = $r->model_class;
27 my $base = $r->config->uri_base;
31 objects => $r->objects,
38 my $classmeta = $args{classmetadata} ||= {};
39 $classmeta->{name} ||= $class;
40 $classmeta->{description} ||= $class->description;
41 $classmeta->{table} ||= $class->table;
42 $classmeta->{columns} ||= [ $class->display_columns ];
43 $classmeta->{list_columns} ||= [ $class->list_columns ];
44 $classmeta->{colnames} ||= { $class->column_names };
45 $classmeta->{related_accessors} ||= [ $class->related($r) ];
46 $classmeta->{moniker} ||= $class->moniker;
47 $classmeta->{plural} ||= $class->plural_moniker;
48 $classmeta->{cgi} ||= { $class->to_cgi };
50 # User-friendliness facility for custom template writers.
51 if ( @{ $r->objects || [] } > 1 ) {
52 $args{ $r->model_class->plural_moniker } = $r->objects;
55 ( $args{ $r->model_class->moniker } ) = @{ $r->objects || [] };
60 local $r->{template_args} = $r->{template_args};
61 delete $r->{template_args}{classmetadata}; # already overrides
62 %args = ( %args, %{ $r->{template_args} || {} } );
67 my ( $self, $r ) = @_;
68 $r->{content_type} ||= "text/html";
69 $r->{document_encoding} ||= "utf-8";
70 my $status = $self->template($r);
71 return $self->error($r) if $status != OK;
76 my ( $self, $r, $desc ) = @_;
77 $desc = $desc ? "$desc: " : "";
78 carp $desc . $r->{error};
79 if ( $r->{error} =~ /not found$/ ) {
81 # This is a rough test to see whether or not we're a template or
83 return -1 unless @{ $r->{objects} || [] };
87 <H1> Template not found </H1>
89 This template was not found while processing the following request:
91 <B>@{[$r->{action}]}</B> on table <B>@{[ $r->{table} ]}</B> with objects:
94 @{[join "\n", @{$r->{objects}}]}
97 Looking for template <B>@{[$r->{template}]}</B> in paths:
100 @{[ join "\n", $self->paths($r) ]}
103 $r->{content_type} = "text/html";
104 $r->{output} = $r->{error};
107 $r->{content_type} = "text/plain";
108 $r->{output} = $r->{error};
113 sub template { die shift() . " didn't define a decent template method!" }
120 Maypole::View::Base - Base class for view classes
124 This is the base class for Maypole view classes. This is an abstract class
125 that defines the interface, and can't be used directly.
129 This is the entry point for the view. It templates the request and returns a
130 C<Maypole::Constant> indicate success or failure for the view phase.
132 Anyone subclassing this for a different rendering mechanism needs to provide
133 the following methods:
137 In this method you do the actual processing of your template. it should use
138 L<paths> to search for components, and provide the templates with easy access
139 to the contents of L<vars>. It should put the result in C<$r-E<gt>output> and
140 return C<OK> if processing was sucessfull, or populate C<$r-E<gt>error> and
141 return C<ERROR> if it fails.
143 =head1 Other overrides
145 Additionally, individual derived model classes may want to override the
149 The default constructor does nothing. You can override this to perform actions
150 during view initialization.
154 Returns search paths for templates. the default method returns factory, custom
155 and E<lt>tablenameE<gt> under the configured template root.
159 returns a hash of data the template should have access to. The default one
160 populates classmetadata if there is a table class, as well as setting the data
161 objects by name if there is one or more objects available.