モジュール言語翻訳の上書き
Liferay DXP 7.4 U4/Portal 7.4 GA8+の場合、 言語オーバーライドツール の使用が推奨されます。
特定のアプリケーションで言語翻訳を上書きすることは、グローバル言語翻訳を上書きすることと似ています。
モジュール言語ファイルの検証
Liferay DXP 2025.Q1+/ポータル GA132+
Liferay 7.4 の初期バージョンの場合は、 言語プロパティによるグローバル言語翻訳の上書きの手順に従ってください。 Liferay の以前のバージョンの場合は、 モジュール翻訳のオーバーライドを使用してください。
モジュールの言語翻訳をオーバーライドするには、まず Gogo シェルでモジュールに関する情報を収集する必要があります。 たとえば、ブログモジュールの言語ファイルをオーバーライドする場合は、grepでキーワードblogsを使用します。 Gogoコマンドと出力は次のようになります。
g! lb | grep Blogs
Output
418|Active | 10|Liferay Collaboration - Liferay Blogs - API (1.0.0)|1.0.0
419|Active | 10|Liferay Blogs API (6.4.5)|6.4.5
420|Active | 10|Liferay Blogs Item Selector API (4.0.5)|4.0.5
421|Active | 10|Liferay Blogs Recent Bloggers API (4.0.5)|4.0.5
570|Active | 10|Liferay Adaptive Media Blogs Editor Configuration (4.0.5)|4.0.5
571|Active | 10|Liferay Adaptive Media Blogs Item Selector Web (4.0.5)|4.0.5
572|Active | 10|Liferay Adaptive Media Blogs Web (4.0.9)|4.0.9
573|Resolved | 10|Liferay Adaptive Media Blogs Web Fragment (4.0.6)|4.0.6
671|Active | 15|Liferay Sharing Blogs (2.0.6)|2.0.6
1126|Active | 10|Liferay Collaboration - Liferay Blogs - Impl (1.0.0)|1.0.0
1127|Active | 10|Liferay Blogs Editor Configuration (4.0.8)|4.0.8
1128|Active | 15|Liferay Blogs Item Selector Web (5.0.9)|5.0.9
1129|Active | 10|Liferay Blogs Layout Prototype (5.0.8)|5.0.8
1130|Active | 10|Liferay Blogs Reading Time (3.0.11)|3.0.11
1131|Active | 15|Liferay Blogs Recent Bloggers Web (5.0.11)|5.0.11
1132|Active | 10|Liferay Blogs Service (4.0.24)|4.0.24
1133|Active | 10|Liferay Blogs UAD (5.0.6)|5.0.6
1134|Active | 15|Liferay Blogs Web (5.0.36)|5.0.36
true
モジュールのID番号をメモします。 バンドルのヘッダーのリストを取得するには、headersコマンドを使用します。 この場合は、Liferay Blogs Webモジュールの1134です。
g! headers 1134
Output
Bundle headers:
Bnd-LastModified = 1601503219290
Bundle-ManifestVersion = 2
Bundle-Name = Liferay Blogs Web
Bundle-SymbolicName = com.liferay.blogs.web
Bundle-Vendor = Liferay, Inc.
Bundle-Version = 5.0.36
...
Web-ContextPath = /blogs-web
Bundle-SymbolicName、Bundle-Version、およびWeb-ContextPathに注目してください。 /に続くWeb-ContextPath値は、モジュールのコンテクスト名です。
バンドルのシンボリック名またはコンテクスト名を使用して、モジュール固有の言語ファイルを検索します。 モジュールのJARファイルを見つけて、その言語ファイルを調べます。 Liferayは、このモジュールのJARファイルの命名規則に従います。
[bundle symbolic name]-[version].jar
たとえば、Blogs Webバージョン5.0.36モジュールはcom.liferay.blogs.web-5.0.36.jarにあります。
モジュールの場所は次のとおりです。
- Liferayの Nexusリポジトリ
[Liferay Home]/osgi/modules- ソースコードは
liferay-[dxp|portal]/modules/appsにあります。
言語プロパティファイルは、モジュールのsrc/main/resources/contentフォルダにあります Language[xx_XX].propertiesファイルでオーバーライドする言語ファイルを特定します。
さまざまな言語とロケールの言語ファイルは、ファイル名の末尾で識別できます。 たとえば、Language_ja.propertiesは日本語用です。
この例では、デフォルトのAdd Blog Entry言語ファイルをカスタム言語ファイルに変更します。 今度はそれをデプロイします。
新しいLiferay インスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132
http://localhost:8080でLiferayにサインインします。 メールアドレス test@liferay.com とパスワード testを使用してください。 プロンプトが表示されたら、パスワードを learnに変更します。
次に、以下の手順に従います。
-
liferay-e6u7.zipをダウンロードして解凍します。curl https://resources.learn.liferay.com/examples/liferay-e6u7.zip -Ounzip liferay-e6u7.zip -
モジュールのルートから、ビルドおよびデプロイします。
cd liferay-e6u7./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)注このコマンドは、デプロイされたjarをDockerコンテナ上の
/opt/liferay/osgi/modulesにコピーするのと同じです。 -
Liferay Dockerコンテナコンソールでデプロイを確認します。
STARTED com.acme.e6u7.impl_1.0.0 [1650] -
コンテンツ & データ → ブログに移動します。 カーソルを追加アイコン (
) の上に移動します。 メッセージにカスタム言語ファイルが表示されます。
-
チュートリアルコードには、他のロケールの例も含まれています。 たとえば、言語セレクターを使用してブラジルのポルトガル語または日本語を選択すると、カスタム言語ファイルが表示されます。 モジュールは、モジュールに含める各ロケールの言語ファイルをオーバーライドします。

