null

Liferay 6.2: встраиваем портлет в тему портала

Liferay позволяет интегрировать портлеты непосредственно в тему страниц. Подразумевается, что это небольшие портлеты, не влияющие на производительность, которые добавляют теме дополнительную функциональность (навигация, поиск, смена языка) или служат для гибкой настройки контента (веб-контент). Привычный механизм “перетаскивания” для таких портлетов не работает, поскольку они находятся за пределами лейаута страницы. Их местоположение жестко определяется в шаблонах (templates) темы. Рассмотрим, какие существуют способы встроить портлет в Velocity шаблоны темы.

 

Идентификатор портлета

Прежде всего разберёмся, как обратиться к определённому портлету. В Liferay каждый портлет имеет уникальный идентификатор (Portlet ID). В интерфейсе ИД портлета можно посмотреть в:

  • Настройки портлета ➝ Look and Feel ➝ Advanced Styling (часть после #portlet_);
  • Control Panel ➝ Plugins Configuration (поле Plugin ID).

От типа портлета зависит формат записи идентификатора. На сайте Liferay приводится следующая таблица.

Naming Convention Description
portletID Non-instanceable core portlet
portletID_INSTANCE_instanceID Instanceable core portlet
portletID_WAR_webAppContext Non-instanceable custom portlet
portletID_WAR_webAppContext_INSTANCE_instanceID Instanceable custom portlet

 

Встроенные (core) портлеты имеют простой числовой идентификатор, например 71 у портлета Navigation или 58 у Login.

ИД пользовательского портлета состоит из комбинации имени портлета из xml-конфигураций и контекста сервлета (имени WAR-файла), при этом специальные символы (такие как тире и точка) опускаются. Например, если у вас есть портлет my-portlet упакованный в WAR файл с именем my-portlet-1.0.war, идентификатор портлета будет myportlet_WAR_myportlet10.

Если портлет может иметь несколько инстансов, к его ИД добавляется ИД инстанса. Как правило, это произвольные 4 символа (буквы и цифры), уникальные для инстанса и следующие после слова _INSTANCE_, например 47_INSTANCE_abc1.

Ид многих встроенных портлетов можно посмотреть здесь.

 

Использование параметров темы

Часто нужно, чтобы ИД портлета был не жёстко задан в теме, а мог вводиться пользователем. В таком случае его выносят в параметры темы (theme settings), которые определяются в файле liferay-look-and-feel.xml. Ниже приведён пример конфигурации.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 6.1.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_6_1_0.dtd">
 
<look-and-feel>
  <compatibility>
    <version>6.2.*+</version>
  </compatibility>
  <theme id="example" name="Example Site Theme">
    <settings>
      <setting configurable="true" key="language-portlet-id" value="82" />
      <setting configurable="true" key="about-content-id" />
      <setting configurable="true" key="contacts-portlet-id" value="contactform_WAR_contactform10" />
    </settings>
  </theme>
</look-and-feel>

Внутри тега <settings> задаются параметры темы, имеющие уникальный ключ (key) и значение по умолчанию (value), если нужно. Затем значения параметров считываются из Velocity шаблонов, как правило этот код выносится в файл init_custom.vm.

## ---------- Settings ---------- ##
#set ($languagePortletId = $theme_settings.getProperty("language-portlet-id"))
#set ($aboutUsContentId = $theme_settings.getProperty("about-content-id"))
#set ($contactsPortletId = $theme_settings.getProperty("contacts-portlet-id"))

Далее init_custom.vm подключается добавлением в начало файла portal_normal.vm строки:

#parse ($init)

Таким же образом через переменные темы можно задавать настройки встраиваемых портлетов.

 

Способ 1: универсальный

В общем случае встроенные и пользовательские портлеты добавляются вызовом $theme.runtime() в файле portal_normal.vm.

$theme.runtime($myPortletId, $queryString, $velocityPortletPreferences.toString())

В старых версиях Liferay для этой цели использовался вызов $taglibLiferay.runtime().
Функция принимает следующие параметры:

$myPortletId - ид портлета,
$queryString - параметры времени выполнения (runtime parameters),
$velocityPortletPreferences - настройки портлета (preferences).

ИД портлета мы уже обсудили выше. С помощью параметра $queryString вы можете передать портлету параметры, как если бы они пришли из строки запроса. При этом параметры задаются парами "ключ-значение", разделёнными амперсандом.

#set ($queryString = "param1=value1&param2=value2")

Для передачи портлету желаемых настроек используется встроенная переменная $velocityPortletPreferences, представляющая собой карту Map<String, String>. Это могут быть как встроенные настройки Liferay, такие как свойство portlet-setup-show-borders, отвечающее за видимость границ портлета, так и пользовательские свойства ваших собственных портлетов.

#set ($VOID = $velocityPortletPreferences.setValue('displayStyle', 'custom'))
#set ($VOID = $velocityPortletPreferences.setValue('portletSetupShowBorders', 'false'))}}}

После использования переменную очищают.

#set ($VOID = $velocityPortletPreferences.reset())

 

Приведём несколько примеров.

Вставка портлета Hello World

$theme.runtime("47", "", "")

Вставка инстанса портлета Navigation с заданными параметрами отображения:

$velocityPortletPreferences.setValue('displayStyle', 'relative-with-breadcrumb')
$velocityPortletPreferences.setValue('portletSetupShowBorders', 'true')
$theme.runtime("71_INSTANCE_abc1", "", $velocityPortletPreferences.toString())
$velocityPortletPreferences.reset()

Вставка пользовательского портлета Contact Form с заданием параметров:

$velocityPortletPreferences.setValue('email', 'info@tune-it.ru'))
$velocityPortletPreferences.setValue('companyName', 'TuneIT'))
$velocityPortletPreferences.setValue('title', "Свяжитесь с нами!"))
$theme.runtime($contactFormId, '', $velocityPortletPreferences.toString())
$velocityPortletPreferences.reset())

