Integrating External Applications
ご覧のページは、お客様の利便性のために一部機械翻訳されています。また、ドキュメントは頻繁に更新が加えられており、翻訳は未完成の部分が含まれることをご了承ください。最新情報は都度公開されておりますため、必ず英語版をご参照ください。翻訳に問題がある場合は、 こちら までご連絡ください。

カスタム要素でルーティングを使用する

Liferay DXP 7.4+

カスタム要素クライアント拡張機能は、Liferay のフロントエンド インフラストラクチャを使用して、外部アプリケーションを Liferay プラットフォームに登録し、ウィジェットとしてレンダリングします。 複数のルートを含むアプリケーション (例: React Router) の場合、リモート アプリケーション プロパティを定義して、実行時にウィジェットに使用されるルートを決定できます。 これらのプロパティは、Liferayのリモートアプリケーションメニュー、またはデプロイ後のウィジェットの設定オプションからアプリケーションに設定することができます。

警告

他のタイプのクライアント拡張機能と同様にカスタム要素または IFrame をデプロイすることは、Liferay 7.4 の ベータ機能 です。 このチュートリアルでは、カスタム要素のリモートアプリケーションを異なる方法でデプロイしますが、将来のアップデートまでは、この方法が推奨されます。

このチュートリアルでは、Liferay の create_custom_element.sh スクリプトを使用して基本的な React アプリケーションを作成します。このスクリプトは、 hello-worldhello-foohello-barの 3 つのルートを持つサンプル アプリを生成します。 アプリケーションをコンパイルし、 .js および .css ファイルをホストした後、アプリケーションを Liferay に登録し、ページウィジェットとしてデプロイします。 最後に、それぞれの代替ルートを使用するように設定します。

代替ルートを持つ基本的なカスタム要素リモート アプリケーションを作成し、ルート プロパティを使用してレンダリングされるものを構成します。

カスタム要素クライアントの拡張は、構築、パッケージ化、ホスティングの方法に関係なく、あらゆるテクノロジーを使用できます。 このチュートリアルでは、基本ルーティングを使用したカスタム要素アプリケーションのサンプルのみを提供しています。

create_custom_element.sh を実行するには、最新バージョンの Node.JSNPM、および YARNが必要です。 先に進む前に、これらのツールがインストールされていることを確認してください。

Reactアプリケーションの作成、ビルド、ホスティング

  1. 新しいLiferay DXP 7.4以降のコンテナを起動します。 コンテナが起動する間、次のステップに進むことができます。

    docker run -it -m 8g -p 8080:8080 liferay/dxp:2025.q1.6-lts
    
  2. 別の端末でこのコマンドを実行し、Reactアプリケーションを生成します。

    curl -Ls https://github.com/liferay/liferay-portal/raw/master/tools/create_custom_element.sh | bash -s j1v3-custom-element react
    
  3. アプリケーションが正常に作成されたことを確認します。

    スクリプトは、これらの要素で j1v3-custom-element という新しい React アプリケーションを作成します:

    j1v3-custom-element
    ├── node_modules
    ├── README.md
    ├── package.json
    ├── public
    │   └── index.html
    ├── src
    │   ├── common
    │   │   ├── services
    │   │   │   └── liferay
    │   │   │       ├── api.js
    │   │   │       └── liferay.js
    │   │   └── styles
    │   │       ├── hello-world.scss
    │   │       ├── index.scss
    │   │       └── variables.scss
    │   ├── index.js
    │   └── routes
    │       ├── hello-bar
    │       │   └── pages
    │       │       └── HelloBar.js
    │       ├── hello-foo
    │       │   └── pages
    │       │       └── HelloFoo.js
    │       └── hello-world
    │           └── pages
    │               └── HelloWorld.js
    └── yarn.lock
    
  4. 新しい j1v3-custom-element フォルダに移動し、アプリケーションをビルドします。

    cd j1v3-custom-element
    
    yarn build
    
  5. ビルドが成功したことを確認し、アプリケーションの .js.css ファイルをメモしておきます。

    Creating an optimized production build...
    Compiled successfully.
    
    File sizes after gzip:
    
    43.51 kB  build/static/js/main.114dde4a.js
    121 B     build/static/css/main.9877909d.css
    
  6. メールアドレス test@liferay.com とパスワード testを使用して、 <http://localhost:8080> で Liferay にサインインします。 プロンプトが表示されたら、パスワードを learnに変更します。

  7. サイト メニュー (Site Menu) を開き、 コンテンツ & データを展開して、 ドキュメントとメディアに移動します。

  8. 追加 (Add Button) をクリックし、 複数ファイルのアップロードを選択します。

  9. .js.css のファイルをアップロードエリアにドラッグ&ドロップしてください。

    .js と .css ファイルを Liferayドキュメントライブラリにアップロードします。

  10. 公開をクリックします。

これにより、ファイルが Liferay ドキュメント ライブラリに追加され、リモート アプリケーションの作成に使用する一意の WebDAV URL が割り当てられます。

ヒント

このチュートリアルでは、デモンストレーションの目的で、アプリケーションの静的リソースを Liferay のドキュメント ライブラリにホストします。 運用環境では、静的リソースのホスティングに最適化されたサーバー上でアプリケーションのファイルをホストする必要があります。

各ファイルの URL を表示するには、 情報 アイコン (Info Icon) をクリックし、一度に 1 つのファイルを選択します。 各ファイルのWebDAV URLをコピーし、次のステップで使用するために保存してください。

各ファイルのWebDAV URLをコピーします。

例:

  • http://localhost:8080/webdav/guest/document_library/main.114dde4a.js
  • http://localhost:8080/webdav/guest/document_library/main.9877909d.css

