Linuxなどのメモ書き

Magento2 エクステンションの作成 その4


Rev.9を表示中。最新版はこちら

1. 概要

Magento2 エクステンションの作成 その3の続き。

ここでは、管理画面に投稿内容の一覧表示ページを作成する。「Magento2 エクステンションの作成 その2」で作成した/admin/topic/posts/indexのページに一覧データを表示する。

2. テンプレートの修正

まずはlayoutファイルを修正する。「Magento2 エクステンションの作成 その2」でview/adminhtml/layout/topic_posts_index.xmlを作成したが、このファイルを修正する。

view/adminhtml/layout/topic_posts_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchem
aLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <title>
            Posts
        </title>
    </head>
    <body>
        <referenceContainer name="content">
            <!-- 外部のテンプレートファイルを読み込みview/adminhtml/templates/posts.htmlを参照 -->
            <block class="Magento\Backend\Block\Template" template="BitHive_Topic::posts.phtml"/>
            <!-- -view/adminhtml/ui_component/topic_listing.xmlを参照 -->
            <uiComponent name="topic_listing"/>
        </referenceContainer>
    </body>
</page>

赤の行を追加した。

Magento2ではUI componentsという仕組みを使い、xmlでGrid(一覧表示用のテーブル)やフォームの定義を行い、それを呼び出す形でページを作成していく。追加した<uiComponent name="topic_listing"/>はview/adminhtml/ui_component/topic_listing.xmlで定義したコンポーネントを呼び出すことを意味する。

次にUI componentsのコンポーネントであるview/adminhtml/ui_component/topic_listing.xmlを作成して一覧表示用のGridを定義する。このファイルで、Gridのカラム等を定義する。

view/adminhtml/ui_component/topic_listing.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">topic_listing.topic_listing_data_source</item>
        </item>
    </argument>
    <settings>
        <spinner>spinner_columns</spinner>
        <deps>
            <dep>topic_listing.topic_listing_data_source</dep>
        </deps>
        <buttons>
            <!-- 追加ボタンを置く -->
            <button name="add">
                <url path="*/*/new"/>
                <class>primary</class>
                <label translate="true">Add New Topic</label>
            </button>
        </buttons>
    </settings>
    <!-- Gridに表示するデータの取得方法を指定 -->
    <dataSource name="topic_listing_data_source" component="Magento_Ui/js/grid/provider">
        <settings>
            <storageConfig>
                <param name="indexField" xsi:type="string">post_id</param>
            </storageConfig>
            <updateUrl path="mui/index/render"/>
        </settings>
        <dataProvider class="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider" name="topic_listing_data_source">
            <settings>
                <requestFieldName>id</requestFieldName>
                <primaryFieldName>post_id</primaryFieldName>
            </settings>
        </dataProvider>
    </dataSource>
    <listingToolbar name="listing_top">
<!--
        <bookmark name="bookmarks"/>
-->
        <columnsControls name="columns_controls"/>
        <filters name="listing_filters"/>
        <paging name="listing_paging"/>
    </listingToolbar>
    <!-- Gridに表示するカラムの定義 -->
    <columns name="spinner_columns">
        <selectionsColumn name="ids">
            <settings>
                <resizeEnabled>false</resizeEnabled>
                <resizeDefaultWidth>60</resizeDefaultWidth>
                <indexField>post_id</indexField>
            </settings>
        </selectionsColumn>
        <column name="post_id">
            <settings>
                <filter>textRange</filter>
                <sorting>asc</sorting>
                <label translate="true">ID</label>
            </settings>
        </column>
        <column name="message">
            <settings>
                <filter>text</filter>
                <dataType>text</dataType>
                <label translate="true">Message</label>
            </settings>
        </column>
        <column name="date" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
            <settings>
<!-- timezone設定をfalseにするとUTCのまま表示される
                <timezone>false</timezone>
-->
                <filter>dateRange</filter>
                <dataType>date</dataType>
                <label translate="true">Date</label>
            </settings>
        </column>
	<column name="created" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
            <settings>
                <filter>dateRange</filter>
                <dataType>date</dataType>
                <label translate="true">Created</label>
            </settings>
        </column>
	<column name="modified" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
            <settings>
                <filter>dateRange</filter>
                <dataType>date</dataType>
                <label translate="true">Updated</label>
            </settings>
        </column>
        <!-- Actionカラムの内容はBitHive\Topic\Ui\Component\Listing\Columns\PostActionsで作成する -->
        <actionsColumn name="actions" class="BitHive\Topic\Ui\Component\Listing\Columns\PostActions" sortOrder="200">
            <settings>
                <indexField>post_id</indexField>
            </settings>
        </actionsColumn>
    </columns>
</listing>

 

編集中

3. DataProvider関連の設定

etc/di.xmlファイルを作成し、DataProvider関連のDependency Injectionの設定を行う。

etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="BitHive\Topic\Model\ResourceModel\Post\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">bithive_topic_post</argument>
            <argument name="resourceModel" xsi:type="string">BitHive\Topic\Model\ResourceModel\Post</argument>
        </arguments>
    </virtualType>
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="topic_listing_data_source" xsi:type="string">BitHive\Topic\Model\ResourceModel\Post\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
</config>

