Mailing List Archive

How to get default()-like behavior outside of the Root controller
Some of my top-level controllers represent different, er... "major
pieces" of my application. They have, among other things, different
default views, which are mainly just for configuring different page
wrappers. These controllers have this action pattern:

package MyApp::Admin;
sub base : Chained('/') : PathPart('admin') : CaptureArgs(0) { ... }
sub index : Chained('base') : PathPart('') : Args(0) { ... }

package MyApp::Survey;
sub base : Chained('/') : PathPart('survey') : CaptureArgs(0) { ... }
...etc...

Requests for non-extant paths fall through to Root->default(), which
gives the (undesired) default root view. I tried giving my top-level
controllers their own default() methods, but as others have found [1],
'default() : Path' has precedence over 'index : Chained'. Otherwise, I
get the appropriate view with 'Page Not Found' content for bad urls,
e.g. /admin/blargh or /survey/123/nurgle

I am looking for suggestions/solutions to get the desired behavior.

Changing index() to 'index : Path' is not a viable option.


Thanks,
--Trevor

[1] http://www.gossamer-threads.com/lists/catalyst/users/24883

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: How to get default()-like behavior outside of the Root controller [ In reply to ]
I'd rather split one application into several (admin app, survey app,
etc) and "join" its via middleware.

But you can try this:

In MyApp::Admin:
sub default : Path('admin') {
# or
# sub default : Chained(base) PathPart('') Path {
my ( $self, $c ) = @_;
$c->response->body( 'Page not found in /admin/...' );
$c->response->status(404);
}


In MyApp::Survey;
sub default : Path('survey') {
# or
# sub default : Chained(base) PathPart('') Path {
my ( $self, $c ) = @_;
$c->response->body( 'Page not found in /survey/...' );
$c->response->status(404);
}

On 7 February 2015 at 01:51, Trevor Leffler <tleffler@uw.edu> wrote:
> Some of my top-level controllers represent different, er... "major pieces"
> of my application. They have, among other things, different default views,
> which are mainly just for configuring different page wrappers. These
> controllers have this action pattern:
>
> package MyApp::Admin;
> sub base : Chained('/') : PathPart('admin') : CaptureArgs(0) { ... }
> sub index : Chained('base') : PathPart('') : Args(0) { ... }
>
> package MyApp::Survey;
> sub base : Chained('/') : PathPart('survey') : CaptureArgs(0) { ... }
> ...etc...
>
> Requests for non-extant paths fall through to Root->default(), which gives
> the (undesired) default root view. I tried giving my top-level controllers
> their own default() methods, but as others have found [1], 'default() :
> Path' has precedence over 'index : Chained'. Otherwise, I get the
> appropriate view with 'Page Not Found' content for bad urls, e.g.
> /admin/blargh or /survey/123/nurgle
>
> I am looking for suggestions/solutions to get the desired behavior.
>
> Changing index() to 'index : Path' is not a viable option.
>
>
> Thanks,
> --Trevor
>
> [1] http://www.gossamer-threads.com/lists/catalyst/users/24883
>
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/



--
//wbr, Dmitry L.

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: How to get default()-like behavior outside of the Root controller [ In reply to ]
On 9 February 2015 at 10:59, Dmitry L. <dim0xff@gmail.com> wrote:
> I'd rather split one application into several (admin app, survey app,
> etc) and "join" its via middleware.

I wrote a blog article a few months ago:
http://blogs.perl.org/users/davewood/2014/08/splitting-a-catalyst-app-and-recombining-it-with-plackbuilder.html

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: How to get default()-like behavior outside of the Root controller [ In reply to ]
On 2/9/2015 1:59 AM, Dmitry L. wrote:
> I'd rather split one application into several (admin app, survey app,
> etc) and "join" its via middleware.
>
> But you can try this:
>
> In MyApp::Admin:
> sub default : Path('admin') {
> # or
> # sub default : Chained(base) PathPart('') Path {
> my ( $self, $c ) = @_;
> $c->response->body( 'Page not found in /admin/...' );
> $c->response->status(404);
> }

Neither of these work, as in both cases default() wins over index()
except when index is defined as 'sub index : Path', which isn't a good
option for me.

