Продолжая тему препарирования 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]
|
Список элементов:
|
[url=www.tune-it.ru]Гиперссылка[/url] |
Гиперссылка |
Собственно, всё! Теперь можно заполнить тестовое описание товара в каталоге и убедиться, что наша цель достигнута:
