Bailador / Bailador

A light-weight route-based web application framework for Perl 6
MIT License
179 stars 46 forks source link

gradual serving #120

Open szabgab opened 7 years ago

szabgab commented 7 years ago

I wonder if this is possible:

A user creates a file app.pl with

use v6;
use Bailador;
baile;

That, without any additional configuration, will map any 'nice' URL to the corresponding .html file in the views/ directory So the user can created views/index.html and it will be served by the route / and the user can create about.html and it will be served by the route /about. The html files will be served by calling template() If the requested route does not have a corresponding .html file Bailador will automaticly try to serve it from the public/ directory as a static file. (css, js, ico, tx, images etc.) If no such file either then 404

Then if the user wants to be more dynamic she can change the html files to include other template files (eg. header, footer) and have parameters in them as well.

If the user wants more control she can start to add routes to the app.pl that will work as expected.

I am not sure if either of these are needed, but the static file serving can be turned off with some configuration parameter. Also the automatic route to html mapping can be turned off by a configuration parameter.

My, not yet successful attempt to implement something like this in a bailador file looks like this:

use v6;
use Bailador;
use Bailador::Route::StaticFile;

#my $files = Bailador::Route::StaticFile.new: directory => $dir, path => '/html/:file';
#add_route: $files;

# this is planned to be a bit more generic than needed here
my $root = $*PROGRAM.absolute.IO.dirname;
if $root.IO.basename eq 'bin' {
    $root = $root.IO.dirname;
}
my $files = Bailador::Route::StaticFile.new: directory => $root, path => /.*/;

get '/(.*)' => sub ($url) {
    my $file  = ($url eq '' ?? 'index' !! $url) ~ '.html';
    my $path = $root.IO.child('views').child($file).Str;
    if $path.IO.e {
        return template($file)
    }

    return False if $url eq '';
    my $static = $root.IO.child('public').child($url);
    content_type('text/css') if $url ~~ /\.css$/;
    content_type('image/x-icon') if $url ~~ /\.ico$/;
    return $static if $static.f;

    return False;
}

baile();
szabgab commented 7 years ago

There is now a module https://github.com/Bailador/bailador.net/blob/main/lib/BailadorGradual.pm in bailador.net that serves this purpose, but must be loaded at the end of the file, just before we call baile() or it will preempt all the other routes. The nice way to use this should be:

use v6;
use Bailador;
use Bailador::Gradual;
baile()

or even

use v6;
use Bailador::Gradual;
baile()
szabgab commented 7 years ago

See e532a64

ufobat commented 6 years ago

I think we should move it into Bailador::Feature::Gradual In order to use it we can do:

use v6.c;
use Bailador;

use-feature('Gradual');
....
baile()
szabgab commented 6 years ago

Go for it. Though as I mentioned elsewhere, currently I think it might be nice to have this out of the box without writing anything. In any case moving to Bailador::Feature::Gradual would be a good step.