初心者向けチュートリアル
このチュートリアルは、Ibexa DXP で Web サイトを構築するためのステップバイステップガイドです。
初心者向けチュートリアル
想定される読者
このチュートリアルは、 Ibexa DXP の使用経験がほとんどないユーザーを対象としています。
以下の点が必要です。
- HTMLとCSSの基本的な知識を持っている。
- 選択したデータベースの基本的な知識を持っている。
学習成果
このチュートリアルを終了すると、次のことができるようになります。
- Web サイトのコンテンツモデルの構築方法がわかる。
- テンプレートを使って、ニーズに合わせてコンテンツを表示することができる。
- ユーザーと権限の管理方法がわかる。
シナリオ
このチュートリアルでは、自転車の乗り心地を記録し、共有するための Web サイトを構築します。ユーザーがルートの情報や写真を追加し、旅行中にどのような興味深いポイントを訪れることができるかを示すことができるようになります。
ステップ
このチュートリアルでは、次の手順を実行します。
- 準備する
- コンテンツモデルの作成
- フロントページのカスタマイズ
- コンテンツの表示
- コンテンツの一覧表示
- 設定の改善
- コンテンツの埋め込み
- アカウント登録の有効化
ステップ1 — Get ready
チュートリアルを始めるには Ibexa DXP のクリーンインストールが必要です。
「Ibexa DXP のインストール手順」にしたがって対応してください。 Web サーバー、リレーショナルデータベース、PHP が必要です。
クリーンインストールには、ウェルカムページを表示するルートコンテンツアイテムのみが含まれています。
ステップ3でウェルカムページを独自のものに置き換えます。
とりあえず削除するには、config/packages/
に移動して ibexa_welcome_page.yaml
ファイルを削除してください。
これで、コンテンツモデルの作成に取りかかることができます。
ステップ 2 — コンテンツモデルの作成
Ibexa DXP プロジェクトでは、コンテンツをどのように構造化するかは非常に重要なポイントになります。これは、アプリケーションのデータベース設計と考えることができます。
完全な情報を得るには、コンテンツモデルのドキュメントページをお読みください。以下は、このチュートリアルに必要な点のみをカバーした短い紹介文です。
コンテンツモデルの概要
Ibexa DXP コンテンツ リポジトリは、コンテンツアイテムを中心に構成されています。コンテンツアイテムは、記事、製品レビュー、場所など、1つのコンテンツのピースです。
すべてのコンテンツアイテムは、コンテンツタイプのインスタンスです。コンテンツタイプは、各コンテンツアイテムにどのようなフィールドが含まれるかを定義します。例えば、記事には、タイトル、画像、要約、記事本文、出版日、著者リストなどのフィールドが含まれます。
フィールドは、インストールされているフィールドタイプのいずれかに属することができ、デフォルトのディストリビューションでは約30種類が用意されています。各フィールドタイプは、テキスト行、リッチテキストのブロック、画像、コンテンツアイテムとの関係のコレクションなど、特定のタイプのデータを表現するために構築されています。完全なリストは、フィールドタイプのリファレンスセクションを参照してください。各フィールドタイプは独自のオプションを持つことができ、独自の編集および表示インターフェイスが付属しています。
コンテンツタイプの作成
このサイトでは2種類のコンテンツタイプを使用します。 「Ride」と「Landmark」です。「Ride」は自転車旅行のルートです。途中の面白い場所である「Landmark」を1つ以上含むことができます。複数の「Ride」が同じ「Landmark」を訪れることができるので、データベースにおける N-N リレーションシップモデルに似ています。
このステップでは、最初のコンテンツタイプである「Ride」を作成します。
管理画面(<yourdomain>/admin
)に移動し、デフォルトのユーザー名: admin
、デフォルトのパスワード: publish
でログインします。
左サイドメニューから「コンテンツタイプ」を選択します。
コンテンツタイプグループのリストが表示されます。これらは、コンテンツタイプを論理的な方法でグループ化するために使用されます。
[Content] を選択し、 [+ Add new] ボタンをクリックします。
この基本情報をフォームに入力してください。
- 名前:
Ride
- 識別子:
ride
次に、以下の内容ですべてのフィールドを作成します。
Field Type | Name | Identifier | Required | Searchable | Translatable |
---|---|---|---|---|---|
Text line | 名前 | name |
☑ | ☑ | ☑ |
Image Asset | 写真 | photo |
☐ | ☐ | ☐ |
Rich text | 説明 | description |
☑ | ☑ | ☑ |
Map location | 開始位置 | starting_point |
☑ | ☑ | ☐ |
Map location | 終了位置 | ending_point |
☑ | ☑ | ☐ |
整数 | 長さ | length |
☑ | ☑ | ☐ |
入力が終わったら「新規作成」ボタンをクリックします。
「Rides」の作成
備考
Ibexa Experience を使用している場合、インストールのルートコンテンツ項目は「Ibexa Digital Experience Platform」と呼ばれるページです。
このチュートリアルでは、その子である「Ibexa Platform」というフォルダと入れ替えます。
「Ibexa Digital Experience Platform」に移動し、[ロケーション] タブを選択して [Swap Locations] セクションで [Ibexa Platform] に移動します。
ページの操作方法については、別のチュートリアルで紹介されています。
左メニューの「コンテンツ構成」を選択して、コンテンツに戻ります。次に、コンテンツツリーを参照し、画面右上の [+ Create content] ボタンを使用して、「All Rides」という名前のフォルダを作成します。フォルダを公開します。
フォルダ内で、コンテンツ作成ボタンを使っていくつかの「Rides」を作成し、写真を追加して公開します。
フォルダに2つ以上の「Rides」があれば、Web サイトのトップページをカスタマイズする準備が整います。
ステップ3 — フロントページのカスタマイズ
このステップでは、サイトのグローバルレイアウトを作成し、カスタムテンプレートを使用してコンテンツを表示します。
まず、サイトのルート(<yourdomain>
)に移動してください。すると、何のレイアウトもない、クリーンインストールのホームページが表示されるはずです。このステップでは、このコンテンツアイテムをレンダリングするためにカスタムテンプレートを使用するようにプラットフォームに指示することで、カスタマイズします。
コンテンツレンダリングの設定
ルートコンテンツをレンダリングする際にカスタムテンプレートを使用するには、 ibexa
の content_view
設定ブロックを作成します。
備考
YAML コードを貼り付けるときは、インデントとレベルに注意してください。ここで示されるコードブロックは YAML ファイルの完全な構造を含むので、新しいブロックをどこに設置すればよいのか学ぶのに役立ちます。YAML は既存のキーを重複させないように注意してください。
config/packages/ibexa.yaml
を編集します。インデント(字下げ)に注意しながら、 site
の下に以下のブロックを追加します - content_view
は site
の一階層下にあるべきです。
ibexa:
system:
site:
content_view:
full:
home_page:
template: full/home_page.html.twig
match:
Id\Location: 2
これは、「Location ID」が 2
のコンテンツをレンダリングするときに template
を使用するよう Ibexa DXP に指示します。 2
はルートコンテンツ項目のデフォルトの場所です。
Id\Location
は、さまざまな基準に応じてレンダリングをカスタマイズするために使用できる、いくつかのビューマッチャーのうちの1つです。
キャッシュのクリア
YAML ファイルを変更するたびに、キャッシュをクリアする必要があります。開発環境では必須ではありません。
キャッシュをクリアするには:
php bin/console cache:clear
テンプレートとレイアウトの作成
最初のテンプレートの作成
次に、設定で指定したテンプレートを作成する必要があります。
さしあたりテンプレートにお約束の「Hello world」メッセージを記入します。
templates/full/
に home_page.html.twig
ファイルを作成します。
<div>
<h1>Hello World!</h1>
</div>
ページを更新すると、シンプルでスタイルにこだわらないメッセージが表示されます。
備考
それでもまだウェルカムページが表示される場合は、config/packages/
に移動して、ibexa_welcome_page.yaml
ファイルが削除されていることを確認してください。
メインレイアウトの追加
多くのサイトでは、ロゴ入りヘッダーやフッターなど、一般的なレイアウトが決まっています。これはすべてのページに表示され、ページのコンテンツはその中に配置されます。
このようなテンプレートをサイトに追加するには、 templates/
に main_layout.html.twig
ファイルを作成し、以下のコードを貼り付けてください。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Ibexa DXP beginner tutorial">
<title>Ibexa DXP Beginner Tutorial</title>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/jquery/dist/jquery.min.js') }}"></script>
{{ encore_entry_link_tags('tutorial') }}
<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Roboto+Slab' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Fjalla+One' rel='stylesheet' type='text/css'>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-default navbar-fixed-top" id="total-navbar">
<div class="container">
<!-- Brand and toggle -->
<div class="navbar-header page-scroll">
<a class="navbar-brand" href="/">
<img alt="Brand" src="{{ asset('../assets/images/logo.png') }}">
</a>
</div>
</div>
</nav>
<!-- Header -->
<header class="below-navbar">
<div class="container">
<div class="row" id="banner">
<div class="col-xs-12">
<div class="banner-header-block">
<img alt="Go Bike! logo" src="{{ asset('../assets/images/wordmark.png') }}" style="width:100%" />
<h3 class="banner-header">{{ 'Discover new rides! Go Bike!'|trans }}</h3>
</div>
</div>
</div>
</div>
</header>
<section>
<div class="container">
<div class="row regular-content-size">
<div class="col-xs-12 box-style">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="text-center">
<div class="footer-color-one">
</div>
<div class="footer-color-two">
<div class="container">
<div class="row regular-content-size">
<div class="col-xs-8 col-xs-offset-2 footer-links-block">
<ul class="list-inline footer-links">
<li><a href="#">{{ 'About Us'|trans }}</a></li>
<li><a href="/">{{ 'All Rides'|trans }}</a></li>
<li><a href="#">{{ 'Submit a Ride'|trans }}</a></li>
<li><a href="#">{{ 'My Account'|trans }}</a></li>
<li><a href="#">{{ 'FAQ'|trans }}</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="footer-color-three">
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="small">Website design & content © copyright {{ "now"|date("Y") }} Ibexa. This website was made with Ibexa DXP.</p>
</div>
</div>
</div>
</div>
</footer>
{{ encore_entry_script_tags('tutorial-js') }}
</body>
</html>
12行目と89行目で、テンプレートが Symfony Webpack Encore を利用していることに注意してください。このチュートリアルでは、Webpack の設定方法を説明しますが、まずアセットが必要です。
アセットの追加
このサイトには、まだスタイルシートやアセットがありません。用意されたアセットファイルが含まれる assets.zip をダウンロードする必要があります。
そして、その中身を以下のディレクトリに解凍してください。
-
css
,fonts
,js
フォルダをassets/
に -
images
フォルダをpublic/assets/
に
先に進む前に、追加したファイルの構成が以下のようになっていることを確認してください。
Webpack の設定
Ibexa DXP では、Symfony Webpack Encore - Webpack の統合により、CSS スタイルシートと JS スクリプトのバンドルを構築し、プロジェクトに追加することが可能です。詳細については、バンドルからアセットをインポートするを参照してください。
バンドルを作成するには、まず、どのファイルをバンドルに含めるかを指定します。
プロジェクトのルートフォルダにある webpack.config.js
ファイルを開きます。 Encore.addEntry('app', './assets/app.js');
のすぐ下に、以下のコードを貼り付けます。
Encore
.addStyleEntry('tutorial', [
path.resolve(__dirname, './assets/css/normalize.css'),
path.resolve(__dirname, './assets/css/bootstrap.min.css'),
path.resolve(__dirname, './assets/css/bootstrap-theme.css'),
path.resolve(__dirname, './assets/css/style.css')
])
.addEntry('tutorial-js', [
path.resolve(__dirname, './assets/js/bootstrap.min.js')
]);
.addStyleEntry('tutorial', [])
と .addEntry('tutorial-js', [])
は、それぞれ main_layout.html.twig
の {{ encore_entry_link_tags('tutorial') }}
と {{ encore_entry_script_tags('tutorial-js') }}
に該当することに注意ください。この設定は、テンプレートに追加されるファイルからなるバンドルを作成します。
この時点でバンドルが作成され、すぐに使用できるようになります。
テンプレートの拡張
あとは、 home_page.html.twig
テンプレートに、アセットを利用する main_layout.html.twig
テンプレートを追加してください。
あるテンプレートを別のテンプレートに追加するには、 templates/full/home_page.html.twig
を編集して、次のコードに置き換えます。
{% extends "main_layout.html.twig" %}
{% block content %}
<div class="col-xs-10 col-xs-offset-1 text-justified">
<h1>Hello World!</h1>
</div>
{% endblock %}
テンプレート言語Twigは、テンプレートの継承をサポートしています。テンプレートは名前付きブロックを含むことができます。どのテンプレートも他のテンプレートを拡張することができ、その親によって定義されたブロックを変更することができます。
上のコードは、1行目で main_layout.html.twig
を指しています。また、"Hello world "メッセージをコンテンツブロックにラップしています。メインレイアウトのテンプレートを見返すと、空の {% block content %}{% endblock %}
セクションがあります(52〜53行目)。ここが home_page.html.twig
がレンダリングされる場所です。
以下のコマンドを実行して、キャッシュをクリアし、アセットを再生成してください。
php bin/console cache:clear
php bin/console assets:install
yarn encore <dev|prod>
Tip
yarn encore
コマンドは、使用している環境で実行する必要があります。
デフォルトでは、 Ibexa DXP は dev 環境にインストールされます。prod に変更した場合は、yarn encore prod
を使用してください。
ページを更新すると、スタイル付きレイアウトの中に「Hello world」が配置されているのが確認できるはずです。
この時点では、テンプレートは静的です。リポジトリから動的なデータをレンダリングすることはありません。
ステップ4 — コンテンツの表示
次のステップでは、ここにすべての乗り物のリストをレンダリングします。しかしその前に、既存のページレイアウトを使用して、単一の「Ride」のコンテンツをレンダリングすることができます。
「Ride」ビューの作成
以下のコードで Twig テンプレート templates/full/ride.html.twig
を作成します。
{% extends "main_layout.html.twig" %}
{% block content %}
<div class="col-xs-10 col-xs-offset-1 text-justified">
<section>
<div class="row regular-content-size">
<div class="col-xs-12">
<h3 class="center bottom-plus new-header">{{ content.name }}</h3>
</div>
</div>
</section>
<section>
<div class="row regular-content-size">
<div class="row">
<div class="col-xs-6">
<h4 class="underscore">{{ 'Starting point'|trans }}</h4>
{{ ibexa_render_field(content, 'starting_point', {'parameters': { 'width': '100%', height: '200px', 'showMap': true, 'showInfo': false }}) }}
</div>
<div class="col-xs-6">
<h4 class="underscore">{{ 'Ending point'|trans }}</h4>
{{ ibexa_render_field(content, 'ending_point', {'parameters': { 'width': '100%', height: '200px', 'showMap': true, 'showInfo': false }}) }}
</div>
</div>
</div>
</section>
<section>
<div class="row regular-content-size">
<div class="col-xs-12 padding-box">
<div class="col-xs-2">
<div class="box-ride">
<p class="special-number">{{ ibexa_render_field( content, 'length') }} km</p>
</div>
</div>
<div class="col-xs-8">
<h4 class="underscore">{{ 'Description'|trans }}</h4>
{{ ibexa_render_field( content, 'description') }}
</div>
</div>
</div>
</section>
</div>
{% endblock %}
このテンプレートは main_layout.html.twig
を再利用し、再びテンプレートをコンテンツブロックに配置します。
変数のプレビュー
現在のテンプレートで利用可能な変数は、Twig 関数の dump()
で確認することができます。
{{ dump() }}
また、特定の変数をダンプすることも可能です。
{{ dump(location) }}
次に、このテンプレートがいつ使われるべきかを示す必要があります。
config/packages/ibexa.yaml
に戻り、以下の設定を追加します(既存の content_view
の full
キーの下に :)。
site:
content_view:
full:
# existing keys, do not change them
ride:
template: full/ride.html.twig
match:
Identifier\ContentType: ride
「Ride」 full ビューの確認
フロントページにはまだライドのリストがないため、ライドをクリックするだけでプレビューすることはできません。しかし、2つの方法でテンプレートがどのように機能するかを確認することができます。
管理画面でのプレビュー
管理画面での編集中にプレビューを使用し、コンテンツがどのように表示されるかを全画面で確認することができます。
「Ride」ページの表示
「Ride」の URL に直接アクセスすることもできます。
「All Rides」フォルダにある「Ride」コンテンツの URL は http://<yourdomain>/all-rides/<ride-name>
です。
ステップ5 — コンテンツの一覧表示
1 つのコンテンツを表示する方法がわかったので、次はコンテンツのリストを表示する方法を説明します。
このステップでは、フロントページにすべての乗り物のテーブルを表示します。
トップページテンプレートのカスタマイズ
templates/full/home_page.html.twig
で、"Hello world" を既存のすべての「Rides」の一覧を表示するテーブルと置き換えます。
{% extends "main_layout.html.twig" %}
{% block content %}
<div class="col-xs-10 col-xs-offset-1 text-justified">
<table class="table table-hover">
<thead>
<tr class="table-header">
<th>{{ 'Ride'|trans }}</th>
<th>{{ 'From'|trans }}</th>
<th>{{ 'To'|trans }}</th>
<th>{{ 'Distance'|trans }}</th>
</tr>
</thead>
<tbody>
{% for ride in rides.currentPageResults %}
{{ render( controller( 'ibexa_content::viewAction', { 'location': ride.valueObject, 'viewType': 'line' } )) }}
{% endfor %}
</tbody>
</table>
{% if rides.haveToPaginate() %}
<div class="col-xs-12 text-center">
<div class="pagerfanta pagination">
{{ pagerfanta(rides, 'ibexa') }}
</div>
</div>
{% endif %}
</div>
{% endblock %}
上記の15行目で使用する rides
変数には、すべての「Rides」の一覧が含まれている必要があります。この一覧を取得するために Query Type を使用します。
トップページ用の QueryType の作成
QueryType オブジェクトは、Content Item クエリの結果を制限したり、ソートしたりするために使用されます。詳細は、「組み込みの Query Type」を参照してください。
ここでは、公開されている(可視化されている) ride
オブジェクトを表示する必要があります。 src/QueryType
に RideQueryType.php
ファイルを作成します。
<?php
namespace App\QueryType;
use Ibexa\Contracts\Core\Repository\Values\Content\LocationQuery;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Core\QueryType\QueryType;
class RideQueryType implements QueryType
{
public static function getName()
{
return 'Ride';
}
public function getQuery(array $parameters = [])
{
return new LocationQuery([
'filter' => new Criterion\LogicalAnd(
[
new Criterion\Visibility(Criterion\Visibility::VISIBLE),
new Criterion\ContentTypeIdentifier(['ride']),
]
)
]);
}
public function getSupportedParameters()
{
}
}
この Query Type は、 ride
コンテンツタイプに属するすべての可視コンテンツアイテムを検索します(21~22行目)。
ここで、この Query Type が設定に使用されることを示す必要があります。
Query Type の設定への追加
config/packages/ibexa.yaml
を編集します。ホームページのビュー設定で、このビューがクエリタイプを使用することを示します。
site:
content_view:
full:
# existing keys, do not change them
home_page:
controller: ibexa_query::pagingQueryAction
template: full/home_page.html.twig
match:
Id\Location: 2
params:
query:
query_type: Ride
limit: 4
assign_results_to: rides
12行目の query_type
パラメータは、どの Query Type を使用するかを示しています。Query Type ファイルの Ride
という名前は getName
メソッドで定義しました。
組み込みの ibexa_query
コントローラの pagingQueryAction
を使用すると(6行目)、ページネーションされた結果を自動的に取得することができます。 limit
パラメータで1ページあたりの結果の上限を設定することができます。
View types
これまで、ライドの全景を表示するために full
ビュータイプを使用してきました。一方ここでは、ホームページのテンプレートで 'viewType': 'line'
と表示されているように line
ビューを使用しています(16行目)。
カスタムビュータイプは、設定に含める限り好きな名前で設定することができます。では、「Rides」の line
ビューでやってみましょう。
「Rides」の line テンプレートの作成
config/packages/ibexa.yaml
ファイルに ride
テンプレートのルールを追加します。line
は full
と同じレベルである必要があります。
system:
site:
content_view:
line:
ride:
template: line/rides.html.twig
match:
Identifier\ContentType: ride
templates/line/rides.html.twig
テンプレートを作成します。
このテンプレートはテーブルの中に表示されるため <tr>
タグで始まります。
<tr>
<td>
<a href="{{ path( "ibexa.url.alias", { 'locationId': content.contentInfo.mainLocationId } ) }}"
target="_self">
<strong>
{{ content.name }}
</strong>
{% if not ibexa_field_is_empty( content, 'photo' ) %}
{{ ibexa_render_field(content, 'photo') }}
{% endif %}
</a>
</td>
<td>
{{ ibexa_render_field(content, 'starting_point', {'parameters': {'width': '100%', 'height': '100px', 'showMap': true, 'showInfo': true }}) }}
</td>
<td>
{{ ibexa_render_field(content, 'ending_point', {'parameters': {'width': '100%', 'height': '100px', 'showMap': true, 'showInfo': true }}) }}
</td>
<td>
<p>{{ ibexa_render_field( content, 'length' ) }} Km</p>
</td>
</tr>
さて、あなたのホームページのトップページに行くと、乗り物のリストが表示されます。しかし、ライドの写真が大きすぎて、テーブルを引き伸ばしています。次のステップでは、それらが適切な大きさで表示されていることを確認します。
ステップ6 — 設定の改善
画像バリエーションの定義
画像バリエーションは、同じ画像の異なるバージョンです。画像の拡大縮小、切り取り、エフェクトの追加などに利用できます。
ここまでは「Ride」一覧の画像を自動的にテンプレートに当てはめたものですが、その結果はあまり良いものではありません。今度は、バリエーションを作成して画像の見え方を細かく指定します。
以下を含む config/packages/image_variations.yaml
ファイルを新規に作成します。
ibexa:
system:
default:
image_variations:
ride_list:
reference: null
filters:
- {name: geometry/scaledownonly, params: [140, 100]}
次に、これらのバリエーションを使用するようにテンプレートを変更します。バリエーション名は、画像コンテンツをレンダリングする際のパラメータとして提供されます。
templates/line/rides.html.twig
で、8~10行目に以下のように 'alias': 'ride_list'
パラメータを追加してください。
{% if not ibexa_field_is_empty( content, 'photo' ) %}
{{ ibexa_render_field(content, 'photo', {
'parameters': {
'alias': 'ride_list'
}
}) }}
{% endif %}
これにより、一覧の各「Ride」の横に表示される写真は、比率を維持したまま適切に縮小されます。
キャッシュをクリアして、トップページを更新してください。写真が通常のサイズになり、表に収まるようになりました。
ビュー設定の分離
大規模なサイトでは、設定が必要な要素がたくさんあります。それをより整理するために、設定の一部を別のファイルに分割することができます。
例として、すべてのコンテンツビューの設定を独自のファイルに分離することができます。config/packages/views.yaml
ファイルを作成します。 config/packages/ibexa.yaml
から content_view
以下をすべてコピーして、新しいファイルに移動します。 ibexa.yaml
から対応するコードを削除します。
views.yaml
ファイルは次のようになります。
ibexa:
system:
site:
content_view:
full:
home_page:
controller: ibexa_query::pagingQueryAction
template: full/home_page.html.twig
match:
Id\Location: 2
params:
query:
query_type: Ride
limit: 4
assign_results_to: rides
ride:
template: full/ride.html.twig
match:
Identifier\ContentType: ride
line:
ride:
template: line/rides.html.twig
match:
Identifier\ContentType: ride
ステップ7 — コンテンツの埋め込み
コンテンツタイプとそのアイテムの一覧や詳細ビューを作成するには、多くの場合、関連するリソースを読み込む必要があります。このステップでは、「Ride」のページに表示される関連オブジェクトである「Landmark」を追加します。
関連リソースはいくつでも追加することができます。
「Landmark」コンテンツタイプの作成
このサイトに必要な2つ目のコンテンツタイプである「Landmark」を作成する必要があります。
[コンテンツタイプ] に移動し、 [コンテンツ] グループで「Landmark」コンテンツタイプを作成します。
ランドマークは、ライドが通過する興味深い場所です。それぞれの「Ride」は複数の「Landmark」に関連することがあります。
- 名前:
Landmark
- 識別子:
landmark
次に、以下の情報を持つすべてのフィールドを作成します。
Field Type | Name | Identifier | Required | Searchable | Translatable |
---|---|---|---|---|---|
Text line | 名前 | name | ☑ | ☑ | ☑ |
Rich text | 説明 | description | ☐ | ☑ | ☑ |
Image Asset | 写真 | photo | ☑ | ☐ | ☐ |
Map location | 場所 | location | ☑ | ☑ | ☐ |
コンテンツタイプの作成を確認するため、「作成」を選択します。
「Landmarks」Folder を作成し、「Landmark」をいくつか追加します。なお、「Landmark」を表現するために、写真(「写真」フィールド用)が必要です。
「Ride」コンテンツタイプ定義への「Landmarks」の追加
次に、「Ride」コンテンツタイプを編集して、2つのコンテンツタイプの間に Multiple Content Relation を追加します。「Landmarks」という新しい「コンテンツ関係(複数)」フィールドを作成し、識別子として landmark
を指定し、コンテンツタイプ「Landmark」を追加できるようにします。
[保存] をクリックして確認します。
既存の「Ride」に戻り、編集し、「Landmark」をリンクさせます。 [公開] をクリックします。
「Ride」ビューの「Landmarks」一覧の表示
「Landmark」の line ビューの作成
「Landmark」用の line
ビューを作成します。
config/packages/views.yaml
で新しいオーバーライドルールを宣言します。
ibexa:
system:
site:
content_view:
#full views here
line:
landmark:
template: line/landmark.html.twig
match:
Identifier\ContentType: landmark
templates/line/landmark.html.twig
を作成し、「Landmark」の line
ビューのテンプレートを追加します。
<section>
<div class="col-xs-4 photos-box">
<a href="#bikeModal{{ content.id }}" data-toggle="modal">
{{ ibexa_render_field( content, 'photo', { parameters: { 'alias': 'landmark_list', 'class': 'img-rounded'}}) }}
</a>
</div>
<div class="bike-modal modal fade" id="bikeModal{{ content.id }}" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-content">
<div class="close-modal" data-dismiss="modal">
<div class="lr">
<div class="rl">
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<div class="modal-body text-center">
<h2>{{ content.name }}</h2>
<hr class="featurette-divider">
{{ ibexa_render_field( content, 'photo', { parameters: { 'alias': 'large'}, attr: { 'class': 'img-responsive img-rounded' }}) }}
{{ ibexa_render_field( content, 'description', { attr: { 'class': 'padding-box text-justify' }}) }}
{{ ibexa_render_field( content, 'location', { parameters: {'width': '100%', 'height': '250px', 'showMap': true, 'showInfo': false }}) }}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
前回同様、ここ(4行目)で画像バリエーションを使うので、それを設定する必要があります。config/packages/image_variations.yaml
に ride_list
と同じ階層に以下のセクションを追加します。
landmark_list:
reference: null
filters:
- {name: geometry/scalewidth, params: [200]}
RideController の作成
「Ride」オブジェクトを表示する際に、追加で情報を提供する必要があります。これには、カスタムコントローラを作成する必要があります。コントローラは ContentService
を使用して、特定の「Ride」の関連リソース(Landmark)をロードします。
src/Controller/RideController.php
ファイルを作成します。
<?php
namespace App\Controller;
use Ibexa\Bundle\Core\Controller;
use Ibexa\Core\MVC\Symfony\View\ContentView;
use Ibexa\Contracts\Core\Repository\ContentService;
class RideController extends Controller
{
private $contentService;
public function __construct(ContentService $contentService)
{
$this->contentService = $contentService;
}
public function viewRideWithLandmarksAction(ContentView $view)
{
$currentContent = $view->getContent();
$landmarksListId = $currentContent->getFieldValue('landmarks');
$landmarksList = [];
foreach ($landmarksListId->destinationContentIds as $landmarkId) {
$landmarksList[$landmarkId] = $this->contentService->loadContent($landmarkId);
}
$view->addParameters(['landmarksList' => $landmarksList]);
return $view;
}
}
config/packages/views.yaml
を更新して、 RideController.php
に言及するように、ビュー設定に controller
キーを含む行を追加します。
ibexa:
system:
site:
content_view:
full:
ride:
template: full/ride.html.twig
controller: App\Controller\RideController::viewRideWithLandmarksAction
match:
Identifier\ContentType: ride
「Ride」の full ビューでの「ランドマーク」の追加
次に、「Ride」の full
ビューテンプレートを変更し、「Landmark」の一覧と、先ほど作成したコントローラを追加します。templates/full/ride.html.twig
の最後の </div>
と終了タグ {% endblock %}
の前に、以下の行を追加してください。
{% if landmarksList is not empty %}
<div class="row regular-content-size">
<section class="photos">
<div class="col-xs-12">
<h4 class="underscore">{{ 'Landmarks'|trans }}</h4>
</div>
{% for landmark in landmarksList %}
{{ render( controller( "ibexa_content::viewAction", { 'content': landmark, 'viewType': 'line'} )) }}
{% endfor %}
</section>
</div>
{% endif %}
これで再び「Ride」ページを確認すると、接続されているすべての「Landmarks」が表示されるようになりました。
ヒント
Twig テンプレートで dump()
を使用すると、利用可能なすべての変数を表示することができます。
ステップ8 — アカウント登録の有効化
このステップでは、他のユーザーがサイトにアカウントを作成し、管理画面にアクセスしてコンテンツを作成できるようにします。
ユーザー登録の有効化
左メニューの Admin (歯車のアイコン)から、「ロール」の管理画面に移動し、 Anonymous ロールをクリックします。
「Anonymous User」に User/Register
ポリシーを追加します。これにより Web サイトへの訪問者であれば誰でも登録フォームにアクセスできるようになります。
その後、 <yourdomain>/register
にアクセスします。登録フォームはスタイルなしなので、テンプレートを追加する必要があります。
登録フォームのカスタマイズ
config/packages/views.yaml
ファイルに、content_view
と同じレベルの site
の下に user_registration
キーを追加してください。
ibexa:
system:
site:
# existing content_view keys
user_registration:
templates:
form: user/registration_form.html.twig
これは、登録フォームのレンダリングに使用されるテンプレートを示します。
templates/user/registration_form.html.twig
を作成します。
{% extends "main_layout.html.twig" %}
{% block page_head %}
{% set title = 'Register user'|trans %}
{{ parent() }}
{% endblock %}
{% block content %}
{% import 'user/registration_content_form.html.twig' as registrationForm %}
<div class="container">
<section class="user-form col-md-6 col-md-offset-3">
<h2>{{ 'Member Registration'|trans }}</h2>
<div class="legend">* {{ 'All fields are required'|trans }}</div>
{{ registrationForm.display_form(form) }}
</section>
</div>
{% endblock %}
10行目では registration_content_form.html.twig
という別のファイルがインポートされていることがわかります。2つ目のテンプレートは、登録フォームの実際のフィールドをレンダリングするものです。このファイルも作成します (templates/user/registration_content_form.html.twig
とします)。
{% macro display_form(form) %}
{{ form_start(form) }}
{% for fieldForm in form.fieldsData %}
{% set fieldIdentifier = fieldForm.vars.data.fieldDefinition.identifier %}
{% if fieldIdentifier == 'first_name' or fieldIdentifier == 'last_name' %}
{% if fieldIdentifier == 'first_name' %}
<div class="row">
{% endif %}
<div class="col-md-6">
<div class="field-name">
<label class="required">{{ fieldForm.children.value.vars.label }}:</label>
</div>
{{ form_errors(fieldForm.value) }}
{{ form_widget(fieldForm.value, {
'contentData': form.vars.data
}) }}
</div>
{% if fieldIdentifier == 'last_name' %}
</div>
{% endif %}
{% endif %}
{% if fieldIdentifier == 'user_account' %}
<div class="row">
<div class="col-md-6">
{{ form_widget(fieldForm.value, {
'contentData': form.vars.data
}) }}
</div>
</div>
{% endif %}
{%- do fieldForm.setRendered() -%}
{% endfor %}
<div class="row">
<div class="col-md-4 col-md-offset-4">
{{ form_widget(form.register, {'attr': {
'class': 'btn btn-block btn-primary'
}}) }}
</div>
</div>
{{ form_end(form) }}
{% endmacro %}
3つ目に用意するテンプレートは、ユーザーが登録を完了したときに表示される確認ページです。まず、コンフィギュレーションで新しいテンプレートを指定します。config/packages/views.yaml
に confirmation
キーを追加します。
user_registration:
templates:
form: user/registration_form.html.twig
confirmation: user/registration_confirmation.html.twig
次に templates/user/registration_confirmation.html.twig
テンプレートを作成します。
{% extends "main_layout.html.twig" %}
{% block page_head %}
{% set title = 'Registration complete'|trans %}
{{ parent() }}
{% endblock %}
{% block content %}
<div class="container">
<section class="user-form-confirmation col-md-4 col-md-offset-4">
<h2>{{ 'Registration completed'|trans }}</h2>
<div class="row confirmation-label">
{{ 'You are all set up and ready to go'|trans }}
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<button type="button" class="btn btn-block btn-primary" onclick="window.location='{{ path('login') }}';">{{ 'Log in'|trans }}</button>
</div>
</div>
</section>
</div>
{% endblock %}
ここで、 <yourdomain>/register
に戻ります。
フォームに必要事項を入力し、ユーザーを登録します。
ヒント
この時点で新しいユーザーでログインした場合、管理画面(<yourdomain>/admin
)でログアウトし、再度 Admin でログインし直す必要があります。
権限の設定
登録フォームから作成されたユーザーは、「Guest accounts」ユーザーグループに所属します。作成されたユーザーは、このグループに割り当てられたロールを持つことになります。
ヒント
新しいユーザーを配置するグループを変更することができます(ただし、このチュートリアルでは変更する必要はありません)。詳しくは、「新規ユーザーの登録」を参照してください。
この時点では、登録した誰もが Web サイトにコンテンツを追加できるようにする必要はありません。そのため、追加の権限を持つ新しいユーザーグループを作成します。管理者が新しいユーザーを受け入れると、この新しいグループに移動させることができます。
ユーザーグループの作成
Admin のユーザー画面で、 [+ Create content] ボタンをクリックし、「Go Bike Members
」というユーザーグループを作成します。
「Rids」のためのフォルダの作成
All Rides
フォルダに移動し、その中に Member Rides
という名前の新しいフォルダを作成します。「Go Bike Members」はこのフォルダにのみコンテンツを作成することができます。
「Go Bike Members」の権限の設定
ロール画面の Admin から、「Contributors」という名前の新しいロールを作成します。
ここで、「Contributors Role」に以下のポリシーを追加します。
User/Login
User/Password
Content/Read
Content/Versionread
-
Content/Create
with Limitations: Content Type limited toRide
andLandmark
Content Types and Subtree to theMember Rides
-
Content/Publish
with Limitations: Content Type limited toRide
andLandmark
Content Types and Subtree to theMember Rides
-
Content/Edit
with Limitation: Owner limited toSelf
Section/View
Content/Reverserelatedlist
ヒント
制限機能は、ユーザーの権限管理を細かく設定するための強力なツールです。技術的な詳細の制限に関するドキュメントを参照してください。
ポリシーが設定できたら、「Assignments」タブで、ユーザーグループ「Go Bike Members」にロールを割り当てます。
次に、ユーザーページに移動します。先ほど作成したユーザーを選択し、「Go Bike Members」のユーザーグループに移動させます。
「Go Bike Member」でのコンテンツの作成
管理者としてログアウトし、新しいユーザーの資格情報で管理画面に再ログインします。これで、選択したフォルダに新しい「Ride」や「Landmark」を作成することができるようになりました。
Congratulations!
これで Ibexa DXP で最初の Web サイトが作成できました。
あなたは以下のことを学びました。
- コンテンツモデルの作成
- Ibexa DXP プロジェクトのファイルの構成
- 異なるコンテンツタイプに対応したビューの設定
- Ibexa DXP プロジェクトへのアセットの追加
- Webpack Encore の使用と設定
- Twig テンプレートとコントローラを使ったコンテンツの表示
- ユーザー登録の有効化
- ユーザー権限の管理