類似結果ウィジェットへのカスタムコンテンツの提供
購読者
この機能は、Liferay DXP 7.3 以降にバンドルされているサービスプロバイダーインターフェイス (SPI) に依存しています。 これは、Liferay DXP 7.2 の Fix Pack 5+ で、 Liferay Marketplaceから Similar Results ウィジェットをインストールすることで利用できます。
SimilarResultsContributorを実装することで、アプリケーションのカスタム コンテンツを Similar Results ウィジェット に表示できます。 コントリビューターが機能するには、類似結果ウィジェットがコンテンツをページのメインアセットとして検出できる必要があります。 つまり、サポートされているLiferay DXPアセット(ブログエントリやWikiページなど)のように、「表示ウィジェット」のURLを介して表示できる必要があります。 類似結果ウィジェットは、カスタムコントリビューターを必要とせずに、Lifery DXPのアセットパブリッシャーに表示されるコンテンツですでに使用できることに注意してください。

ナレッジベース(KB)アプリケーションは、すぐにはKB記事の SimilarResultsContributor を実装しないため、このサンプルで実装します。 簡単にするために、ここではアプリケーションのルートフォルダーにあるKB記事のみを扱います。
ナレッジベース記事用のSimilarResultsContributorを導入する
新しいLiferay DXPインスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/dxp:2025.q1.6-lts
メールアドレス test@liferay.com とパスワード testを使用して、 http://localhost:8080 で Liferay にサインインします。 プロンプトが表示されたら、パスワードを learnに変更します。
次に、次の手順に従って、サンプルの SimilarResultsContributor を Liferay DXP インスタンスで起動して実行します。
-
Acme Similar Results Contributorをダウンロードして解凍します。
curl https://resources.learn.liferay.com/examples/liferay-r1s1.zip -Ounzip liferay-r1s1.zip -
モジュールのルートから、ビルドおよびデプロイします。
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)注このコマンドは、デプロイされたjarをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。
-
Liferay Dockerコンテナコンソールでデプロイを確認します。
STARTED com.acme.r1s1.impl_1.0.0 [1009] -
サンプルのコントリビューターが機能していることを確認します。 まず、ブラウザで
https://localhost:8080を開きます。 -
サイト メニュー → コンテンツ → ナレッジ ベースに KB 記事をいくつか追加します。
同様の タイトル と コンテンツ フィールドがあることを確認します。 これらの文字列を使用して、3つの記事を作成できます(タイトルとコンテンツに同じ文字列を使用します)。
KB記事1をテストする
KB記事2をテストする
KB記事3をテストする
-
ナレッジベース表示ウィジェットをページに追加し、続いて類似結果ウィジェットを追加します。
-
類似結果ウィジェットのウィジェット構成を開き、これらの設定に必ず 1 値を設定してください。
最小用語頻度: 1 最小文書頻度: 1
-
KB記事の1つをクリックして、表示するメインアセットとして選択します。
類似結果ウィジェットに、他の関連する KB 記事が表示されるようになりました。

