CatalystX::Controller::Sugar::ActionPack::Merge - Merge static files


CatalystX-Controller-Sugar-ActionPack documentation Contained in the CatalystX-Controller-Sugar-ActionPack distribution.

Index


Code Index:

NAME

Top

CatalystX::Controller::Sugar::ActionPack::Merge - Merge static files

DESCRIPTION

Top

Provides an action which can serve multiple files in one request. The reason for this is easier maintenance of css and js files, while having less request to the web server.

SAMPLE CONFIG FILE

Top

 <Controller::Root>
   <merge> # <-- "js" from "/merge/foo.js"
     <js>
       content_type text/javascript
       foo file1.js # <-- "foo" from "/merge/foo.js"
       foo file2.js # <--/ /
       foo file3.js # <---/
     </js>
   </merge>
 </Controller::Root>

The example above requires this module to be injected into the Root controller.

ACTIONS

Top

Endpoint /merge/*

 go '/merge', [$virtual_file];

Will merge files from the static directory, based on requested path.

Example: Will serve "file1.js", "file2.js" and "file3.js", if $virtual_file is "foo.js", based on the config from SAMPLE CONFIG FILE.

LICENSE

Top

AUTHOR

Top

See CatalystX::Controller::Sugar::ActionPack.


CatalystX-Controller-Sugar-ActionPack documentation Contained in the CatalystX-Controller-Sugar-ActionPack distribution.
package CatalystX::Controller::Sugar::ActionPack::Merge;

use CatalystX::Controller::Sugar::Plugin;
use File::Slurp qw/ read_file /;

chain '/' => 'merge' => sub {
    my $key = shift || '';
    my $config = controller->{'merge'} || controller;
    my $section;

    if($key =~ s/\.(\w{2,4})$//) {
        $section = $1;
    }
    else {
        go '/error' => ['not_found', 'Nothing to merge'];
    }

    my $base = c->path_to('root', 'static', $section);
    my $files = $config->{$section}{$key};
    my $content_type = $config->{$section}{'content_type'};
    my $modified = time;
    my $body = '';

    unless($content_type) {
        go '/error' => ['bad_request', 'Content type missing'];
    }
    unless($files) {
        go '/error' => ['not_found', 'Files not found'];
    }

    $files = [$files] unless(ref $files eq 'ARRAY');

    FILE:
    for my $file (grep { not m,/, } @$files) {
        my @stat = stat "$base/$file";

        eval {
            $body .= read_file("$base/$file");
        } or do {
            report error => 'Could not merge %s: %s', $file, $@;
            next FILE;
        };

        $modified = $stat[9] if($modified < $stat[9]);
    }

    res->headers->content_type($content_type);
    res->headers->last_modified($modified);
    res->headers->content_length(length $body);
    res->body($body);
};

1;