このエントリはMagento Advent Calendarの14日目です。
概要
前回の記事で、Magentoにエクステンションとして認識させる段階まで作業を行いました。
今回はそれに引き続き、Magento上に独自のルーティングを定義し、新たな画面を作成する方法について書いていきます。
前提として、前回の記事で作成したプラグインの内容を引き継ぎ、エクステンション名だけ「Secondext」と変えたものが手元にあるものとしています。
画面の作成の大まかな手順
画面作成の大まかな手順は以下のとおりです。
今回は、「一番単純なやり方」と「一般的なやり方」の2つに分けてご紹介します。
(Magentoはカスタマイズ性が高い分、一つの目的を達成するにも利用可能な定義ファイルが多く、少々説明がしにくいと感じたためです。。。)
単純なやり方
- 「(エクステンションのフォルダ)/etc/config.xml」に、ルーティングの情報を定義する。
- 「(エクステンションのフォルダ)/controllers/IndexController.php」というファイルを作成し、テンプレートを指定して画面をレンダリングするコードを書く(ここでは、テンプレート名を「secondext/index.phtml」とする)。
- 「app/design/frontend/base/default/template/secondext/index.phtml」を作成し、そこにPHPのテンプレートを書く。
通常のやり方
- 「(エクステンションのフォルダ)/etc/config.xml」にブロックの定義、レイアウト更新の定義ファイルの場所(ここでは、second_ext.xmlとする)、ルーティングの情報を定義する。
- 「(エクステンションのフォルダ)/Block/ExtForm.php」というファイル(*ファイル名は何でも良いが、ここでは便宜的にそうする)を作成し、ビューに対応するクラスを作成する。
- 「app/desing/frontend/base/default/layout/second_ext.xml」というファイルを作成し、特定のルーティング(url)が開かれた時に利用するブロック、及び、そのブロックで利用するデザイン情報を定義する。利用するテンプレートの情報もこちらに記述する(secondext/ext_form.phtmlとする)。
- 「app/design/frontend/base/default/template/secondext/ext_form.phtml」を作成し、そこにPHPのテンプレートを書く。
なおControllerは特定のURLが開かれた時に実行されるメソッドに関する処理を、Block
はビューの描画に関する処理を担当するクラスとなります。
「単純なやり方」の詳細
作業は以下の3点です。
- 前回作成したconfig.xmlを編集する。
- controllers/IndexController.phpを作成する。
- テンプレートとなるphtmlファイルを作成する。
<?xml version="1.0"?>
<config>
<modules>
<Advent2015_Secondext>
<version>0.0.1</version>
</Advent2015_Secondext>
</modules>
<frontend>
<routers>
<secondext>
<use>standard</use>
<args>
<module>Advent2015_Secondext</module>
<!-- 「ext-test」というURLを割り当てる -->
<frontName>ext-test</frontName>
</args>
</secondext>
</routers>
</frontend>
</config>
<?php
class Advent2015_Secondext_IndexController extends Mage_Core_Controller_Front_Action {
public function indexAction() {
$this->loadLayout();
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'secondext',
array('template' => 'secondext/index.phtml') //画面に表示するテンプレートファイルを指定。
);
$this->getLayout()->getBlock('root')->setTemplate('page/3columns.phtml'); //画面のレイアウトを指定
$this->getLayout()->getBlock('content')->append($block);
$this->getLayout()->getBlock('head')->setTitle('タイトル');
$this->_initLayoutMessages('core/session');
$this->renderLayout();
}
}
<!-- この内容は適当 -->
<div>テストです</div>
<div>テストです</div>
<div>テストです</div>
ここまで作成してアップロードし、ブラウザで「(Magentoのインストール先)/ext-test」にアクセスしてください。
おそらく、以下のような画面になるはずです。
簡単ですが、こちらが「単純なやり方」となります。
*サンプルコードについて、記事の一番下にリンクを置いていますので、そちらも参考にして下さい。
phtmlファイルを編集するだけでなく、IndexController.phpで指定するレイアウトを「page/3columns.phtml」から「page/1column.phtml」に変えたり、titleの部分を変更したりしても、画面表示が変わりますので、そちらも試してみて頂ければと思います。
なおcssやjsを追加する場合、そのやり方にも作法があるのですが「デザインテーマ」という別の領域に入ってきてしまいますので、今回は解説しません。
「通常のやり方」の詳細
作業は以下の4点です。
先ほどの「簡単なやり方」が完了した状態で、さらに追記していくものとします。
- config.xmlを編集する。
- controllers/IndexController.phpを編集する。
- ブロックに対応するphpファイルを作成する。
- レイアウトを更新するためのxmlファイルを作成する。
- テンプレートとなるphtmlファイルを作成する。
<?xml version="1.0"?>
<config>
<modules>
<Advent2015_Secondext>
<version>0.0.1</version>
</Advent2015_Secondext>
</modules>
<global>
<!-- 「一般的なやり方」で必要な部分↓ -->
<blocks>
<Advent2015_Secondext>
<class>Advent2015_Secondext_Block</class>
</Advent2015_Secondext>
</blocks>
<!-- 「一般的なやり方」で必要な部分↑ -->
<helpers>
<Advent2015_Secondext>
<class>Advent2015_Secondext_Helper</class>
</Advent2015_Secondext>
</helpers>
</global>
<frontend>
<!-- 「一般的なやり方」で必要な部分↓ -->
<layout>
<updates>
<secondext>
<file>second_ext.xml</file>
</secondext>
</updates>
</layout>
<!-- 「一般的なやり方」で必要な部分↑ -->
<routers>
<!-- ↓「簡単なやり方」と「一般的なやり方」で必要な部分↓ -->
<secondext>
<use>standard</use>
<args>
<module>Advent2015_Secondext</module>
<frontName>ext-test</frontName>
</args>
</secondext>
<!-- ↑「簡単なやり方」と「一般的なやり方」で必要な部分↑ -->
</routers>
</frontend>
</config>
<?php
class Advent2015_Secondext_IndexController extends Mage_Core_Controller_Front_Action {
/*
「/ext-test」もしくは「/ext-test/index」にアクセスした場合に呼ばれる。
「簡単なやり方」の画面を表示するルーティング
*/
public function indexAction() {
$this->loadLayout();
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'secondext',
array('template' => 'secondext/index.phtml')
);
$this->getLayout()->getBlock('root')->setTemplate('page/3columns.phtml'); //画面のレイアウトを指定
$this->getLayout()->getBlock('content')->append($block);
$this->getLayout()->getBlock('head')->setTitle('タイトル');
$this->_initLayoutMessages('core/session');
$this->renderLayout();
}
/*
「/ext-test/index/form」にアクセスした場合に呼ばれる。
「一般的なやり方」の画面を表示するルーティング
*/
public function formAction() {
$this->loadLayout();
$this->renderLayout();
}
}
<?php
class Advent2015_Secondext_Block_ExtForm extends Mage_Core_Block_Template {
//動作確認のために作成した、適当なメソッド
public function hoge() {
return 'hoge';
}
}
<?xml version="1.0"?>
<layout version="0.0.1">
<secondext_index_form translate="label">
<label>Test Form</label>
<!-- HTMLの<head>部分に対する定義 -->
<reference name="head">
<action method="setTitle" translate="title" module="Advent2015_Secondext"><title>Test Form</title></action>
</reference>
<!-- 全体の画面レイアウトに関する定義 -->
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
<action method="setHeaderTitle" translate="title" module="Advent2015_Secondext"><title>Test Form</title></action>
</reference>
<!-- 表示するコンテンツに関する定義 -->
<reference name="content">
<block type="Advent2015_Secondext/ExtForm" template="secondext/ext_form.phtml"/>
</reference>
</secondext_index_form>
</layout>
<?php
echo $this->hoge();
?>
<div>test!</div>
<div>test!</div>
<div>test!</div>
ここまでの内容をアップロードし、ブラウザから「(Magentoのインストール先)/ext-test/index/form」で、以下のような内容が表示されれば成功です。
*こちらのサンプルコードもGitHubにアップロードしています。
注意点
うまく動かない場合、以下の部分をチェックしてみてください。
config.xml
必要なタグの記述があるか、また、その記述が合っているか(大文字/小文字の違い, タイプミス)を確認します。
- global/block, frontent/layout, frontend/routers の3つの要素が入っているか。
- 「blocks」の中のモジュール名のタグが、modulesの下のモジュール名のタグと大文字・小文字を含めて合っているか。
- frontend/routes, frontend/layoutの下に書くモジュール名のタグは全て小文字。
- frontend/routes/の下にあるmoduleタグの中に入る文字列は、「Advent2015_Secondext_IndexController」から「_IndexController」を除いたものとする。
Controller, Block
ファイル名とクラス名がルールに合っているかどうかをチェックします。
-
ブロックの場合
-
クラス名は、config.xmlで設定した「blocks/[モジュール名]/class」で指定した名前をプレフィクスとし、「_」で区切って独自のブロック名を入れる。
-
ファイル名は、クラス名の一番最後の「_」より後の文字になる。
-
例えばクラス名が「Advent2015_Secondext_Block_ExtForm」であれば、ファイル名は「Block/ExtForm.php」でなければならない。大文字、小文字が違ってもダメ。
-
コントローラーの場合
-
クラス名は、config.xmlで指定した「frontend/routers/[モジュール名]/args/module」で指定したモジュール名 + 「_IndexController」となる。
-
ファイル名は「IndexController.php」となる。
余談ですが、Controllerには以下のような側面もあります。
- IndexController.phpでは、「(ルーティング名) + Action」というメソッドを定義することで、特定のURLにアクセスした場合に呼ばれる処理を決められる。
- 「indexAction」は「/index」もしくは「/」に対応する。
- 「formAction」は「/index/form」に対応する。
- モジュール名として更に「_」を追加し、別のコントローラを作成することもできる。
例:
<routers>
<secondext>
<use>standard</use>
<args>
<module>Advent2015_Secondext</module>
<frontName>ext-test</frontName>
</args>
</secondext>
<!-- 追加部分 -->
<secondext_hoge>
<use>standard</use>
<args>
<module>Advent2015_Secondext_Hoge</module>
<frontName>ext-test-hoge</frontName>
</args>
</secondext_hoge >
</routers>
上記のようにconfig.xmlを編集した後、「controllers/Hoge/IndexController.php」を作成します。
<?php
class Advent2015_Secondext_Hoge_IndexController extends Mage_Core_Controller_Front_Action {
public function indexAction() {
$this->loadLayout();
$this->renderLayout();
}
}
このようにすると、ブラウザから「/ext-test-hoge」にアクセスした場合に、上記のコントローラのindexActionが呼ばれます。
*ルーティングに関しては、筆者本人もまだ理解が浅いので、まだ勉強をしなければならないところです。
レイアウト更新xmlファイル
「layout」直下のタグは「routes」の下に書いたモジュール名 + コントローラの名前 + アクション名となります。
例えば今回の場合「secondext_index_form」となっていますが、こちらは
- 「secondext → モジュール名」
- 「index → IndexController」
- 「form → public function formAction()」
という3つの要素から成り立っています。
また
<action method="setTitle" translate="title" module="Advent2015_Secondext"><title>Test Form</title></
と書かれている部分の「module」にはconfig.xmlの「global/helpers」の直下に書かれているタグの文字列と同じものを入れます(これも大文字, 小文字が区別されます)。
テンプレートファイル
「phtml」という拡張子ですが、言語としてはphpとなります。
またphtmlファイル内で利用される変数$thisは、現在のphtmlを呼び出している元のブロッククラスとなります。
今回の場合、$thisは「Advent2015_Secondext_Block_ExtForm」になります。
まとめ
今回は筆者が実際に利用した範囲を中心に、新規画面の作成方法について説明しました。
これからMagentoを始める方にとって、何らか参考になれば幸いです。
また、記事に間違い等があればご指摘を頂ければと思います。
明日はHirokazuNishさんのExtension ConverterでMagento1.xのエクステンションを変換してみるとなります。
どうぞよろしくお願いします。
参考
今回のコードはGitHubにアップしていますので、そちらも参考にしてください。