例が適切に動作することを確認したので、それがどのように機能するかを学びます。
SimilarResultsContributorを調べる
デプロイされたサンプルを確認します。 これには、クラスが1つだけ含まれています。これは、類似結果ウィジェットのカスタムコンテンツを有効にするコントリビューターです。
OSGi登録のコントリビュータークラスに注釈を付ける
R1S1SimilarResultsContributor は、 SimilarResultsContributor インターフェースを実装しています。
@Component(service = SimilarResultsContributor.class)
public class R1S1SimilarResultsContributor implements SimilarResultsContributor {
サービス コンポーネントプロパティは、実装を SimilarResultsContributor サービスとして登録します。
SimilarResultsContributor インターフェースを確認する
インターフェースから3つのメソッドを実装します。
public void detectRoute(RouteBuilder routeBuilder, RouteHelper routeHelper);
エンティティのURLパターンの特徴的な部分を提供するために detectRoute を実装して、類似結果ウィジェットがコントリビューターを呼び出す必要があるかどうかを検出できるようにします。 URLパターンは、 RouteBuilder オブジェクトの属性として追加されます。 RouteHelper は、解析のためにURL文字列全体を取得するのに役立ちます。
各表示ウィジェットには、1 つの SimilarResultsContributor のみがサポートされます。
public void resolveCriteria(
CriteriaBuilder criteriaBuilder, CriteriaHelper criteriaHelper);
ページのメインエンティティを使用して対応する検索エンジンドキュメントを検索するには、 resolveCriteria を実装します。 これは、検出されたルートが、コントリビューターが適切なものであることを示している場合に呼び出されます。
public void writeDestination(
DestinationBuilder destinationBuilder,
DestinationHelper destinationHelper);
ユーザーが類似結果ウィジェットのリンクをクリックしたときにメインアセットを更新するには、 writeDestination を実装します。
類似結果のコントリビューターを完了する
detectRoute メソッドを実装する
@Override
public void detectRoute(
RouteBuilder routeBuilder, RouteHelper routeHelper) {
String[] pathParts = StringUtil.split(
_http.getPath(routeHelper.getURLString()),
Portal.FRIENDLY_URL_SEPARATOR);
String[] parameters = StringUtil.split(
pathParts[pathParts.length - 1], CharPool.FORWARD_SLASH);
if (!parameters[0].matches("knowledge_base")) {
throw new RuntimeException(
"Knowledge base article was not detected");
}
routeBuilder.addAttribute("urlTitle", parameters[1]);
}
エンティティのURLパターンの特徴的な部分をチェックするロジックを挿入するには、 detectRoute を実装します。 類似結果ウィジェットはこのチェックを使用して、正しい SimilarResultsContributorを見つけます。 エンティティの表示URLが検出された場合は、後で使用するために少なくとも1つの属性をURLルートに追加します。 ここでは、Friendly URL で "knowledge_base" を確認し、検出された場合はメソッド シグネチャで渡された RouteBuilder に属性として "urlTitle" を追加しています。
routeHelper.getUrlString 呼び出しは、仮想インスタンス内で検出されたアセットの相対URLを取得するために使用できるため、重要です。 例えば、
/web/guest/page-title/-/knowledge_base/kb-article-url-title
RouteBuilderに属性として追加されるIDは、resolveCriteriaメソッドでエンティティと対応する検索エンジンドキュメントをフェッチするために使用されます。 。
resolveCriteria メソッドを実装する
@Override
public void resolveCriteria(
CriteriaBuilder criteriaBuilder, CriteriaHelper criteriaHelper) {
String urlTitle = (String)criteriaHelper.getRouteParameter("urlTitle");
KBArticle kbArticle = _kbArticleLocalService.fetchKBArticleByUrlTitle(
criteriaHelper.getGroupId(),
KBFolderConstants.DEFAULT_PARENT_FOLDER_ID, urlTitle);
if (kbArticle == null) {
return;
}
AssetEntry assetEntry = _assetEntryLocalService.fetchEntry(
criteriaHelper.getGroupId(), kbArticle.getUuid());
if (assetEntry == null) {
return;
}
String uidField = String.valueOf(kbArticle.getPrimaryKeyObj());
if (ReleaseInfo.getBuildNumber() ==
ReleaseInfo.RELEASE_7_2_10_BUILD_NUMBER) {
uidField = String.valueOf(kbArticle.getResourcePrimKey());
}
criteriaBuilder.uid(Field.getUID(assetEntry.getClassName(), uidField));
}
ページに表示されているエンティティに対応する検索エンジンドキュメントを検索します。 criteriaBuilder.uid メソッドに適切な検索エンジンドキュメントの uid フィールドの値を指定する必要があります(これは通常、ドキュメントのElasticsearchで指定された _id フィールドと同じです)。 Liferay DXPインデックスでは、このフィールドはエントリクラス名とクラスプライマリーキーの構成です。 両方を文字列として Field.getUID に渡して値を取得します。 この例では、最初に detectRoute メソッド( urlTitle)で属性に追加したIDを使用してモデルエンティティをフェッチし、それを使用してアセットエントリを取得します。
Liferay DXP 7.2とLiferay DXP 7.3には違いがあるので、バージョンを確認するための条件を、それぞれのロジックで提供しています。 Liferay DXP 7.3 では、 getPrimaryKeyObj がクラス名と組み合わせて使用されますが、Liferay DXP 7.2 では、 getResourcePrimKey が必要です。
一致するドキュメントが見つかったので、同様の結果が更新されるようにリンク先URLを記述します。
writeDestination メソッドを実装する
@Override
public void writeDestination(
DestinationBuilder destinationBuilder,
DestinationHelper destinationHelper) {
String urlTitle = (String)destinationHelper.getRouteParameter(
"urlTitle");
AssetRenderer<?> assetRenderer = destinationHelper.getAssetRenderer();
KBArticle kbArticle = (KBArticle)assetRenderer.getAssetObject();
destinationBuilder.replace(urlTitle, kbArticle.getUrlTitle());
}
ユーザーが類似結果ウィジェットのリンクをクリックしたときにメインアセットを更新するには、 writeDestination を実装します。 その他の類似結果クエリは検索エンジンに再送信され、類似結果リストは新しいメインアセットに一致するように再レンダリングされます。 KB記事の場合、作業全体は、(メインアセットの)元のURLの urlTitle を、一致したエンティティの urlTitle で置き換えることです。
destinationHelper.getRouteParameter 呼び出しが重要です。 検索前演算子である DestinationHelper からの唯一のメソッドとして、メインアセットまたは類似結果リンクを再レンダリングする前に、常に現在選択されているメインアセットからデータを返します。 DestinationHelper メソッドの残りの部分(ここに示されている他のメソッド getAssetRendererを含む)は、一致したアセットのデータを返します。 このメソッドは、一致した結果ごとに繰り返し実行されます。
サービスの依存関係を宣言する
このコードは、OSGiコンテナにデプロイされたサービスに依存しています: AssetEntryLocalService、 KBArticleLocalService、及び のHttp。 org.osgi.service.component.annotations.Referenceによって提供されるDeclarative Services @Reference アノテーションを使用して、それらの必要性を宣言します。 それらを公開フィールドに設定します。
@Reference
private AssetEntryLocalService _assetEntryLocalService;
@Reference
private Http _http;
@Reference
private KBArticleLocalService _kbArticleLocalService;
追加の詳細
エンティティの URL の各実装は大幅に異なる可能性があるので、独自のアプリケーションのコントリビューターを作成するときにさらにヒントが必要な場合は、GitHub の SimilarResultsContributor インターフェース とバンドルされている 実装 を参照してください。
アプリケーションのカスタムコンテンツを類似結果ウィジェットに提供するために必要な作業の多くは、表示URLを使用することです。 Liferay独自のアセットが表示URLを作成する方法を学ぶには、エンティティの * AssetRenderer クラスの getURLView メソッドを調べます。
JournalArticleAssetRenderer#getURLView、Liferay DXP 7.3.2 GA3
WikiPageAssetRenderer#getURLView、Liferay DXP 7.3.2 GA3
BlogsEntryAssetRenderer#getURLView、Liferay DXP 7.3.2 GA3
DLFileEntryAssetRenderer#getURLView、Liferay DXP 7.3.2 GA3
前述のとおり、このサンプルでは、アプリケーションのルートフォルダーにあるKB記事で機能する SimilarResultsModelDocumentContributor を作成する方法を示しています。 KBフォルダーのサポートを追加することは可能であり、やる気のある読者にとって興味深い演習です。 インスピレーションを得るには、 DocumentLibrarySimilarResultsContributor のソース コードを参照してください。
トラブルシューティング:アセットUIDアーキテクチャ
uid は、Liferay DXP 7.3以降の標準的な方法で構築されます。 com.liferay.portal.search.internal.model.uid.UIDFactoryImpl クラスは、Liferayのインデックスアーキテクチャによって制御されているすべてのドキュメントに uid を設定する責任があります。 現在は標準化されているので、推測をする必要はありません。
同様に、バージョン7.2および7.1では、エンティティにComposite Indexer APIでインデックスが付けられている(つまり、ModelDocumentContributor クラスが )場合、 uid はLiferayの実装によって設定され、標準化されます。
ただし、レガシーインデクサーAPIでインデックス付けされたエンティティ(つまり、エンティティにはLiferayの BaseIndexerを拡張する *インデクサー クラスがある)は、 uidを設定するロジックをオーバーライドしている可能性があるため、エンティティのインデックス付けの実装を調べる価値があります。