Sunday, December 16, 2007
Update to 'Tags and search and DBIx::Class'
I think it is a nice technique.
Saturday, December 08, 2007
Have you ever forgotten where some subroutine comes from?
Until discovering Pod::POM::Web I did not know that what I need is actually a full text search over all the Pod documents - you cut and paste the unknown method name into the search box press Enter and voila you have list of modules that document that method. And if you know that it comes from one of the DBIx::Class submodules you just add DBIx::Class to the search criteria - and don't get all the Class::DBI documentation pages. No problem with too long index lists. Someone should hack it to run against a full CPAN mirror and beat the other CPAN search websites.
Wednesday, September 12, 2007
Catalyst::Example::InstantCRUD updated to newer versions of underlying libraries
Saturday, September 08, 2007
Comment spam
Monday, July 02, 2007
Fat Model
After moving parameter validation and transactions into the Model it looks OK. I think it can lead to something enough abstracted to become a CPAN module - but for now I am sure that it'll not be as simple as DBIx::Class::Validation.
Monday, April 23, 2007
Catalyst::Controller::PathArgs
There is still need for the PathPart parameter - for the case when you have paths like "/book/$book_id/edition/$edition_id" and "/book/$book_id/edition", i.e. two paths that differ only in the number of parameters taken by the actions. Since you can have only one "edition" subroutine in the "Book" controller you need to alias a subroutine with a different name to act as if it has the name "edition" - this is what you can do with the PathPart attribute. I am tempted to also rename that one to Alias too - so that it would be more mnemonic.
Anyway the source can be downloaded from it's subdir in the Cat repository. Below is the POD for the Catalyst::Controller::PathArgs controller. And I am waiting for comments before I submit it to CPAN.
NAME
Catalyst::Controller::PathArgs - syntactic sugar for the Catalyst::DispatchType::Chained manpage.
SYNOPSIS
package MyApp::Controller::Root;
use base 'Catalyst::Controller::PathArgs';
__PACKAGE__->config->{namespace} = '';
sub pathargsroot : PathArgs(1) {}
use Catalyst::Controller::PathArgs;
package TestApp::Controller::Pathargsroot;
use base 'Catalyst::Controller::PathArgs';
sub pathargsend : PathArgs(1) EndPoint { }
DESCRIPTION
This Catalyst Controller base adds two new action attributes: PathArgs (taking one numerical argument) and EndPoint. This is entirely syntactic sugar over the the Catalyst::DispatchType::Chained manpage full machinery for paths like '/book/$book_id/edition/$edition_id/view' - with PathArgs you can chain the 'book', 'edition' and 'view' methods and declare how many parameters they take. EndPoint is needed to declare an ation as the end of the chain (in theory this should be computable - but for now I don't see any easy way to do that).
This package uses the Class::C3 manpage this means that you cannot use NEXT in classes based on it - but C3 looks like a good replacement for NEXT.
To declare that the book subroutine is the root chained action with one argument you need to declare it in the Root controller with:
sub book : PathArgs(1) {
If we had a non chained path with /book/edition - the edition sub would be declared in the 'Book' controller - and this is the same case here - you just add PathArgs(1)
to indicate that it is indeed chained and that it takes one parameter. So in the Book controller you add:
sub edition : PathArgs(1) {
For the last action in the chain you need to add EndPoint. So in the Book::Edition controller you would need:
sub view : PathArgs(0) EndPoint {
You can also mix PathArgs with PathPart (new in Catalyst 5.7007). For example if you wanted to have an action responding for the address ``/book/$book_id/edition'' you would need a subroutine called 'edition' in the Book controller, but there is already one routine called 'edition' in that controller. What you can do in that case is make a sub with a different name and declare that from the outside it's name should be really 'edition':
sub edition_mascarade: PathPart('edition') PathArgs(0) EndPoint {
yeah - you need to add EndPoint there as well.
An example is included in the example directory of this distribution.
Internally PathArgs and EndPoint are converted to 'Chained(.)' and appriopriate CaptureArgs or Args attributes. For more sophisticated chaining you might need to use the Catalyst::DispatchType::Chained manpage directly.
create_action
This is the overriden method from Catalyst::Controller used here to compute the new attributes.
BUGS
SUPPORT
AUTHOR
Zbigniew Lukasiak
CPAN ID: ZBY
http://perlalchemy.blogspot.com/
COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
SEE ALSO
Thursday, April 12, 2007
MatchParams for auto actions
Here is how it would work - using the canonical example for Catalyst::DispatchType::Chained (for the path "/wiki/FooBarPage/rev/23/view"):
sub wiki : PathPart('wiki') Chained('/') CaptureArgs(1) {
my ( $self, $c, $page_name ) = @_;
# load the page named $page_name and put the object
# into the stash
}
sub rev : PathPart('rev') Chained('wiki') CaptureArgs(1) {
my ( $self, $c, $revision_id ) = @_;
# use the page object in the stash to get at its
# revision with number $revision_id
}
sub view : PathPart Chained('rev') Args(0) {
my ( $self, $c ) = @_;
# display the revision in our stash. Another option
# would be to forward a compatible object to the action
# that displays the default wiki pages, unless we want
# a different interface here, for example restore
# functionality.
}
would become
package Wiki;
sub auto : MatchParams ( qr/\w+/ ) {
my ( $self, $c, $page_name ) = @_;
# load the page named $page_name and put the object
# into the stash
}
package Wiki::Rev;
sub auto : MatchParams ( qr/\d+/ ) {
my ( $self, $c, $revision_id ) = @_;
# use the page object in the stash to get at its
# revision with number $revision_id
}
sub view : Local {
my ( $self, $c ) = @_;
# display the revision in our stash. Another option
# would be to forward a compatible object to the action
# that displays the default wiki pages, unless we want
# a different interface here, for example restore
# functionality.
}
Does it not look simpler? Instead of a completely new language for chaining actions it uses the standard directory tree model that we are all accustomed to. And it works in the spirit of the common practice of using auto to put some prerequisites to the stash.