php5フレームワークsymfonyを勉強しました。その3

前回の続き。7章を勉強しました。

ビューレイヤーの内側

サンプルのindexSuccess.phpテンプレート

<h1>ようこそ</h1>
<p>お帰りなさい、<?php echo $name ?></p>
<ul>何をなさりたいですか?
  <li><?php echo link_to('最新の記事を読む', 'article/read') ?></li>
  <li><?php echo link_to('新しい記事を書き始める', 'article/write') ?></li>
</ul>

input_tagヘルパー

<?php echo input_tag('nickname') ?>
 => <input type="text" name="nickname" id="nickname" value="" />

auto_link_textヘルパー

<?php echo auto_link_text('我々のサイトにお越し下さい www.example.com') ?>
 => 我々のサイトにお越し下さい <a href="http://www.example.com">www.example.com</a>

ヘルパーを宣言する

// このテンプレート内で特定のヘルパーグループを使う
<?php use_helper('Text') ?>
...
<h1>説明</h1>
<p><?php echo auto_link_text($description) ?></p>

共通のデフォルトのヘルパー

// Helperグループ
<?php use_helper('HelperName') ?>
<?php use_helper('HelperName1', 'HelperName2', 'HelperName3') ?>
 
// Tagグループ
<?php echo tag('input', array('name' => 'foo', 'type' => 'text')) ?>
<?php echo tag('input', 'name=foo type=text') ?>  // 代替のオプション構文
 => <input name="foo" type="text" />
<?php echo content_tag('textarea', 'ダミーの内容', 'name=foo') ?>
 => <textarea name="foo">ダミーの内容</textarea>
 
// Urlグループ
<?php echo link_to('クリックして下さい', 'mymodule/myaction') ?>
=> <a href="/route/to/myaction">クリックして下さい</a>  // ルーティングの設定による
 
// Assetグループ
<?php echo image_tag('myimage', 'alt=foo size=200x100') ?>
 => <img src="/images/myimage.png" alt="foo" width="200" height="100"/>
<?php echo javascript_include_tag('myscript') ?>
 => <script language="JavaScript" type="text/javascript" src="/js/myscript.js"></script>
<?php echo stylesheet_tag('style') ?>
 => <link href="/stylesheets/style.css" media="screen" rel="stylesheet"type="text/css" />

その他ヘルパー

オンラインのAPIドキュメント(http://www.symfony-project.org/api/1_0/)

独自のヘルパーを追加する

ヘルパー関数(HTMLコードを返す通常のPHP関数)はFooBarHelper.phpという名前のファイルに保存されます。FooBarはヘルパーグループの名前です。ファイルをapps/myapp/lib/helper/ディレクトリ(もしくはプロジェクトのlib/フォルダの1つの元で作られたhelper/ディレクトリ)に保存すればインクルードする際にuse_helper('FooBar')ヘルパーによって自動的に見つかります。

テンプレートのショートカット

$sf_context: コンテキスト全体のオブジェクト(sfContextのインスタンス)
$sf_request: リクエストオブジェクト(sfRequestのインスタンス)
$sf_params: リクエストのパラメータ
$sf_user: 現在のユーザーセッションのオブジェクト(sfUserのインスタンス)

// 長いバージョン
<?php echo $sf_request->getParameter('total'); ?>
 
// 短いバージョン
<?php echo $sf_params->get('total'); ?>
 
// 次のアクションコードと同等
echo $this->getRequestParameter('total');

パーシャルをmymoduleモジュールのテンプレートの中に含める

// myapp/modules/mymodule/templates/_mypartial1.phpパーシャルをインクルードする
// テンプレートとパーシャルは同じモジュールにあるので、
// モジュール名を省略できる
<?php include_partial('mypartial1') ?>
 
// myapp/modules/foobar/templates/_mypartial2.phpパーシャルをインクルードする
// この場合モジュール名は必須
<?php include_partial('foobar/mypartial2') ?>
 
// myapp/templates/_mypartial3.phpパーシャルをインクルードする
// 'global'モジュールの一部として見なされる
<?php include_partial('global/mypartial3') ?>

mymodule/actions/actions.class.phpの中で、アクションが変数を定義する

class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $this->total = 100;
  }
}

mymodule/templates/indexSuccess.phpの中で、テンプレートが変数をパーシャルに渡す

<p>Hello, world!</p>
<?php include_partial('mypartial',
array('mytotal' => $total)
) ?>

mymodule/templates/_mypartial.phpの中で、パーシャルは変数を利用できる

<p>合計: <?php echo $mytotal ?></p>

modules/news/actions/components.class.phpの中で、コンポーネントクラス

class newsComponents extends sfComponents
{
  public function executeHeadlines()
  {
    $c = new Criteria();
    $c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
    $c->setLimit(5);
    $this->news = NewsPeer::doSelect($c);
  }
}

modules/news/templates/_headlines.phpの中の、パーシャル

<div>
  <h1>最新のニュース</h1>
  <ul>
  <?php foreach($news as $headline): ?>
    <li>
      <?php echo $headline->getPublishedAt() ?>
      <?php echo link_to($headline->getTitle(),'news/show?id='.$headline->getId()) ?>
    </li>
  <?php endforeach ?>
  </ul>
</div>

パラメータをコンポーネントとテンプレートに渡す

// コンポーネントへのコール
<?php include_component('news', 'headlines', array('foo' => 'bar')) ?>
 