And... I'd imagine that having both default and index defined with " :
Chained('base') PathPart('') Args(0)" would lead to a collision and/or
non-deterministic behavior...?

--Trevor

>
> In MyApp::Survey;
> sub default : Path('survey') {
> # or
> # sub default : Chained(base) PathPart('') Path {
> my ( $self, $c ) = @_;
> $c->response->body( 'Page not found in /survey/...' );
> $c->response->status(404);
> }
>
> On 7 February 2015 at 01:51, Trevor Leffler <tleffler@uw.edu> wrote:
>> Some of my top-level controllers represent different, er... "major pieces"
>> of my application. They have, among other things, different default views,
>> which are mainly just for configuring different page wrappers. These
>> controllers have this action pattern:
>>
>> package MyApp::Admin;
>> sub base : Chained('/') : PathPart('admin') : CaptureArgs(0) { ... }
>> sub index : Chained('base') : PathPart('') : Args(0) { ... }
>>
>> package MyApp::Survey;
>> sub base : Chained('/') : PathPart('survey') : CaptureArgs(0) { ... }
>> ...etc...
>>
>> Requests for non-extant paths fall through to Root->default(), which gives
>> the (undesired) default root view. I tried giving my top-level controllers
>> their own default() methods, but as others have found [1], 'default() :
>> Path' has precedence over 'index : Chained'. Otherwise, I get the
>> appropriate view with 'Page Not Found' content for bad urls, e.g.
>> /admin/blargh or /survey/123/nurgle
>>
>> I am looking for suggestions/solutions to get the desired behavior.
>>
>> Changing index() to 'index : Path' is not a viable option.
>>
>>
>> Thanks,
>> --Trevor
>>
>> [1] http://www.gossamer-threads.com/lists/catalyst/users/24883
>>
>> _______________________________________________
>> List: Catalyst@lists.scsys.co.uk
>> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>> Dev site: http://dev.catalyst.perl.org/
>
>
>

--
Trevor Leffler, Sr. Software Engineer
Office of Educational Assessment
University of Washington
4311 11th Ave NE, Seattle, WA 98195
tel 206.616.1479 | fax 206.543.3961
http://www.washington.edu/oea

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: How to get default()-like behavior outside of the Root controller [ In reply to ]
Hi Trevor,

* Trevor Leffler <tleffler@uw.edu> [2015-02-07 00:00]:
> Requests for non-extant paths fall through to Root->default(), which
> gives the (undesired) default root view. I tried giving my top-level
> controllers their own default() methods, but as others have found [1],
> 'default() : Path' has precedence over 'index : Chained'.

package MyApp::Admin;
sub default : Chained('base') PathPart('') { ... }
package MyApp::Survey;
sub default : Chained('base') PathPart('') { ... }

Note how you don’t specify any particular number of arguments. So it
will match any number of trailing URL segments.

I *think* this will work. I haven’t tried it.

