3
1

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のアセットパブリッシャー用アプリケーション・ディスプレイ・テンプレート(ADT)サンプル

Last updated at Posted at 2018-11-25

本記事はLiferay 6.2 のWebコンテンツテンプレートを使い倒すとペアになる記事です。

##ADT(アプリケーション・ディスプレイ・テンプレート)とは?
LiferayにはAssetPublisher(アセットパブリッシャー)という、デフォルトで組み込まれているWebコンテンツやドキュメントとメディア、ブログやWikiといった様々なデータ形式のデータを、様々な方法でフィルタして一覧表示できるポートレットがあります。

ポータルサイトを作成する際には、対象となるデータに絞り込んだり、タグでフィルタを掛けたりして一覧表示が必ず必要になってきますが、その際にまず必ずといっていいほど利用するポートレットになるかと思います。

##Webコンテンツのテンプレートと、ADTの違い
基本的に同じような変数が利用できるのですが、ADTの方が組み込み関数が充実しており、様々な値の取得が容易です。

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

##利用可能な全組み込み変数/クラスの出力方法
こちらと同様の方法で取得可能です。

##組み込みサービスの取得方法
こちらと同様の方法で取得可能です。

##よく使う値の取得方法
####Webコンテンツ表示系で絶対使うであろう変数

<#assign
	languageId = languageUtil.getLanguageId(locale)
	tagUtil = serviceLocator.findService("com.liferay.portlet.asset.service.AssetTagLocalService")
	serviceContext = staticUtil["com.liferay.portal.service.ServiceContextThreadLocal"].getServiceContext()
	httpServletRequest = serviceContext.getRequest()
	themeDisplay = serviceContext.getThemeDisplay()
	rootPortletId = portletDisplay.getRootPortletId()
	currentPortletURL = renderResponse.createRenderURL()
/>
変数 説明
languageId 現在の表示言語から作成したLocaleオブジェクト
tagUtil AssetTagを利用するためのサービス
serviceContext サービスコンテキスト
httpServletRequest リクエスト
themeDisplay テーマディスプレイ
rootPortletId ルートポートレットID。(例えば"56"などの文字列)
currentPortletURL 現在のページを表示しているURL文字列

####Webコンテンツデータ取得
WebコンテンツのクラスであるJournalArticleからデータを取得してくると、データ構造はXMLとなっています。それをパースするのに以下のようなユーティリティ関数を作成する必要があります。

<#function value_of docXml field language_id>
    <#local default_language_id = docXml.valueOf("/root/@default-locale") />
    <#local value = docXml.valueOf("//dynamic-element[@name='" + field + "']/dynamic-content[@language-id='"+ language_id + "']/text()") />
    <#if !value?has_content>
        <#local value = docXml.valueOf("//dynamic-element[@name='" + field + "']/dynamic-content[@language-id='"+ default_language_id + "']/text()") />
    </#if>
    <#return value />
</#function>

使い方としては以下のような感じになります。Webコンテンツのストラクチャー構造が

root
├── wcm_title
└── wcm_contents

と仮定した場合、(wcm_titleはタイトル用テキストフィールド)

<#assign
    journalArticle = assetRenderer.getArticle()
    docXml = saxReaderUtil.read(journalArticle.getContent())
    wcm_title = value_of(docXml, "wcm_title", languageId)
>

といった形でタイトル部分の文字列が取得できます。

####取得文字列の切り詰め(truncate)
ADTでコンテンツのリスト表示をする際に、よく記事を規定の文字数で切り詰めて、「・・・続きを読む」的な感じの文字列を追加したり、という処理をすることがよくあるかと思います。その処理をするのが以下のユーティリティ関数になります。

<#function truncate field size>
	<#local value = field />
	<#if field?length &lt; size>
		<#local value = field />
	<#else>
		<#local value = field?substring(0,size) + "..." />
	</#if>
	<#return value />
</#function>

以下のような使い方をします。

