JSPのオーバーライド
OSGi フラグメントを使用して JSP を完全にオーバーライドできます。 このアプローチは強力ですが、ホスト モジュールをアップグレードすると不安定になる可能性があります。
-
JSP 全体をオーバーライドすると、新しいホスト モジュール バージョンに不可欠な新しいコンテンツや新しいウィジェットを考慮しない可能性があります。
-
フラグメントは特定のホスト モジュール バージョンに関連付けられます。 ホスト モジュールがアップグレードされると、フラグメントはそこから切り離されます。 このシナリオでは、元の JSP は引き続き使用可能であり、モジュールは機能します (ただし、JSP 拡張機能は欠落しています)。
-
Liferay では、フラグメントによってオーバーライドされた JSP がアップグレードできることを保証できません。
OSGi フラグメントを使用して JSP をオーバーライドするのは、最後の手段としてのみ行う必要があります。 動的インクルード および ポートレット フィルター は、オーバーライドしても安全な JSP の特定の部分をカスタマイズし、オーバーライドを特定のホスト モジュール バージョンに制限しないため、安定性が向上します。
JSP をオーバーライドする OSGi フラグメントには、次の 2 つが必要です。
-
OSGi ヘッダー
Fragment-Host宣言内のホスト モジュールのシンボリック名とバージョン。 -
Liferay のデフォルトの JSP 上に構築された変更された JSP。
フラグメント モジュールの詳細については、 OSGi Alliance のドキュメントを参照してください。
オーバーライドされたJSPを提供する
ホストのオリジナル JSP を対象とする命名規則には、 ポータル または オリジナルの 2 つがあります。 たとえば、元の JSP がフォルダー /META-INF/resources/login.jspにある場合、フラグメント バンドルには、次のパターンを使用して、同じパスを持つ JSP が含まれている必要があります。
<liferay-util:include
page="/login.original.jsp" (or login.portal.jsp)
servletContext="<%= application %>"
/>
次に、JAR をオーバーライドするときにホスト モジュールのフォルダー構造を模倣するように変更を作成します。 例えば、ログインアプリケーションの login.jsp をオーバーライドする場合は、独自の login.jsp を
my-jsp-fragment/src/main/resources/META-INF/resources/login.jsp
出力を後処理する必要がある場合は、パターンを更新して Liferay DXP のバッファリング メカニズムを含めることができます。 以下は、元の create_account.jspをオーバーライドする例です。
<%@ include file="/init.jsp" %>
<liferay-util:buffer var="html">
<liferay-util:include page="/create_account.portal.jsp"
servletContext="<%= application %>"/>
</liferay-util:buffer>
<liferay-util:buffer var="openIdFieldHtml"><aui:input name="openId"
type="hidden" value="<%= ParamUtil.getString(request, "openId") %>" />
</liferay-util:buffer>
<liferay-util:buffer var="userNameFieldsHtml"><liferay-ui:user-name-fields />
</liferay-util:buffer>
<liferay-util:buffer var="errorMessageHtml">
<liferay-ui:error
exception="<%= com.liferay.portal.kernel.exception.NoSuchOrganizationException.class %>" message="no-such-registrationcode" />
</liferay-util:buffer>
<liferay-util:buffer var="registrationCodeFieldHtml">
<aui:input name="registrationCode" type="text" value="">
<aui:validator name="required" />
</aui:input>
</liferay-util:buffer>
<%
html = com.liferay.portal.kernel.util.StringUtil.replace(html,
openIdFieldHtml, openIdFieldHtml + errorMessageHtml);
html = com.liferay.portal.kernel.util.StringUtil.replace(html,
userNameFieldsHtml, userNameFieldsHtml + registrationCodeFieldHtml);
%>
<%=html %>
フラグメントホストの宣言
カスタム フラグメントは、選択したホスト モジュールの一部としてレンダリングされます。 ホストを選択するには、モジュールの bnd.bndで次の 2 つのことを宣言する必要があります。
-
ホスト モジュールのバンドル シンボリック名。 これは元の JSP を含むモジュールです。
-
フラグメントが属するホスト モジュールの正確なバージョン。
両方とも、OSGiマニフェストヘッダー Fragment-Hostを使用して一緒に宣言されます。
Fragment-Host: com.liferay.login.web;bundle-version="[1.0.0,1.0.1)"
特定のホスト モジュール バージョンを指定することが重要です。 そのバージョンのモジュールが存在しない場合、フラグメントはホストに接続されません。 これは、ホスト モジュールの新しいバージョンによって JSP が変更されている可能性があるため、設計によるものです。 現在互換性のないバージョンの JSP をホスト モジュールに適用すると、ホストの機能が損なわれます。
フラグメントホスト内部パッケージの使用
内部(エクスポートされていない)ホスト パッケージを使用するには、フラグメントで Import-Package: マニフェスト ヘッダーからパッケージを明示的に除外する必要があります。 たとえば、この Import-Package ヘッダーは、 com.liferay.portal.search.web.internal.*に一致するパッケージを除外します。
Import-Package: !com.liferay.portal.search.web.internal.*,*
デフォルトでは、OSGi モジュールはパッケージを Import-Package: ヘッダーに追加するため、手動で除外する必要があります。 エクスポートされていないパッケージを要求しながらフラグメントを開始しようとすると、パッケージが未解決の要件であるため失敗します。 各フラグメントは、すでに内部 (エクスポートされていない) パッケージを含むホスト パッケージに完全にアクセスできます。