Liferay 7 принёс с собой много новых и полезных особенностей, в том числе некоторые привычные вещи теперь делаются несколько иначе. В этой статье мы поговорим об одном из таких нововведений - декораторах портлетов.
В Liferay 6.2 границы портлета настраивались в разделе Look and Feel настроек портлета, где вы могли выбрать отображать их или не отображать. В Liferay 7 эта опция заменена более мощным механизмом декораторов.
Рис.1 Интерфейс настроек портлета Liferay 6.2
Каждый портлет обёрнут в некоторое количество родительских тегов, обеспечивающих базовые функции, такие как перетаскивание и стиль границ. Для защиты этих функций, изменение данного уровня разметки из темы невозможно. Поскольку в настройках портлета было выбрано скрывать границы, в коде можно увидеть соответствующий класс portlet-borderless.
Рис. 2. Разметка портлета со скрытыми границами
Декораторы предлагают способ добавления пользовательских CSS-классов к одному из тегов-обёрток через настройки портлета. Определив в теме правила для каждого класса, вы получаете возможность менять стили границ, а не только включать или выключать их.
	Decorate - включает заголовок портлета, границы и белый фон 
	Borderless - только заголовок 
	Barebone - никаких обрамлений 
 
Декораторы описываются в файле настроек темы liferay-look-and-feel.xml, пример для упомянутых декораторов из классической темы Лайфрея приведён ниже.
<?xml version="1.0"?>
<!DOCTYPE look-and-feel PUBLIC "-//Liferay//DTD Look and Feel 7.0.0//EN" "http://www.liferay.com/dtd/liferay-look-and-feel_7_0_0.dtd">
<look-and-feel>
  <compatibility>
    <version>7.0.0+</version>
  </compatibility>
  ...
  <theme id="classic" name="Classic">
    ...
    <portlet-decorator id="barebone" name="Barebone">
      <portlet-decorator-css-class>portlet-barebone</portlet-decorator-css-class>
    </portlet-decorator>
    <portlet-decorator id="borderless" name="Borderless">
      <portlet-decorator-css-class>portlet-borderless</portlet-decorator-css-class>
    </portlet-decorator>
    <portlet-decorator id="decorate" name="Decorate">
      <default-portlet-decorator>true</default-portlet-decorator>
      <portlet-decorator-css-class>portlet-decorate</portlet-decorator-css-class>
    </portlet-decorator>
  </theme>
</look-and-feel>
 
Атрибуты id и name тега portlet-decorator, а также тег portlet-decorator-css-class являются обязательными. Name используется в интерфейсе как отображаемое имя декоратора, а с помощью id на декоратор можно сослаться из темплейта страницы. Тег portlet-decorator-css-class задаёт имя CSS-класса, который будет добавлен к тегу-обёртке.
Рис. 3. Разметка портлета с декоратором barebone в Liferay 7
Можно объявить любое количество декораторов в рамках одной темы и менять их в настройках портлета, а также назначить дефолтный декоратор для темы.
Рис.4 Интерфейс настроек портлета Liferay 7
Стили для каждого декоратора задаются в CSS-файлах темы.
_portlet_decorator.scss 
.portlet-decorate .portlet-content {
  background:#fff;
  border-color:#e7e7e7;
  border-style:solid;
  border-width:1px 1px 1px 1px;
  word-wrap:break-word
}
.portlet-barebone .portlet-content {
  padding:0
} 
_custom.scss 
@import "portlet_decorator" 
В шаблонах страниц можно определить декоратор для конкретного портлета или изменять вёрстку в зависимости от выбранного декоратора (ниже примеры из официальной документации).
navigation.ftl 
<#assign VOID = freeMarkerPortletPreferences.setValue("portletSetupPortletDecoratorId", "barebone")>
<div aria-expanded="false" class="collapse navbar-collapse" id="navigationCollapse">
    <#if has_navigation && is_setup_complete>
        <nav class="${nav_css_class} site-navigation" id="navigation" role="navigation">
           <div class="navbar-form navbar-right" role="search">
             <@liferay.search default_preferences="${freeMarkerPortletPreferences}" />
           </div>
           <div class="navbar-right">
             <@liferay.navigation_menu default_preferences="${freeMarkerPortletPreferences}" />
           </div>
        </nav>
    </#if>
</div>
<#assign VOID = freeMarkerPortletPreferences.reset()>
 
portlet.ftl 
<#if portlet_display.getPortletDecoratorId() != "barebone">
        <h2 class="portlet-title-text">${portlet_title}</h2>
</#if>
 
 
Полезные ссылки 
From Liferay Portal 6 to 7 Portlet Decorators Adding Portlet Decorators to a Theme Upgrading Your Theme from Liferay Portal 6.2 to 7.0