// コンポーネント自身にて
echo $this->foo;
 => 'bar'
 
// _headlines.phpパーシャルにて
echo $foo;
 => 'bar'

'sidebar'スロットをレイアウト内部でインクルードする

div id="sidebar">
<?php if (has_slot('sidebar')): ?>
  <?php include_slot('sidebar') ?>
<?php else: ?>
  <!-- default sidebar code -->
  <h1>文脈上の領域</h1>
  <p>この領域はページのメインの内容と関連したリンクと情報を含みます。</p>
<?php endif; ?>
</div>

サンプルのモジュールレベルのview.yml

editSuccess:
  metas:
    title: プロファイルを編集する

editError:
  metas:
    title: プロファイルを編集している間に発生したエラー

all:
  stylesheets: [my_style]
  metas:
    title: 私のウェブサイト

apps/myapp/config/view.ymlの中の、アプリケーションレベルのビューのデフォルト設定

default:
  http_metas:
    content-type: text/html

  metas:
    title:        symfony project
    robots:       index, follow
    description:  symfony project
    keywords:     symfony, project
    language:     en

  stylesheets:    [main]

  javascripts:    [ ]

  has_layout:     on
  layout:         layout

アクションはsfResponseオブジェクトメソッドにアクセスできる

class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $response = $this->getResponse();
 
    // HTTPヘッダー
    $response->setContentType('text/xml');
    $response->setHttpHeader('Content-Language', 'en');
    $response->setStatusCode(403);
    $response->addVaryHttpHeader('Accept-Language');
    $response->addCacheControlHttpHeader('no-cache');
 
    // クッキー
    $response->setCookie($name, $content, $expire, $path, $domain);
 
    // メタ情報とページのヘッダー
    $response->addMeta('robots', 'NONE');
    $response->addMeta('keywords', 'foo bar');
    $response->setTitle('My FooBar Page');
    $response->addStyleSheet('custom_style');
    $response->addJavaScript('custom_behavior');
  }
}

view.ymlの中の「キー: 値」の組としてのメタの定義

http_metas:
  cache-control: public

metas:
  description:   Finance in France
  keywords:      finance, France

レスポンスアクションのレスポンス設定としてのメタの定義

$this->getResponse()->addHttpMeta('cache-control', 'public');
$this->getResponse()->addMeta('description', 'Finance in France');
$this->getResponse()->addMeta('keywords', 'finance, France');

view.ymlの中のタイトルの定義

indexSuccess:
  metas:
    title: 3匹の子豚

アクションの中のタイトルの定義 -- 動的なタイトルを可能にする

$this->getResponse()->setTitle(sprintf('%d匹の子豚', $number));

view.ymlの中で、ファイルをインクルードする

indexSuccess:
  stylesheets: [mystyle1, mystyle2]
  javascripts: [myscript]

ファイルをアクション内部でインクルードする

$this->getResponse()->addStylesheet('mystyle1');
$this->getResponse()->addStylesheet('mystyle2');
$this->getResponse()->addJavascript('myscript');

view.ymlの中でメディアを指定したスタイルシートインクルージョン

indexSuccess:
  stylesheets: [main, paper: { media: print }]

アクション内部でメディアを指定したスタイルシートをインクルードする

$this->getResponse()->addStylesheet('paper', '', array('media' => 'print'));

view.ymlの中のレイアウトの定義

indexSuccess:
  layout: my_layout

アクション内部のレイアウトの定義

$this->setLayout('my_layout');

view.ymlの中でレイアウトの除外

indexSuccess:
  has_layout: false

アクションの中でレイアウトの除外

$this->setLayout(false);

'sidebar'という名前のコンポーネントをインクルードする

<div id="sidebar">
  <?php include_component_slot('sidebar') ?>
</div>

myapp/config/view.ymlの中で、デフォルトの'sidebar'スロットコンポーネントを定義する

default:
  components:
    sidebar:  [bar, default]

myapp/modules/user/config/view.ymlの中で、'sidebar'スロットコンポーネントを特化する

all:
  components:
    sidebar:  [bar, user]

modules/bar/actions/components.class.phpの中で、'sidebar'スロットによって使用されるコンポーネント

class barComponents extends sfComponents
{
  public function executeDefault()
  {
  }
 
  public function executeUser()
  {
    $this->current_user = $this->getUser()->getCurrentUser();
    $c = new Criteria();
    $c->add(ArticlePeer::AUTHOR_ID, $this->current_user->getId());
    $this->nb_articles = ArticlePeer::doCount($c);
  }
}

modules/bar/templates/の中で、'sidebar'スロットコンポーネントによって使用されるパーシャル

// _default.php
<p>この領域はコンテキスト上の情報を含みます。</p>
 
// _user.php
<p>ユーザー名: <?php echo $current_user->getName() ?></p>
<p><?php echo $nb_articles ?> articles published</p>

view.ymlの中でコンポーネントスロットを無効にする

all:
  components:
    sidebar:  []

myapp/config/settings.ymlの中で、出力エスケーピング機能を有効にする

all:
  .settings:
    escaping_strategy: both
    escaping_method:   ESC_ENTITIES

生のデータを出力することが必要なとき、getRaw()メソッドを呼び出します。

echo $sf_data->getRaw('test');
 => <script>alert(document.cookie)</script>

[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/