35.4. ビューヘルパー

ビュースクリプトの中で、複雑な関数を繰り返し実行しなければならないこともあるでしょう (例えば日付のフォーマット、フォーム要素の作成、リンクの作成など)。 このような作業を行うために、ヘルパークラスを使用することができます。

ヘルパーの正体は、単なるクラスです。たとえば 'fooBar' という名前のヘルパーを使用するとしましょう。 デフォルトでは、クラス名の先頭には 'Zend_View_Helper_' がつきます (ヘルパーのパスを設定する際に、これは独自のものに変更できます)。 そしてクラス名の最後の部分がヘルパーの名前となります。 このとき、単語の先頭は大文字にしなければなりません。つまり、 ヘルパーのクラス名は Zend_View_Helper_FooBar となります。このクラスには、最低限ヘルパー名と同じ名前 (camelCase 形式にしたもの) のメソッド fooBar() が含まれていなければなりません。

[注意] 注意

ヘルパー名は常に camelCase 形式となります。 つまり、最初は常に小文字となります。

ビュースクリプト内でヘルパーを使用するには、 $this->helperName() をコールします。これをコールすると、裏側では Zend_ViewZend_View_Helper_HelperName クラスを読み込み、 そのクラスのインスタンスを作成して helperName() メソッドをコールします。 オブジェクトのインスタンスは Zend_View インスタンスの中に残り続け、 後で $this->helperName() がコールされたときには再利用されます。

35.4.1. 付属のヘルパー

Zend_View には、はじめからいくつかのヘルパークラスが付属しています。 これらのほとんどはフォーム要素の生成に関するもので、 適切なエスケープ処理を自動的に行います。 さらに、ルートにもとづいた URL と HTML の一覧を作成したり、 変数を宣言したりするものもあります。 現在付属しているヘルパーは、次のとおりです。

  • declareVars(): strictVars() を使用する際に同時に使用します。 このヘルパーを使用すると、テンプレート変数を宣言することができます。 この変数は、すでにビュースクリプトで設定されているものでもいないものでもかまいません。 また、同時にデフォルト値も設定します。 このメソッドへの引数として配列を渡すとデフォルト値を設定します。 それ以外の場合は、もしその変数が存在しない場合は空文字列を設定します。

  • formButton($name, $value, $attribs): <input type="button" /> 要素を作成します。

  • formCheckbox($name, $value, $attribs, $options): <input type="checkbox" /> 要素を作成します。 $options パラメータは配列で、最初の値が "checked" に対応する値、2 番目が "unchecked" に対応する値となります (デフォルトは '1' および '0' です)。$value が "checked" の値に一致すると、チェックボックスがチェックされた状態になります。

  • formFile($name, $value, $attribs): <input type="file" /> 要素を作成します。

  • formHidden($name, $value, $attribs): <input type="hidden" /> 要素を作成します。

  • formLabel($name, $value, $attribs): <label> 要素を作成します。for 属性の値は $name に、そしてラベルのテキストは $value になります。 attribsdisable を渡すと、結果を何も返しません。

  • formPassword($name, $value, $attribs): <input type="password" /> 要素を作成します。

  • formRadio($name, $value, $attribs, $options): 一連の <input type="radio" /> 要素を、 $options の要素ごとに作成します。$options は、 ラジオボタンの値をキー、ラベルを値とする配列となります。 $value はラジオボタンの初期選択状態を設定します。

  • formReset($name, $value, $attribs): <input type="reset" /> 要素を作成します。

  • formSelect($name, $value, $attribs, $options): <select>...</select> ブロックを作成します。 $options の要素ごとに <option> を作成します。 $options は、選択肢の値をキー、 ラベルを値とする配列となります。$value は初期選択状態を設定します。

  • formSubmit($name, $value, $attribs): <input type="submit" /> 要素を作成します。

  • formText($name, $value, $attribs): <input type="text" /> 要素を作成します。

  • formTextarea($name, $value, $attribs): <textarea>...</textarea> ブロックを作成します。

  • url($urlOptions, $name, $reset): 指定したルートにもとづく URL 文字列を作成します。 $urlOptions は、そのルートで使用する キー/値 のペアの配列となります。

  • htmlList($items, $ordered, $attribs): $items で渡した内容をもとに 順序つきリストあるいは順序なしリストを作成します。 $items が多次元配列の場合は、入れ子状のリストとなります。

これらをビュースクリプト内で使用するのはとても簡単です。 以下に例を示します。ただ単に、ヘルパーをコールするだけでよいことに注意しましょう。 読み込みやインスタンス作成は、必要に応じて自動的に行われます。

<?php
// ビュースクリプト内では、$this は Zend_View のインスタンスを指します。
// 
// select の選択肢を、変数 $countries に
// array('us' => 'United States', 'il' => 'Israel', 'de' => 'Germany')
// として設定済みであることにします。
?>
<form action="action.php" method="post">
    <p><label>メールアドレス:
        <?php echo $this->formText('email', 'you@example.com', array('size' => 32)) ?>
    </label></p>
    <p><label>国:
        <?php echo $this->formSelect('country', 'us', null, $this->countries) ?>
    </label></p>
    <p><label>メールを受け取りますか?
        <?php echo $this->formCheckbox('opt_in', 'yes', null, array('yes', 'no')) ?>
    </label></p>
</form>
        

ビュースクリプトの出力結果は、次のようになります。

<form action="action.php" method="post">
    <p><label>メールアドレス:
        <input type="text" name="email" value="you@example.com" size="32" />
    </label></p>
    <p><label>国:
        <select name="country">
            <option value="us" selected="selected">United States</option>
            <option value="il">Israel</option>
            <option value="de">Germany</option>
        </select>
    </label></p>
    <p><label>メールを受け取りますか?
        <input type="hidden" name="opt_in" value="no" />
        <input type="checkbox" name="opt_in" value="yes" checked="checked" />
    </label></p>