<#assign
    journalArticle = assetRenderer.getArticle()
    docXml = saxReaderUtil.read(journalArticle.getContent())
    wcm_contents = value_of(docXml, "wcm_contents", languageId)
    truncate_length = 28
    truncated_wcm_contents = htmlUtil.escape(truncate(wcm_contents?replace('<[^>]+>','','r'),truncate_length))
>

Webコンテンツ内のフィールドwcm_contentsから文字列を取得し、それを28文字で区切っています。

####Assetデータ処理サンプル

上記の説明を1つのADTにまとめると、以下のようになります。Webコンテンツのストラクチャー構造が

root
├── wcm_title
└── wcm_contents

と仮定した場合、

<#assign
	languageId = languageUtil.getLanguageId(locale)
	tagUtil = serviceLocator.findService("com.liferay.portlet.asset.service.AssetTagLocalService")
	serviceContext = staticUtil["com.liferay.portal.service.ServiceContextThreadLocal"].getServiceContext()
	httpServletRequest = serviceContext.getRequest()
	themeDisplay = serviceContext.getThemeDisplay()
	rootPortletId = portletDisplay.getRootPortletId()
	currentPortletURL = renderResponse.createRenderURL()
/>

<#function value_of docXml field language_id>
    <#local default_language_id = docXml.valueOf("/root/@default-locale") />
    <#local value = docXml.valueOf("//dynamic-element[@name='" + field + "']/dynamic-content[@language-id='"+ language_id + "']/text()") />
    <#if !value?has_content>
        <#local value = docXml.valueOf("//dynamic-element[@name='" + field + "']/dynamic-content[@language-id='"+ default_language_id + "']/text()") />
    </#if>
    <#return value />
</#function>

<#function truncate field size>
	<#local value = field />
	<#if field?length &lt; size>
		<#local value = field />
	<#else>
		<#local value = field?substring(0,size) + "..." />
	</#if>
	<#return value />
</#function>

<#if entries?has_content>
    <#list entries as entry>
        <#assign
            assetRenderer = entry.getAssetRenderer()
            className = assetRenderer.getClassName()
            entryTitle = htmlUtil.escape(assetRenderer.getTitle(locale))
            entryId = entry.getEntryId()
            tags = entry.getTags()
            viewURL = assetPublisherHelper.getAssetViewURL(renderRequest, renderResponse, entry)
            displayDateFormat = "yyyy.MM.dd"
            tagDateFormat = "yyyy-MM-dd"
            displayDate = dateUtil.getDate(entry.getPublishDate(), displayDateFormat, locale)
            tagDate = dateUtil.getDate(entry.getPublishDate(), tagDateFormat, locale)
        />
            <#-- Only JournalArticle -->
            <#if className == "com.liferay.portlet.journal.model.JournalArticle">
                <#assign
                    journalArticle = assetRenderer.getArticle()
                    docXml = saxReaderUtil.read(journalArticle.getContent())
                    wcm_title = value_of(docXml, "wcm_title", languageId)
                    wcm_contents = value_of(docXml, "wcm_contents", languageId)
                    truncate_length = 28
                    truncated_wcm_contents = htmlUtil.escape(truncate(wcm_contents?replace('<[^>]+>','','r'),truncate_length))
                    author_name = entry.getUserName()
                    tags = tagUtil.getAssetEntryAssetTags(entryId)
                >
                <h2>${wcm_title}</h2>
                <p>${truncated_wcm_contents}</p>
            </#if>
    </#list>
</#if>

##自力でのADTサンプルの探し方
Googleで検索は基本なのですが、Github検索が結構役立ちます。Github検索で、キーワードとしてはassetRendererdynamic-elementなどとして、詳細検索画面で拡張子をftlに絞りこんで検索すると、Liferayのテンプレートが色々ヒットします。自分もそれをだいぶ参考にさせてもらいました。

##まとめ
Liferayの公式ドキュメントには基本的な部分のみ載っている感じなので、実際の現場で利用するADTを晒してみました。お役に立てれば幸いです。

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?