null

Автоматизация импорта шаблонов публикаторов контента в Liferay 7.3

В Liferay публикаторы контента (Content Display Templates) используются для визуализации и форматирования данных, полученных из различных источников. Как правило, они реализуются с помощью шаблонов на FreeMarker (FTL) и применяются для вывода списков сущностей, результатов поиска, фильтров и прочих визуальных компонентов.
Ручное добавление таких шаблонов через интерфейс администратора может быть неудобным и подверженным ошибкам. Главной причиной создания данного модуля стало стремление к полной автономности Liferay-модулей: после их деплоя в систему больше не требуется ручного вмешательства для создания или обновления шаблонов.


Структура решения

Решение включает:

  • .properties-файл со списком шаблонов и их метаданными;
  • FTL-файлы самих шаблонов;
  • OSGi-модуль, который загружает шаблоны, проверяет их наличие и обновляет/создаёт при необходимости.

Пример конфигурационного файла


Файл templates.properties содержит информацию о шаблонах:

TEST_TEMPLATE_KEY=Тестовый публикатор,adt/test_publisher.ftl,1.0,com.liferay.portal.search.web.internal.result.display.context.SearchResultSummaryDisplayContext

Каждая строка описывает шаблон и состоит из:

  • Ключа шаблона (templateKey);
  • Имени (templateName);
  • Пути к FTL-файлу (templatePath);
  • Версии (templateVersion);
  • Класса отображения (templateClassName).

Компоненты модуля


TemplateData
Класс-обёртка для метаданных шаблона:

public class TemplateData {
    private String templateKey;
    private String templateName;
    private String templatePath;
    private String templateVersion;
    private String templateClassName;

    public TemplateData(String templateKey, String templateName, String templatePath, String templateVersion, String templateClassName) {
        this.templateKey = templateKey;
        this.templateName = templateName;
        this.templatePath = templatePath;
        this.templateVersion = templateVersion;
        this.templateClassName = templateClassName;
    }

    // Геттеры
}

ResourceLoader
Загрузка FTL-файлов и .properties:

public String loadTemplate(InputStream inputStream) throws Exception {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
        return reader.lines().collect(Collectors.joining("\n"));
    }
}

public Properties loadTemplateProperties(InputStream inputStream) throws IOException {
    Properties properties = new Properties();
    try (Reader reader = new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8)) {
        properties.load(reader);
    }
    return properties;
}


TemplateCreator
Создание и обновление шаблонов:

public void createTemplate(Group group, long resourceClassNameId, TemplateData templateData, InputStream inputStream) {
    // ...
    ddmTemplateLocalService.addTemplate(
        UserLocalServiceUtil.getDefaultUserId(group.getCompanyId()),
        group.getGroupId(),
        PortalUtil.getClassNameId(templateData.getTemplateClassName()),
        0,
        resourceClassNameId,
        templateData.getTemplateKey(),
        nameMap,
        null,
        DDMTemplateConstants.TEMPLATE_TYPE_DISPLAY,
        null,
        "ftl",
        templateScript,
        false,
        false,
        null,
        null,
        serviceContext
    );
}

 

TemplateRegistrator
Главная точка входа — регистрация шаблонов:

public List<TemplateData> getTemplateList(InputStream inputStream) {
    Properties properties = resourceLoader.loadTemplateProperties(inputStream);
    List<TemplateData> templates = new ArrayList<>();

    for (String key : properties.stringPropertyNames()) {
        String value = properties.getProperty(key);
        String[] parts = value.split(",", 4);
        if (parts.length == 4) {
            templates.add(new TemplateData(key, parts[0].trim(), parts[1].trim(), parts[2].trim(), parts[3].trim()));
        }
    }

    return templates;
}

Проверка существования и сравнение версий шаблонов:

if (template.getTemplateKey().equals(newTemplate.getTemplateKey())) {
    if (Double.parseDouble(template.getVersion()) < Double.parseDouble(newTemplate.getTemplateVersion())) {
        templateCreator.updateTemplate(template, newTemplate, inputStream);
    }
    found = true;
}

Использование

 

  1. Поместите .ftl шаблоны в resources/adt/.
  2. Укажите шаблоны в templates.properties.
  3. При загрузке модуля вызовите getTemplateList() и затем для каждого шаблона вызовите addTemplate(...).

Это можно сделать вручную или автоматически в @Activate-методе OSGi-компонента.