</form>
        

35.4.2. ヘルパーのパス

ビュースクリプトと同様、 Zend_View がヘルパークラスを探すパスをコントローラから積み重ねて指定することができます。 デフォルトでは、Zend_View は "Zend/View/Helper/*" からヘルパークラスを探します。 Zend_View に別の場所を探すように指定するには setHelperPath() および addHelperPath() メソッドを使用します。 さらに、クラスプレフィックスを指定することもできます。 これにより、ヘルパークラスに名前空間を設定できるようになります。 デフォルトでクラスプレフィックスを指定しなかった場合は、 'Zend_View_Helper_' であると見なされます。

<?php
$view = new Zend_View();

// パスを /path/to/more/helpers 、プレフィックスを 'My_View_Helper' とします
$view->setHelperPath('/path/to/more/helpers', 'My_View_Helper');
?>
        

addHelperPath() メソッドを使用すると、検索パスを「積み重ねる」 ことができます。これを使用すると、Zend_View は一番最後に追加されたパスからヘルパークラスを探し始めます。 これにより、付属しているヘルパーの内容を上書きしたり、 新しいヘルパーを追加したりすることができるようになります。

<?php
$view = new Zend_View();
// /path/to/some/helpers をクラスプレフィックス 'My_View_Helper' で追加します
$view->addHelperPath('/path/to/some/helpers', 'My_View_Helper);
// /other/path/to/helpers をクラスプレフィックス 'Your_View_Helper' で追加します
$view->addHelperPath('/other/path/to/helpers', 'Your_View_Helper');

// $this->helperName() をコールすると、Zend_View は
// まず最初に "/other/path/to/helpers/HelperName.php" で "My_View_Helper_HelperName" という名前のクラスを探し、
// 次に "/path/to/some/helpers/HelperName" で "Your_View_Helper_HelperName" という名前のクラスを探し、
// そして最後に "Zend/View/Helpers/HelperName.php" で "Zend_View_Helper_HelperName" という名前のクラスを探します。
?>
        

35.4.3. 独自のヘルパーを書く

独自のヘルパーを書くのは簡単です。以下の規則に従ってください。

  • クラス名は、少なくとも最後はヘルパーの名前と同じである必要があります。 CamelCaps 方式を使用します。たとえば "specialPurpose" という名前のヘルパーを作成した場合は、そのクラス名には 最低限 "SpecialPurpose" が含まれている必要があります。 このクラス名にプレフィックスを指定することができます。 プレフィックスの一部に 'View_Helper' を含めることを推奨します。たとえば "My_View_Helper_SpecialPurpose" のようになります (addHelperPath()setHelperPath() にはプレフィックスを指定する必要があります。 最後のアンダースコアは含めても含めなくてもかまいません)。

  • クラスは、ヘルパーと同じ名前の public メソッドを持っている必要があります。 テンプレートが "$this->specialPurpose()" をコールした際に、 このメソッドがコールされます。"specialPurpose" ヘルパーの例では、 "public function specialPurpose()" というメソッドが必要です。

  • 一般に、クラスでは echo や print その他の出力を行ってはいけません。 その代わりに、print あるいは echo される内容を返します。 返り値は、適切にエスケープしなければなりません。

  • クラスは、ヘルパークラスと同じ名前のファイルに作成しなければなりません。 再び "specialPurpose" ヘルパーを例にとると、ファイル名は "SpecialPurpose.php" でなければなりません。

指定したヘルパーパスのどこかにヘルパークラスのファイルを配置すると、 Zend_View は自動的にそれを読み込んでインスタンスを作成し、 必要に応じて実行します。

SpecialPurpose ヘルパーのコードの例を示します。

<?php
class My_View_Helper_SpecialPurpose 
{
    protected $_count = 0;
    public function specialPurpose()
    {
        $this->_count++;
        $output = "'The Jerk' を {$this->_count} 回見ました。";
        return htmlspecialchars($output);
    }
}
?>
        

そして、ビュースクリプト内で SpecialPurpose ヘルパーを必要なだけコールします。いちどインスタンスが作成された後は、 Zend_View インスタンスの中でそれが持続します。

<?php
// ビュースクリプト内では、$this は Zend_View インスタンスを指すことを覚えておきましょう。
echo $this->specialPurpose();
echo $this->specialPurpose();
echo $this->specialPurpose();
?>
        

出力結果は、次のようになります。

'The Jerk' を 1 回見ました。
'The Jerk' を 2 回見ました。
'The Jerk' を 3 回見ました。
        

時には Zend_View オブジェクトを使用したくなることもあるでしょう。 たとえば登録されているエンコーディングを使用する必要があったり、 ヘルパー内で別のビュースクリプトをレンダリングしたくなったりといった場合です。 ビューオブジェクトにアクセスするには、ヘルパークラス内で次のような setView($view) メソッドを定義しなければなりません。

<?php
class My_View_Helper_ScriptPath
{
    public $view;

    public function setView(Zend_View_Interface $view)
    {
        $this->view = $view;
    }

    public function scriptPath($script)
    {
        return $this->view->getScriptPath($script);
    }
}
?>

ヘルパークラスで setView() メソッドを定義しておくと、 最初にインスタンスが作成される際に自動的にこのメソッドがコールされ、 現在のビューオブジェクトが引数として渡されます。 渡されたオブジェクトをクラス内でどのように管理するかは特に決まっていません。 お好みの方法で管理してください。