However, contrary to what you claimed, splitting the app into multiple
Cat apps joined together at the PSGI level *will* also work just fine.
That will lead to requests for /admin/* always being dispatched to
MyApp::Admin – which gets to have its own MyApp::Admin::Controller::Root
with a `default` action that applies only to it. Likewise requests for
/survey/* will always be dispatched to MyApp::Survey which equally has
its own root controller with a `default` action that applies only to it.
If the parts of your app are not closely related, this will be a more
natural structure.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: How to get default()-like behavior outside of the Root controller [ In reply to ]
Hi Aristotle,

On 02/10/2015 02:39 AM, Aristotle Pagaltzis wrote:
> Hi Trevor,
>
> * Trevor Leffler <tleffler@uw.edu> [2015-02-07 00:00]:
>> Requests for non-extant paths fall through to Root->default(), which
>> gives the (undesired) default root view. I tried giving my top-level
>> controllers their own default() methods, but as others have found [1],
>> 'default() : Path' has precedence over 'index : Chained'.
>
> package MyApp::Admin;
> sub default : Chained('base') PathPart('') { ... }
> package MyApp::Survey;
> sub default : Chained('base') PathPart('') { ... }
>
> Note how you don’t specify any particular number of arguments. So it
> will match any number of trailing URL segments.
>
> I *think* this will work. I haven’t tried it.

I had tried this earlier with poor results. However, I spun up a quick
Foo catalyst project for testing and found that if I defined *all* the
defaults()'s as :Chained in Root/Admin/Survey/etc. then they played well
with my other methods, all of which are :Chained. Once you go
:Chained... ;)

> However, contrary to what you claimed, splitting the app into multiple
> Cat apps joined together at the PSGI level *will* also work just fine.
> That will lead to requests for /admin/* always being dispatched to
> MyApp::Admin – which gets to have its own MyApp::Admin::Controller::Root
> with a `default` action that applies only to it. Likewise requests for
> /survey/* will always be dispatched to MyApp::Survey which equally has
> its own root controller with a `default` action that applies only to it.
> If the parts of your app are not closely related, this will be a more
> natural structure.

I don't think I spoke against splitting my app up, rather I just ignored
that line of thought. ;) There may be too many
relationships/dependencies across the major areas to split it up in the
immediate future, but I can see some architectural advantages to doing
so. Simply the fact that I've got variations in template wrappers may
be an indicator.

Thanks,
--Trevor

> Regards,
>

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: How to get default()-like behavior outside of the Root controller [ In reply to ]
It turns out the length of the chaining is a variable in this equation.

In my Test Controller...

This gives "good" behavior:
sub base : Chained('/') PathPart('test') CaptureArgs(0) {}
sub another : Chained('base') PathPart('') CaptureArgs(0) {}
sub index : Chained('another') PathPart('') Args(0) {...}
sub default : Chained('another') PathPart('') Args() { ... }

But this gives too much "weight" to default, allowing it to "win" over
index():
sub index : Chained('another') PathPart('') Args(0) {...}
sub default : Chained('base') PathPart('') Args() { ... }

So, the shorter chain wins, eh? This latter scenario is more common for
me. I'll look into having my index() $c->forward to the bits I need.

--Trevor

On 02/10/2015 02:19 PM, Trevor Leffler wrote:
> Hi Aristotle,
>
> On 02/10/2015 02:39 AM, Aristotle Pagaltzis wrote:
>> Hi Trevor,
>>
>> * Trevor Leffler <tleffler@uw.edu> [2015-02-07 00:00]:
>>> Requests for non-extant paths fall through to Root->default(), which
>>> gives the (undesired) default root view. I tried giving my top-level
>>> controllers their own default() methods, but as others have found [1],
>>> 'default() : Path' has precedence over 'index : Chained'.
>>
>> package MyApp::Admin;
>> sub default : Chained('base') PathPart('') { ... }
>> package MyApp::Survey;
>> sub default : Chained('base') PathPart('') { ... }
>>
>> Note how you don’t specify any particular number of arguments. So it
>> will match any number of trailing URL segments.
>>
>> I *think* this will work. I haven’t tried it.
>
> I had tried this earlier with poor results. However, I spun up a quick
> Foo catalyst project for testing and found that if I defined *all* the
> defaults()'s as :Chained in Root/Admin/Survey/etc. then they played well
> with my other methods, all of which are :Chained. Once you go
> :Chained... ;)
>
>> However, contrary to what you claimed, splitting the app into multiple
>> Cat apps joined together at the PSGI level *will* also work just fine.
>> That will lead to requests for /admin/* always being dispatched to
>> MyApp::Admin – which gets to have its own MyApp::Admin::Controller::Root
>> with a `default` action that applies only to it. Likewise requests for
>> /survey/* will always be dispatched to MyApp::Survey which equally has
>> its own root controller with a `default` action that applies only to it.
>> If the parts of your app are not closely related, this will be a more
>> natural structure.
>
> I don't think I spoke against splitting my app up, rather I just ignored
> that line of thought. ;) There may be too many
> relationships/dependencies across the major areas to split it up in the
> immediate future, but I can see some architectural advantages to doing
> so. Simply the fact that I've got variations in template wrappers may
> be an indicator.
>
> Thanks,
> --Trevor
>
>> Regards,
>>
>
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/

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