Обратите внимание, что в силу особенностей реализации Liferay значения свойств считываются один раз для каждого инстанса портлета и далее не обновляются, если вы попытаетесь изменить их значение в portal-normal.vm. Чтобы новое значение свойства было прочитано, нужно поменять ИД инстанса портлета или удалять предыдущие значения (подробнее см. тут).

 

Способ 2: встраиваем веб-контент

В случае, если требуется вставить на страницу веб-контент, можно воспользоваться сервисом journalContentUtil. В таком случае будет вставлено только HTML-содержимое, без свойственного портлетам обрамления и всплывающих настроек.

$journalContentUtil.getContent($group_id, $article_id, $template_id, "$locale", $theme_display)

Метод getContent принимает следующие параметры:

$group_id - ИД сайта, к которому относится веб-контент (community ID),
$article_id - ИД веб-контента,
$template_id - ИД шаблона структуры веб-контента (template ID),
$locale - локаль (предустановленная переменная),
$theme_display - ссылка на объект Theme Display (предустановленная переменная).

Первый параметр зависит от того, какому сайту принадлежит веб-контент, в простейшем случае берётся ИД текущего сайта, доступное в шаблоне через одноимённую переменную $group_id, или, что то же самое, $theme_display.scopeGroupId и $theme_display.getLayout().getGroupId().

Второй параметр можно посмотреть в Панель управления ➝ Контент ➝ Сетевой контент, открыв интересующий веб-контент (поле ID). Если контент основан на структуре, к которой привязано несколько шаблонов, можно выбрать конкретный шаблон, указав его template ID.

Последние две переменные - $locale и $theme_display - также доступны из Velocity шаблонов под соответствующими именами, их нужно просто передать в функцию, обязательно заключив локаль в кавычки.

#set ($partnersContentId = $theme_settings.getProperty("partners-portlet-id"))
#set ($ourPartners = $journalContentUtil.getContent($group_id, $partnersContentId, null, "$locale", $theme_display))

<section id="partners" class="content-wrapper">
  $ourPartners
</section>

 

Полезности

При работе с Velocity переменными следует учитывать, их дефолтное поведение при неопределённом (undefined) значении. В частности, если в последнем примере пользователь введёт неверный ИД веб-контента, переменная $ourPartners останется неинициализированной, и на странице будет отображено её имя "$ourPartners", а не пустая строка, как вы могли ожидать.

Чтобы переопределить это поведение перед переменной ставится восклицательный знак.

<section id="partners" class="content-wrapper">
  $!{ourPartners}
</section>

 

Кроме того

Портлеты можно встраивать не только в шаблоны темы (velocity templates), но и в лейауты (layout templates), и даже в веб-контент. Эти темы не были рассмотрены в статье, но я приведу несколько примеров в качестве ключевых слов для дальнейшего поиска информации.

Для вставки портлета в веб-контент используется тег <runtime-portlet>.

<runtime-portlet name="56" instance="ah44" queryString=""/>

Для вставки портлета в колонку лейаута используется вызов $processor.processPortlet().

<div class="portlet-column portlet-column-only" id="column-1">
  $processor.processPortlet("71_INSTANCE_xyz1")
  $processor.processColumn("column-1", "portlet-column-content portlet-column-content-only")
</div>

 

Ссылки

Embedding portlets in themes on Liferay
Two ways to embed web content in Liferay themes
Embedding a portlet in the theme
Liferay - интеграция портлета в тему портала (mirror)
Embedding Portlets in a Layout Template
Embedding a portlet in web content

Fully Qualified Portlet ID (FQPI)
Liferay Wiki | Portlet IDs
List Intanceable and Non-Instanceable OOTB Portlets in Liferay