null

Liferay - добавляем поддержку bb-тегов в онлайн-магазин

Продолжая тему препарирования Liferay Portal и модификации его стандартных портлетов под собственные нужды, расскажу о том, как добавить продвинутые возможности форматирования в описания товаров интегрированного онлайн-магазина портала (Shopping Portlet), который используется у нас в качестве основы для каталога курсов.

Сам по себе этот портлет достаточно "наворочен" (например, есть возможность подключения PayPal-аккаунта для перевода денег покупателей, поддержка разнообразных стандартов банковских карт, расчёт стоимости доставки и т.д.), но для наших задач он не совсем подходит, в частности, потому, что описание товара выводится как plain text без всякого форматирования, что плохо для описаний курсов. Попробуем исправить этот недостаток.

Интерфейс интегрированных в Liferay портлетов формируется посредством jsp-страниц, расположенных в директории $SRC_ROOT/portal-web/docroot/html/portlet (или html/portlet для war-архива). Внутри этой директории все страницы "раскиданы" по каталогам соответствующих портлетов. Интересующие нас страницы находятся в подкаталоге shopping.

Для начала, уберём вывод описания товара в списке товаров категории - это описание и так там смотрится не очень, а когда в нём появятся ещё и bb-теги, всё будет выглядеть ещё печальнее :). Ищем на странице categories.jspf такой код (строки 285-308):

...
sb = new StringBuilder();

sb.append(item.getName());

if (Validator.isNotNull(item.getDescription())) {
    sb.append("<br />");
    sb.append(item.getDescription());
}

Properties props = new OrderedProperties();

PropertiesUtil.load(props, item.getProperties());

Enumeration enu = props.propertyNames();

while (enu.hasMoreElements()) {
    String propsKey = (String)enu.nextElement();
    String propsValue = props.getProperty(propsKey, StringPool.BLANK);

    sb.append("<br />");
    sb.append(propsKey);
    sb.append(": ");
    sb.append(propsValue);
}
...

Вырезаем отсюда всё, связанное с описанием товара (строки листинга 4-7), и, опционально, его свойства (строки 8-18). В итоге из атрибутов товара у нас в этой ячейке таблицы-списка останется только его наименование.

Теперь перейдём собственно к добавлению bb-тегов. Для этого нам нужно немного пофиксить вывод описания товара на странице view_item.jsp. Открываем этот файл и ищем там код, выводящий описание (строки 113-117):

<c:if test="<%= Validator.isNotNull(item.getDescription()) %>">
    <br />

    <%= item.getDescription() %>
</c:if>

Дописываем к выводу описания жутковатый replace:

<c:if test="<%= Validator.isNotNull(item.getDescription()) %>">
    <br />

    <%= item.getDescription()
            .replace("\n[*]", "[*]")
            .replace("\n[ul]", "[ul]")
            .replace("[/ul]\n", "[/ul]")
            .replace("\n", "<br/>")
            .replace("[s]", "<s>")
            .replace("[/s]", "</s>")
            .replace("[u]", "<u>")
            .replace("[/u]", "</u>")
            .replace("[i]", "<i>")
            .replace("[/i]", "</i>")
            .replace("[b]", "<b>")
            .replace("[/b]", "</b>")
            .replace("[ul]", "<ul>")
            .replace("[/ul]", "</ul>")
            .replace("[*]","<li>")
            .replace("[/url]","</a>")
            .replaceAll("(.*)\\[url=(.*)\\](.*)", "$1<a href=$2>$3") %>
</c:if>

Что он делает? Он заменяет перечисленные ниже bb-теги на соответствующие теги html и подставляет тег <br /> вместо переносов строк. Строки листинга 4 и 5 предотвращают "расползание" вёрстки в списках (т.к. там не надо генерить <br /> вместо переносов строк между элементами). Приведённый выше пример реализует поддержку следующего набора bb-тегов:

[b]Полужирный текст[/b] Полужирный текст
[i]Курсив[/i] Курсив
[u]Подчёркнутый текст[/u] Подчёркнутый текст
[s]Зачёркнутый текст[/s] Зачёркнутый текст

Список элементов:
[ul]
[*]item1

[*]item2
[*]item3
[/ul]

Список элементов:
  • item1
  • item2
  • item3
[url=www.tune-it.ru]Гиперссылка[/url] Гиперссылка

Собственно, всё! Теперь можно заполнить тестовое описание товара в каталоге и убедиться, что наша цель достигнута:

Коротко о себе:

Работаю ведущим программистом в компании Tune IT и ассистентом кафедры Вычислительной техники в Университете ИТМО .

Занимаюсь проектами, связанными с разработкой разного рода веб-приложений (порталы, CRM-системы, системы электронного документооборота), а также, в рамках научной работы на кафедре, изучаю возможности применения семантического анализа в задачах САПР.