#!/usr/bin/perl use strict; use warnings; use YAML; use File::Spec; use Template; use PadWalker 'peek_my'; sub dir { mkdir File::Spec->catfile(@_), 0777 } sub file { my @args = @_; my $tmpl = pop @args; my $ofile = File::Spec->catfile(@args); my $tt = Template->new( TAG_STYLE => 'asp' ); $tt->process(\$tmpl, {proj => ${peek_my(1)->{'$proj'}}}, $ofile) or die $tt->error; $ofile; } sub executable($) { chmod oct(766), shift } my $proj = shift @ARGV or die "Usage: $0 ProjectName"; dir $proj; dir $proj, 'lib'; dir $proj, 'tmpl'; dir $proj, 'htdocs'; dir $proj, 'htdocs', 'js'; dir $proj, 'htdocs', 'css'; file $proj, 'lib', "$proj.pm" => <<'...'; package <% proj %>; use strict; use warnings; 1; ... file $proj, 'lib', $proj, "C.pm" => <<'...'; package <% proj %>::C; use strict; use warnings; use strict; use warnings; use base 'Sledge::Pages::CGI'; use Sledge::Template::TT; use Scalar::Util qw/blessed/; use Carp; use Sledge::Utils; use autobox; use autobox::Core; use Sledge::Plugin::Stash; use Template::Provider::Encoding; use Sledge::Authorizer::Null; sub create_authorizer { Sledge::Authorizer::Null->new(shift) } use Sledge::SessionManager::Null; sub create_manager { Sledge::SessionManager::Null->new(shift) } use Sledge::Session::File; sub create_session { Sledge::Session::File->new(shift) } use Sledge::Charset::UTF8; sub create_charset { Sledge::Charset::UTF8->new(shift) } use <% proj %>::Config; sub create_config { <% proj %>::Config->instance } *config = *create_config; sub set_args { my ( $self, $args ) = @_; croak "this is instance method" unless blessed $self; $self->{args} = $args; $self; } sub args { shift->{args} } sub tmpl_dirname { my $class = shift; my $proto = ref $class || $class; $proto =~ s/^<% proj %>::C:://; my $ret = $proto->split(qr/::/)->map( sub { my $path = shift; String::CamelCase::decamelize($path); } )->join('/'); return "/$ret"; } __PACKAGE__->add_trigger( BEFORE_DISPATCH => sub { my $self = shift; $self->tmpl->add_option( LOAD_TEPLATES => [ Template::Provider::Encoding->new ], ); } ); 1; ... file $proj, 'lib', $proj, 'C', 'Root.pm' => <<'...'; package <% proj %>::C::Root; use strict; use warnings; use base '<% proj %>::C'; sub dispatch_index { } 1; ... file $proj, 'lib', $proj, 'Router.pm' => <<'...'; package <% proj %>::Router; use strict; use warnings; use Carp; use Switch; sub route { my ($class, $path) = @_; croak "path is empty" unless defined $path; switch ($path) { case '/' { return {controller => '<% proj %>::C::Root', page => 'index'}; } else { die "unknown path: $path"; } } } 1; ... file $proj, 'lib', $proj, 'Config.pm' => <<'...'; package <% proj %>::Config; use strict; use warnings; use Class::AutoAccess::Deep; use FindBin; use File::Spec; my $conf = { tmpl_path => File::Spec->catfile($FindBin::Bin, '..', 'tmpl'), }; sub instance { Class::AutoAccess::Deep->new($conf) } 1; ... file $proj, 'tmpl', 'include', 'header.html' => <<'...';