Mailing List Archive

more intelligence inside $c->uri_for()
Hi everyone,

currently I am building a small JS/CSS-combining and minifying
controller. To build my URI I am doing business as usual:

$c->uri_for(MyApp->Controller('Js')->action_for('default'), qw
(list of js-files to combine));

yielding (after some hacks) a URI like:

http://localhost/js/list/of/js-files/to/combine.js?m=12345667

which works fine. However, I would like to automatically get added a
Query-Parameter after the URI that reflects the timestamp of the most-
recent file in the URI to allow the browser to do caching properly.
As far as I understand there is currently no way to let the
Controller construct the URI.

As a bad hack, I did something like:

# in my App:
around 'uri_for' => sub {
my $orig = shift;
my $c = shift;
my $path = shift;
my @args = @_;

if (blessed($path) && $path->class && $path->class->can
('uri_for')) {
# simply let the component do the job
return $c->component($path->class)->uri_for($c, $path, @args);
}

return $c->$orig($path, @args);
};

# in my Controller:
sub uri_for :Private {

# logic to create the URI I want

}


Of course it is great that Catalyst allows something like that. Are
there any plans to offer something alike out of the box?


Regards,
Wolfgang Kinkeldei

--

' /\_/\ ' .print[split??,"".(($/=q|Cms)+-03467:;<=|)=~tr!C-z -B! -z!)x
'( o.o )' .$/]->[hex]foreach split qr<>,qq+1ecd039ad65b025b8063475b+||
' > ^ < ' .q<!-- Wolfgang Kinkeldei - mailto:wolfgang@kinkeldei.de -->
Re: more intelligence inside $c->uri_for() [ In reply to ]
On Thu, Apr 30, 2009 at 2:54 PM, Wolfgang Kinkeldei
<wolfgang@kinkeldei.de>wrote:

> Hi everyone,
>
> currently I am building a small JS/CSS-combining and minifying controller.
> To build my URI I am doing business as usual:
>
> $c->uri_for(MyApp->Controller('Js')->action_for('default'), qw(list of
> js-files to combine));
>
> yielding (after some hacks) a URI like:
>
> http://localhost/js/list/of/js-files/to/combine.js?m=12345667
>
> which works fine. However, I would like to automatically get added a
> Query-Parameter after the URI that reflects the timestamp of the most-recent
> file in the URI to allow the browser to do caching properly. As far as I
> understand there is currently no way to let the Controller construct the
> URI.
>
>

This really seems like a good controller base class, rather than something
"out of the box". There is a Catalyst::View::JavaScript::Minifier, but it
seems just a thin layer on top of JavaScript::Minifier::XS and doesn't
handle any cache headers, etc.

I'm also torn on using the most recent mtime as a timestamp in the query
parameter... seems cleaner to have a version scheme for your resources to
bundle them together.

To answer your question, Chained lets you create any URL scheme you can
reasonably think of.

Assuming 'magic_method' gives you the valid files and the mtime, you
probably want something like this:

package MyApp::Controller::JS;

sub serve_files : Chained('/') PathPart('js') Args { ... }

sub generate_url : Private {
my ( $self, $c, @files ) = @_;

my @valid_files, $latest_mtime = magic_method(@files);

$c->uri_for(
# The $action object
$c->controller('JS')->action_for('serve_files'),
# Args to pass in (Yay Chained!)
@valid_files,
# Query parameters to append
{ mtime = $latest_mtime }
);
}

1;