Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Catalyst: Users

Best practice: How to build app parts reusable?

 

 

Catalyst users RSS feed   Index | Next | Previous | View Threaded


mdietrich at cpan

May 31, 2009, 9:06 AM

Post #1 of 11 (968 views)
Permalink
Best practice: How to build app parts reusable?

Hi,

in one of my Catalyst apps I'm building application parts that I want
to reuse in other Catalyst apps where possible. What's the best
practice to do that? I mean the complete parts from controller, to
model, DBIC schema classes and templates.

Let's assume one part is a guestbook (no, it's not but it's a funny
example ;)). The integration of the controller class is very easy. I
just would build a new controller inside the app which uses the
guestbook controller as base class and sets the correct namespace,
where the guestbook should appear. A similar procedure would get me
the model and schemes into my app, but it requires a wrapper class for
each class the guestbook brings with. And the templates? The only
way I know of is to copy and paste them into the 'root' folder of the
app.

There has to be a better way. But which?

I'm also thinking about whole reusable applications. For example a
shopping system which can be extended and modified by overwriting
methods while the base system can be upgraded seamlessly. (I know
MojoMojo as a standalone Catalyst app, but it's only standalone and
not to be extended locally.)

matt

--
rainboxx Matthias Dietrich
Freier Software Engineer

rainboxx | Tel.: +49 (0) 151 / 50 60 78 64
Tölzer Str. 19 | Mail: matt[at]rainboxx.de
70372 Stuttgart | WWW : http://www.rainboxx.de

XING: https://www.xing.com/profile/Matthias_Dietrich18
GULP: http://www.gulp.de/profil/rainboxx.html
Attachments: PGP.sig (0.19 KB)


mdietrich at cpan

Jun 1, 2009, 9:48 AM

Post #2 of 11 (912 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

Hm, should this be posted on Catalyst-dev?


Am 31.05.2009 um 18:06 schrieb Matthias Dietrich:

> Hi,
>
> in one of my Catalyst apps I'm building application parts that I
> want to reuse in other Catalyst apps where possible. What's the
> best practice to do that? I mean the complete parts from
> controller, to model, DBIC schema classes and templates.
>
> Let's assume one part is a guestbook (no, it's not but it's a funny
> example ;)). The integration of the controller class is very easy.
> I just would build a new controller inside the app which uses the
> guestbook controller as base class and sets the correct namespace,
> where the guestbook should appear. A similar procedure would get me
> the model and schemes into my app, but it requires a wrapper class
> for each class the guestbook brings with. And the templates? The
> only way I know of is to copy and paste them into the 'root' folder
> of the app.
>
> There has to be a better way. But which?
>
> I'm also thinking about whole reusable applications. For example a
> shopping system which can be extended and modified by overwriting
> methods while the base system can be upgraded seamlessly. (I know
> MojoMojo as a standalone Catalyst app, but it's only standalone and
> not to be extended locally.)
>
> matt

--
rainboxx Matthias Dietrich
Freier Software Engineer

rainboxx | Tel.: +49 (0) 151 / 50 60 78 64
Tölzer Str. 19 | Mail: matt[at]rainboxx.de
70372 Stuttgart | WWW : http://www.rainboxx.de

XING: https://www.xing.com/profile/Matthias_Dietrich18
GULP: http://www.gulp.de/profil/rainboxx.html
Attachments: PGP.sig (0.19 KB)


zzbbyy at gmail

Jun 2, 2009, 2:05 AM

