2011-09-07 12 views
5

¿Hay alguna manera de tener una aplicación en bailarín pero con varios appdirs?Directorios de aplicaciones múltiples con Dancer perl

O me podría hacer algo como esto:

Mi proyecto se encuentra en dir 'foo'. Y digamos que tengo una 'barra' de directorio (no dentro de 'foo') que tiene un directorio llamado 'público'. Lo que mi aplicación 'foo' para utilizar este público como su propio público y si busca, digamos '/css/style.css' y no está en '/ bar/public /' debe buscar el '/ foo/público/'. ¿Cómo puedo hacer eso?

Respuesta

2

Una de las formas de escribir un complemento que haga que sea estático (y reemplace algunas funciones). Puede usar Dancer::Plugin::Thumbnail como ejemplo.

Otra forma que veo es a monkey-patch get_file_response() en Dancer::Renderer que no es realmente una buena idea.

El siguiente código busca archivos estáticos en cada directorio @dirs array. Es sucio, feo e inseguro. Esto se puede romper en la versión futura y puede causar problemas con otras partes del framework Dancer con las que no estoy familiarizado. Estas advertido

#!/usr/bin/env perl 
use Dancer; 
use Dancer::Renderer; 
use MyWeb::App; 

my $get_file_response_original = \&Dancer::Renderer::get_file_response; 
my @dirs = ('foo'); 

*Dancer::Renderer::get_file_response = sub { 
    my $app = Dancer::App->current; 

    my $result; 

    # Try to find static in default dir 
    if ($result = $get_file_response_original->(@_)) { 
     return $result; 
    } 

    # Save current settings 
    my $path_backup = $app->setting('public'); 

    # Go through additional dirs 
    foreach my $dir (@dirs) { 
     $app->setting(public => $dir); 
     if ($result = $get_file_response_original->(@_)) { 
      last; 
     } 
    } 

    # Restore public 
    $app->setting('public' => $path_backup); 

    return $result 
}; 

dance; 

terceras vías es dejar que nginx acaba de hacer este trabajo para usted escribiendo config nginx correcto para su aplicación.

+0

La idea es que ambos directorios deben permanecer separados. – bliof

+0

@bliof Actualicé mi respuesta, puede intentar esto, pero mejor vaya con nginx. – yko

+0

Estaba pensando en otra cosa. ¿Podría hacer 'foo' un complemento y usarlo en 'barra'? La verdadera pregunta es si un plugin de Dancer tiene la funcionalidad de una aplicación de bailarina. Me refiero a ¿podría mapear URL desde allí y cargar plantillas desde su carpeta 'vistas'?/Nunca he escrito un complemento/ – bliof

7

OK, aquí está la buena manera de hacerlo. Por supuesto, puede ser un complemento.

Nunca se debe hacer este tipo de cosas por la piratería en el interior del núcleo del bailarín, que más bien siempre se debe considerar la implementación de un controlador de ruta para hacer el trabajo:

#!/usr/bin/env perl 
use Dancer; 
use File::Spec; 
use Dancer::FileUtils 'read_file_content'; 
use Dancer::MIME; 
use HTTP::Date; 

# your routes here 

# then the catchall route for 
# serving static files 

# better in config 
my @public_dirs = qw(/tmp/test/foo /tmp/test/bar /tmp/test/baz); 

get '/**' => sub { 
    my $path = request->path; 
    my $mime = Dancer::MIME->instance; 

    # security checks 
    return send_error("unauthrorized request", 403) if $path =~ /\0/; 
    return send_error("unauthrorized request", 403) if $path =~ /\.\./; 

    # decompose the path_info into a file path 
    my @path = split '/', $path; 

    for my $location (@public_dirs) { 
     my $file_path = File::Spec->catfile($location, @path); 

     next if ! -f $file_path; 

     my $content = read_file_content($file_path); 
     my $content_type = $mime->for_file($file_path); 
     my @stat = stat $file_path; 

     header 'Content-Type', $content_type; 
     header 'Content-Length', $stat[7]; 
     header 'Last-Modified', HTTP::Date::time2str($stat[9]); 
     return $content; 
    } 

    pass; 
}; 

start; 

Un ejemplo de esta aplicación en ejecución:

$ mkdir -p /tmp/test/foo /tmp/test/bar /tmp/test/baz 
$ echo 1 > /tmp/test/foo/foo.txt 
$ echo 2 > /tmp/test/bar/bar.txt 
$ echo 3 > /tmp/test/baz/baz.txt 
$ ./bin/app.pl 
$ curl -I http://0:3000/baz.txt 
HTTP/1.0 200 OK 
Content-Length: 2 
Content-Type: text/plain 
Last-Modified: Fri, 14 Oct 2011 11:28:03 GMT 
X-Powered-By: Perl Dancer 1.3051 
Cuestiones relacionadas