AEM開発者ブログ by YAMATO

アドビ社のデリバリーパートナー大和株式会社のAEM開発者ブログです。

OverlayとOverrideってどう違うの? - Sling Resource Merger

AEM Developerの皆様、お元気ですか?

大和の蒲生です

今回はSlingフレームワークの軸といっても過言ではないSling Resource Merger1を中心にAEMの基本機能のカスタム手法であるOverlayとコンポーネント開発には欠かせないOverrideのメカニズムについてまとめていきたいと思います!2

AEM開発に携わっていたら、1番と言っていいほど多く利用するこのメカニズムを深く理解する一助になれれば嬉しいです!

ブログの目的

このブログを読むことで、次のことができるようになります。

  • Sling Resource Mergerについて説明する。

  • Sling Resource Mergerが提供する役立つプロパティを列挙する。

  • OverlayとOverrideの違いについて説明する。

  • どうして/libs配下を直接編集してはいけないかの理由について説明する。

  • Overlayの利点を列挙する。

Sling Resource Mergerをしっかり知る

そもそも、AEM上でOverlayとOverrideを可能にしているのが、Sling Resource Mergerなんですが、一体どんなものかというと、

Sling Resource Merger(org.apache.sling.resourcemerger) はSlingフレームワークのbundleの一つで、下記の異なる2つのメカニズムを提供しています。どちらも複数のリソースをマージした状態で見せることを可能にする機能ですが、マージのメカニズムはOverlay とOverrideで異なっています。

  • 検索パス(Resource Search Path)ベースのマージ

こちらがOverlayのマージメカニズムですが、Resource Search Pathの設定値をもとに優先順位を決定し、リソースをマージします。

  • リソースタイプ階層ベースのマージ

こちらがOverrideのマージメカニズムでTouch UIのコンポーネントダイアログ(cq:dialog)に利用でき、sling:resourceSuperTypeで指定した参照先のリソースをマージします。

Resource Picker 3

OverlayのResource Picker

リソース検索パスベースのマージ

機能 マージ後のパス マージの順番
リソース検索パス(Resource Search Path)に従ってマージ /mnt/overlay/<リソースの相対パス> 最後のResource Search Pathがベース (マージ順番はResource Search Pathの降順)

Resource Resolver Factoryの Resource Search Pathとは4

リソース検索パス(Resource Search Path)の設定を行っているbundleです。

Webコンソール > OSGi > ConfigurationでApache Sling Resource Resolver Factoryと検索すると、

下記のOSGi設定画面が開きます。

f:id:yamato_tech:20200608100731p:plain:w700

上記のように、デフォルトでは [ "/apps", "/libs" ]の順番のため、最後のResource Search Pathがベースでマージされるため、同じ内容があった場合、/apps配下の内容のほうが/libsより優先されるのでoverlay先のapps/配下が内容が最終的に表示されるメカニズムになっています。

Resource Search Pathの優先順位を変更するのは推奨されていません。

Overlayのマージメカニズム

下記の例だと、

child1は/apps配下でsling:hideResource = trueになっているため、Overlay後は表示されず、

child2のproperty1は/libsと/appsの両方にあるためマージされ、apps/配下の値になり、

child3のproperty1とproperty2は異なるプロパティ名のため、/libsと/appsが両方保持されます。

f:id:yamato_tech:20200605172747p:plain:w700

OverrideのResource Picker

リソースタイプ階層ベースのマージ

機能 マージ後のパス マージの順番
sling:resourceSuperTypeに従ってマージ /mnt/override/<リソースの絶対パス> 最上位のリソースタイプ(そのリソース自体がsling:resourceSuperTypeを持たないもの)がベース。不特定なものから特定的なもの(継承順位が最上位)の順番でオーバレイされる。

Overrideのマージメカニズム

下記のOverrrideの例だと、

sling:resourceSuperType = "/apps/sling/base"をOverrideしていますが、

child1はsling:hideResource = trueになっているためOverride後は表示されず、

child2の property1は同じプロパティ名のためマージされてOverride元の値が表示され、

child3は異なるプロパティ名のため、Override元のプロパティとOverride先のプロパティの両方が保持されます。

f:id:yamato_tech:20200608101706p:plain:w700

便利なマージプロパティたち

sling:hideProperties (String もしくはString[ ]) 5

指定したプロパティやプロパティの一覧を隠すことができます。

sling:hideResource (Boolean)

指定したリソース、その子も含めて完全に隠されます。

sling:hideChildren (String もしくは String[])

子ノードを隠すことが可能です。 ワイルドカードを使用するとすべてが隠されます。

sling:orderBefore (String)

このプロパティで指定した兄弟ノードの前に自身のノードを挿入することが可能です。

JCRの物理的ノード順番を無視して、指定したノードの前に挿入してくれます。

例えば下記のノード構造があったとき、occupationノードにsling:orderBefore (String) = nameを入れると、

f:id:yamato_tech:20200605173932p:plain:w700

フィールドの並び順はJCRの物理ノードの順番ですが、このsling:orderBefore プロパティによって、occupationフィールドがnameフィールドの前に来ます。

f:id:yamato_tech:20200605174036p:plain:w700

Overlayの方法6

AEMの基本UIや基本機能をカスタムする手法です。

/libs配下にある製品コードを/apps配下にコピーしてきて、カスタムしたい内容をオーバレイしてきたノードに変更を加えていきます。

例えば、スタート画面の"Assets"を"Images"に変えたい場合、

下記のように、/libs/cq/core/content/nav/assetsをapps配下にOverlayし、

f:id:yamato_tech:20200605172014p:plain:w700

Overlayしたjcr:titleを"Images"に変更すると、Overlayによって"Assets"タイトルが変更されます。

f:id:yamato_tech:20200605172141p:plain:w700

下記のように"Images"に変わりました!

f:id:yamato_tech:20200605172237p:plain:w700

/libs配下を直接編集してはいけない理由

そもそも、AEMの基本機能をカスタムする際にOverlayが必要な理由ってご存じでしょうか?

/libs配下を直接編集してはいけない理由は下記のアクションでカスタム編集した内容が消されてしまう可能性があるからなんです。

  1. インスタンスのアップグレード

  2. ホットフィックス適応

  3. 機能パック適応

Overlayの利点

/libs配下を直接編集せずに Overlayをすることには下記の利点もあります。

  1. 変更箇所の追跡が簡単

  2. 移行しやすい

  3. バックアップをとりやすい

  4. カスタム箇所のデバックが行いやすい

Overrideの方法

画像コンポーネントを新規プロジェクトのために開発したい場合、/apps/core/wcm/components/image/v2/imageのコアコンポーネントをsling:resourceSuperTypeでOverrideをしてプロジェクト用に拡張します。

f:id:yamato_tech:20200608111348p:plain:w700

しかし、画像コンポーネントにあるキャプションフィールドはオーサリング時に入力してほしくないという要件があった場合、 Sling Resource Mergerのsling:resourceHide={Boolean}trueを利用することで要件の実現が可能です。

/apps/yamato/components/content/image/cq:dialog/content/items/tabs/items/metadata/items/columns/items/column/items/captionGroupに下記のようにsling:resourceHide={Boolean}trueを入れると、

f:id:yamato_tech:20200608110936p:plain:w700

キャプショングループのプロパティフィールドが下記のように隠れます。

f:id:yamato_tech:20200608111033p:plain

というわけで今回はAEM開発者にとってキーポイントであるSling Resource Mergerのコンセプトについてまとめました!

最後まで読んでいただきありがとうございます

またお会いしましょう~