ZendFramework2(ZF2)でSmarty3を使う方法!!


ZendFramework2(ZF2)ではview機構がかなり強化され、
いわゆるphtmlファイルでも出来る幅が広がりました。

しかし、いつも使い慣れているSmartyを使いたいという需要は高い様です。

今回は、そんなZendFramework2(ZF2)でもSmartyを使いたいという方向けに
ZendFramework2(ZF2)用ののSmartyモジュールを使用した
Smartyの導入方法について解説致します。

  1. Smarty3最新版を準備しよう
  2. ZendFramework2(ZF2)専用のSmartyモジュールを入手しよう
  3. ZendFramework2(ZF2)にZendSmarty(ZSmarty)を導入する
  4. モジュールの追加をアプリに設定しよう
  5. コントローラ内でのSmarty3の使用方法


Smarty3最新版を準備しよう




まずはSmarty本体の準備です


下記URLよりSmartyの最新版をダウンロードして下さい。
ブログ執筆時ではSmarty 3.1.13が最新でしたので
Smarty 3.1.13を基本に解説して行きます


Smartyをダウンロードする
http://www.smarty.net/download



ダウンロードしましたら、お好きな場所に配置してください。
後程、配置したSmartyまでのパスを設定します。




ZendFramework2(ZF2)専用のSmartyモジュールを入手しよう






ZendFramework2(ZF2)からSmarty3を使用する為に、
今回はZendSmartyモジュールを使用します。
モジュールは下記のGitより入手して下さい


ZendSmarty(ZSmarty)
https://github.com/ryanknu/ZendSmarty



ダウンロードしますと、中身の構成は下記の様になっています。

ZSmarty
-Module.php
-SmartyModel.php
-SmartyRenderer.php
-SmartyStrategy.php
-StrategyFactory.php





ZendFramework2(ZF2)にZendSmarty(ZSmarty)を導入する





導入するプロジェクトは、先日ご紹介したスケルトンプロジェクトを使用したいと思います
スケルトンプロジェクトについては下記をご参照下さい。




ZendFramework2のスケルトンプロジェクト『ZendSkeletonApplication』のディレクトリ構造とファイル構成



それでは、早速ダウンロードしましたSmartyモジュールを配置します

配置する場所は、
プロジェクトディレクトリ/vendor/ZSmartyです。


配置したプロジェクトディレクトリからの位置関係は下記の様になります



プロジェクトディレクトリ
│  
├─config
├─data
├─module
├─public
└─vendor
    │  README.md
    │  
    ├─ZF2
    └─ZSmarty(ここに配置する)
            Module.php
            SmartyModel.php
            SmartyRenderer.php
            SmartyStrategy.php
            StrategyFactory.php




そして、Smartyのコンパイルファイルを格納する為のキャッシュフォルダを作成します
作成する場所はプロジェクトフォルダ内で、『templates_c』という名前で作成します

作成後のディレクトリ構造は下記の様になります。

プロジェクトディレクトリ
│  
├─config
├─data
├─module
├─public
├─templates_c(ここに配置します)
└─vendor
    │  README.md
    │  
    ├─ZF2
    └─ZSmarty
            Module.php
            SmartyModel.php
            SmartyRenderer.php
            SmartyStrategy.php
            StrategyFactory.php





ZSmartyがSmartyを使用する為に、先程ダウンロードして適当な場所に配置した
Smarty3までのパスを設定します。

修正するファイルはZSmarty内のModule.phpです。

ファイル内の

$o_file = __DIR__ . '/libs/Smarty.class.php';

と書かれている個所がパスを設定している所です。
デフォルトでは上記の位置を想定していますが、
別の場所に配置したい方はパスを設定しなおしてください。

もしくは、include_pathにパスを設定しても

$file = stream_resolve_include_path('Smarty.class.php');

で解決してくれますので、
お好きな指定方法を選択して下さい。

最終的に読み込みたいファイルはSmarty.class.phpです。

class Moduleの__constructがSmarty.class.phpを返却出来れば
良いので、皆さんの環境によって読み込み方法は検討して見てください。

筆者は、ライブラリ関係は他のプロジェクトでも使用出来る様に
ある場所に纏めてありますので、

