Phalcon で Tag のヘルパを拡張してみる

ヘルパによる表示は Phalcon\Tag クラスを継承して書くとよいらしい．
Form クラスを使っていて form.render() を使ってレンダリングしている場合は Tag クラスを拡張して DI に設定しても影響しないようなので注意．

# 実装例

以下は Bootstrap の表示に対応するように拡張してみた例． array_merge だとさらに class 追加できないので使い勝手悪いからそこんところよろしく．

```php:Bootstrap/Helpers/Tag.php
<?php

namespace Bootstrap\Helpers;

use Phalcon\Tag as PhTag;

class Tag extends PhTag
{
    /**
     * @param array $parameters
     * @return string
     */
    public static function submitButton($parameters)
    {
        return parent::submitButton(array_merge(array(
            'class' => 'btn btn-primary'
        ), $parameters));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function textArea($parameters)
    {
        return parent::textArea(array_merge(array(
            'class' => 'form-control'
        ), $parameters));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function textField($parameters)
    {
        return parent::textField(array_merge(array(
            'class' => 'form-control'
        ), $parameters));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function passwordField($parameters)
    {
        return parent::passwordField(array_merge(array(
            'class' => 'form-control'
        ), $parameters));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function emailField($parameters)
    {
        return static::inputGroup('<div class="input-group-addon">@</div>'.parent::emailField(array_merge(array(
            'class' => 'form-control'
        ), $parameters)));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function numberField($parameters)
    {
        return parent::numberField(array_merge(array(
            'class' => 'form-control'
        ), $parameters));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function dateField($parameters)
    {
        return parent::dateField(array_merge(array(
            'class' => 'form-control'
        ), $parameters));
    }

    /**
     * @param array $parameters
     * @return string
     */
    public static function numericField($parameters)
    {
        return parent::numericField(array_merge(array(
            'class' => 'form-control'
        ), $parameters));
    }

    /**
     * @param string $str
     * @param string
     */
    private static function inputGroup($str)
    {
        return '<div class="input-group">'.$str.'</div>';
    }
}
```

DI に下記のように設定するとビュー側で特に指定せずに使えるようになる．

```php:services.php
$di->set('tag', function() {
    return new Bootstrap\Helpers\Tag();
}); 
```

# 使用例

```volt:volt
{{ text_field('hoge') }}
{{ password_field('hoge') }}
{{ file_field('hoge') }}
{{ check_field('hoge') }}
{{ radio_field('hoge') }}
{{ date_field('hoge') }}
{{ email_field('hoge') }}
{{ numeric_field('hoge') }}
{{ submit_button() }}
{{ select_static('hoge', ['A': 'Active', 'B': 'Inactive'], 'multiple': '') }}
{{ select('hoge', ['A': 'Active', 'B': 'Inactive']) }}
{{ text_area('hoge', 'value': 'This is contents.') }}
```

下記出力例は表示の都合で改行を追加している．ここでは全部 id が同じになってるけど本当は id は重複してはいけない．

```html:html
<input type="text" id="hoge" name="hoge" class="form-control" />
<input type="password" id="hoge" name="hoge" class="form-control" />
<input type="file" id="hoge" name="hoge" />
<input type="checkbox" id="hoge" name="hoge" />
<input type="radio" id="hoge" name="hoge" />
<input type="date" id="hoge" name="hoge" class="form-control" />
<div class="input-group"><div class="input-group-addon">@</div><input type="email" id="hoge" name="hoge" class="form-control" /></div>
<input type="number" id="hoge" name="hoge" class="form-control" />
<input type="submit" class="btn btn-primary" />
<select id="hoge" name="hoge" multiple="">
	<option value="A">Active</option>
	<option value="B">Inactive</option>
</select>
<select id="hoge" name="hoge">
	<option value="A">Active</option>
	<option value="B">Inactive</option>
</select>
<textarea id="hoge" name="hoge" value="This is contents." class="form-control">This is contents.</textarea>
```

## 表示例

DI に登録しない場合

![screenshot 2014-07-23 5.02.12.png](https://qiita-image-store.s3.amazonaws.com/0/6975/b8d2dc2f-7a44-d0b5-2f33-aadc4208e744.png)

した場合．

![screenshot 2014-07-23 4.59.26.png](https://qiita-image-store.s3.amazonaws.com/0/6975/6b8fda8c-b020-a1af-9dd1-46b36c66b61d.png)