Post #3 of 11 (908 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Sun, May 31, 2009 at 6:06 PM, Matthias Dietrich <mdietrich[at]cpan.org> wrote:
> Hi,
>
> in one of my Catalyst apps I'm building application parts that I want to
> reuse in other Catalyst apps where possible.  What's the best practice to do
> that?  I mean the complete parts from controller, to model, DBIC schema
> classes and templates.
>
> Let's assume one part is a guestbook (no, it's not but it's a funny example
> ;)).  The integration of the controller class is very easy.  I just would
> build a new controller inside the app which uses the guestbook controller as
> base class and sets the correct namespace, where the guestbook should
> appear.  A similar procedure would get me the model and schemes into my app,
> but it requires a wrapper class for each class the guestbook brings with.
>  And the templates?  The only way I know of is to copy and paste them into
> the 'root' folder of the app.

Just one idea - in the TT view there is a
http://search.cpan.org/~mramberg/Catalyst-View-TT-0.29/lib/Catalyst/View/TT.pm#DYNAMIC_INCLUDE_PATH
option. I have never eventually used that - but when I was adding it
what I had in mind was something like template inheritance. By
splitting the templates into separate files you can use it to override
those individual templates just like you can override methods in a
class. The difference is that a class is a file and method is a part
of that file - here the the corresponding things are a directory and
an individual template.

>
> There has to be a better way.  But which?
>
> I'm also thinking about whole reusable applications.  For example a shopping
> system which can be extended and modified by overwriting methods while the
> base system can be upgraded seamlessly.  (I know MojoMojo as a standalone
> Catalyst app, but it's only standalone and not to be extended locally.)

There is Handel - I have never explored it but I think the design goal
was to make it extendable.


--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

_______________________________________________
List: Catalyst[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


iainhubbard at googlemail

Jun 2, 2009, 2:51 AM

Post #4 of 11 (903 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Tue, 2009-06-02 at 11:05 +0200, Zbigniew Lukasiak wrote:

> Just one idea - in the TT view there is a
> http://search.cpan.org/~mramberg/Catalyst-View-TT-0.29/lib/Catalyst/View/TT.pm#DYNAMIC_INCLUDE_PATH
> option.

This is exactly what we used in this situation, as mentioned before we
have wrapper classes with use lib/base to get at the shared code and
then in the shared base controller we setup the alternate TT search
paths.

sub apath : Chained('/') : CaptureArgs(0) {
my ( $self, $c ) = @_;
$c->stash->{'additional_template_paths'} =
['/path/to/shared/templates'];
return 1;
}

The good thing about this for us is that we can override the path in the
child controller.

sub apath : PathPart('different/path') Chained('/') CaptureArgs(0) {
my ( $self, $c ) = @_;
$self->NEXT::apath($c);
}

This has allowed us to have the same code for a number of sites with
different urls and site specific stuff kept in the respective child
controllers.

Iain.


_______________________________________________
List: Catalyst[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


edencardim at gmail

Jun 2, 2009, 6:42 AM

Post #5 of 11 (900 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Sun, May 31, 2009 at 1:06 PM, Matthias Dietrich <mdietrich[at]cpan.org> wrote:
> in one of my Catalyst apps I'm building application parts that I want to
> reuse in other Catalyst apps where possible.  What's the best practice to do
> that?  I mean the complete parts from controller, to model, DBIC schema
> classes and templates.
>
> Let's assume one part is a guestbook (no, it's not but it's a funny example
> ;)).  The integration of the controller class is very easy.  I just would
> build a new controller inside the app which uses the guestbook controller as
> base class and sets the correct namespace, where the guestbook should
> appear.  A similar procedure would get me the model and schemes into my app,
> but it requires a wrapper class for each class the guestbook brings with.

You don't really need a wrapper, you can shove all your classes into a
single namespace and selectively load the ones you want into your app
via $c->config->{setup_components} and the Module::Pluggable API.

>  And the templates?  The only way I know of is to copy and paste them into
> the 'root' folder of the app.

Assuming you're using Catalyst::View::TT, just change the INCLUDE_PATH setting.

--
Eden Cardim Need help with your Catalyst or DBIx::Class project?
Code Monkey http://www.shadowcat.co.uk/catalyst/
Shadowcat Systems Ltd. Want a managed development or deployment platform?
http://edenc.vox.com/ http://www.shadowcat.co.uk/servers/

_______________________________________________
List: Catalyst[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


dbix-class at trout

Jun 8, 2009, 11:55 AM

Post #6 of 11 (844 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Sun, May 31, 2009 at 06:06:48PM +0200, Matthias Dietrich wrote:
> Hi,
>
> in one of my Catalyst apps I'm building application parts that I want
> to reuse in other Catalyst apps where possible. What's the best
> practice to do that? I mean the complete parts from controller, to
> model, DBIC schema classes and templates.
>
> Let's assume one part is a guestbook (no, it's not but it's a funny
> example ;)). The integration of the controller class is very easy. I
> just would build a new controller inside the app which uses the
> guestbook controller as base class and sets the correct namespace,
> where the guestbook should appear. A similar procedure would get me
> the model and schemes into my app, but it requires a wrapper class for
> each class the guestbook brings with. And the templates? The only
> way I know of is to copy and paste them into the 'root' folder of the
> app.
>
> There has to be a better way. But which?

