対応バージョン
Liferay DXP SP1以降 / Liferay 7 CE
はじめに
プロジェクトの要件で、Liferayの上部に表示される管理ナビゲーションバー(Control Menu)の表示を制御したいという要件は多くある。その場合の対応方法を説明する。
公式ドキュメント:THEME CONTRIBUTORS
公式ドキュメント:CONTEXT CONTRIBUTORS
に対応方法の説明が載っているが、実際のポートレットの作成方法をここに説明する。
前提条件
Liferay workspaceは作成されていて、bladeツール、Theme作成ツール各種はインストールされている前提とする。以下の資料でセットアップ方法は説明している。
テストシナリオとして、Liferayの標準ロール、Administrator権限があるユーザーにのみControl Menuを表示させる、という仕様で実装する。
Template context contributorの作成
$(liferay_workspace)/modulesの下に移動。
そこでControl Menuのバンドルを置換するためのTheme contributerを作成する必要がある。Liferay Developer Studio / IDEの File -> New -> Liferay Module Projectを選択、Project Template Nameでtemplatecontextcontributorを選択。
もしくはコマンドラインで
blade create -t template-context-contributor -p com.liferay.product.navigation.control.menu.theme.contributor -c SampleProductNavigationControlMenu sample-product-navigation-control-menu-theme-contributor
でbladeツールを使ってモジュールプロジェクトを作成する。
SampleProductNavigationControlMenuTemplateContextContributorの作成
Control Menuのベースとなるファイルを開く
vi /liferay-portal/modules/apps/web-experience/product-navigation/product-navigation-control-menu-theme-contributor/src/main/java/com/liferay/product/navigation/control/menu/theme/contributor/internal/ProductNavigationControlMenuTemplateContextContributor.java
以下の部分をSampleProductNavigationControlMenuTemplateContextContributor.javaにコピーする。
@Override
public void prepare(
Map<String, Object> contextObjects, HttpServletRequest request) {
boolean isShowControlMenu = isShowControlMenu(request);
contextObjects.put("isShowControlMenu", String.valueOf(isShowControlMenuFlg));
}
protected boolean isShowControlMenu(HttpServletRequest request) {
ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
WebKeys.THEME_DISPLAY);
if (themeDisplay.isImpersonated()) {
return true;
}
if (!themeDisplay.isSignedIn()) {
return false;
}
User user = themeDisplay.getUser();
if (!user.isSetupComplete()) {
return false;
}
return true;
}
次に、標準ロールのAdministrator権限がある場合にのみ表示を絞る、またその表示条件をTheme側に出力する変数をセットする処理を追加すると、以下のようになる。
@Override
public void prepare(
Map<String, Object> contextObjects, HttpServletRequest request) {
//Theme側でメニューの表示非表示を判断できるようにするための変数を書き込む。
boolean isShowControlMenu = isShowControlMenu(request);
contextObjects.put("isShowControlMenu", String.valueOf(isShowControlMenu));
}
protected boolean isShowControlMenu(HttpServletRequest request) {
ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
WebKeys.THEME_DISPLAY);
if(!isAdmin(request)) {
return false;
}
if (themeDisplay.isImpersonated()) {
return true;
}
if (!themeDisplay.isSignedIn()) {
return false;
}
User user = themeDisplay.getUser();
if (!user.isSetupComplete()) {
return false;
}
return true;
}
/**
* Extra check for test
*
* @param request
* @return
*/
protected boolean isAdmin(HttpServletRequest request) {
ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
WebKeys.THEME_DISPLAY);
boolean bRet = false;
try {
//管理者権限がある時のみ表示したい。
//ここでは説明的にわかりやすように、文字列でロールを取得しているが、実プロジェクトではロールIDを使うようにする方がよいかもしれない。
//(実プロジェクトでは管理者のロール名が変更される可能性もあるので。ロールIDがDB毎に変わる可能性がある場合は、Administratorなどの文字列をキーにする方がいいケースもある。)
Role adminRole = RoleLocalServiceUtil.getRole(themeDisplay.getCompanyId(), "Administrator");
List<Role> roles = themeDisplay.getUser().getRoles();
for(Role role : roles) {
if(role.getName().equals(adminRole.getName())) {
bRet = true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return bRet;
}
次に、bnd.bndファイルを以下のように変更する。
Bundle-SymbolicName: sampleproductnavigationcontrolmenutemplatecontextcontributor
Bundle-Version: 2.0.6
Liferay-Releng-Module-Group-Description:
Liferay-Releng-Module-Group-Title: Product Navigation
Liferay-Theme-Contributor-Type: product-navigation-control-menu
Web-ContextPath: /product-navigation-control-menu-theme-contributor
Bundle-Version、Liferay-Theme-Contributor-Type、Web-ContextPathは現行のDXPに含まれているProductNavigationControlMenuTemplateContextContributor.javaのbnd.bndをコピーする。
これでTheme Contributorの準備ができたので、
blade deploy
でデプロイ、続いてThemeの作成を行う。
Themeの作成
$(liferay_workspace)/themesディレクトリに移動し、Liferay CEのクラシックテーマを持つテーマを作成する。(Liferay 7 / DXPでのテーマの作り方を参照)
以下を変更
<#if isShowControlMenuFlg>
css_class = css_class?replace("has-control-menu", "")
css_class = css_class?replace("open", "")
</#if>
のようにCSSのクラスを変更した上で、
<@liferay.control_menu />
を
<#assign isShowControlMenu = htmlUtil.escape(isShowControlMenu!) />
<#if "true" == isShowControlMenu >
<@liferay.control_menu />
</#if>
に変更、
gulp deploy
でデプロイ。
上記のContributor / Themeをデプロイした場合、Administrator権限をもつユーザーにはControl Menuが表示され、それ以外のユーザーにほ表示されなくなるはず。