FuelPHPのThemeを使ってスマホとPCでテンプレートを切り替える~Smarty編~
自分が運営しているサイトをスマートフォン対応しようと思って戦った時のメモ。
環境
- さくらのレンタルサーバスタンダード
- PHP5.4.11
- FuelPHP 1.5
- Smarty3
なぜ戦うことになったのか
Themeを使ってスマホとPCでテンプレートを切り替える方法についてはこのブログを参考にした。
Smartyを使うにあたってcoreのコード(fuel/core/classes/theme.php)を読むと、まずTheme#set_templateは
public function set_template($template) { // make sure the template is a View if (is_string($template)) { $this->template = $this->view($template); } else { $this->template = $template; } // return the template view for chaining return $this->template; }
引数($template)が文字列でなければそのままセットする、という実装になっているのでView_Smartyのオブジェクトをそのまま投げてしまえば使える。
問題はTheme#viewで、
public function view($view, $data = array(), $auto_filter = null) { if ($this->active['path'] === null) { throw new \ThemeException('You must set an active theme.'); } return \View::forge($this->find_file($view), $data, $auto_filter); }
activeなテーマのpathを探してViewのオブジェクトを作って返す、という実装になっている。
Controllerで$this->theme->view('hoge/foo')としたときに返して欲しいのはView_Smartyのオブジェクトなのでこのままでは使えない(と思う)。
というわけで、Themeを継承したサブクラスを作ってTheme#viewをオーバーライドしてしまうことにした。
Themeクラスを継承して適当にSmartyThemeとかいうクラスを作る。
class SmartyTheme extends \Fuel\Core\Theme { public function view($view, $data = array(), $auto_filter = NULL) { if ($this->active['path'] === null) { throw new \ThemeException('You must set an active theme.'); } return View_Smarty::forge($this->find_file($view)); } }
ControllerではThemeの代わりに作ったSmartyThemeを使うようにする。
$this->theme = SmartyTheme::instance( 'custom', array( 'active' => 'pc', 'fallback' => 'pc', 'paths'=> array(APPPATH.'views'), 'view_ext' => '.tpl' ) );
これでControllerで$this->theme->view('hoge/foo')としたときはアクティブなテーマのパスを検索しView_Smartyオブジェクトを返すようになる。