次に、コードがどのように機能するかを確認します。
言語プロパティファイルを作成する
オーバーライドする翻訳ファイルを選択します。 たとえば、このチュートリアルコードは、Add Blog Entry言語ファイルをオーバーライドします。
オーバーライドする言語ファイルを決定したら、モジュールのsrc/main/resources/contentフォルダに言語プロパティファイルを作成します。 ファイルで言語ファイルを定義します。 ファイル名がオーバーライドするロケールと一致していることを確認してください。 たとえば、日本語の場合は、Language_ja.propertiesを使用します。
add-blog-entry=E6U7 ブログの追加
言語リソースバンドルを作成する
モジュールで、オーバーライドするロケールのjava.util.ResourceBundleを拡張するクラスを作成します。 en_USロケールのリソースバンドルクラスの例を次に示します。
@Component(property = "language.id=en_US", service = ResourceBundle.class)
public class E6U7EnglishResourceBundle extends ResourceBundle {
@Override
public Enumeration<String> getKeys() {
return _resourceBundle.getKeys();
}
@Override
protected Object handleGetObject(String key) {
return _resourceBundle.getObject(key);
}
private final ResourceBundle _resourceBundle = ResourceBundle.getBundle(
"content.Language_en_US", UTF8Control.INSTANCE);
}
クラスの_resourceBundleフィールドにはResourceBundleが割り当てられます。 ResourceBundle.getBundleの呼び出しには、2つのパラメーターが必要です。 content.Language_en_USパラメーターは、モジュールのsrc/main/resources/contentフォルダに対する言語ファイルの修飾名です。 2番目のパラメーターは、リソースバンドルの言語構文を設定するcontrolです。 Liferayの構文と同じ言語構文を使用するには、Liferayのcom.liferay.portal.kernel.language.UTF8Controlクラスをインポートし、2番目のパラメーターをUTF8Control.INSTANCEに設定します。
クラスの@Componentアノテーションは、それをOSGi ResourceBundle サービスコンポーネントとして宣言します。 そのlanguage.idプロパティは、en_USロケール用にそれを指定します。
@Component(property = "language.id=en_US", service = ResourceBundle.class)
クラスは次のメソッドをオーバーライドします。
handleGetObject:モジュールのリソースバンドル(モジュールの言語プロパティファイルに基づく)で言語ファイルを検索し、キーの値をObjectとして返します。
getKeys: リソースバンドルのキーの 列挙 を返します。
リソース バンドル サービス コンポーネントは、デフォルトの言語翻訳をモジュールの言語翻訳オーバーライドにリダイレクトします。
注:複数のロケールのモジュール言語ファイルをオーバーライドするには、ロケールごとに個別のリソースバンドルクラスが必要です。 たとえば、このチュートリアルコードには、英語、日本語、ポルトガル語用があります。 各リソースバンドルは、language.idコンポーネントのプロパティ定義と言語ファイルの修飾名パラメーターでロケールを指定する必要があります。 たとえば、日本語ロケールでは次のようになります。
コンポーネント定義:
@Component(property = "language.id=ja", service = ResourceBundle.class)
リソースバンドルの割り当て:
private final ResourceBundle _resourceBundle = ResourceBundle.getBundle(
"content.Language_ja", UTF8Control.INSTANCE);
モジュールのリソースバンドルに優先順位を付ける
ターゲット モジュールでカスタム言語翻訳を使用するには、OSGi マニフェスト ヘッダーでリソース バンドルを指定する必要があります。 最初にモジュールを一覧表示することで、ターゲットモジュールのリソースバンドルよりもそのリソースバンドルを優先させます。 これにより、2つのリソースが集約されます。 チュートリアルモジュールcom.acme.e6u7.implの例では、ターゲットモジュールcom.liferay.blogs.webのリソースバンドルよりもリソースバンドルを優先しています。
Provide-Capability:\
liferay.language.resources;\
module.only=true;\
resource.bundle.base.name="content.Language",\
liferay.language.resources;\
bundle.symbolic.name=com.liferay.blogs.web;\
module.only=true;\
resource.bundle.aggregate:String="(bundle.symbolic.name=com.acme.e6u7.impl),(bundle.symbolic.name=com.liferay.blogs.web)";\
resource.bundle.base.name="content.Language";\
サンプルのProvide-Capabilityヘッダには、次の2つの部分があります。
-
liferay.language.resources;module.only=true;resource.bundle.base.name="content.Language"は、モジュールが基本名content.Languageのリソースバンドルを提供することを宣言します。 -
liferay.language.resources;resource.bundle.aggregate:String=...ディレクティブは、集約するリソース バンドルを含むバンドルのリスト、ターゲット バンドル、ターゲット バンドルのリソース バンドル名、およびこのサービスのランキングを指定します。-
"(bundle.symbolic.name=com.acme.e6u7.impl),(bundle.symbolic.name=com.liferay.blogs.web)": サービスは、バンドルcom.acme.e6u7.implとcom.liferay.blogs.webからリソースバンドルを集約します。 必要な数のバンドルを集約します。 リストされたバンドルは降順で優先されます。 -
bundle.symbolic.name=com.liferay.blogs.web;resource.bundle.base.name="content.Language":com.liferay.blogs.webバンドルのリソースバンドルcontent.Languageを上書きします。 -
module.only=true: これらの言語キーはこのモジュールに固有です。 グローバル翻訳をローカルで上書きすることはできますが、それを共有している他のモジュールは影響を受けません。 -
service.ranking:Long="2": リソースバンドルのサービスランキングは2です。 OSGiフレームワークは、このサービスがcom.liferay.blogs.webのcontent.Languageリソースバンドルを対象とする他のすべてのリソースバンドルサービスを上回る場合、このサービスを適用します。 -
servlet.context.name=blogs-web:ターゲットリソースバンドルはサーブレットコンテキストblogs-webにあります。
-
オーバーライドが表示されない場合は、 Gogo シェル を使用して、競合するリソース バンドル サービスを確認します。 別のサービスのランクのほうが高い可能性があります。 たとえば、集約に com.liferay.blogs.webのリソースバンドルが含まれる競合するリソースバンドルサービスを確認するには、次の Gogo シェルコマンドを実行します。
services "(bundle.symbolic.name=com.liferay.blogs.web)"
言語キー名が同じであれば、DXP 7.4 以降で言語翻訳オーバーライドを引き続き使用できます— /modules/apps/portal-language/portal-language-lang/src/main/resources/content/Language[_xx_XX].properties ファイルを確認してください。 オプションとして、 ResourceBundle クラスを削除し、 bnd.bnd ファイル内の Provide-Capability ヘッダーを、 言語プロパティによるグローバル言語翻訳のオーバーライドで示されているヘッダーに置き換えることで、モジュールを簡素化できます。
結果を検索して、ランキングが高いリソースバンドル集約サービスを探します。
以前のバージョンでのモジュール翻訳の上書き
Liferay DXP 7.4/Portal 7.4 以前
以前のバージョンでは、モジュール固有の言語キーはLanguageResourcesExtenderの代わりにLanguageExtenderを使用し、Liferayはliferay.language.resourcesの代わりにliferay.resource.bundleを使用して翻訳されたキーを自動生成していました。 module.only=trueも使用しません。 例えば、
Bundle-Name: Acme E6U7 Implementation
Bundle-SymbolicName: com.acme.e6u7.impl
Bundle-Version: 1.0.0
Provide-Capability:\
liferay.resource.bundle;\
resource.bundle.base.name="content.Language",\
liferay.resource.bundle;\
bundle.symbolic.name=com.liferay.blogs.web;\
resource.bundle.aggregate:String="(bundle.symbolic.name=com.acme.e6u7.impl),(bundle.symbolic.name=com.liferay.blogs.web)";\
resource.bundle.base.name="content.Language";\
service.ranking:Long="2";\
servlet.context.name=blogs-web