di.xmlはDependency Injectionの設定/カスタマイズを行うためのファイル。Topic/etc/di.xmlではTopicモジュール内でのDIの設定を行うことになる。このetc/di.xmlでは以下の二つの設定を行っている。

(1) DIでCollectionFactoryを作成する際のコンストラクタ引数を指定

これは<type>タグで指定している。

Topicモジュール内でMagento\Framework\View\Element\UiComponent\DataProvider\CollectionFactoryを生成する際、$collectionsコンストラクタ引数に以下のような配列を渡すように設定している。

コンストラクタ引数($collections)へ渡される引数

[
    'topic_listing_data_source' => 'BitHive\Topic\Model\ResourceModel\Post\Grid\Collection'
]

'topic_listing_data_source'はtopic_listing.xmlの<dataProvder>タグのname属性の値と合わせておく。これでDataProviderから'topic_listing_data_source'のデータ取得要求があった場合に、BitHive\Topic\Model\ResourceModel\Post\Grid\Collectionを返すようになる。

 

(2) BitHive\Topic\Model\ResourceModel\Post\Grid\Collectionの定義

(1)で指定したBitHive\Topic\Model\ResourceModel\Post\Grid\Collectionクラスは存在しない。<virtualType>タグでどのようなクラスかを定義すれば、Magento2が自動で作成しDIで注入してくれる。

ここでは、BitHive\Topic\Model\ResourceModel\Post\Grid\CollectionはMagento\Framework\View\Element\UiComponent\DataProvider\SearchResultを継承し、コンストラクタ引数に以下の値を渡すように指定している。

  • $mainTable: 'bithive_topic_post'
  • $resourceModel: 'BitHive\Topic\Model\ResourceModel\Post'

$mainTableと$resourceModelでどのテーブルからデータを取得してくるかを指定できる。

4. Actionカラムの内容を生成

Gridのアクションカラムの内容をBitHive\Topic\Ui\Component\Listing\Columns\PostActionsで作成するように設定したので、本クラスを作成する。

Ui/Component/Listing/Columns/PostActions.php

<?php
namespace BitHive\Topic\Ui\Component\Listing\Columns;

use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\UrlInterface;

class PostActions extends Column
{
    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param UrlInterface $urlBuilder
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = []
    ) {
        $this->urlBuilder = $urlBuilder;
        parent::__construct($context, $uiComponentFactory, $components, $data);
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as &$item) {
                $item[$this->getData('name')]['edit'] = [
                    'href' => $this->urlBuilder->getUrl(
                        'topic/posts/edit',
                        ['id' => $item['post_id']]
                    ),
                    'label' => __('Edit'),
                    'hidden' => false,
                ];
                $item[$this->getData('name')]['delete'] = [
                    'href' => $this->urlBuilder->getUrl(
                        'topic/posts/delete',
                        ['id' => $item['post_id']]
                    ),
                    'label' => __('Delete'),
                    'hidden' => false,
                    'confirm' => [
                        'title' => __('Delete ID: %1', $item['post_id']),
                        'message' => __('Are you sure you want to delete a ID: %1 record?', $item['post_id'])
                    ]
                ];
            }
        }

        return $dataSource;
    }
}

ここでは、それほど難しいことはしていないので詳細は省略するが、Edit/Deleteボタンを生成している。

5. 表示の確認

ここまでで作業は完了。あとは./bin/magento cache:cleanと./bin/magento setup:di:compileを実行してページにアクセスすればGridが表示されるはず。

まだデータが無いので空のGridが表示されるが、以下のようの直接SQLを実行してテスト用のデータを挿入してみればレコードも表示される。

INSERT INTO  bithive_topic_post (message, date) VALUES ('Hello', NOW());

 

図1 作成したGridページ

 

現時点でTopic配下は以下のようになっている。

./registration.php
./Model/ResourceModel/Post/Collection.php
./Model/ResourceModel/Post.php
./Model/Post.php
./view/adminhtml/templates/posts.phtml
./view/adminhtml/layout/topic_posts_index.xml
./view/adminhtml/ui_component/topic_listing.xml
./Ui/Component/Listing/Columns/PostActions.php
./Setup/InstallSchema.php
./Controller/Adminhtml/Posts/Index.php
./etc/module.xml
./etc/di.xml
./etc/adminhtml/menu.xml
./etc/adminhtml/routes.xml

編集中


最終更新 2018/12/05 15:04:40 - kztomita
(2018/12/05 12:53:10 作成)
添付ファイル
ss.jpg - kztomita


リンク

その他のWiki
Linuxメモ
Xnuメモ

会社
(有)ビットハイブ
受託開発やってます。

よくやる仕事

・Webシステム開発(LAMP環境)
・Linuxサーバー設定関連
サーバー移転作業代行

開発事例にデジタルカタログ/マンガビューワーを追加しました。

draggable.jsのスマホ対応版デモページを追加しました。説明はこちら

検索

Adsense
最近のコメント