Sledge based application does not know "Where am I?".
so, Sledge configurations are slightly verbose.
package MyApp::Config::_common;
use strict;
use vars qw(%C);
*Config = \%C;
$C{TMPL_PATH} = '/path/to/view';
#...
1;
I should specify the fullpath of templates dir.
this is a typical directory structure of mine.
MyApp/ - HOME directory.
lib/
MyApp/
MyApp/Pages.pm
view/ - template files.
index.tt
htdocs/ - static files. (images, JavaScript, CSS)
logo.gif
etc/ - config files.
Catalyst like path_to impl.
package Sledge::Plugin::PathTo;
use strict;
use Path::Class;
sub import {
my $pkg = caller(0);
no strict 'refs';
$pkg->mk_classdata(qw(home));
$pkg->home(find_home($pkg));
*{"$pkg\::path_to"} = sub {
my ( $self, @path ) = @_;
my $path = dir( $self->home, @path );
if ( -d $path ) {
return $path;
}
else {
return file( $self->home, @path );
}
};
}
sub find_home {
my $class = shift;
(my $file = "$class.pm") =~ s{::}{/}g;
if ( my $inc_entry = $INC{$file} ) {
my $path = file($inc_entry)->absolute->cleanup->stringify;
$path =~ s/$file$//;
my $home = dir($path);
$home = $home->parent while $home =~/(b?lib|site_perl)$/;
return $home->stringify if -d $home;
}
}
yeah, I do not have to write the fullpath in config.
package MyApp::Pages;
use strict;
use Sledge::Pages::Compat;
use Sledge::Plugin::PathTo;
sub create_config {
my $self = shift;
my $config = MyApp::Config->instance;
$config->{tmpl_path} = $self->path_to('view');
$config;
}
actually, Sledge does not have real plugin system..
currently, typical plugin codes are below.
write sub import {} and modify symbol tables directly.
package Sledge::Plugin::Foo;
use strict;
sub import {
my $class = shift;
my $pkg = caller;
no strict 'refs';
*{"$pkg\::foo"} = sub {
# do something
};
$pkg->register_hook(
AFTER_DISPATCH => sub {
# do something.
},
);
}
I think this style is slightly complex..
so, I propose some modules to write plugins easily.
use Sledge::Plugin as a baseclass.
package Sledge::Plugin::Bar;
use strict;
use base qw(Sledge::Plugin);
__PACKAGE__->add_methods(
plugin_method => sub {
my $self = shift;
#...
},
);
__PACKAGE__->register_hooks(
AFTER_DISPATCH => sub {
my $self = shift;
#...
},
);
in your Pages, use Sledge::PluginLoader.
package MyApp::Pages::Root;
use strict;
use base qw(MyApp::Pages::Base);
use Sledge::PluginLoader qw(Bar); # load Sledge::Plugin::Bar.
sub dispatch_index {
my $self = shift;
# You can call the method which provided by plugins.
$self->plugin_method;
}
I wrote the Sledge::Engine, the modern dispatcher of Sledge application.
http://svn.shebang.jp/repos/Sledge-Engine/
write application top-level module. MyApp.pm
package MyApp;
use Sledge::Engine;
__PACKAGE__->setup;
mod_perl handler.
<Location
/>
SetHandler perl-script
PerlHandler MyApp
</Location>
CGI mode. write index.cgi.
#!/usr/bin/perl
use strict;
use MyApp;
MyApp->run;
TODO:
* handle extra path as arguments. (like Catalyst)
/item/detail/23 -> MyApp::Pages::Item->dispatch_detail with 1 argument '23'.
* custom mapping rules.
* mod_perl2 and FastCGI support.