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

Model
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;

View
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;

Controller
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;

Schema
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;

TT Template
<?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>

Web Page Output
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."


In reply to Catalyst - Model Data Not Rendering in TT Template by roho

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.