Posted in catalyst, logo, trademark, oreilly
Thu, 01 Jun 2006 22:05:00 GMT
A while back the Catalyst framework open source community was working on a mascot for their project. The idea was to have a flying camel made up of Lego-like building blocks. This would convey key characteristics of the project including (a) Catalyst would make your project fly, (b) Catalyst is very modular and (c) Catalyst is written in Perl. There was a lot of excitement and Tim Gould was kind enough to make the following camel for the group:
Unfortunately, the idea did not get the approval of O'Reilly Media, Inc. which holds a trademark on the camel image. Their policies are described on their Perl Camel Usage and Trademark Information page. Tim O'Reilly mentioned their Perl Camel policies in his response to the recent "Web 2.0" service mark controversy which caused me to wonder if O'Reilly Media, Inc.'s commercial trademark policies are in the spirit of open source.
In the open source world, you can typically take someone's copyrighted information and modify with attribution, especially for a non-commercial use. If that standard were applied to logos, especially mascot-type logos, then it would seem that the spirit of open source is in line with modifying and giving attribution for mascot logos as well. Two popular mascots that have been altered and published include Tux for Linux and Mozilla originally for Netscape. These alterations have arguably made Tux and Mozilla even more popular and recognizable, thus strengthening the brand, than they would otherwise be. Unlike Netscape and Linux, O'Reilly has chosen to use a strong hand in preventing modification of the Camel logo for use by open source projects such as the Catalyst. Is O'Reilly's policy too stringent for the open source community or acceptable business practices?
3 comments
Posted in catalyst, perl
Thu, 01 Jun 2006 15:52:00 GMT
Catalyst 5.66 introduced the Root controller (e.g. MyApp::Controller::Root) as a best practice. It's purpose is to remove the need for the Application Class (a.k.a. App Class; e.g. MyApp.pm) to have actions or be a controller. Previously, Local top-level actions (e.g. /login) would be put in the App Class; the Root controller replaces this because it's base path is /. I asked mst why the Root controller is important and he told me the following.
Having the Application Class be a controller makes it a controller on a class-based level that can lead to several problems. One problem is name collision between App Class actions and $c methods, for example an App Class login action will cause problems with $c->login used by Catalyst::Plugin::Authentication. This and other problems can now be avoided entirely.
A typical App Class includes:
use Catalyst qw/.../;
This makes the App Class isa Catalyst::Controller because "use Catalyst" automatically injects Catalyst and Catalyst::Controller as base classes if the calling class isn't isa Catalyst. This can be avoided by making the App Class isa Catalyst before calling "use Catalyst" with the following:
use base qw/Catalyst/;
use Catalyst qw/.../;
Once the App Class is no longer isa Catalyst::Controller, it should no longer have any actions or subroutines with attributes, including the auto, default and end subroutines.
The Catalyst helper script will create a MyApp::Controller::Root controller for you, but the name can actually be anything. There's only one line that distinguishes the Root controller from any other one and it's a config setting that sets the name space to ''. You can make any controller the root by simply add the following line, just be sure the action attributes are updated if necessary:
__PACKAGE__->config->{namespace} = '';
Previously, you could avoid actions in the App Class by using Global actions, now you can with Local actions as well.
no comments
Posted in json, catalyst, perl, ajax, prototype
Thu, 01 Jun 2006 00:42:00 GMT
I use the prototype.js library (aka prototype) for AJAX and recently moved to using JSON to return multiple elements instead of a single one. I had to rearchitect my client request code and my server code to handle JSON but it's worth it to minimize the number of HTTP requests. I use Catalyst and JSON::Syck which make generating the JSON response on the server-side very easy.
Prototype.js is interesting in that it auto-evals a JSON object that's placed in the X-JSON header instead of the response body like other libaries such as Dojo Toolkit. This allows you to send HTML in the response body but I'm not convinced this is a good implementation since it supports only one HTML fragment in the response body. I think it would be better to simply put the JSON object in the response body and have all the HTML fragments in the JSON object. I just seems cleaner to put all the HTML fragments in JSON instead of fragment 1 in the response body and fragments 2-n in JSON. Although I have the X-JSON header working, I may just move to the more standard JSON in response body approach and eval the JSON string myself. To read the auto-evaled JSON response, the following example expects a JSON associative array and displays the value of the myItem key (more code is available in the wiki link below):
onComplete: function( request, json ) {
alert( json.myItem );
}
On the server-side, I use the Catalyst framework to set the header and JSON::Syck to transform Perl data structures to JSON. JSON::Syck is a wrapper around the C libsyck library and very fast. There is a view, Catalyst::View::JSON, however it puts the JSON string in the response body because that is what Dojo and other libraries expect. Since AJAX libraries don't idnetify themselves in anyway to the server (e.g. user agent), the Catalyst View would probably need a patch to with a configuration switch to populate X-JSON instead of the response body. For now, I'm using JSON::Syck directly. The following are the minimal calls to use. If you have UTF-8 output, see C::V::JSON for UTF-8 encoding.
$c->res->header(
'X-JSON' => JSON::Syck::Dump( \%args );
);
I've put together some example code that I thought would be better placed on the wiki. It can be found at: Prototype.js, JSON and Catalyst.
UPDATE: After running into the IE max header length issue, I've decided to put the JSON object in the response body and manually eval request.responseText on the client.
6 comments
Posted in catalyst, perl, templatetoolkit
Wed, 31 May 2006 23:54:00 GMT
Catalyst::View::TT 0.23, the Template Toolkit View for the Catalyst MVC framework, was recently released on May 27, 2006 and just in time. It breaks out the render functionality as a separate method from the process method allowing direct rendering of TT templates in addition to handling the overall catalyst response. This is useful when you want to render a template for say an email body or fragments in a JSON response. The render method is accessed as follows:
my $output = $c->view('TT')->render(
$c, 'mytemplate.tt', \%args
);
Prior to this, Catalyst::Plugin::SubRequest was the recommended way for rendering a TT template when C::V::TT was being used, e.g. the email body example in the SubRequest POD. This method is a kludge because SubRequest is designed to make public action requests, not for just rendering a template. I didn't mind using SubRequest just once to render a TT template for email, however I grew concerned when I starting using it multiple times to render HTML fragments to return via JSON. I was converting more private methods to public actions just so they could be called by SubRequest when I decided this was too kludgy and went to see if I could call TT directly. I went code diving in C::V::TT where I found the render method in 0.23 on search.cpan.org. I had to install 0.23 from the tarball directly since my CPAN shell would only give me 0.22.
SubRequest also seems to have a problem in that it nukes the Catalyst::Request parameters so $c->req->params is no longer populated correctly after a $c->subreq call. This created strange results without errors that were hard to pinpoint for me. On #catalyst, network_ninja mentioned he got around this problem by copying the params to $c->req->parameters and giving that to SubRequest. My solution is to just stop using SubRequest, at least when I only want to render a template.
Thanks to the Cat team for breaking out render and releasing it just when I went looking for it.
1 comment