$o_file = dirname(__FILE__) . '/../../../library/Smarty-3.1.13/libs/Smarty.class.php';

の様な形でライブラリまでのパスを設定しました






モジュールの追加をアプリに設定しよう





そして、ZSmartyモジュールの追加をプロジェクトに知らせる為に、
config/application.config.php内のmoduleにZSmartyを追加します



    // This should be an array of module namespaces used in the application.
    'modules' => array(
        'Application',
        'ZSmarty'
    ),




次に、ZSmartyを使用するモジュールに生成情報を設定する為に
module\Application\config\module.config.php内のservice_managerにあるfactoriesに

'Smarty' => 'ZSmarty\StrategyFactory'

を追加します



追加後のソースは下記の様な形です


    'service_manager' => array(
        'factories' => array(
            'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
            'Smarty' => 'ZSmarty\StrategyFactory',
        ),
    ),


続いて、同じファイル内のview_managerに

'strategies' => array('Smarty'),

を追加します。



追加後のソースはは下記の様な形です



    'view_manager' => array(
        'strategies' => array('Smarty'),
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => array(
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'Application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ),
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
    ),





コントローラ内でのSmarty3の使用方法





後は、いよいよsmartyの使用方法です。

Smartyテンプレートを出力したいコントローラでは
冒頭でuseにてSmartyModelを読み込みます

use ZSmarty\SmartyModel;


アクション内ではViewModelと同じ様にインスタンスを作成し、
返却する事でviewとして扱われます。

その間に、使用するテンプレートを指定したり、
テンプレートへ受け渡す値のセットを行ないます。

サンプルのアクションは下記の様になります

    public function indexAction()
    {
        //  smartyモジュールのインスタンスを作成
        $sm = new SmartyModel; 

        //  使用するテンプレートファイルを指定する
        $sm->setTemplate('/user/index/index.tpl'); 

        //  テンプレートへ受け渡したい値を設定する
        $sm->hero = "hero"; 

        //  viewとしてsmartyモジュールを返却する
        return( $sm ); 
    }


後はphtmlのビューと同じルールにてtplファイルを配置すれば
tplファイル内でSmarty構文が使える様になります。


コントローラではuseを忘れない様に気をつけて下さいね。




これでZendFramework2(ZF2)でSmarty3を使える様になります


37 Responses to ZendFramework2(ZF2)でSmarty3を使う方法!!

  1. はじめまして。
    こちらのサイトを元にZF2でSmarty3を使えるよう設定しているのですが
    Missing template nameでこけてしまします。
    他に見落としやすいところの設定ができていないのでしょうか?

    返信削除
    返信
    1. はじめまして。こんにちは。
      この度は当ブログをお読み頂きまして、誠に有難う御座います。

      >Missing template nameでこけてしまいます。

      私なりの見解を述べますと、
      『Missing template name』というのは、ファイルパスを含めたファイル名が違うよ!
      と言っているようですので、
      smartyモジュールがviewファイルを見つけるのにあたって、
      何かしらの指定が間違っているのかと推測します。

      実ファイルがphtmlからtplへ変更されているか?ファイルまでのパスは正しいか?
      等を確認してみて下さい。

      尚、module.config内の『template_path_stack』の値には
      viewディレクトリまでのパスを指定しますが、
      ここの値が間違っていると、
      『Missing template name』というエラーが出る事を確認しています。
      ディレクトリ構成を変更して使用されている場合は、
      該当モジュールのviewディレクトリ迄のパスが合っているか?
      も合わせてご確認頂ければ、何か解決の糸口が見つかるかも知れません。

      解決しない場合は、何なりとお問合せ頂ければ幸いです。
      今後とも宜しくお願い致します。

      削除
    2. 返信ありがとうございます。
      仰る通り、template_path_stackの値がviewディレクトリまで指していませんでした。
      また、上記サンプル通りにテンプレート側に値を渡した時に
      テンプレート側ではどのような記述をすればよろしいでしょうか?

      削除
    3. この度はご返信、誠に有難う御座います。

      >上記サンプル通りにテンプレート側に値を渡した時に
      >テンプレート側ではどのような記述をすればよろしいでしょうか?


      例えば、今回の記事では

      $sm->hero = "hero";

      の様に値をセットしていますが、
      tplで上記の値を取得する時は

      {$hero}

      と記述すれば文字列の『hero』が取得できます。
      tpl内では、smarty3の構文ルールに従って記述して下さい。

      例えば、通常のPHPからのsmartyテンプレートへの値の受け渡しは、

      $smarty->assign( 'key', 'value' );

      の様に行うかと思いますが、同じ事を今回の『ZF2+Smarty3』で行おうとすると

      $smarty->key = "value";

      の様な記述となり、共にテンプレートファイルでは

      {$key}

      と書く事で『value』が取得出来ます。

      削除
    4. ご返信ありがとうございます。
      おかげさまで連携がうまくいきました。

      また、別記事でのことですがレイアウトをコントローラから動的に変更する際も
      template_path_stackのパス指定がうまくいかないと下記のようなエラーが発生してしまうのでしょうか?

      PHP Fatal error: Uncaught exception 'Zend\\View\\Exception\\RuntimeException' with message 'Zend\\View\\Renderer\\PhpRenderer::render: Unable to render template "layout/test"; resolver could not resolve to a file'

      度々、申し訳ございませんがご教授いただければと存じます。

      削除
    5. この度はご連絡、誠に有難う御座います。

      template_path_stackの指定が上手く行っていないと、
      そもそもview自体を読み込めませんので、
      ご投稿頂きましたエラーメッセージを拝見致しました所、
      該当ファイルが存在しないのかな?と予想します。

      レイアウトファイルは拡張子抜きにて指定しますので
      少し分かり難いですが、smartyと連携させた場合は
      レイアウトファイルもsmarty用のtplファイルである必要があります。

      ご指定の『layout/test』でしたら、
      期待する実ファイルは『layout/test.tpl』です。

      その辺りを今一度ご確認頂ければ幸いです。

      削除
    6. ご返信ありがとうございます。
      レイアウトファイルを.tplではなく.phtmlで作成していました。
      色々とご教授いただきありがとうございます。
      また、何かありましたらお手数おかけ致しますが
      ご教授いただければと存じます。

      削除
    7. 黒沢大介様

      無事に導入できた様で何よりです。
      また何か御座いましたら、お気軽にご連絡下さい。
      今後とも当ブログを宜しくお願い致します。

      削除
    8. 濱田様

      smartyについて質問があります。
      ZendFramework2でhttp://ameblo.jp/toxicsweet/entry-11283998788.html
      のURLのように、使用するテンプレートファイルをコントローラー内で記述しない方法は有りますでしょうか?

      削除
    9. 黒沢大介様

      この度はご連絡、誠に有難う御座います。

      >使用するテンプレートファイルをコントローラー内で記述しない方法は有りますでしょうか?

      テンプレート名を記述しない場合は、既存の処理と同じようにアクション名のビューファイルが適用されます。

      例えば、testAction内でテンプレートを指定しない場合に適用される(読み込もうとする)テンプレートファイルはtest.tplとなります。

      逆に、テンプレートの出力を行わない様にする為には、

      setTerminal()でtrueを指定する事でレイアウトファイルを無効化し、
      $this->getResponse()を返却して下さい。


      例:
      public function testAction()
      {
      // レイアウトを無効化して、テンプレートの出力を行わない
      $sm = new SmartyModel();
      $sm->setTerminal( true );
      return( $this->getResponse() );
      }

      削除
    10. ご返信ありがとう御座います。
      ご教授の通り、テンプレートを指定しない場合はアクション名のviewが
      適用されました。
      ですが、view側でsmartyの記述が無効になり、文字として表示されるように
      なってしまいました。

      また、ZendFramework1では設定することで
      $sm->hero = "hero";でreturnせずにviewへ値を渡すことが
      出来ましたがZendFramework2でも同じようなことは可能でしょうか?

      お忙しい中、大変恐縮ですがご教授いただければと
      存じます。

      削除
    11. 今回のケースでは、Smartyをモジュールとして扱い、
      通常のViewModelを継承してSmarty用に拡張した物を独自に使用するといった処理内容です。

      従って、通常のレンダリング処理(Smartyモジュールを介さない)は、
      ZendFramework2が通常のViewModelを使用しますので、
      Smarty構文が無効になったかと思われます。

      ZendFramework2側が出力しようとしているデフォルトのビューを
      SmartyModelをreturnする事によって、上書きするイメージでしょうか。
      returnを行わないと、SmartyModelをZendFramework2へ渡す手段が無いので、
      使用されずに破棄されてしまいます。

      直接、ZendFramework2でViewModelをnewしている箇所を触れば可能かも知れませんが、
      お勧め出来ません。

      今回の記事で紹介したsmartyモジュールでは、上記の様な処理内容となる為、
      テンプレートの指定とreturnが必須になるかと思われます。

      削除
    12. ご返信ありがとう御座います。
      smartyモジュールをreturnする形で使用していきたいと思います。
      とてもわかり易い説明までしていただき、ありがとう御座いました。

      また、何かありましたらお手数おかけ致しますが
      ご教授いただければと存じます。

      削除
  2. はじめまして。

    こちらの記事を参考にZF2とSmarty3の連携を試してみているのですが、
    以下のエラーが発生してしまいます。

    Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\InvalidServiceNameException' with
    message 'An alias by the name "translator" or "translator" already exists'


    当方の使用しているZF2のバージョンは2.2.0で、
    module\Application\config\module.config.php内のservice_managerの記述がこちらの記事とは違っていたため、
    factoriesの設定を単純に追加してみたのですが、この設定ではダメなのでしょうか?


    'service_manager' => array(
    'abstract_factories' => array(
    'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
    'Zend\Log\LoggerAbstractServiceFactory',
    ),
    'aliases' => array(
    'translator' => 'MvcTranslator',
    ),
    'factories' => array(
    'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
    'Smarty' => 'ZSmarty\StrategyFactory',
    ),
    ),


    お忙しい中、大変恐縮なのですが、ご教授いただけたら助かります。

    返信削除
    返信
    1. 永田様

      はじめまして。この度はコメント頂き誠に有難う御座います。
      ご質問頂きました内容に付きまして、
      最新のスケルトンプロジェクトはまだ触っていませんので、
      想像の域を出ませんが私なりの見解を述べさせて頂きます。

      エラーメッセージの内容を拝見致しますと『translator』が既に定義されていると言っている様に見えます。
      ソースを拝見した所、エイリアスでの設定名として『translator』が使用されているのに、
      項目名でも『translator』が使用されている事が原因かと考えられます。

      『MvcTranslator』とは何を指すのか分かりませんが、名前からして翻訳関係なのは間違いないでしょう。
      エイリアスは別名として定義するものですので、きっと『Zend\I18n\Translator\TranslatorServiceFactory』と実態は同じかと想像します。

      対応策としては、どちらかの『translator』を消してみては如何でしょうか?
      特に『MvcTranslator』内にて、ファクトリーを構築しているかも知れませんので、『Zend\I18n\Translator\TranslatorServiceFactory』の方が必要無い気がします。

      そのあたりを一度お試し頂けれ幸いです。
      今後とも宜しくお願い致します。

      削除
  3. 返信ありがとうございます。
    教えて頂いたように"Zend\I18n\Translator\TranslatorServiceFactory"の記述を削除することで
    エラーが起こらずに動作するようになりました。ありがとうございます。

    濱田様の見解をもとにMvcTranslatorというキーワードでZF2のソースコードを検索したところ、
    Zend\ModuleManager\Listener\ServiceListener.php内にて
    'MvcTranslator' => 'Zend\Mvc\Service\TranslatorServiceFactory'の記述があり、
    Zend\Mvc\Service\TranslatorServiceFactoryは
    Zend\I18n\Translator\TranslatorServiceFactoryを継承していましたので、
    確かに実態は同等のものを指すようでした。

    ところでこの方法でビューにSmartyを使う場合、
    phtmlの時にview内で使えていた$this->translate('XXX')などは使えなくなってしまうのでしょうか?
    {$this->translate('XXX')}とするとエラーとなってしまいます。

    お手数をおかけしますが、ご存知でしたらご教授頂けないでしょうか。

    返信削除
    返信
    1. 永田様

      お世話になっております。

      >phtmlの時にview内で使えていた$this->translate('XXX')などは
      >使えなくなってしまうのでしょうか?
      >{$this->translate('XXX')}とするとエラーとなってしまいます。

      こちらのエラー内容を教えて頂けませんでしょうか?もしかすると『$this->translate('XXX')』の『$this』がSmartyオブジェクト自体を指しているかもしれません。

      例えばSmartyへ値を渡す際に『$sm->mvc = $this;』等として、Smarty側では『$mvc->translate('XXX')』の様に使用する事は出来ますでしょうか?

      そのあたりを一度お試し頂けれ幸いです。
      今後とも宜しくお願い致します。

      削除
    2. 返信ありがとうございます。

      エラーは以下の3つが出力されていました。
      Notice: Undefined index: this
      Notice: Trying to get property of non-object
      Fatal error: Call to a member function translate() on a non-object

      コントローラ内で『$sm->mvc = $this;』、テンプレート内で『{$mvc->translate('XXX')}』としてみましたが、
      Zend\Mvc\Controller\PluginManager::get was unable to fetch or create an instance for translate
      というエラーが出て上手く使用できませんでした。

      濱田様の助言を手がかりにphtmlでの$thisが何を指すのか調べたところ、
      Zend\View\Renderer\PhpRendererを指しているようでしたので、
      このクラスを継承しているZSmarty\SmartyRendererのrenderメソッド内で
      『$this->assign('mvc', $this);』という記述を追加することで正常に表示されるようになりました。
      ライブラリのコードを直接修正するので微妙な感じもしますが、、、

      今回は唐突な質問にもかかわらず、丁寧なご対応ありがとうございました。

      削除
    3. 永田 様

      お世話になります。
      この度はご連絡、誠に有難う御座います。

      上手く機転を効かせて頂き、更に対処法のご提示、
      誠に有難う御座います。
      上手く動作した様で何よりです。

      Smartyの導入方法にも様々な方法がある様ですし、
      今回採用しているSmartyモジュールも結局の所Viewの拡張ですので、
      更に使いやすい様に拡張する分には問題無いかと思います。

      まだまだ新しいフレームワークなので、
      こういったTips的な情報がもっと増えれば良いですね。

      今後とも、どうぞ当ブログを宜しくお願い致します。

      削除
  4. はじめまして。
    こちらの記事を参考にZF2でSmarty3を使えるよう設定しておりますが、
    IndexControllerをからindex.tplがうまく表示されず行き詰ってしまいました。
    templates_cフォルダには確かにコンパイル済みのファイルが存在していますが、
    ブラウザにはPHPのコードが表示されてしまいます。
    何処か設定が足りないのでしょうか。
    お忙しい中大変恐縮ですが、ご教授ただけましたら幸いです。

    返信削除
  5. 追記です。
    PHPのコードが表示される現象は解決いたしました。
    失礼いたしました。
    しかしながら未だindex.tplが読み込めず、layout.tplのみが表示されている状態です。
    両ファイルともSmarty3にてコンパイルされていることは確認しておりますので、
    どこにミスがあるのか見当もつかない状況です。
    何度もすみませんが、ご教授いただけませんでしょうか?

    返信削除
    返信
    1. 日高様

      お世話になります。
      この度はコメント頂き、誠に有難う御座います。


      コンパイルも出来ていて特にエラーも出力されていない様ですので、layout.tplからindex.tplの読み込みが上手く行っていない様に思えます。(アクションの判別、ビューの生成は問題無く動作している)

      layout.tpl内で、アクション毎のビューを読み込む部分はどの様に記述されていますでしょうか?

      期待値としては、『{$content}』と設定されている事です。

      お手数お掛けいたしますが、もう一度ご確認頂ければ幸いです。
      何卒、宜しくお願いいたします。

      削除
    2. 返信いただきましてありがとうございます。
      {$content}をlayout.tplに記述したところすんなりとindex.tplの内容が表示されました。
      適切なご回答ありがとうござました。
      しかしながらなぜ{$content}なのかなどまだまだ理解不足な点がありますので、
      今後もこちらのサイトを参考にさせていただきます。

      削除
    3. 日高様

      お世話になります。
      この度はコメント頂き、誠に有難う御座います。

      問題なく表示出来た様でなによりです。
      また何か御座いましたらお気軽にコメント下さい。
      今後とも宜しくお願い致します。

      削除
    4. なんども恐れ入ります。
      ZSmartyを使用して{$content}以外に{$header}や{$footer}などいくつかのTPLを読み込んでlayout内に表示させることは可能なのでしょうか。
      ご教授いただけると幸いです。
      よろしくお願いいたします。

      削除
    5. 日高様

      お世話になります。
      この度はコメント頂き、誠に有難う御座います。

      単純に別のテンプレートを読み込むだけであれば、smartyの構文を使用しては如何でしょうか?
      『include』構文を使用すると、外部のtplファイルを読み込んで表示する事が出来ます。
      詳しくは下記URLの公式サイトを参照下さい。

      http://www.smarty.net/docsv2/ja/language.function.include.tpl

      他にも、何かご不明点が御座いましたら
      お気軽にコメント下さい。
      今後とも宜しくお願い致します。

      削除
    6. ご返答ありがとうございます。
      SmartyではPHP内に$smarty->assign('header','/***/header.tpl');
      などと記述し、TPL内にて
      {include file=$smarty}等を記述することで表示できますが、
      ZSmartyを使用する場合はエラーが表示され、うまくいきませんでした。
      記述がわるいのかもしれませんが原因がつかめません。
      ご教授いただけませんでしょうか。

      削除
    7. 日高様

      お世話になります。
      この度はコメント頂き、誠に有難うございます。
      ちなみに、どの様なエラーが出ますでしょうか?
      また、{include file=$smarty}と記述する場所はビューでしょうか?
      レイアウトでしょうか?

      >ZSmartyを使用して{$content}以外に{$header}や{$footer}など
      >いくつかのTPLを読み込んで

      上記コメントから推測する限り、
      レイアウトファイルへ変数の受け渡しに失敗していると考えられます。
      アクションからレイアウトへ変数を渡すには、
      レイアウトのオブジェクトに対して変数を設定する方法と、
      レイアウトからビューの変数を参照しに行く方法があります。

      ◎アクションからレイアウトへ変数の値を渡す
      方法としては三種類あります。
      レイアウトオブジェクトが持つ『setVariable()』メソッドにて変数を設定する方法と、
      レイアウトオブジェクトのプロパティへ直接設定する方法。
      レイアウトオブジェクトが持つ『setVariables()』メソッドにて配列で纏めて設定する方法があります。

      // setVariableメソッドで変数を設定
      $this->layout()->setVariable('var', 'value');
      // プロパティに直接設定する
      $this->layout()->var = 'value';

      // 配列で纏めて指定する
      $this->layout()->setVariables(array(
      'var' => 'val',
      ));

      ◎レイアウトからアクションで設定された変数を参照する
      レイアウトファイルはアクションで作成されたオブジェクトとは異なるので、
      値を取得するには少し手間がかかります。
      『getChildren()[0]』で一番初めの子を取得し、『getVariable()』メソッドで
      指定の変数の値を取得します。

      // レイアウトファイルからアクションの値を取得する
      $this->layout()->getChildren()[0]->getVariable('var');


      いずれかの方法をお試し頂ければ幸いです。
      何卒よろしくお願いいたします。

      削除
  6. 濱田様
    はじめまして。
    いつも当サイトを参考にさせていただいております。
    ありがとうございます。

    さて、当ページのSmartyとZF2との連携についてなのですが、
    従来のSmartyで可能だったfetch関数にてレンダー後のHTMLを取得するといった方法は、
    今回の拡張モジュールでも使用可能なのでしょうか。

    もしご存知であればご教授いただきたく存じます。
    何卒よろしくお願い申し上げます。

    返信削除
    返信
    1. 遠藤様

      お世話になります。
      この度はご返信頂き、誠に有難う御座います。

      Smartyのfetch関数の使用についてですが、使用自体は可能です。
      現に、拡張モジュール内でも勿論使用しています。

      ただ、レイアウトや選択されたアクションに対するビューを構築するのは、
      アクションでの処理を終えた後の話ですので、
      もしもアクション内で『fetch()』を使用する場合は
      それなりのカスタマイズが必要ではないかな?と感じます。

      他にも、何かご不明な点が御座いましたら
      お気軽にコメント下さい。
      今後ともよろしくお願いいたします。

      削除
    2. 濱田様

      ご返信ありがとうございます。

      当方、アクション内でfetch関数を使用し、
      レンダー後の文字列取得を目的としております。

      カスタマイズの具体的な方法またはヒントなどおわかりであれば、
      ご教授いただけないでしょうか。

      何卒よろしくお願いもうしあげます。

      削除
    3. 遠藤様

      お世話になります。
      この度はご返信頂き、誠に有難う御座います。

      感覚的には、カスタマイズするにはMVCイベントをハックして最終的なレンダリングまで
      シミュレートさせる必要がるのかな?といった予想です。
      ちなみにアクション内でレンダリング後の文字列を取得する意図は何でしょうか?
      かなり異例な処理となるので、目的によっては別の方法があるのでは?と考えます。

      他にも、何かご不明な点が御座いましたら
      お気軽にコメント下さい。
      今後ともよろしくお願いいたします。

      削除
  7. 濱田優様

    はじめまして、濱田様の「Zend Framework 2 徹底解説」を買いました。
    とてもわかりやすく、ここ数週間、毎日この本で勉強しております。
    ありがとうございます。

    質問なのですが
    新規会員登録画面表示時に、Smarty3を適用させて書く書き方がわからなくて、ここ数日悩んでおります。
    例えば、
    UserForm.phpを書き⇒UserController.phpにaddAction()を書き⇒add.phtmlで新規登録画面を表示する、という処理があるのですが

    add.phtmlで
    $form = $this->form;
    $form->setAttribute('action', $this->url(・・・
    echo $this->form()->openTag($form);
    echo $this->formHidden($form->get('id'));。。。。のようになっている部分が
    smartyでadd.tplになると、どう書くのか、わからず困っております。

    また、UserController.phpのaddAction()でsmarty3のやり方で
    UserFormをセットする方法も悩んでおります
    (↓今userController.phpのaddAction()はこのように書いています)

    public function addAction()
    {
     $form = new UserForm();
     $values = array(
      'form' => $form,
     );
     $sm = new SmartyModel;
     $sm->setTemplate('\application\user\add.tpl');
    $sm->values = $values;
    return ($sm);
    }

    上記サンプルのように
    $sm->hero = "hero";
    という記述を
    {$hero }で表示する。というところはできております。
    お忙しいところすみません、何かヒント等ございましたらよろしくお願いします。

    返信削除
    返信
    1. お世話になっております。
      この度は「Zend Framework 2 徹底解説」をご購入頂き、
      誠に有難う御座います。

      ご質問の件について解答させて頂きます。

      当ブログにコメント頂きました永田様からのご報告で、
      ZSmarty\SmartyRendererのrenderメソッド内へ
      『$this->assign('mvc', $this);』と追記する事で、
      『phtml』時の『$this』を『tpl』時に『$mvc』と扱える事を確認しています。

      また、

      $view = new SmartyModel();
      $form = new UserForm('add');
      $values = array(
      'form' => $form,
      );
      $view->values = $values;
      $view->setTemplate('application/index/smarty.tpl');
      return $view;

      の様に、$valueへ連想配列を作成し、$view->valuesに入れますと、
      『tpl』上では$valuesに対して
      連想配列でアクセスする事が出来ます。

      『$values['form']』

      これらをふまえまして、『phtml』時の『echo $this->form()->openTag($form);』は、
      『tpl』では『{$mvc->form()->openTag( $values['form'] )}』の様に、

      『echo $this->formHidden($form->get('id'));』は
      『{$mvc->formHidden($values['form']->get('id'))}』の様に書く事が出来ます。

      また、『phtml』内の

      $form->setAttribute('action', $this->url(
      'application',
      array(
      'controller' => 'user',
      'action' => 'add',
      )
      ));

      を『tpl』内で再現させる為には、一工夫必要です。
      必要となる値を3ステップにわけ、assign構文にてtpl内で変数へセットして行きます。

      {assign var="ary" value=['controller'=>'user', 'action'=>'add']}
      {assign var="url" value=$mvc->url("application",$ary)}
      {assign var=$values['form'] value=$values['form']->setAttribute('action', $url)}

      3ステップに分けて記述していますが、1ステップ目では

      array(
      'controller' => 'user',
      'action' => 'add',
      )

      を{assign var="ary" value=['controller'=>'user', 'action'=>'add']}
      として変数『$ary』に格納しています。

      2ステップ目では、

      $this->url(
      'application',
      パラメータの配列
      )

      を、先程作成しました『$ary』を利用して
      {assign var="url" value=$mvc->url("application",$ary)}
      としています。

      最後に

      $form->setAttribute('action', URL文字列);

      を、これまで作成してきた変数を利用して

      {assign var=$values['form'] value=$values['form']->setAttribute('action', $url)}

      の様に作成しています。


      以上の方法で、ご質問にありました部分は『tpl』上でも再現できるかと思います。

      この辺りはSmartyの仕様ですので、
      詳しくはSmarty公式のドキュメントを参考にして頂ければ幸いです。

      他にも、何かご不明な点が御座いましたら
      お気軽にご連絡下さい。
      今後とも宜しくお願い致します。

      削除
    2. 濱田優様

      お忙しい中、ご返信ありがとうございます。
      濱田様のご解説のおかげで、smarty3でも、フォーム画面の作成ができるようになりました。
      本当に感謝しております。

      ご教授いただいた、こちらのコメントもそうですが
      「Zend Framework 2 徹底解説」も説明がとてもわかりやすい内容で
      こんな本が欲しかったと感動しました。こんなに大事に何度も読み返した技術書はありません。
      心より御礼申し上げます。

      削除
    3. 細田友香 様

      お世話になります。
      この度はとても嬉しいコメント、誠に有難うございます。
      とてもモチベーションが上がり、今後の励みになります!

      そして問題も解消された様で、何よりです。
      他にも何かご不明な点が御座いましたら
      お気軽にコメント下さい。

      今後ともよろしくお願いいたします。

      削除
  8. 濱田様

    初めまして。
    最近Zend2に触れるようになり、書籍・当サイト共に参考にさせていただいております。

    早速質問なのですが・・・
    #内容の重複がありましたらすいません。。


    ZSmartyを使用した場合の、smartyの設定パラメータ(default_modifiersや開始・終了タグ)の変更方法について
    ご教示願えますでしょうか?


    保守的な観点から、極力ZSmartyのソースコードには直接手を加えたくありません。
    また、できればZSmartyのコードを継承、という方法も取らずに済めば幸いです。

    Controller側からsmartyインスタンスを取り出せる方法があれば一番助かります。
    #SmartyRenderer->getEngine()を呼び出す事できれば・・・


    お手数ですが、よろしくお願いします。

    返信削除

人気の投稿

Category

Algorithm (2) Android (8) ASP/aspx (1) Blogger (2) C/C++ (1) Chrome (5) CSS (9) Firefox (4) Fortran (1) Google (9) GoogleMap (2) HTML (12) IE (3) Information (4) iOS (2) iPhone/iPad/iPod (2) Java (6) JavaScript (16) jQuery (9) JSP (1) LifeRecipe (5) Linux (2) Macintosh (2) MapKit (4) Marketing (7) MySQL (3) NAMAZU (2) Objective-C (7) Other (7) Perl (1) PHP (9) Python (1) RSS/Atom (2) Ruby (1) Safari (2) SEO (11) Smarty (2) SQL (2) Tex (1) Three.js (1) Twitter (1) TwitterLog (313) UIKit (5) Unix (1) VBA/VBS (1) Windows (5) WordPress (3) Writing (5) XAMPP (1) XML (1) Yahoo (2) ZendFramework2 (14)

Archives