http://www.perlmonks.org?node_id=911574

tospo has asked for the wisdom of the Perl Monks concerning the following question:

I'm stuck with the following problem at the moment:
In a Catalyst Controller I get a result that is a Bio::Seq object, which is an object containing biological sequence data and additional information about the sequence but it could be any other object, really.
In my views, I can then show a textual representation of the object, for example a Bio::Seq object has a 'seq' method that returns the actual sequence string (AGCAACG...), so in my (TT) view, I can have:

The sequence is:[% bio_seq.seq %]
where $c->stash->{bio_seq} was populated with a Bio::Seq object in the controller. So far so good...

What I would now want to do is to use the information that comes with the Bio::Seq object to render a more informative version of it, which should use styles to highlight some sequence features. Basically, I would like a view helper method that takes the Bio::Seq object as an argument and returns a snippet of HTML with the sequence and style information to insert into the view. I know how to use TT FILTERs but they wouldn't work with the object, so I found the 'expose_methods' config option in Catalyst::View::TT, which sound like just the ticket but I'm not having any luck with it.
In MyApp::Controller::BioSeq.pm

sub bioseq :Global { my ( $self, $c ) = @_; my $bio_seq_obj = Bio::Seq->new(); # ... a lot of stuff, finally this: $c->{stash}{bio_seq} = $bio_seq_obj; }
In MyApp::View::TT (just a silly example that would return a static text just to see if it works)
__PACKAGE__->config( # some config ... expose_methods => [qw/colorised_seq_features/], ); # for testing purposes sub colorised_seq_features { return 'testing, testing, 1,2'; }
And in the template file that is rendered in the end:
The sequence is: [% colorised_seq_features(bio_seq) %]
But colorised_seq_features simply renders nothing and there is no error message either (I did turn on DEBUG in the View::TT config).
I tried to use a method name that definitely doesn't exist and the view still doesn't complain, so I'm not sure where thie is going wrong.
Does anybody have any experience with expose_methods? The documentation is very short and I can't find much else about it. I have used similar techniques (view helpers) in Ruby on Rails and I was hoping to use the same technique in Catalyst. Am I completely on the wrong tracks (excuse the pun...)? I should also mention that I could of course do all of this in the controller and populate the stash with a HTML snippet but I would like to use the same technique in different views and I really think that the controller shouldn't provide HTML snippets and let the view sort that out.
Thanks for your help!

Replies are listed 'Best First'.
Re: Catalyst::VIew::TT - format an object
by chrestomanci (Priest) on Jun 27, 2011 at 21:08 UTC

    Why do you want to use TT Filter?

    The way I would approach this problem would be to add some methods to your Bio::Seq class that return html to pretty print your sequence. That way your template just becomes:

    The sequence is:[% bio_seq.seq_pretty_display %]

    This will have the effect of moving the pretty printing code into your class where it is easier to test, but breaks the strict MVC paradigm of keeping the View separate from the model and controller.

    My answer to any pedant who raises that point, is that perl has always been about being pragmatic and getting things done, rather than blind adherence to a particular design pattern.

      I don't want to use a filter, I would like to access a method defined in the view class in the view itself. The Bio::Seq class is part of the large BioPerl bundle and I don't want to subclass it (and use the subclass everywhere in my code) just to add a method that really doesn't belong to a class that is all about handling sequence data. What if I want to change the HTML code of the output? I would have to do that in My::Bio::Seq and then what if I use this in more than one web app and I want different rendering of the seq features? I don't think that would be a good idea for the same reason that you wouldn't want to provide a "to_html" method to every DBIx result set class.
Re: Catalyst::VIew::TT - format an object
by tospo (Hermit) on Jun 28, 2011 at 13:18 UTC
    ah, found the problem - turns out that my above code was correct and is working as expected but expose_methods was only introduced two version ago in Catalyst::View::TT and my installed version was simply too old. I would still be interested to hear about ways of debugging something like this. Is there a way of making Catalyst throw an error if there is an unknown config option or if a function is called in a template that isn't defined?