肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

ActionFormの定義をYAMLでしてAction生成時に自動的にフォーム定義するプラグイン

てなわけで。

某MLに触発されて、アクションフォームの自動生成を作ってみました。定義用ファイルのフォーマットには、symfonyでも使われているというYAMLを採用してみました。(でもまだsymfony触ったことないから一体どこで使われてるのか知らないというまぬけさ。勉強しますごめんなさい)

でまあ。Ethna触っててやっぱりなにが面倒かって、DBまわりとアクションフォームだと思うのです。ただ、フォーム定義は、「あとで楽するための面倒」だから結構作ってるときは気持ちが良いです(笑)*1
で、その楽をするための面倒ですが、やっぱりいっぱい定義してると面倒になってきます。' とか _ とか、結構ね。タイポするし><

そんなわけで、YAMLで作ってみようキャンペーン。ちなみに検証はEthna-2.3.2でしかしてません。

先におことわりしておくと、あんま面白いことやってないかもしれません。というのも、あんま時間かけて検証してないので、もしかしたらいろいろ変なところがあるかもです。時間あるときにちゃんと使えるモノにしていきたいなーとは思っとります。

1. プラグインを用意する

今回用意するファイルは3つ+spyc(PHPでYAML使うためのライブラリ) です。

Ethna標準のプラグインじゃないのにプレフィックスを「Ethna_」にしていいのか不安。別の名前にするとコントローラで定義しないといけないからめんどかったからなんだけど。で、ファイルはSTRK.JPにアップロードしときましたんで、適当にもってっちゃってください。
spycもダウンロードしてください。

2. ファイルを設置

  • Ethna-2.3.2-Plugin-ActionYaml.tar.gz
    • 展開すると、Ethnaのディレクトリまんまになってるので、そのまま置いていただいても結構ですし、ベースのEthanに入れない場合はappディレクトリ内のPluginに設置しても大丈夫だと思います(たぶん)
    • Plugin/Generator/Ethna_Plugin_Generator_ActionYaml.php
    • Plugin/Handle/Ethna_Plugin_Handle_AddActionYaml.php
    • てなカンジになると思います。
    • skelファイルも、どっちにおいても大丈夫です。
  • spyc
    • 展開して生成された spyc ディレクトリごと、アプリケーションのlibディレクトリにおいてください。

3. YAMLファイルを用意

  • yamlディレクトリの作成
    • アプリケーションのBASE_DIR 直下に、yaml ディレクトリを作ってください。YAMLファイルはこの中から読み込みます。

まあ今回はテストってことで、とりあえず、下記のようなファイルを用意します。Ethna本体の文字コードにあわせて、EUC-JPで保存してください。

id:
  type:int
  form_type:text
  required:true
email:
  type:string
  form_type:text
  name:メールアドレス
  max:63
  required:false
  custom:checkMailaddress
name:
  name:お名前
  type:string
  required:true
  mbregexp:^[ぁ-んー]+$
  mbregexp_encoding:EUC-JP
job:
  type:int
  form_type:select
  option:
    1:社会人
    2:学生
    3:必殺アルバイト
job2:
  type:int
  form_type:radio
  option:
    1:社会人
    2:学生
    3:必殺アルバイト

4. アクションファイルを生成する

とりあえず、適当なところで ethna って打ってみます。ドキドキ。

[sotaro@centos sample]# ethna
usage: ethna [option] [command] [args...]

available options are as follows:

...(中略)

  add-action-yaml -> add new action with action form (generate by yaml) to project:
    add-action-yaml [-b|--basedir=dir] [-y|--yamlfile=yamlfile] [-s|--skelfile=file] [-g|--gateway=www|cli|xmlrpc] [action]

こんなカンジで出ます。コマンド名もなんか微妙です。良いのが思いつかないまま、ファイルまで作ってしまっってごめんなさい。。

で、肝心のファイル生成ですが、(例えばUserというアクションを作るとき、フォーム定義も自動生成する)

[sotaro@centos sample]# ethna add-action-yaml user

これでOKです。yamlのファイル名は省略可能で、省略した場合、user.yaml (この場合は)になります。アクション名.yamlがデフォルトです。ほかのファイルを指定する場合は、

[sotaro@centos sample]# ethna add-action-yaml --yamlfaile=XXX.yaml user

または

[sotaro@centos sample]# ethna add-action-yaml -y XXX.yaml user

で。いずれも BASE_DIR/yaml にファイルはおいてください。

5. 生成されたファイルの確認

  • BASE_DIR/app/action/User.php
<?php

... 中略
class Sample_Form_User extends Sample_ActionForm
{
    ...
    var $form = array(
        'id'  =>  array(
            'type'  =>  VAR_TYPE_INT,
            'form_type'  =>  FORM_TYPE_TEXT,
            'required'  =>  true,
        ),
        'email'  =>  array(
            'type'  =>  VAR_TYPE_STRING,
            'form_type'  =>  FORM_TYPE_TEXT,
            'name'  => 'メールアドレス',
            'max'  =>  63,
            'required'  =>  false,
            'custom'  => 'checkMailaddress',
        ),
        'name'  =>  array(
            'name'  => 'お名前',
            'type'  =>  VAR_TYPE_STRING,
            'required'  =>  true,
            'mbregexp'  => '^[ぁ-んー]+$',
            'mbregexp_encoding'  => 'EUC-JP',
        ),
        'job'  =>  array(
            'type'  =>  VAR_TYPE_INT,
            'form_type'  =>  FORM_TYPE_SELECT,
            'option'  =>  array(
                '1'  => '社会人',
                '2'  => '学生',
                '3'  => '必殺アルバイト',
            ),
    ),
        'job2'  =>  array(
            'type'  =>  VAR_TYPE_INT,
            'form_type'  =>  FORM_TYPE_RADIO,
            'option'  =>  array(
                '1'  => '社会人',
                '2'  => '学生',
                '3'  => '必殺アルバイト',
            ),
    ),
        
    );

6. アクセスして確認

みたいなカンジで、$this->af->get() できるか確認。まあ定義が間違ってなければデキル!

7. 仕様とか言い訳とか

  • 仕様
    • type と form_type は省略形が使えます。このへんがおいしいと思います。
      • ex.) VAR_TYPE_INT → int
      • ex.) FORM_TYPE_PASSWORD → pass
    • Ethnaの定数と数値とBOOLEAN以外は全部シングルクオートで囲んでます
  • 言い訳&謝罪
    • WWW以外のゲートウェイは未対応
    • ほとんどAddActionのままです。YAMLに関する記述を加えただけですので><
      • クレジットとかも、どうすればよいのかわからないのでふじもとさんのまま。
    • type と form_type 以外は、チェックしてません。本来使えない定義を書いても丁寧に自動生成してくれます。
    • インデントそろえるためになんかむちゃくちゃな処理してます。しかも、ちょっとうまくいってないです。

8. TODO

  • フォームテンプレート使いたいときの処理とか
    • 全然考えてない!
  • 定義のチェックとか。
    • 実は ActionForm の $def とかチェックすればいいだけ?
  • インデントなんとかする。
  • ちゃんと運用してみて問題点を見つけてみる
    • 使ってみないと見えてこないものがたくさんありますよね世の中。
  • 結局そんなに楽じゃないんじゃないかみたいな噂は聞かないことにしておく。

*1:今回はDBについては言及せず。MLでS2Ethnaの新しいのがリリースされたと宣伝があったので、触ってみようかなあ。。