Just have your controller base class set:

$c->stash(additional_template_paths => $self->template_paths);

in a begin or auto or whatever action.

See Catalyst::Plugin::AutoCRUD for injecting extra components into the
various areas during application setup.

--
Matt S Trout Catalyst and DBIx::Class consultancy with a clue
Technical Director and a commit bit: http://shadowcat.co.uk/catalyst/
Shadowcat Systems Limited
mst (@) shadowcat.co.uk http://shadowcat.co.uk/blog/matt-s-trout/

_______________________________________________
List: Catalyst[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


robertkrimen at gmail

Jun 8, 2009, 8:29 PM

Post #7 of 11 (835 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Mon, Jun 8, 2009 at 11:55 AM, Matt S Trout <dbix-class[at]trout.me.uk>wrote:

>
> See Catalyst::Plugin::AutoCRUD for injecting extra components into the
> various areas during application setup.


I had this problem last week, and released a solution today:

http://search.cpan.org/perldoc?CatalystX::InjectComponent

Based of off the ::AutoCRUD code

Rob


rmb32 at cornell

Jun 8, 2009, 8:42 PM

Post #8 of 11 (834 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

Matt S Trout wrote:
> Just have your controller base class set:
>
> $c->stash(additional_template_paths => $self->template_paths);

Can you do something similar if using Mason?

Rob


_______________________________________________
List: Catalyst[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


stephenclouse at gmail

Jun 9, 2009, 9:21 AM

Post #9 of 11 (832 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Mon, Jun 8, 2009 at 10:42 PM, Robert Buels <rmb32[at]cornell.edu> wrote:

> Matt S Trout wrote:
>
>> Just have your controller base class set:
>>
>> $c->stash(additional_template_paths => $self->template_paths);
>>
>
> Can you do something similar if using Mason?
>

Yes, use multiple comp_roots:

<code>
package MyApp::View::Mason;
use parent 'Catalyst::View::Mason';

__PACKAGE__->config(
comp_root => [
[ foo => '/myapp/root/templates/foo' ],
[ bar => '/myapp/root/templates/bar' ],
],
);
</code>

The comp_roots are treated as a single component tree by the Mason
resolver. If the same template path exists in multiple comp_roots, the one
in the first listed comp_root is used; the later ones are never seen. All
standard Mason mechanics apply to the resulting component tree.

This config syntax, however, can be a pain to include in external config
files, since it's an array of arrays (YAML looks ugly, Config::General can't
even do it at all, the rest I don't know). My hack was to use a COMPONENT
hook to transform a single key/value into whatever I needed. Here's an
example of one I use with a multiple-client app to setup a client-specific
template directory followed by a common template set:

<code>
sub COMPONENT {
my $self = shift;
my($c,$arguments) = @_;
$arguments->{comp_root} ||= [
[ client => $c->path_to('root/template/client',
lc($c->config->{client})) ],
[ base => $c->path_to('root/template/base') ],
];
$self->next::method(@_);
}
</code>

So the above with config:

<MyApp>
client foo
</MyApp>

results in the equivalent of:

<code>
MyApp->config(
comp_root => [
[ client => '/myapp/root/template/client/foo' ],
[ base => '/myapp/root/template/base' ],
],
);
</code>

--
Stephen Clouse <stephenclouse[at]gmail.com>


bobtfish at bobtfish

Jun 9, 2009, 1:39 PM

Post #10 of 11 (829 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On 9 Jun 2009, at 04:29, Robert Krimen wrote:
> On Mon, Jun 8, 2009 at 11:55 AM, Matt S Trout <dbix-
> class[at]trout.me.uk> wrote:
>
> See Catalyst::Plugin::AutoCRUD for injecting extra components into the
> various areas during application setup.
>
> I had this problem last week, and released a solution today:
>
> http://search.cpan.org/perldoc?CatalystX::InjectComponent
>
> Based of off the ::AutoCRUD code

This is neat, but in no way taking advantage of the new Moose code.

I have some code in the CatalystX::DynamicComponent namespace meant
to solve this problem:

http://github.com/bobtfish/catalyst-dynamicappdemo/tree/master
http://search.cpan.org/dist/CatalystX-DynamicComponent/

CatalystX::DynamicComponent (which solves around the same problem
you're solving) is fairly solid at this point. The other things based
off it which are also in the dist - much less so...

My initial approach was to provide an application class role, but I
think I may prefer your approach of putting all of the logic into
it's own class, which you then pass the application class to permute.

Would you be interested in collaborating on this? Initially I think
I'd fork your code and compose my pre-existing role onto it to see
how far that gets us / how much of the ugly code you inherited from
AutoCRUD goes away.

Sound reasonable?

Cheers
t0m


robertkrimen at gmail

Jun 10, 2009, 11:02 AM

Post #11 of 11 (807 views)
Permalink
Re: Best practice: How to build app parts reusable? [In reply to]

On Tue, Jun 9, 2009 at 1:39 PM, Tomas Doran <bobtfish[at]bobtfish.net> wrote:

>
> This is neat, but in no way taking advantage of the new Moose code.
>
> I have some code in the CatalystX::DynamicComponent namespace meant to
> solve this problem:
>
> http://github.com/bobtfish/catalyst-dynamicappdemo/tree/master
> http://search.cpan.org/dist/CatalystX-DynamicComponent/
>

I actually stumbled on this when I was poking around the AutoCRUD code. It
looked really interesting, but also a lot more complex than what AutoCRUD
was doing

<http://search.cpan.org/dist/CatalystX-DynamicComponent/>
> CatalystX::DynamicComponent (which solves around the same problem you're
> solving) is fairly solid at this point. The other things based off it which
> are also in the dist - much less so...
>
>
My initial approach was to provide an application class role, but I think I
> may prefer your approach of putting all of the logic into it's own class,
> which you then pass the application class to permute.
>

My idea was also to provide a Catalyst::Plugin::InjectComponent for people
that wanted to integrate that functionality directly into their Catalyst
application. It would provide an ->inject_components stage and an
->inject_component helper... possibly even scanning
$config->{'Plugin::InjectComponent'} for stuff to load


> Would you be interested in collaborating on this? Initially I think I'd
> fork your code and compose my pre-existing role onto it to see how far that
> gets us / how much of the ugly code you inherited from AutoCRUD goes away.
>
> Sound reasonable?
>

Sure, I'll take a look. I think there's room enough on CPAN for both
solutions. My stupid simple AutoCRUD reimplementation, and your more
advanced role-based compositing. I'd be happy to include a SEE ALSO and a
mention in DESCRIPTION so that people can find both easily.

Rob

Catalyst users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.