これは、複数のパートで構成されているチュートリアルの第 5 章です。パート 4 はこちら、概要はこちらから確認できます。
GitHub で完成済みコードを参照するか、ソリューションパッケージをダウンロードできます。
ダウンロード
AEM 実装では、コンテンツ階層を計画することが重要です。コンテンツ階層は、コンテンツを整理する際の主なメカニズムです。サイトナビゲーションはコンテンツ階層の影響を大きく受けることが多く、考え抜かれた階層はアプリケーションを簡素化できます。また、コンテンツ階層を計画する際には、権限や複数の言語のサポートも大きな役割を果たします。
架空の WKND サイトは、何をすべきかについての記事が複数のカテゴリに分かれたライフスタイルに関するサイトです。この組織を反映するコンテンツ階層を作成します。ナビゲーションは、コンテンツ階層に基づいて動的に設定されます。また、将来的に AEM 翻訳機能を使用できるよう、言語ルートを使用してサイトを設定することもできます。

Core コンポーネントには、ヘッダーやフッターの作成に活用するナビゲーションコンポーネントが含まれています。ナビゲーションコンポーネントは、サイト構造に基づいてナビゲーションを作成します。このコンポーネントはプロジェクトに合わせて既にプロキシ化されています。デザインに合わせてスタイルをいくつか追加します。
ナビゲーションの BEM 表記:
BLOCK cmp-navigation ELEMENT cmp-navigation__group ELEMENT cmp-navigation__item MOD cmp-navigation__item--active MOD cmp-navigation__item--level-* ELEMENT cmp-navigation__item-link
ナビゲーションは 2 つの方法(ヘッダー用とフッター用)で実装されます。構造を提供する追加レイアウトコンテナを使用して、最初にフッターナビゲーションが実装されます。
ui.apps モジュールが更新されます。
-
/* WKND Layout Container Footer Style */ @footer-background-color: #000; @footer-text-color: #fff; .cmp-layout-container--footer { background: @footer-background-color; min-height: 365px; margin-top: 3em; padding: 0 3em; >.aem-Grid { .container-content(); } @media (max-width: @screen-medium) { min-height:267px; } p { color: @footer-text-color; font-size: @font-size-xsmall; text-align:center; } }
-
ナビゲーションのフッタースタイルを作成する
ナビゲーションコンポーネントのフッタースタイルを作成します。
/apps/wknd/clientlibs/clientlib-site/components の下で、次の手順をおこないます。
- navigation という名前の新しいフォルダーを作成します。
- navigation フォルダーの下に、navigation.less という名前の新しいファイルを作成します。
- navigation フォルダーの下に、styles という名前の新しいフォルダーを作成します。
- styles フォルダーの下に nav-footer.less という名前の新しいファイルを作成します。
-
/* WKND Navigation Footer Style */ @footer-color: #fff; .cmp-navigation--footer { .cmp-navigation { width: 100%; text-align: center; float: left; margin-top: 3em; .cmp-navigation__group { margin-top:2em; margin-left:2em; margin-right: 2em; .cmp-navigation__item { float:left; display: block; .cmp-navigation__item-link { font-size: @font-size-xsmall; text-transform: uppercase; color: @footer-color; height:6em; width: 10em; text-align: center; text-decoration: none; padding-top: 4em; float:left; &:hover, &:focus { background-color: @brand-primary; color: @text-color; } } } li.cmp-navigation__item--active .cmp-navigation__item-link { background-color: rgba(255, 233, 0, 0.4); color: @brand-primary; } @media (max-width: @screen-medium) { margin-top: 2em; } } } }
-
/* main.less */ ... /* Component Styles */ @import "components/breadcrumb/breadcrumb.less"; @import "components/contentfragment/contentfragment.less"; @import "components/header/header.less"; @import "components/image/image.less"; @import "components/layout-container/layout-container.less"; @import "components/list/list.less"; /* import navigation.less */ @import "components/navigation/navigation.less"; @import "components/text/text.less"; @import "components/title/title.less";
-
記事テンプレートでフッターレイアウトコンテナを作成する
- 記事テンプレート(http://localhost:4502/editor.html/conf/wknd/settings/wcm/templates/article-page-template/structure.html)に移動します。
- 新しいレイアウトコンテナを、最後のレイアウトコンテナとなるようドラッグします(ヘルプが必要な場合は、固定幅コンテナの外側にあるコンポーネントツリーを使用します)。
-
ランディングテンプレートを使用して上記の手順を繰り返します(http://localhost:4502/editor.html/conf/wknd/settings/wcm/templates/landing-page-template/structure.html)。
WKND フッターおよび WKND ナビゲーション - フッターポリシーをそれぞれのコンポーネントで再使用できる必要があります。

-
ヘッダーダイアログを更新する
ダイアログ(スパナアイコン)は、作成者がコンテンツを変更するために使用します。ここまで、core コンポーネントのスタイルを設定しており、定義済みのダイアログに依存しています。このダイアログでは、ユーザーは WKND ロゴとリンクさせるようルートパスを設定することができます。
- /apps/wknd/components/structure/header の下で、cq:dialog を編集します。
- xml を直接編集する方法が最も簡単なので、aem-guides-wkind.ui.apps/src/main/content/jcr_root/apps/wknd/components/structure/header/_cq_dialog/.content.xml を開きます。
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured" jcr:title="Header" sling:resourceType="cq/gui/components/authoring/dialog"> <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <tabs jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/tabs" maximized="{Boolean}true"> <items jcr:primaryType="nt:unstructured"> <header jcr:primaryType="nt:unstructured" jcr:title="Header Settings" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns" margin="{Boolean}true"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <rootpath jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/pathfield" fieldDescription="Populate the link of the WKND logo" fieldLabel="Root Path" name="./rootPath" rootPath="/content/wknd"/> </items> </column> </items> </header> </items> </tabs> </items> </content> </jcr:root>
-
ヘッダーデザインダイアログ(ポリシー)を更新する
デザインダイアログを使用すると、ユーザーはコンポーネントのポリシーを更新できます。ポリシーはテンプレート間で適用できるので、テンプレート間で再使用される構造的なコンポーネントを操作する場合には、ポリシーを使用すると便利です。
ヘッダーデザインダイアログを作成すると、ユーザーはポリシー経由でルートパスを WKND ロゴにリンクさせるよう設定できます。
- /apps/wknd/components/structure/header の下で、名前が cq:design_dialog 、タイプが nt:unstructured の新しいノードを作成します。
- xml を直接編集する方法が最も簡単なので、/wknd-sites-guide.ui.apps/src/main/content/jcr_root/apps/wknd/components/structure/header/_cq_design_dialog/.content.xml を開きます。
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured" jcr:title="Navigation" sling:resourceType="cq/gui/components/authoring/dialog"> <content granite:class="cmp-navigation__editor" jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <tabs jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/tabs" maximized="{Boolean}true"> <items jcr:primaryType="nt:unstructured"> <properties jcr:primaryType="nt:unstructured" jcr:title="Properties" sling:resourceType="granite/ui/components/coral/foundation/container" margin="{Boolean}true"> <items jcr:primaryType="nt:unstructured"> <rootpath jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/pathfield" fieldDescription="Populate the link of the WKND logo" fieldLabel="Root Path" name="./rootPath" rootPath="/content/wknd"/> </items> </properties> <styletab jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/include" path="/mnt/overlay/cq/gui/components/authoring/dialog/style/tab_design/styletab"/> </items> </tabs> </items> </content> </jcr:root>
-
header.html script を更新してナビゲーションコンポーネントや検索コンポーネントを含める
- /apps/wknd/components/structure/header/header.html を更新します。
<!--/* Header Component for WKND Site */--> <header class="wknd-header"> <div class="container"> <a class="wknd-header-logo" href="${properties.rootPath || currentStyle.rootPath @ extension='html'}">WKND</a> <div class="cmp-search--header" data-sly-resource="${'search' @ resourceType='wknd/components/structure/search'}"></div> <div class="cmp-navigation--header" id="header-navbar" data-sly-resource="${'navigation' @ resourceType='wknd/components/structure/navigation'}"></div> </div> </header>
スニペット ${properties.rootPath || currentStyle.rootPath @ extension='html'}
ダイアログまたはデザインダイアログから、作成者が選択したパスを挿入します。最初に rootPath のプロパティ値が存在するか(ダイアログ)を確認した後、フォールバックして currentStyle で rootPath の値を確認します(デザインダイアログ)。
properties と currentStyle は両方とも、すべてのコンポーネント HTL スクリプトで利用可能な Global Objects です。
スニペット data-sly-resource="${'search' @ resourceType='wknd/components/structure/search'}" には検索コンポーネントが含まれ、search という名前のヘッダーの下でリソースとしてこれを検索します。
ナビゲーションコンポーネントも同じ方法( data-sly-resource="${'navigation' @ resourceType='wknd/components/structure/navigation'}")で含められます。
これは HTL ブロックステートメントの例です。詳細はこちらを参照してください。
-
cq:template を追加する
複合コンポーネントを作成する場合は常に、JCR で埋め込みコンポーネントまたはサブコンポーネントに実際の nodes/resources が作成されるよう、cq:template を作成するのがベストプラクティスです。サブコンポーネントにマッピングする間違ったコードがあった場合、保存するとダイアログやポリシーで異常な動作が発生する可能性があります。
/apps/wknd/components/structure/header の下で、- 名前が cq:template、タイプが nt:unstructured の新しいノードを作成します。
- 編集を容易におこなうために、.content.xml を開きます。
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured"> <navigation jcr:primaryType="nt:unstructured" sling:resourceType="wknd/components/structure/navigation"/> <search jcr:primaryType="nt:unstructured" sling:resourceType="wknd/components/structure/search"/> </jcr:root>
-
ヘッダーでナビゲーション用の新しいスタイルを追加する
次に、ヘッダーでナビゲーションコンポーネント用に新しいスタイルを追加します。
/apps/wknd/clientlibs/clientlib-site/components/navigation/styles の下で、次の手順をおこないます。
- nav-header.less という名前の新しいファイルを作成します。
- 以下のように記述します。
/* WKND Navigation Header styles */ @mobile-nav-bg-color: #000; @mobile-nav-link-color: #fff; .cmp-navigation--header { float:right; padding-top: .25em; min-width: 100px; margin-right: 0.25em; margin-left: 0.25em; .cmp-navigation { float:right; .cmp-navigation__group { list-style: none; margin:0; } .cmp-navigation__item { display: block; float: left; } .cmp-navigation__item-link { color: @text-color; font-size: @font-size-medium; text-transform: uppercase; font-weight: bolder; padding: 15px 17px; text-decoration: none; &:hover, &:focus { background-color: @brand-primary; } } .cmp-navigation__item--active .cmp-navigation__item-link { background-color: @brand-primary; } } @media (max-width: @screen-medium) { display:none; } }
nav-header.less ファイルを含めるよう /apps/wknd/clientlibs/clientlib-site/components/navigation/navigation.less を更新します。
/* WKND navigation styles */ @import (once) "styles/nav-footer.less"; @import (once) "styles/nav-header.less";
-
/* WKND Search Header styles */ @search-width: 165px; @search-width-expand: 265px; @search-width-mobile: @search-width /2; @search-width-mobile-expand: @search-width; .cmp-search--header { float: right; margin-right: -12px; padding-right: @gutter-padding; .cmp-search { &__form { .cmp-search__icon { top: 0.7rem; } .cmp-search__clear-icon { top: 0.7rem; } .cmp-search__input { background-color: #ebebeb8a; color:@text-color; font-size: @font-size-medium; border-radius: 0px; border:none; height:40px; width:@search-width; padding-right: 2rem; padding-left: 1.8rem; transition: ease-in-out, width .35s ease-in-out; &:focus { background-color: @body-bg; outline: none !important; border:1px solid @text-color; box-shadow: none; width: @search-width-expand; } &::placeholder { text-transform: uppercase; } @media (max-width: @screen-small) { width: @search-width-mobile; &:focus { width: @search-width-mobile-expand; } } } } .cmp-search__results { margin-top: 0.5em; background: @gray-dark; a.cmp-search__item { color: @brand-third; font-size: @font-size-small; height: 50px; text-overflow: ellipsis; padding: 0.5em; margin-top:0.25em; } a.cmp-search__item:hover { text-decoration:none; background: @gray-base; } .cmp-search__item-mark { background: @gray-base; color: @brand-third; } } } @media (max-width: @screen-medium) { .cmp-search__input { height:50px; } } @media (max-width: @screen-small) { margin-right: 1em; position: absolute; right: 0; z-index: 100; margin-top: 0.25em; } }
-
/* main.less */ ... /* Component Styles */ @import "components/breadcrumb/breadcrumb.less"; @import "components/contentfragment/contentfragment.less"; @import "components/header/header.less"; @import "components/image/image.less"; @import "components/layout-container/layout-container.less"; @import "components/list/list.less"; @import "components/navigation/navigation.less"; /* import search styles */ @import "components/search/search.less"; @import "components/text/text.less"; @import "components/title/title.less";
http://localhost:4502/editor.html/conf/wknd/settings/wcm/templates/article-page-template/structure.html で、navigation および search を含むヘッダーコンポーネントが表示されているはずです。
ただし、コンポーネントを設定するには、その前に削除してから再度追加する必要があります。これは、ヘッダーコンポーネントは「複合」コンポーネントとなり、navigation コンポーネントと search コンポーネントが埋め込まれているためです。正常に機能させるためには、search ノードと navigation ノードをテンプレート構造に追加する必要があります。以前設定した cq:template は、適切なノード構造が作成されるようにします。
ヘッダー設定の大まかな手順:
- CRXDE-Lite で記事ページテンプレートとランディングページテンプレートからヘッダーノードを削除します。
- 記事ページテンプレートにヘッダーコンポーネントを再度追加します。
- ヘッダーコンポーネントでナビゲーションコンポーネントを設定します。
- ヘッダーコンポーネントで検索コンポーネントを設定します。
- ランディングページテンプレートで手順 2~4 を繰り返し、ナビゲーションおよび検索ポリシーを再使用します。
以下のビデオでは、これらの大まかな手順を説明します。
この時点では、AEM スタイルシステムを使用し、core コンポーネントで作成された既存のマークアップのスタイルを設定します。LESS および CSS はコンポーネントの表示を変える非常に強力なツールですが、要件によっては制限があります。また、読み込んだ後で core コンポーネントのマークアップを操作するために、JavaScript を使用することもできます。このようにすると、コンポーネントのマークアップの目的を変更して別の方法で使用することができますが、バックエンドコードを変更する必要はありません。
モバイルナビゲーションの場合は、左側からナビゲーションがポップアウトし、ページの本文を画面から「押し出す」のが理想的です。ヘッダーコンポーネントのナビゲーションの位置はネストされているので、CSS 単体でこのビヘイビアーを実現することはできません。代わりに、短い Javascript を使用してヘッダーナビゲーションマークアップのコピーを作成し、本文タグに追加します。これにより、モバイルナビゲーションの視覚効果を作成できるようになります。

-
モバイルナビゲーションに新しいスタイルを追加する
/apps/wknd/clientlibs/clientlib-site/components/navigation/styles の下で、次の手順をおこないます。
- nav-mobile.less という名前の新しいファイルを作成します。
- 以下のように記述します。
/* WKND Navigation - Mobile */ @nav-item-mobile-top-level-color: #fff; @nav-item-mobile-hover-color: @brand-primary; @nav-item-mobile-text-color: #888; @nav-item-mobile-border : solid 1px rgba(255, 255, 255, 0.05); .cmp-navigation--mobile { .cmp-navigation__group { list-style: none; display: inline-block; margin: 0; padding: 0; } .cmp-navigation__item { display: inline-block; float: left; width: 100%; } .cmp-navigation__item-link { display: block; color: @nav-item-mobile-text-color; text-decoration: none; height: 44px; line-height: 44px; border-top: @nav-item-mobile-border; padding: 0 1em 0 1em; &:hover { color: @nav-item-mobile-hover-color; } } .cmp-navigation__item--level-0, .cmp-navigation__item--level-1 { > .cmp-navigation__item-link { color: @nav-item-mobile-top-level-color; &:hover { color: @nav-item-mobile-hover-color; } } } .cmp-navigation__item--level-2 { padding-left: 2em; } .cmp-navigation__item--level-3 { padding-left: 4em; } } #mobileNav, #toggleNav { display: none; } /*Styles to push mobile nav into view */ @media (max-width: @screen-medium) { .root.responsivegrid { -moz-backface-visibility: hidden; -webkit-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden; -moz-transition: -moz-transform 0.5s ease; -webkit-transition: -webkit-transform 0.5s ease; -ms-transition: -ms-transform 0.5s ease; transition: transform 0.5s ease; padding-bottom: 1px; } #toggleNav { -moz-backface-visibility: hidden; -webkit-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden; -moz-transition: -moz-transform 0.5s ease; -webkit-transition: -webkit-transform 0.5s ease; -ms-transition: -ms-transform 0.5s ease; transition: transform 0.5s ease; display: block; height: 44px; left: 0; position: fixed; top: 6px; width: 40px; z-index: 10001; border-top-right-radius: 2px; border-bottom-right-radius: 2px; } .scrolly { #toggleNav { background: #edededa8; } } #toggleNav .toggle { width: 80px; height: 60px; font-size: 40px; color: @text-color; &:hover { text-decoration:none; color: @text-color; } } #mobileNav { -moz-backface-visibility: hidden; -webkit-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden; -moz-transform: translateX(-275px); -webkit-transform: translateX(-275px); -ms-transform: translateX(-275px); transform: translateX(-275px); -moz-transition: -moz-transform 0.5s ease; -webkit-transition: -webkit-transform 0.5s ease; -ms-transition: -ms-transform 0.5s ease; transition: transform 0.5s ease; display: block; height: 100%; left: 0; overflow-y: auto; position: fixed; top: 0; width: 275px; z-index: 10002; color: #858484; background: #000; box-shadow: inset -3px 0px 5px 0px rgba(0, 0, 0, 0.35); } body.navPanel-visible { overflow-x: hidden; .root.responsivegrid { -moz-transform: translateX(290px); -webkit-transform: translateX(290px); -ms-transform: translateX(290px); transform: translateX(290px); } #toggleNav { -moz-transform: translateX(275px); -webkit-transform: translateX(275px); -ms-transform: translateX(275px); transform: translateX(275px); } #mobileNav { -moz-transform: translateX(0); -webkit-transform: translateX(0); -ms-transform: translateX(0); transform: translateX(0); } } }
モバイルナビゲーションの範囲はcmp-navigation--mobile クラスで設定されます。モバイルナビゲーションの開閉動作には、複数の CSS 変形ルールが使用されています。
最後に、/apps/wknd/clientlibs/clientlib-site/components/navigation/navigation.less を更新し、nav-mobile.less ファイルが含まれるようにします。
/* WKND navigation styles */ @import "styles/nav-footer.less"; @import "styles/nav-header.less"; @import "styles/nav-mobile.less";
-
モバイルナビゲーション用の JavaScript を作成する
/apps/wknd/clientlibs/clientlib-site/components/navigation の下で、次の手順をおこないます。
- navigation.js という名前の新しいファイルを作成します。
- 以下のように記述します。
// Wrap bindings in anonymous namespace to prevent collisions jQuery(function($) { "use strict"; function applyComponentStyles() { //Top Level Navigation (expected to only be one of these) $("#header-navbar .cmp-navigation").not("[data-top-nav-processed='true']").each(function() { // Mark the component element as processed to avoid the cyclic processing (see .not(..) above). var nav = $(this).attr("data-top-nav-processed", true), $body = $('body'); // Toggle Nav $('<div id="toggleNav">' + '<a href="#mobileNav" class="toggle"><i class="wkndicon wkndicon-ico-bm" aria-hidden="true"></i></a>' + '</div>' ).appendTo($body); // Navigation Panel. $( '<div id="mobileNav" class="cmp-navigation--mobile">' + '<nav class="cmp-navigation">' + $(this).html() + '</nav>' + '</div>' ) .appendTo($body) .panel({ delay: 500, hideOnClick: true, hideOnSwipe: true, resetScroll: true, resetForms: true, side: 'left', target: $body, visibleClass: 'navPanel-visible' }); }); } applyComponentStyles(); $(".responsivegrid").bind("DOMNodeInserted", applyComponentStyles); });
上記のコードは、responsivegrid が DOM に追加されたときに呼び出されます。最初の jQuery セレクターはヘッダーでナビゲーションを探します。ナビゲーションの数は 1 つであることが想定されます。AEM エディター経由でコンポーネントが追加された場合に備え、処理の重複を防ぐ大まかなチェックがおこなわれます。
次に、アンカータグが本文に追加されます。ユーザーはこれをクリックすることでモバイルナビゲーションを切り替えます。その後、ヘッダーナビゲーションは ID が mobileNav、クラスが cmp-navigation--mobile の新しい div にコピーされます。これはモバイルナビゲーションであり、本文に追加されます。
最後に、モバイルナビゲーションの表示を切り替えるパネル機能が追加されます。このパネルの機能はサードパーティのユーティリティファイルで定義されます。
-
サードパーティ util.js を追加する
次に、https://html5up.net/ から変更されたサードパーティ javascript ファイルを追加し、モバイルナビゲーションでのクリックおよびスワイプに対応できるようにします。
/apps/wknd/clientlibs/clientlib-site の下で、次の手順をおこないます。
- js という名前の新しいフォルダーを作成します。
- js フォルダーの下に、util.js という名前の新しいファイルを作成します。
- 次の util.js を使用して設定します
(コードスニペットが非常に長くなるので、GitHub へのリンクを含めています)。
行き詰まったり、追加の質問がある場合は、AEM 用 Experience League フォーラムを確認するか、既存の GitHub の問題を参照してください。
探していた情報が見つからなかった場合やエラーが見つかった場合は、WKND プロジェクトの問題として GitHub で報告してください。
チュートリアルの次のパート:
- AEM Sites の概要(第 6 章)- 署名テスト
- 完了したコードを GitHub で参照するか、チュートリアルのこのパートで完了したパッケージをダウンロードしてください。
ダウンロード