Skeleton::CoC

フレームワークにそってアプリケーションを開発していると、これを追加するには、このクラスとこのクラスを作って、ここにテンプレートを追加する、といったことがよくある。

railsとかだとscript/generateとかあってテンプレートを元にファイルを自動生成できるので、似たようなのを簡単に作れると便利なこともありそうだな、ということで今さらながら書いてみた。

他にも似たようなのありそうだなぁと思いつつ、意外とそれっぽいのがなくて、わりと簡単に使えるのではないかなと思う。

もちろんrubigenでもよいのだけど、環境によってはrubyやらgemがあまり入ってない環境もあるので。

https://github.com/walf443/p5-skeleton-coc

テンプレートの種別ごとに、define_targetで依存関係と、ファイル名を指定してやり、Data::Section::Simpleで対応するテンプレートファイルを書いてやる。

テンプレートファイルの文法にはText::MicroTemplateを使っているので、ほぼperlで好きなように書ける、といった感じ。

        package YourApp::Skeleton;
        use parent(Skeleton::CoC);
        use String::CamelCase qw();

        __PACKAGE__->define_target('controller' => [], sub {
            my ($self, $pkg) = @_;
            my $path = join "/", split /::/, $pkg;
            return "lib/YourApp/C/$path.pm";
        });

        __PACKAGE__->define_target('action' => ['controller'], sub {
            my ($self, $str) = @_;
            my $path = join "/", map { String::CamelCase::decamelize($_) } split /::/, $self->controller;
            return "assets/tmpl/$path/$str.html";
        });

        __DATA__

        @controller
        ? my $self = shift; # $self is a Skeleton::CoC.
        package <? $self->project ?>::C::<?= $self->controller ?>;
        use strict;
        use warnings;
        use parent qw(YourApp::C);

        ? if ( $self->action ) {

        sub dispatch_<?= $self->action ?> {
            my ($self, ) = @_;
        }

        ? }
        1;

        @@ action
        [% INCLUDE "include/header.html" %]
        [% INCLUDE "include/footer.html" %]

で、生成させるときに呼ぶファイルはこんな風に記述しておく。

        strict;
        warnings;
        use YourApp::Skeleton;
        my $skeleton = YourApp::Skeleton->new(
            project => "YourApp",
            action => "index",
        );
        $skeleton->parse_options(@ARGV);
        $skeleton->generate;

で、こんな感じで実行してやる。

        $ ./skeleton.pl controller Foo::Bar
        # => generate lib/YourApp/C/Foo/Bar.pm

        $ ./skeleton.pl controller Foo::Bar action baz
        # => generate lib/YourApp/C/Foo/Bar.pm
        #    generate assets/tmpl/foo/bar/baz.html

個人的な要望にはわりと沿ってはいるが、まだそんなに使いこんではいないので、使いにくいケースはあるかもしれない。

もうちょい使いつつ、インターフェース等は変えるかもしれない。