5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Magento1.x エクステンション入門(2)

Last updated at Posted at 2015-12-14

このエントリはMagento Advent Calendarの14日目です。

概要

前回の記事で、Magentoにエクステンションとして認識させる段階まで作業を行いました。

今回はそれに引き続き、Magento上に独自のルーティングを定義し、新たな画面を作成する方法について書いていきます。

前提として、前回の記事で作成したプラグインの内容を引き継ぎ、エクステンション名だけ「Secondext」と変えたものが手元にあるものとしています。

画面の作成の大まかな手順

画面作成の大まかな手順は以下のとおりです。
今回は、「一番単純なやり方」と「一般的なやり方」の2つに分けてご紹介します。
(Magentoはカスタマイズ性が高い分、一つの目的を達成するにも利用可能な定義ファイルが多く、少々説明がしにくいと感じたためです。。。)

単純なやり方

  1. 「(エクステンションのフォルダ)/etc/config.xml」に、ルーティングの情報を定義する。
  2. 「(エクステンションのフォルダ)/controllers/IndexController.php」というファイルを作成し、テンプレートを指定して画面をレンダリングするコードを書く(ここでは、テンプレート名を「secondext/index.phtml」とする)。
  3. 「app/design/frontend/base/default/template/secondext/index.phtml」を作成し、そこにPHPのテンプレートを書く。

通常のやり方

  1. 「(エクステンションのフォルダ)/etc/config.xml」にブロックの定義、レイアウト更新の定義ファイルの場所(ここでは、second_ext.xmlとする)、ルーティングの情報を定義する。
  2. 「(エクステンションのフォルダ)/Block/ExtForm.php」というファイル(*ファイル名は何でも良いが、ここでは便宜的にそうする)を作成し、ビューに対応するクラスを作成する。
  3. 「app/desing/frontend/base/default/layout/second_ext.xml」というファイルを作成し、特定のルーティング(url)が開かれた時に利用するブロック、及び、そのブロックで利用するデザイン情報を定義する。利用するテンプレートの情報もこちらに記述する(secondext/ext_form.phtmlとする)。
  4. 「app/design/frontend/base/default/template/secondext/ext_form.phtml」を作成し、そこにPHPのテンプレートを書く。

なおControllerは特定のURLが開かれた時に実行されるメソッドに関する処理を、Block
はビューの描画に関する処理を担当するクラスとなります。

「単純なやり方」の詳細

作業は以下の3点です。

  • 前回作成したconfig.xmlを編集する。
  • controllers/IndexController.phpを作成する。
  • テンプレートとなるphtmlファイルを作成する。
app/code/community/Advent2015/Secondext/etc/config.xml

<?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>


app/code/community/Advent2015/Secondext/controllers/IndexController.php

<?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();
    }

}

app/design/frontend/base/default/template/secondext/index.phtml

<!-- この内容は適当 -->
<div>テストです</div>
<div>テストです</div>
<div>テストです</div>

ここまで作成してアップロードし、ブラウザで「(Magentoのインストール先)/ext-test」にアクセスしてください。

おそらく、以下のような画面になるはずです。

スクリーンショット 2015-12-14 13.08.18.png

簡単ですが、こちらが「単純なやり方」となります。

*サンプルコードについて、記事の一番下にリンクを置いていますので、そちらも参考にして下さい。

phtmlファイルを編集するだけでなく、IndexController.phpで指定するレイアウトを「page/3columns.phtml」から「page/1column.phtml」に変えたり、titleの部分を変更したりしても、画面表示が変わりますので、そちらも試してみて頂ければと思います。

なおcssやjsを追加する場合、そのやり方にも作法があるのですが「デザインテーマ」という別の領域に入ってきてしまいますので、今回は解説しません。

「通常のやり方」の詳細

作業は以下の4点です。
先ほどの「簡単なやり方」が完了した状態で、さらに追記していくものとします。

  • config.xmlを編集する。
  • controllers/IndexController.phpを編集する。
  • ブロックに対応するphpファイルを作成する。
  • レイアウトを更新するためのxmlファイルを作成する。
  • テンプレートとなるphtmlファイルを作成する。
app/code/community/Advent2015/Secondext/etc/config.xml

<?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>


app/code/community/Advent2015/Secondext/controllers/IndexController.php

<?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();
    }

}

app/code/community/Advent2015/Secondext/Block/ExtForm.php

<?php
class Advent2015_Secondext_Block_ExtForm extends Mage_Core_Block_Template {

	//動作確認のために作成した、適当なメソッド
	public function hoge() {
		return 'hoge';
	}

}

app/design/frontend/base/default/layout/second_ext.xml

<?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>

app/design/frontend/base/default/template/secondext/ext_form.phtml

<?php
  echo $this->hoge();
?>

<div>test!</div>
<div>test!</div>
<div>test!</div>

ここまでの内容をアップロードし、ブラウザから「(Magentoのインストール先)/ext-test/index/form」で、以下のような内容が表示されれば成功です。

*こちらのサンプルコードもGitHubにアップロードしています。

スクリーンショット 2015-12-14 13.08.52.png

注意点

うまく動かない場合、以下の部分をチェックしてみてください。

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」を作成します。

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にアップしていますので、そちらも参考にしてください。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?