roho has asked for the wisdom of the Perl Monks concerning the following question:
Environment:
Problem:
I am working through the examples in Chapter 2 of Jonathan Rockway's book "Catalyst: Accelerating Perl Web Application Development".
I completed the code for the 'database' example, but when I open it in my browser I get over 200 lines of debug information
(see "Web Page Output" below).
I have included the "Model", "View", "Controller", and "Schema" packages, and the "TT" template generated by Catalyst for completeness, but the problem appears to be between the "Controller" package, which contains the subroutine 'list_messages' to retrieve and stash data from SQLite, and the TT template, based on the error message displayed on the web page: Couldn't render template "list_messages.tt"
I have independently tested the SQLite database in a standalone Perl program using DBD::SQLite and it is working properly. Any ideas on what is preventing the template from rendering the model data? TIA
package MyApp::Model::TestDatabase; use strict; use base 'Catalyst::Model::DBIC::Schema'; __PACKAGE__->config( schema_class => 'MyApp::Schema::TestDatabase', connect_info => { dsn => 'dbi:SQLite:\tmp\database', user => '', password => '', } ); =head1 NAME MyApp::Model::TestDatabase - Catalyst DBIC Schema Model =head1 SYNOPSIS See L<MyApp> =head1 DESCRIPTION L<Catalyst::Model::DBIC::Schema> Model using schema L<MyApp::Schema::T +estDatabase> =head1 GENERATED BY Catalyst::Helper::Model::DBIC::Schema - 0.4 =head1 AUTHOR A clever guy =head1 LICENSE This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;
package MyApp::View::TT; use strict; use warnings; use base 'Catalyst::View::TT'; __PACKAGE__->config( TEMPLATE_EXTENSION => '.tt', render_die => 1, ); =head1 NAME MyApp::View::TT - TT View for MyApp =head1 DESCRIPTION TT View for MyApp. =head1 SEE ALSO L<MyApp> =head1 AUTHOR A clever guy =head1 LICENSE This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;
package MyApp::Controller::Database; use strict; use warnings; use parent 'Catalyst::Controller'; =head1 NAME MyApp::Controller::Database - Catalyst Controller =head1 DESCRIPTION Catalyst Controller. =head1 METHODS =cut =head2 index =cut sub list_messages :Path :Args(0) { my ( $self, $c ) = @_; $c->stash->{template} = 'list_messages.tt'; $c->stash->{messages} = $c->model('TestDatabase::test'); } =head1 AUTHOR A clever guy =head1 LICENSE This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;
package MyApp::Schema::TestDatabase; # Created by DBIx::Class::Schema::Loader # DO NOT MODIFY THE FIRST PART OF THIS FILE use strict; use warnings; use base 'DBIx::Class::Schema'; __PACKAGE__->load_namespaces; # Created by DBIx::Class::Schema::Loader v0.05003 @ 2010-03-15 17:04:1 +2 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JXK2KkfO7oQ7utxuHZbjpg # You can replace this text with custom content, and it will be preser +ved on regeneration 1;
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Hello, database!</title> </head> <body> <h1>Database</h1> <p>Here's what the database looks like: </p> <ol> [% WHILE (message = messages.next) %] <li> <p>Message <b>[% message.subject | html %]</b> (#[% message.id | html %]):</p> <p>[% message.message | html %]</p> <p>Written at <i>[% message.date | html %]</i>.</p> </li> [% END %] </ol> </body> </html>
MyApp on Catalyst 5.8002 Couldn't render template "list_messages.tt" Request bless({ _path => "database", action => "database", address => "192.168.1.102", arguments => [], base => bless(do{\(my $o = "http://localhost:3000/")}, " +URI::http"), body_parameters => {}, captures => [], cookies => {}, headers => bless({ "accept" => "*/*", "accept-encoding" => "gzip, deflate", "accept-language" => "en-us", connection => "Keep-Alive", host => "localhost:3000", "user-agent" => "Mozilla/4.0 (compatible; MSIE + 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; +Media Center PC 5.0; InfoPath.2; .NET CLR 3.5.30729; .NET CLR 3.0.307 +29; OfficeLiveConnector.1.4; OfficeLivePatch.1.3)", }, "HTTP::Headers"), match => "database", method => "GET", parameters => {}, protocol => "HTTP/1.0", query_parameters => {}, remote_user => undef, secure => 0, uploads => {}, uri => bless(do{\(my $o = "http://localhost:3000/databa +se")}, "URI::http"), user => undef, }, "Catalyst::Request") Response bless({ body => "", cookies => {}, finalized_headers => 0, headers => bless({ "content-type" => "text/html; charset=utf-8", "x-catalyst" => "5.8002", }, "HTTP::Headers"), status => 200, }, "Catalyst::Response") Stash do { my $a = { messages => bless({ _attrs => { alias => "me", as => ["id", "subject", "message", "date"], collapse => {}, from => [ { "-alias" => "me", "-source_handle" => bless({ schema => bless({ class_mappings => { "MyApp::Model::TestD +atabase::Test" => "Test", "MyApp::Schema::Test +Database::Result::Test" => "Test", }, source_registrations => { Test => bless({ _columns => { date => +{ _i +nflate_info => { deflate => sub { "???" }, inflate => sub { "???" } } +, da +ta_type => "DATETIME", de +fault_value => undef, ex +tra => {}, is +_nullable => 1, si +ze => undef, }, id => { da +ta_type => "INTEGER", de +fault_value => undef, ex +tra => {}, is +_nullable => 1, si +ze => undef, }, message +=> { da +ta_type => "TEXT", de +fault_value => undef, ex +tra => {}, is +_nullable => 1, si +ze => undef, }, subject +=> { da +ta_type => "TEXT", de +fault_value => undef, ex +tra => {}, is +_nullable => 1, si +ze => undef, }, }, _columns_info_ +loaded => 0, _ordered_colum +ns => ["id", "subject", "message", "date"], _primaries => +["id"], _relationships + => {}, _unique_constr +aints => { primary => 'fix' }, name => "Test" +, result_class = +> "MyApp::Model::TestDatabase::Test", resultset_attr +ibutes => {}, resultset_clas +s => "DBIx::Class::ResultSet", schema => 'fix +', source_name => + "Test", sqlt_deploy_ca +llback => "default_sqlt_deploy_hook", }, "DBIx::Class: +:ResultSource::Table"), }, storage => bless({ _conn_pid = +> 4448, _connect_info = +> [ + { dsn => "dbi:SQLite:\\tmp\\database", password => "", user => "" + }, + ], _dbh = +> bless({ + # tied DBI::db + }, "DBI::db"), _dbh_autocommit = +> 1, _dbh_gen = +> 0, _dbi_connect_info = +> [ + "dbi:SQLite:\\tmp\\database", + "", + "", + { AutoCommit => 1, PrintError => 0, RaiseError => 1 }, + ], _driver_determined = +> 1, _in_dbh_do = +> 0, _sql_maker = +> bless({ + _cached_syntax => "LimitOffset", + array_datatypes => 1, + bindtype => "columns", + "cmp" => "=", + equality_op => qr/^(\=|is|(is\s+)?like)$/i, + from_bind => [], + having_bind => [], + inequality_op => qr/^(!=|<>|(is\s+)?not(\s+like)?)$/i, + limit_dialect => "LimitOffset", + logic => "OR", + order_bind => [], + special_ops => [ + { handler => "_where_field_BETWEEN", regex = +> qr/^(not )?between$/i }, + { handler => "_where_field_IN", regex => qr/ +^(not )?in$/i }, + ], + sqlfalse => "0=1", + sqltrue => "1=1", + unary_ops => [ + { handler => "_where_op_ANDOR", regex => qr/ +^and (?: \s? \d+ )? $/ix }, + { handler => "_where_op_ANDOR", regex => qr/ +^or (?: \s? \d+ )? $/ix }, + { handler => "_where_op_NEST", regex => qr/^ +nest (?: \s? \d+ )? $/ix }, + { handler => "_where_op_BOOL", regex => qr/^ + (?: not \s )? bool $/ix }, + ], + }, "DBIx::Class::SQLAHacks"), _sql_maker_opts = +> {}, datetime_parser = +> undef, debugobj = +> bless({}, "DBIx::Class::Storage::Statistics"), savepoints = +> [], schema = +> 'fix', transaction_depth = +> 0, }, "DBIx::Class::Stora +ge::DBI::SQLite"), }, "MyApp::Schema::TestDatab +ase"), source_moniker => "Test", }, "DBIx::Class::ResultSourceHandl +e"), me => "Test", }, ], result_class => "MyApp::Model::TestDatabase::T +est", "select" => ["me.id", "me.subject", "me.messag +e", "me.date"], }, _result_class => "MyApp::Model::TestDatabase::Test", _source_handle => bless({ schema => 'fix', source_mo +niker => "Test" }, "DBIx::Class::ResultSourceHandle"), attrs => { alias => "me", result_class => "MyApp::Mo +del::TestDatabase::Test" }, cond => undef, count => undef, cursor => bless({ _dbh_gen => 0, args => [ 'fix', 'fix', undef, { alias => "me", as => 'fix', collapse => 'fix', from => 'fix', result_class => "MyApp::Model: +:TestDatabase::Test", "select" => 'fix', where => 'fix', }, ], attrs => 'fix', "pos" => 1, sth => bless({ # tied DBI::st }, "DBI::st"), storage => 'fix', }, "DBIx::Class::Storage::DBI::Cursor"), pager => undef, }, "DBIx::Class::ResultSet"), template => "list_messages.tt", }; $a->{messages}{_attrs}{from}[0]{"-source_handle"}{schema}{source_reg +istrations}{Test}{_unique_constraints}{primary} = $a->{messages}{_att +rs}{from}[0]{"-source_handle"}{schema}{source_registrations}{Test}{_p +rimaries}; $a->{messages}{_attrs}{from}[0]{"-source_handle"}{schema}{source_reg +istrations}{Test}{schema} = $a->{messages}{_attrs}{from}[0]{"-source_ +handle"}{schema}; $a->{messages}{_attrs}{from}[0]{"-source_handle"}{schema}{storage}{s +chema} = $a->{messages}{_attrs}{from}[0]{"-source_handle"}{schema}; $a->{messages}{_source_handle}{schema} = $a->{messages}{_attrs}{from +}[0]{"-source_handle"}{schema}; $a->{messages}{cursor}{args}[0] = $a->{messages}{_attrs}{from}; $a->{messages}{cursor}{args}[1] = $a->{messages}{_attrs}{"select"}; $a->{messages}{cursor}{args}[3]{as} = $a->{messages}{_attrs}{as}; $a->{messages}{cursor}{args}[3]{collapse} = $a->{messages}{_attrs}{c +ollapse}; $a->{messages}{cursor}{args}[3]{from} = $a->{messages}{_attrs}{from} +; $a->{messages}{cursor}{args}[3]{"select"} = $a->{messages}{_attrs}{" +select"}; $a->{messages}{cursor}{args}[3]{where} = $a->{messages}{cursor}{args +}[2]; $a->{messages}{cursor}{attrs} = $a->{messages}{cursor}{args}[3]; $a->{messages}{cursor}{storage} = $a->{messages}{_attrs}{from}[0]{"- +source_handle"}{schema}{storage}; $a; } Config do { my $a = { "Action::RenderView" => { ignore_classes => [ "DBIx::Class::ResultSource::Table", "DBIx::Class::ResultSourceHandle", "DateTime", ], scrubber_func => sub { "???" }, }, "Plugin::ConfigLoader" => {}, home => "C:\\MyApp", name => "MyApp", root => bless({ dirs => ["", "MyApp", "root"], file_spec_class => +undef, volume => "C:" }, "Path::Class::Dir"), static => { debug => 1, dirs => [], ignore_dirs => [], ignore_extensions => ["tmpl", "tt", "tt2", "html", "xhtml"], include_path => ['fix'], mime_types => {}, mime_types_obj => bless({}, "MIME::Types"), no_logs => 1, }, }; $a->{static}{include_path}[0] = $a->{root}; $a; } MyApp on Catalyst 5.8002
"Its not how hard you work, its how much you get done."
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Catalyst - Model Data Not Rendering in TT Template
by Khen1950fx (Canon) on Mar 16, 2010 at 06:40 UTC | |
by roho (Bishop) on Mar 17, 2010 at 03:41 UTC | |
|
Re: Catalyst - Model Data Not Rendering in TT Template
by roho (Bishop) on Mar 20, 2010 at 20:37 UTC |