Issei.M's Techlog

Web/iOS エンジニアの僕が技術関連のメモ等をつらつらと。主に Symfony について書いています。

[Symfony] LiipThemeBundle でスマホ対応&Assetic を使う際の諸注意

Symfonyスマートフォン対応するにあたって LiipThemeBundle がよさげだったのでご紹介。また当バンドルを使用する際 Assetic でハマる箇所がある為メモ。

Symfony Standard Edition 2.2.1 の AcmeDemoBundle で試してみます。

LiipThemeBundle をインストール

Composer でインストール。

$ php composer.phar require liip/theme-bundle:dev-master

Bundle を登録。

# app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Liip\ThemeBundle\LiipThemeBundle(),
    );
}

config.yml に追記。themesには使用するテーマを定義します。今回は PC とスマホのみなのでweb,phoneを定義します。 path_patternsについては後述。

# app/config/config.yml
liip_theme:
    themes:           ['web', 'phone']
    active_theme:     'web'
    autodetect_theme: true
    path_patterns:
        app_resource:
            - %%app_path%%/views/themes/%%current_theme%%/%%template%%
        bundle_resource:
            - %%bundle_path%%/Resources/views/themes/%%current_theme%%/%%template%%
    cookie:
        name: site_theme
        lifetime: 31536000 # 1 year in seconds
        path: /
        domain: ~
        secure: false
        http_only: false

続いてテーマ切り替えページ用に routing.yml に追記。

# app/config/routing.yml
liip_theme:
    resource: "@LiipThemeBundle/Resources/config/routing.xml"
    prefix:   /theme

スマホ用テンプレートの追加

準備が整ったので早速スマホ用のテンプレートを作成していきます。 src/Acme/DemoBundle/Resources/views 以下に themes/phone/Welcome とディレクトリを作っていき、その中に次のファイルを作成します。

{# src/Acme/DemoBundle/Resources/views/themes/phone/Welcome/index.html.twig #}

{% extends 'AcmeDemoBundle::layout.html.twig' %}
{% block title %}Symfony - Welcome Smartphone!{% endblock %}
{% block content_header '' %}
{% block content %}
    <h1 class="title">スマホレイアウト!!</h1>
    スマホだよ~ん
{% endblock %}

それでは Web ブラウザで確認してみましょう。まず /theme/phone にアクセスします。トップにリダイレクトされたのち、先ほど追加したテンプレートが適用されているのが確認できます。

f:id:issei_m:20130514204557p:plain

※今回autodetect_themeを有効にしているのでスマホで直接アクセスしてもOKです。また、/theme/web にアクセスすると PC 用レイアウトに戻す事ができます。

次にベースレイアウトをスマホに最適化する為、以下を追加します。

{# src/Acme/DemoBundle/Resources/views/themes/phone/layout.html.twig #}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>{% block title %}Demo Bundle{% endblock %}</title>
        <meta content="telephone=no" name="format-detection">
        <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
        <meta content="noarchive" name="robots">
        <style>h1{font-size:16pt;}</style>
    </head>
    <body>
        {% block content %}
        {% endblock %}
    </body>
</html>

試しにスマホで表示するとこのような感じになります。(だいぶ質素になりました)

f:id:issei_m:20130514214742p:plain

ちなみに app/Resources/views にも同様のディレクトリ構造を作ることでスマホ対応が可能です。

このライブラリの最も優れている所は、スマホ用にテンプレートが用意されていないページでも通常のテンプレートを使用してフォールバックしてくれる点です。
試しに /demo/hello/World にアクセスすると、PC 用テンプレートではありますがきちんとページが表示されます。

Assetic を併用する場合の注意点

Assetic は非常に便利ですが、LiipThemeBundle との併用にあたってひとつ注意点があります。
README によると本来ディレクトリ構造は Resources/themes/phone/... のようにするのですが、これだと中のテンプレートで定義しているアセットがphp app/console assetic:dumpでダンプできなくなります。(デバッグ環境では Routing Error が発生します)

これを回避する為テーマディレクトリは Resources/views 以下に配置し、前述のとおり config.yml にpath_patternsを指定します。

それでも問題が発生する時は...

その時はphp app/console cache:clear --no-warmupを試してみて下さい。
--no-warmupが重要です。