-
Notifications
You must be signed in to change notification settings - Fork 3
Showlets mini howto
Widget creation and basic information
- About this howto
- Introduction
- Adding a Widget to the catalog
- Conventions
- The different types of Widget
- Some custom tags of Entando
- Resource, CSS, image tags
- Examples
The purpose of this document is to illustrate the features of Widgets and explain the development process with examples.
This document is for developers who want to create or expand a portal made with Entando.
The examples and concepts in this manual will be useful to developers as a reference for the creation of the Widgets.
In order to effectively utilize the information in this document is necessary to have knowledge of the Entando platform and its Page Models, then HTML, CSS and JSP.
Widgets are a key element in the creation of portals in Entando: in a nutshell, Widgets are dynamic 'blocks' of the portal that are expected to be moved, to be modified or to be adapted during the page management.
In the Entando platform all the information contained in portal pages are served through Widgets. Whatever the information is – contents, Content lists or menus – it is always served through Widgets.
You can create Widgets depending on the information to be provided; there is no limit to the number of Widgets that can be added to the portal.
Internal servlets are a special type of Widgets where the information is carried through a servlet on its own.
Widgets in reality are nothing but JSP fragments placed automatically by the system in the spaces of the portal pages, called Frames, available for that purpose. This process is handled by the system automatically.
For what concerns the HTML code, Widgets are best viewed as part of a complete HTML page: being said that, it is important to understand that the output of a Widget must be in harmony with the Page Models.
It's a mistake to include an entire HTML page in a Widget JSP: this would result, for example, in the tag <head> or <body> being opened within the body of the page (that of the Model)!
From a technical point of view a Widget is composed by:
-
a record in the showletcatalog table in the port database
-
a JSP file placed in the
…/src/main/webapp/WEB-INF/aps/jsp/showlets
of the project; consider that plugins have a slightly different path, being files placed inside a directory plugins inWEB-INF
: for the purpose of the document it doesn't matter. Consult the Developer's Guide – Plugins for information).
Adding a Widget in Entando is a process which requires the following steps to be performed:
-
Create a JSP file within the directory
…/src/main/webapp/WEB-INF/aps/jsp/showlets
. -
Insert a new record in the showletcatalog in the port database; the record is composed by the following fields:
- code: this is the unique name of the Widget, which also happen to be the name of the JSP file aforementioned
- titles: a simple XML containing the description - one for each language of the portal – of the Widget itself
- parameters: XML which defines the actions needed to configure the Widget in the administration area
-
plugincode: the code of the plugin to which the Widget is associated. This field must be specified only when the Widget belongs to a plugin: in that case the JSP file must be placed in the
…/aps/jsp/showlets
within the plugin path. For more information about plugins pattern refer to the Developer's manual – Plugins - parenttypecode: when present, indicates that the Widget is a specialization of another Widget and specifies the code of the Widget we want to extend. The configuration of the Widget then must be specified in defaultconfig
- defaultconfig: this field makes sense only when the parenttypecode is present. This is the XML configuration of the parameters of the Widget; the outcome is a Widget whose type is parenttypecode and with the defaultconfig configuration
- locked: this means that the Widget can be replicated from the administration interface
- maingroup: the group to which the Widget can be shown to; if left blank no restrictions apply
-
Reload the system configuration (from the left menu in the administration area: Tools → Reload Configuration)
-
Now proceed with the insertion of HTML code in the JSP created in the step 1, import the tag libraries needed and create the CSS files. Resources are placed in
…/src/main/webapp/resources/static
. Please create the directoryshowlets
underimg
to place optional Widget images in…/src/main/webapp/resources/static/img/showlets
; create the directoryjs/showlets
to place the optional javascript files in…/src/main/webapp/resources/static/js/showlets
. -
Last, associate the Widget to a frame of a page of choice from the administration area
The names of the JSP files, the codes, and CSS file names used for Widgets follow this formula: servicename_componentname_variant.
For example, the JSP of the search form will be called
search_form.jsp;
results will be eventually shown in
search_result.jsp
.
The JSP files of the navigation Widgets Breadcrumbs and Menu have the following names, respectively: navigation_bradcrumbs.jsp
and navigation_menu.jsp
One of the first question developers ask is about the place where CSS are placed and how to link them to the portal. The aim of this chapter is to answer this question.
It is necessary to use the HeadInfo tag declared in the TLD file aps-core.tld
.
In a nutshell, this tag order the Page Model to show an information. This information is caught by another tag, namely outputHeadInfo which is present in the Page Model.
So all you need in order to include a CSS correctly is:
-
one tag outputHeadInfo in the Page Model
-
one tag headInfo in the Widget
In other words, headInfo is the transmitter and the outputHeadInfo is the receiver. Obviously they must share the same type of information for this they have the type attribute.
Type is a simple string that can be freely used for your needs, with the solely exception of the keyword type=“CSS” which is universally used in the entire framework for CSS inclusions.
The same concepts described for the CSS inclusion is perfectly valid for the Javascript files: again, you use the <outpuHeadInfo> in the Page Model, and a <headInfo> tag in the Widget.
But this time we agreed to used to the type=”JS” to accomplish this task.
With the same technique seen for CSS and JS files, web designers can include CSS for Internet Explorer simply using an appropriate type (e.g. CSS_IE7), provided that the developer has placed the tag within a conditional comment
Entando is always released with a number of built-in Widgets or, better, Stock Widgets which guarantee the basic functionality of the portal.
For example Internal Servlet and Login are stock Widgets.
Custom Widgets are those created by developers to meet specific needs; they can have a mere graphical function or embody complex functionality.
Plugin Widgets are those Widgets added by a plugin to provide specific functionality of the plugin.
The most noticeable example is the jacms plugin, bundled with Entando, which provides all the Widgets needed to publish and search contents.
This chapter briefly shows some custom tags available for use in the Widgets.
This chapter does not apply to Internal Servlet Widgets whose functionality is provided by another servlet and might use different tags_
This tag generates the URL of the portal so it is used by developers to create links.
<wp:url> has two attributes:
-
page: when present generates the URL of a page. When not present will produce the URL of the current page
-
lang: when present, it returns the page in the desired language; when not specified, the current language will be used for the URL generation.
This tag generates the URL to a page whose code is homepage, asking for English localization:
<a href="<wp:url page="homepage" lang="en" />">
Homepage in English
</a>
That tag is expanded with the desired link so that the resulting XML would be similar to the following:
<a href="http://applicationBaseUrl/en/homepage.wp">Homepage in English</a>
This <wp:tag> is used to create list of links. It is able to iterate over the Pages Tree, respecting the given navigation rules.
The spec attribute must contain an expression which specifies the subset of pages which we intend to put in the list.
The body of the tag will be valued for every page found evaluating spec, and the code of the current page being listed will be inserted in the parameter declared using the attribute var.
Given a page whose code is homepage, we can get the list of its children with the following code:
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<%@ taglib prefix="c" uri="c.tld" %>
<wp:nav spec="code(homepage).subtree(1000)" var="currentPage">
<c:out value="${currentPage.title}" /> -
</wp:nav>
The result will be similar to the following:
Homepage - Page 1 - Page 1 1 - Page 1 2 - (....)
To create a HTML list containing the links to the children of the page of the portal, whose code is homepage, the URL a NAV tag can be combined together in this way:
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<%@ taglib prefix="c" uri="c.tld" %>
<ul>
<wp:nav spec="code(homepage).subtree(1000)" var="currentPage">
<li>
<a href="<wp:url page="${currentPage.code}" />"> <c:out value="${currentPage.title}" /></a>
</li>
</wp:nav>
This will result in a HTML similar to the following:
<ul>
<li>
<a href="http://applicationBaseUrl/currentLang/homepage.wp">Homepage</a>
</li>
<li>
<a href="http://applicationBaseUrl/currentLang/page1.wp">page 1</a>
</li>
<li>
<a href="http://applicationBaseUrl/currentLang/page11.wp">page 1 1</a>
</li>
<li>
<a href="http://applicationBaseUrl/currentLang/page12.wp">page 1 2</a>
</li>
(...)
</ul>
In Entando a label in the portal pages is proposed in the current language using the tag <wp:i18n>.
This tags supports three attributes:
-
key: is the unique code of the label. This attribute is mandatory
-
lang: when present, it specifies the desired localization of the label, otherwise the current language will be used
-
var: when present, the value of the label is placed in the variable with the specified name
Given a label with code WELCOME previously created in the administration interface available both in English and Italian, this label retains the two values “Welcome in Entando” and “Benvenuto in Entando”.
In order to visualize this label in a Showet the developer would have to write something like this:
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<%@ taglib prefix="c" uri="c.tld" %>
(...)
<wp:i18n key="WELCOME" />
Note: label codes declared in the attribute key must be in capitol letters; use the underscore _ instead of spaces, e.g. key=”WELCOME_BACK”
Resource, CSS and Image tags all fulfill the same task: get a reference to a static resource. These tags are widely used to include images and CSS.
The tag <wp:resourceURL> returns by default the path to the directory …/resources/static
.
The other two, <wp:cssURL> and <wp:imgURL> are an extension of the tag above, and they return the path to …/resources/static/css
and …/resources/static/img*
.
Let's say that a javascript file, namely test.js, is placed in the directorhttp://localhost:4567/livepreview/images/save_24.pngy …/src/main/webapp/resources/static/js
: to include this resource in the page model the developer would do something similar to
the following code:
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it">
<head>
<script type="text/javascript" src="<wp:resourceURL/>js/test.js"></script>
</head>
(...)
The HTML produced will be somthing similar to the following:
<script type="text/javascript" src="http://applicationbaseurl/resources/static/js/test.js">
</script>
The careful reader will have noticed that the “js” directory, not present in the system by default, must be manually added to the path generated by the tag (furthermore, the “applicationbaseurl” is the actual value of the variable applicationBaseURL as found in the context.xml).
These tags belongs to the Content Management Plugin (whose code is jacms) which is bundled with Entando.
The <jacms:contentList> tag is used to generate a list of contents than can be viewed in the portal. This tag returns a list of content ids which in turn are the input of the <jacms:content> tag which displays them.
This tag supports three attributes:
-
listName: this is the name of the variable in the page context which will contain the list of the found contents. This attribute is mandatory.
-
contentType: when present, it will limit the list to those contents belonging to the given Content Type id configured in the system.
-
Category: this, when present, will limit the list to those contents belonging to the given category code
-
cacheable: it can assume two values, true or false; it specifies whether the list must be generated taking in account the system cache. When set to false, cache entries are not considered. The default value is true.
The <jacms:contentListFilter> is a sub-tag provided with Content List Filter. This tag is used to filter the contents of the list. Several filters can be imposed within the Content List tag: they are applied in the same order as they are declared.
We have several attributes to refine the search:
-
key: this is the code of a metadata, or the name of the attribute; this must be compatible with the Content Type id specified in the Content List tag. Available metadata are:
- *created*: creation date - *modified*: last modification date
-
attributeFilter: it must be set to true when the attribute key above references an attribute of a Content Type present in the system; it must be false otherwise.
-
Value: this is the expected value. It is used when gathering all the contents sharing a given value. A real life example would be to group all the content of type NEW of a given day, say, 22/01/2012.
It is not mandatory; it is considered an alternative of the following attributes, start and end
- start: when performing range search, it assumes the starting value of the filter; for example it could be desirable to search for all contents published after a given date.
It is not mandatory. It is often used in conjunction with the end attribute to define an interval.
- end: when performing range search it assumes the ending value of the filter. For example it can restrict the search to all contents published before a certain date.
It is not mandatory; It is used often with start to define an interval.
-
order: used to sort entries in ascending or descending order, it can assume the following values: ASC or DESC
-
likeOption: it can be set to true or false but it can be only applied to metadata or attributes of type text.
When true the behavior of the filter will be modified so to include in the list all those content ids whose metada or attribute have the pattern specified in the attribute.
The following code is used to list the last five Content Type of type NEW which belongs to the sport category.
<%@ taglib prefix="jacms" uri="/jacms-aps-core" %>
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<%@ taglib prefix="c" uri="c.tld" %>
<wp:i18n key="LATEST_SPORT" />
<hr />
<jacms:contentList listName="listNewsVar" contentType="NEW"
category="sport">
<jacms:contentListFilter key="Data"
attributeFilter="true" order="DESC" />
<jacms:contentListFilter key="Title"
attributeFilter="true" order="ASC" />
</jacms:contentList>
<c:forEach var="contentId" items="${listNewsVar}" begin="0"
end="4">
<jacms:content contentId="${contentId}" modelId="default" />
<hr />
</c:forEach>
The Content List tag - and the two content filters tag within - produce a list of content ids which is stored in the listNewsVar variable in the page context. Later, in the <foreach> tag the content is fully rendered.
This fragment allows the developer to invoke an internal action of the backend.
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<wp:externalFramework />
Example of a search form which points the page with code search_results.
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<form id="searchForm" method="get" action="<wp:url page="search_results" />">
<input type="text" name="search" />
<input type="submit" value="Cerca" />
</form>
This code shows how to list the last 4 news belonging to the category homepage.
<%@ taglib prefix="jacms" uri="/jacms-aps-core" %>
<%@ taglib prefix="wp" uri="aps-core.tld" %>
<%@ taglib prefix="c" uri="c.tld" %>
<jacms:contentList listName="contentList" contentType="NEW" category="homepage">
<jacms:contentListFilter key="Data" attributeFilter="true" order="DESC" />
</jacms:contentList>
<ul>
<c:forEach var="content" items="${contentList}" begin="0" end="3">
<li><jacms:content contentId="${content}" modelId="list" /></li>
</c:forEach>
</ul>
This utilizes the <jacms:content> tag; the rest is done by the configuration
<%@ taglib prefix="jacms" uri="/jacms-aps-core" %>
<jacms:content contentId="${contentId}" />
The variable contentId holds the id of the content to show.
This produces a list configured by the CMS.
<%@ taglib prefix="jacms" uri="/jacms-aps-core" %>
<%@ taglib prefix="wp" uri="/aps-core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
/*
Author: William Ghelfi <william.ghelfi @ elicriso.biz> - 2005/05/23
Author: Eugenio Santoboni <eugeniosant @ tiscali.it> Content list viewer
/
%>
<jacms:contentList listName="contentList" titleVar="titleVar"
pageLinkVar="pageLinkVar" pageLinkDescriptionVar="pageLinkDescriptionVar"
userFilterOptionsVar="userFilterOptionsVar" />
<c:if test="${null != titleVar}">
<h2>
<span>
<c:out value="${titleVar}" />
</span>
</h2>
</c:if>
<c:set var="userFilterOptionsVar" value="${userFilterOptionsVar}"
scope="request" />
<c:import
url="/WEB-INF/plugins/jacms/aps/jsp/showlets/inc/userFilter-module.jsp" />
<c:choose>
<c:when test="${contentList != null && !empty contentList}">
<wp:pager listName="contentList" objectName="groupContent"
pagerIdFromFrame="true" advanced="true" offset="5">
<c:set var="group" value="${groupContent}" scope="request" />
<ul>
<c:forEach var="contentId" items="${contentList}" begin="${groupContent.begin}"
end="${groupContent.end}">
<li>
<jacms:content contentId="${contentId}" />
</li>
</c:forEach>
</ul>
<c:import
url="/WEB-INF/plugins/jacms/aps/jsp/showlets/inc/pagerBlock.jsp" />
</wp:pager>
</c:when>
<c:otherwise>
<c:if test="${not empty userFilterOptionsVar}">
<p>
<wp:i18n key="LIST_VIEWER_EMPTY" />
</p>
</c:if>
</c:otherwise>
</c:choose>
<c:if test="${null != pageLinkVar && null != pageLinkDescriptionVar}">
<p>
<a href="<wp:url page=" $ pageLinkVar } />
">
<c:out value="${pageLinkDescriptionVar}" />
</a>
</p>
</c:if>
<%-- Important: reset variables --%>
<c:set var="userFilterOptionsVar" value="${null}" scope="request" />
<c:set var="contentList" value="${null}" scope="request" />
<c:set var="group" value="${null}" scope="request" />
All the material here contained is published under the GNU Free Documentation License v1.3
The Entando trademark and logo are registered trademarks of Entando, srl. All
Rights Reserved.
All other trademarks are the property of their respective owners.