@tanakashiの技術ブログ

現在個人開発に取り組んでおりまして、
フロントに関して今まで慣れ親しんでいた jQuery から Vue.js へ移行してみよう!の挑戦。

ただ、一気にすべてを変えるのはラーニングコストがかかるので、サーバーサイドは今まで通りにCakePHPでいこう!と決め、いざ望んでみると……なるほど。

CakePHP2にElementを組み込もうとしてたんですが、
ご存知CakePHP2だと

$this->Form->create('Model');

をすると、自動で以下のようなコードが生成されます。

<form id="ModelAddForm" method="post" action="/models/add">

 
いつもは便利だと思い、重宝していたこの機能。

でも今回は!出来ればElementの形に合わせたい!
具体的に言えば <el-form> と、el-を接頭語に付けたい!

そのためにHelperを拡張していきましょう。

 

拡張方法

拡張するHelperは、主に HtmlHelperFormHelperになります。

Element - Form に合わせた形にしたいので、そちらを意識して整形していきます。

 

AppController

class AppController extends Controller {  

    public $helpers = [  
        'Form' => ['className' => 'ExForm'],  
        'Html' => ['className' => 'ExHtml'],  
    ];

これで ExFormHelperExHtmlHelper を作成。
こちらで、lib/Cake/View/Helper の中にある、自動タグ作成を補助してくれる機能たちを上書きしていきます。

 

ExHtmlHelper

<?php  
App::uses('HtmlHelper', 'View/Helper');  

class ExHtmlHelper extends HtmlHelper {  

    protected $_tags = [  
        'meta' => '<meta%s/>',  
        'metalink' => '<link href="%s"%s/>',  
        'link' => '<a href="%s"%s>%s</a>',  
        'mailto' => '<a href="mailto:%s"%s>%s</a>',  
        'form' => '<el-form action="%s"%s>',  
        'formwithoutaction' => '<el-form%s>',  
        'formend' => '</el-form>',  
        'input' => '<el-input name="%s"%s/>',  
        'textarea' => '<textarea name="%s"%s>%s</textarea>',  
        'hidden' => '<el-input type="hidden" name="%s"%s/>',  
        'checkbox' => '<el-input type="checkbox" name="%s"%s/>',  
        'checkboxmultiple' => '<el-input type="checkbox" name="%s[]"%s />',  
        'radio' => '<el-input type="radio" name="%s" id="%s"%s />%s',  
        'selectstart' => '<select name="%s"%s>',  
        'selectmultiplestart' => '<select name="%s[]"%s>',  
        'selectempty' => '<option value=""%s>&nbsp;</option>',  
        'selectoption' => '<option value="%s"%s>%s</option>',  
        'selectend' => '</select>',  
        'optiongroup' => '<optgroup label="%s"%s>',  
        'optiongroupend' => '</optgroup>',  
        'checkboxmultiplestart' => '',  
        'checkboxmultipleend' => '',  
        'password' => '<el-input type="password" name="%s"%s/>',  
        'file' => '<el-input type="file" name="%s"%s/>',  
        'file_no_model' => '<el-input type="file" name="%s"%s/>',  
        'submit' => '<input%s/>',  
        'submitimage' => '<input type="image" src="%s"%s/>',  
        'button' => '<el-button%s>%s</el-button>',  
        'image' => '<img src="%s"%s/>',  
        'tableheader' => '<th%s>%s</th>',  
        'tableheaderrow' => '<tr%s>%s</tr>',  
        'tablecell' => '<td%s>%s</td>',  
        'tablerow' => '<tr%s>%s</tr>',  
        'block' => '<div%s>%s</div>',  
        'blockstart' => '<div%s>',  
        'blockend' => '</div>',  
        'hiddenblock' => '<div style="display:none;">%s</div>',  
        'tag' => '<%s%s>%s</%s>',  
        'tagstart' => '<%s%s>',  
        'tagend' => '</%s>',  
        'tagselfclosing' => '<%s%s/>',  
        'para' => '<p%s>%s</p>',  
        'parastart' => '<p%s>',  
        'label' => '<label for="%s"%s>%s</label>',  
        'fieldset' => '<fieldset%s>%s</fieldset>',  
        'fieldsetstart' => '<fieldset><legend>%s</legend>',  
        'fieldsetend' => '</fieldset>',  
        'legend' => '<legend>%s</legend>',  
        'css' => '<link rel="%s" type="text/css" href="%s"%s/>',  
        'style' => '<style type="text/css"%s>%s</style>',  
        'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s" />',  
        'ul' => '<ul%s>%s</ul>',  
        'ol' => '<ol%s>%s</ol>',  
        'li' => '<li%s>%s</li>',  
        'error' => '<div%s>%s</div>',  
        'javascriptblock' => '<script%s>%s</script>',  
        'javascriptstart' => '<script>',  
        'javascriptlink' => '<script type="text/javascript" src="%s"%s></script>',  
        'javascriptend' => '</script>'  
    ];

form たちの頭にel-を付けてみました。
(まだ作り途中なので一部にのみ付けています)

 
ExFormHelper

<?php  
App::uses('FormHelper', 'View/Helper');  

class ExFormHelper extends FormHelper {  

    public function create($model = null, $options = []) {  
        if(!isset($options['inputDefaults'])) {  
            $options += ['inputDefaults' => [  
                'label' => false,  
                'div' => false,  
            ]];  
        }  
        if(!isset($options[':model'])) {  
            $options += [':model' => $model];  
        }  
        if(!isset($options['status-icon'])) {  
            $options += ['status-icon'];  
        }  
        if(!isset($options[':rules'])) {  
            $options += [':rules' => 'rules'];  
        }  
        return parent::create($model, $options);  
    }  

    public function input($fieldName, $options = []) {  
        if(!isset($options['v-model'])) {  
            $options += ['v-model' => $fieldName];  
        }  
        if(!isset($options['autocomplete'])) {  
            $options += ['autocomplete' => 'off'];  
        }  
        return parent::input($fieldName, $options);  
    }  

    public function elInput($fieldName, $label=null) {  
        $fields = explode('.', $fieldName);  
        $propName = end($fields);  
        echo '<el-form-item label="'.($label?:$propName).'" prop="'.$propName.'">'.$this->input($fieldName).'</el-form-item>';  
    }

フォーム生成時、自動で付けてくれるlabelやdivを引っぺがし、<el-input>たちを生成。
それらを<el-form-item>でwrapper。

$this->Form->elInput('Model.fields', 'ラベル名');

を書くだけで

<el-form-item label="ラベル名" prop="fields">  
    <el-input type="text" v-model="Model.fields" autocomplete="off"></el-input>  
</el-form-item>

が生成されます!
便利だ……。

この調子で引き続き頑張ります!

この記事へのコメント

まだコメントはありません