アプリケーションの登録とデプロイ

  1. グローバル メニュー (Global Menu) を開き、 アプリケーション タブをクリックして、 リモート アプリに移動します。

  2. 追加 (Add Button) をクリックします。

  3. 次の値を入力します。

    項目
    名前J1V3-Custom-Element
    種類カスタム要素
    HTML 要素名j1v3-custom-element
    URLWebDAV URL for the .js file
    CSS の URL.cssファイルのWebDAV URL
    インスタンス化可能
    ポートレットのカテゴリ名リモートアプリケーション
  4. [保存]をクリックします。

保存すると、LiferayはJ1V3-Custom-Elementという名前のウィジェットを作成し、他のページウィジェットと同様にサイトページにデプロイすることができます。 選択したポートレットカテゴリ名の下に表示されます。

J1V3-Custom-Elementはインスタンス化可能なので、1つのページに多数追加し、それぞれを独立した構成にすることが可能です。 この例では、1つのページに2回ウィジェットを追加します.

J1V3-Custom-Elementウィジェットの2つのインスタンスをデプロイしてください。

routeプロパティを使用する場合

自動生成されたアプリには、3つのルートが含まれています。 hello-worldhello-foohello-barです。 デフォルトでは、アプリケーションは hello-world のルートを使用します。 ただし、リモートアプリケーションのプロパティを使用して、別のルートを使用するように設定することができます。 これらのプロパティは、 リモート アプリ メニュー または ウィジェットの構成オプションから設定できます。

リモートアプリケーションでルートプロパティを定義する

  1. グローバル メニュー (Global Menu) を開き、 アプリケーション タブをクリックして、 リモート アプリに移動します。

  2. J1V3-Custom-Elementを選択します。

    J1V3-Custom-Elementを選択します。

  3. プロパティフィールドにroute=hello-fooと入力します。

    プロパティフィールドにroute=hello-fooと入力します。

  4. 公開をクリックします。

  5. デプロイされた両方のウィジェットがHelloFooルートを使用することを確認します。

    両方のウィジェットがHelloFooルートを使用することを確認します。

ポートレット設定でルートプロパティを定義する

  1. J1V3-Custom-Elementウィジェットを含むページを編集します。

  2. ウィジェット ヘッダーの オプション (Widget Options icon) → 構成をクリックします。

    オプションボタンをクリックし、[設定]を選択します。

    Liferay DXP 2025.Q1/Portal GA132 より前では、設定オプションはウィジェットの右上隅に表示されていました。

  3. プロパティフィールドにroute=hello-barと入力します。

    プロパティフィールドにroute=hello-barと入力します。

  4. [保存]をクリックします。

  5. 設定されたウィジェットがhello-barルートを使用し、もう一方のウィジェットがhello-fooルートを使用したままであることを確認します。

    設定されたウィジェットがHelloBarルートを使用していることを確認します。

ルートコードの分析

import React from 'react';
import {createRoot} from 'react-dom/client';

import api from './common/services/liferay/api';
import {Liferay} from './common/services/liferay/liferay';
import HelloBar from './routes/hello-bar/pages/HelloBar';
import HelloFoo from './routes/hello-foo/pages/HelloFoo';
import HelloWorld from './routes/hello-world/pages/HelloWorld';

import './common/styles/index.scss';

const App = ({route}) => {
	if (route === 'hello-bar') {
		return <HelloBar />;
	}

	if (route === 'hello-foo') {
		return <HelloFoo />;
	}

	return (
		<div>
			<HelloWorld />
		</div>
	);
};

class WebComponent extends HTMLElement {
	constructor() {
		super();
	}

	connectedCallback() {
		createRoot(this).render(
			<App
				route={this.getAttribute('route')}
			/>,
			this
		);

		if (Liferay.ThemeDisplay.isSignedIn()) {
			api('o/headless-admin-user/v1.0/my-user-account')
				.then((response) => response.json())
				.then((response) => {
					if (response.givenName) {
						const nameElements = document.getElementsByClassName(
							'hello-world-name'
						);

						if (nameElements.length) {
							nameElements[0].innerHTML = response.givenName;
						}
					}
				});
		}
	}
}

const ELEMENT_ID = 'j1v3-custom-element';

if (!customElements.get(ELEMENT_ID)) {
	customElements.define(ELEMENT_ID, WebComponent);
}

このindex.jsファイルはWebComponentクラスを作成し、HTMLElementインターフェイスを拡張します。 このクラスは、インターフェースの connectedCallback() 関数を実装します。この関数は、 ReactDOM.render を、 App をパラメーターとして呼び出します。 App が呼び出されると、定義されている "route" 属性がチェックされ、その値が利用可能なルートと比較されます。 hello-fooまたはhello-barのいずれかにマッチする場合、該当するルートを返して描画します。 そうでない場合は、hello-worldを返して描画します。

各ルートは、routesフォルダーからindex.jsファイルにインポートされます。

routes
├── hello-bar
│   └── pages
│       └── HelloBar.js
├── hello-foo
│   └── pages
│       └── HelloFoo.js
└── hello-world
    └── pages
        └── HelloWorld.js

HelloWorld.js

const HelloWorld = () => (
	<div className="hello-world">
		<h1>
			Hello <span className="hello-world-name">World</span>
		</h1>
	</div>
);

HelloFoo.js

const HelloFoo = () => (
	<div className="hello-foo">
		<h1>Hello Foo</h1>
	</div>
);

HelloBar.js

const HelloBar = () => (
	<div className="hello-bar">
		<h1>Hello Bar</h1>
	</div>
);