Modificando la visualización de los blogs de Liferay DXP
Application Display Templates (ADT)
El portlet para crear blogs en liferay tiene, dentro de su configuración básica, una serie de opciones que permite cambiar la forma en que se visualizan el listado de los blogs de diversas maneras ya preconfiguradas.
Si lo que quieres es personalizar esta visualización para generar el html que quieras para tener el control sobre el código html generado y cambiar la visualización a tu antojo, tal y como hice con este blog, Liferay te permite hacerlo “fácilmente” con las “application display templates” (ADT para los amigos).
El ADT permite crear plantillas de visualización, usando como lenguajes velocity y freemarker, usando una interfaz de usuario con autocompletado desde la cual podemos indicar el código que queremos generar usando unas variables predefinidas.
Puedes saber mucho más sobre el ADT en la documentación oficial de liferay (ir a la documentación) . La documentación todavía habla de la versión 6.2, pero es completamente válida para la versión 7.
Lo que vamos a crear en este post es una template para cambiar la visualización de los blogs a algo más atractivo y de paso utilizaremos un par de tags semánticos de html5. Más adelante tengo intención de escribir otro post en el que modificaré esta template para añadirle datos estructurados de schema.org y enriquecerla, pero bueno, eso será mas adelante.
El contenido de la template es este:
<#list entries as entry> <#if entry?is_odd_item> <div class="row"> </#if> <#assign viewURL = renderResponse.createRenderURL() /> ${viewURL.setWindowState("MAXIMIZED")} ${viewURL.setParameter("mvcRenderCommandName", "/blogs/view_entry")} ${viewURL.setParameter("redirect", currentURL)} ${viewURL.setParameter("urlTitle", entry.getUrlTitle())} <#assign summary = entry.getDescription() /> <#if validator.isNull(summary)> <#assign summary = entry.getContent() /> </#if> <div class="col-md-6 col-sm-6"> <article class="blog-entry"> <header> <#if entry.getSmallImage()> <img src="${entry.getSmallImageURL(themeDisplay)}" alt="${htmlUtil.escape(entry.getTitle())}" class="circle" /> </#if> <h3><a href="${viewURL}"><span>${htmlUtil.escape(entry.getTitle())}</span></a></h3> <time datetime="${dateUtil.getDate(entry.getCreateDate(), "yyyy-MM-dd'T'HH:mm:ssZ", locale)}" class="meta"> ${dateUtil.getDate(entry.getCreateDate(), "dd MMM yyyy", locale)} </time> <hr /> </header> <div class="body">${stringUtil.shorten(htmlUtil.stripHtml(summary), 200)}</div> <div class="clearfix"> <a href="${viewURL}" class="btn btn-read-more"><@liferay.language key="read-more" /></a> </div> <footer> <#assign blogsEntryClassName = "com.liferay.blogs.kernel.model.BlogsEntry" /> <span class="entry-categories"> <@liferay_ui["asset-categories-summary"] className=blogsEntryClassName classPK=entry.getEntryId() portletURL=renderResponse.createRenderURL() /> </span> <span class="entry-tags"> <@liferay_ui["asset-tags-summary"] className=blogsEntryClassName classPK=entry.getEntryId() portletURL=renderResponse.createRenderURL() /> </span> </footer> </article> </div> <#if entry?is_even_item || !entry?has_next> </div> </#if> </#list>
El código de la template es bastante simple y se entiende bastante bien por sí mismo, pero por clarificarlo el funcionamiento es el siguiente:
- El objeto “entries” es una variable predefinida de Liferay que, en este caso, contiene una lista de los blogs a mostrar.
- Recorremos cada blog y para cada uno de ellos, imprimimos el valor de los atributos que queremos mostrar.
- Usamos los tags article, header, footer y time para ayudar a los motores de búsqueda a entender el contenido.
- Para cada entry, obtenemos su url de visualización indicando que queremos verlo en estado maximizado.
- La imagen que muestro es la imagen que se puede añadir en el abstract del blog
- Y finalmente mostramos las categorías y tags de cada blog
El resto del html es y css son elementos de Twitter Bootstrap para visualizar los blogs correctamente en modo responsive. Lo único un poco difícil de ver tal vez es que muestro las entradas en 2 columnas, por lo que cada 2 elementos abro un div class=”row” y lo cierro al final.
Para hacer este tipo de cosas con freemarker están muy bien las instrucciones que indican si la entrada es par (entry??is_even_item), impar (entry??is_odd_item) o si es la última de la lista (!entry?has_next). Hacen el código muy legible. La documentación sobre estas variables para loops las puedes ver aquí (ir a la documentación)
Una vez creada la template, hay que crear una serie de estilos para mostrar la información como queramos. Yo tengo estos estilos en el custom.css del tema de apariencia - que es donde deben estar -, pero si quieres los puedes poner entre tags <style> en esta misma template para hacer una prueba rápida.
Los estilos son estos:
.blog-entry { background-color: #f2f2f2; border-radius: 10px; box-shadow: 0px 1px 5px rgba(69, 69, 69, 0.5); margin-bottom: 40px; } .blog-entry header { padding-top: 20px; padding-right: 45px; padding-left: 45px; text-align: center; } .blog-entry header img { width: 150px; margin-bottom: 20px; } .circle { border-radius: 50%; } .blog-entry header h3 { color: #303233; margin-top: 0; margin-bottom: 10px; } .blog-entry header h3 a { color: #303233; } .blog-entry header hr { border-top-color: #303233; border-bottom: none; } .blog-entry header .meta { color: #303233; } .blog-entry .body { padding-right: 45px; padding-left: 45px; margin-bottom: 10px; color: #303233; } .blog-entry .btn-read-more { float: right; margin-right: 45px; margin-bottom: 18px; color: #ffffff; background-color: #557088; background-image: linear-gradient(to bottom, #557088 0%, #3d5162 100%); background-repeat: repeat-x; border-color: #3a4c5c; } .blog-entry footer { padding-right: 45px; padding-left: 45px; color: #303233; padding-bottom: 18px; } .blog-entry footer a { color: #303233; }
Y por último, hay que ir a la configuración del portlet de blogs y en “Display template” seleccionar la template que acabamos de crear. El resultado, una vez creados algunos blogs, deberá ser algo similar a esta imagen: