Hi Andrew,

CGI::Prototype as a framework is something of a bit of string lashed 
around a set of power tools.

These tools can do anything you need, but the "framework" provides no 
guidance about how to do it, beyond the "with this" inherent in 
Randall's choice of tools.

Instead of 'use base', I use the Class::Prototyped ability to install 
other classes into your object.

In my base class (CGI::Prototype::Hidden subclass), I've got a method 
that installs my plugins:

sub install_mixins {

    my ($self, @mixins) = @_;
    my $prefix = $self->mixins_prefix . '::';
    foreach my $pkg (@mixins) {
        $self->reflect->addSlot ( [ "$pkg*", 'PARENT' ] => $prefix . $pkg );
        my $plugin = $self->reflect->getSlot("$pkg*"); # the mixin we 
just installed

The mixins_prefix is "configurable":

sub mixins_prefix { return "Miner::Utils" }

And I install my mixins in app_enter in the base class:

sub app_enter {
    my ($self) = @_;
    # connect to the database:
$Config::Site::schema, $Config::Site::schema);
    # load all the Miner::Utils::* packages:
    $self->install_mixins(qw(Links Text Cookie Exec Log Order TimeField 
LOB ));

If I want to use a particular mixin only in one or more specific pages, 
I call install_mixins in their control_enter or respond_enter methods.

My plugin/mixin classes (like Miner::Utils::Cookie, for example) are 
CGI::Prototype::Hidden subclasses, although I could probably make them 
Class::Prototyped subclasses, or independent modules.

The advantage of calling install_mixins in the app_enter is that things 
like the CGI object and the database connection are already set up, so I 
can install classes that mess about with things like the database 
session, like Class::DBI::Plugin::DateFormat::Oracle for example.

Hope this helps,

- Dotan.


Andrew Gianni wrote:

> I'd like to figure out how to get mixins up and running under
> CGI::Prototype. I think I understand the technical aspects of
> Class::Prototyped well enough to pull it off, but I have design questions
> that I'd like feedback on. Assuming all goes well, I'd be happy to
> contribute a CGI::Prototype::Mixin module to CPAN if I can get it that
> generalized. Let me start with three scenarios I'd like to be able to
> address and the issues I see:
> 1. We have at least two applications that have pages that allow users to
> upload files. The page is pretty similar in both applications with only a
> few application specific things, like the table it's using and an extra
> field. What I'd like to do is create an abstract page class for the file
> upload page and then implement it with concrete page classes within the
> applications themselves, overriding necessary methods to customize. I have
> actually done this in the past by not giving the abstract class a base class
> and using multiple inheritance in the concrete class like so:
> use base qw( Abstract::Page::Class My::App );
> And that mostly works, but I'm knew that it could cause problems down the
> line and after only a few months I found a scenario where it breaks: under
> mod_perl, if I use the mixin page for more than one concrete page class in
> my application and use Apache::Reload to reload the concrete page classes, I
> get errors with whichever concrete page class is reloaded second. I don't
> remember exactly what the error is, but I can look into it if anyone is
> interested. Cracking plugability for this example is most important for me
> because we actually have two more page types that we need to be able to do
> this with and right now they're just duplicated in multiple projects.
> 2. I would like to create a pluggable diagnostics module that I could stick
> in front of my app module to override core CGI::P methods at strategic
> locations to capture performance data.
> 3. We currently have two different validation methodologies and I'm not sure
> how soon we'll be picking one or the other to standardize on. I'd like to
> create two separate mixin classes so I can choose the validation
> functionality to use. I know I could make this work with something like a
> Strategy pattern, defining two different validation classes with the same
> interface and telling the app which one to use, but if I can get the first
> two examples working, this could easily come along for the ride.
> The basics of this from a technical perspective should be pretty straight
> forward, right? I just need to take the mixin class and manipulate it's
> parent and the parent of the class that I want to inherit from it, right?
> The complicated part, and perhaps this doesn't have an easy answer, is what
> it I want to insert more than one mixin? What if, for example,
> CGI::Prototype::Hidden became a mixin, as Randal proposed some time ago (did
> I understand that correctly?) and I also have an authentication mixin I'd
> like to use. The problem is that, as a developer, I know the interfaces of
> the two mixins and what they do, but I don't want to have to look at the
> internals of each one to know if I need to put CGI::Prototype::Hidden
> infront of CGI::Prototype::Mixin::Auth or vice versa. Is this actually a
> connundrum or am I overanalyzing this? Any feedback or ideas would be
> appreciated.
> Andrew

This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
cgi-prototype-users mailing list

Reply via email to