1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Liferay 6.2 のWebコンテンツテンプレートのサンプル

Last updated at Posted at 2018-11-25

#LiferayのWebコンテンツ
Liferayでサイトを構築する際に、必ず使うのがこのWebコンテンツです。LiferayのWebコンテンツは、ユーザーがプログラムの知識がなくとも、構造化されたデータ構造を利用してデータを登録し、構造化されつつも、表示は自由な方法でデータ整形できます。それを実現しているのが、データ構造を定義するストラクチャーと、表示フォーマットを規定するテンプレートです。

今回、事情があって6.2を利用することになったのでそれを記述しておきます。すぐに7.1対応が入るので、その際には7.1バージョンの記事も書く予定です。

AssetPublisherから利用するADTに関しましては、こちらに記事を書きましたので合わせて参照ください。

##推奨テンプレート
バージョン7.1現在、使用可能なテンプレートのフォーマットはVelocityFreemarkerがありますが、組み込み機能の充実と、表記の柔軟性、また近年のバージョンのアップデート状況を鑑みて、Freemarkerの利用を推奨します。

##利用可能な全組み込み変数/クラスの出力方法
LiferayのWebコンテンツ、テンプレート内では、Liferay側が提供している変数やクラスが利用できます。利用できる変数やクラス・メソッドを一覧で確認するためのテンプレートをこのGistに置いてあります。使い方は、

  1. ダミーのストラクチャーを作成する。仮にDump Structureとします。
  2. このコードをWebコンテンツのテンプレートとして登録し、Dump Structureをストラクチャーとして指定します。
  3. Dump Structureを指定してWebコンテンツを作成し、任意のページにWebコンテンツディスプレイポートレットを配置、Dump Strucuterを指定して作成したWebコンテンツを選択します。
  4. 該当のページに配置された、Webコンテンツテンプレートで利用できる変数やクラスの一覧が表示されます。

##組み込みサービスの取得方法
たとえば、よく利用するJournalArticleLocalServiceを使う方法を紹介します。まずはportal-ext.propertiesに以下のプロパティを設定します。

portal-ext.properties
freemarker.engine.restricted.variables=

次に、テンプレートに以下の設定を配置します。

<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleLocalService")>

これでjournalArticleLocalServiceという変数でJournalArticleLocalServiceが利用可能になりました。

##よく使う値の取得方法
####Articleの取得

<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleLocalService")>
<#assign article = journalArticleLocalService.getArticle( groupId, .vars["reserved-article-id"].data )>

####該当Articleのタグの取得

<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.portlet.journal.service.JournalArticleLocalService")>
<#assign article = journalArticleLocalService.getArticle( groupId, .vars["reserved-article-id"].data )>
<#assign resourceprimKey = article.getResourcePrimKey()>
<#assign assetEntryLocalService = serviceLocator.findService("com.liferay.portlet.asset.service.AssetEntryLocalService")>
<#assign assetEntry = assetEntryLocalService.getEntry("com.liferay.portlet.journal.model.JournalArticle", resourceprimKey)>
<#assign tagUtil = serviceLocator.findService("com.liferay.portlet.asset.service.AssetTagLocalService")>
<#assign tags = tagUtil.getAssetEntryAssetTags(assetEntry.getEntryId())>

####コンテンツ作成者名

<#assign author_name = .vars['reserved-article-author-name'].data>

####作成日付

<#setting locale="en_US">
<#assign morg_date = .vars['reserved-article-modified-date'].data>
<#assign morg_date = morg_date?date("EEE, d MMM yyyy HH:mm:ss Z")>
<#assign modified_date = morg_date?string("yyyy-MM-dd")>
<#assign modified_date_print = morg_date?string("yyyy.MM.dd")>
<#setting locale="ja_JP">

settinglocaleを変えているのは、日本語で表示させる場合に、Liferay側の初期化設定によって、日付が日本語設定で返ってくる場合、EEEの部分が水曜なら水、というような感じで、比較元がWedなどの文字列の場合、正しく比較できないことがあります。そのため、一時的に強制的に英語ロケールに変換し、比較が終わったところで日本語(もとの言語)に戻しています。これは複数言語でのポータル運用の場合、対応が難しいケースがあるかとは思います。

####サービスコンテクスト(ServiceContext)

<#assign serviceContext = staticUtil["com.liferay.portal.service.ServiceContextThreadLocal"].getServiceContext()>

####リクエスト(HttpServletRequest)

<#assign serviceContext = staticUtil["com.liferay.portal.service.ServiceContextThreadLocal"].getServiceContext()>
<#assign httpServletRequest = serviceContext.getRequest()>

####テーマディスプレイ(ThemeDisplay)

<#assign serviceContext = staticUtil["com.liferay.portal.service.ServiceContextThreadLocal"].getServiceContext()>
<#assign themeDisplay = serviceContext.getThemeDisplay()>

####ルートポートレットID

<#assign rootPortletId = request["theme-display"]["portlet-display"]["root-portlet-id"]>

これはポートレットIDにはよく、INSTANCEとか、ネームスペースのランダム文字列とかが付与されますが、それらが無い、プレーンなポートレットID(56とか101とか)が入ります。

####各種パス

<#assign
	currentPath = themeDisplay.getURLPortal()
	currentParam = themeDisplay.getURLCurrent()
	currentHome = themeDisplay.getURLHome()
	friendlyURL = layoutLocalService.fetchLayout(themeDisplay.getPlid()).getFriendlyURL(locale)
>
変数 説明
currentPath 現在のポートレットのパスhttp://localhost:8080などが入ります。
currentParam /web/guest/aboutなどが入ります。
currentHome http://localhost:8080/web/guestなどが入ります。
friendlyURL 現在Aboutという名前のページにいる場合、/aboutなどが入ります。

##利用方法サンプル
####タグのループ
上記のタグの取得方法で取得したAssetTagのリストがtagsに入っている、とした場合、

<#list tags as tag>
    <#assign portletURL = portletURLFactory.create(httpServletRequest,rootPortletId,themeDisplay.getPlid(),themeDisplay.getLifecycle())>
    <#assign VOID = portletURL.setParameter("tag", tag.getName()) />
    <#assign VOID = portletURL.setParameter("p_p_lifecycle", "0") />
    <#assign VOID = portletURL.setParameter("p_p_state", "maximized") />
    <li><a href="${portletURL}"><i class="fas fa-hashtag" aria-hidden="true"></i>${tag.getName()}</a></li>
</#list>

となります。利用している変数(themeDisplayなど)は、このページの他の部分を参照ください。

####繰り返しコンテンツ(repeatable)の表示方法
Webコンテンツでは繰り返し(repetable)なコンテンツを作成できます。例えば以下のような構造のストラクチャーを持つWebコンテンツを表示させたい場合、

root
├── blog_sec_rp
│      ├── blog_sec_ttl
│      └── blog_sec_contents
├── blog_sec_rp
│      ├── blog_sec_ttl
│      └── blog_sec_contents
├── blog_sec_rp
│      ├── blog_sec_ttl
│      └── blog_sec_contents
.
.
.
<#if blog_sec_rp.getSiblings()?has_content>
    <#list blog_sec_rp.getSiblings() as blog>
        ${blog.getChild("blog_sec_ttl").getData()}
    </#list>
</#if>

のような表示方法になります。最初に要素があるか確認し、ある場合はループさせて内容を表示させていきます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?