For each widget, there is a <widgetName> directory located in: <DATADIR>/webapps/360-mashup-ui/WEB-INF/jsp/widgets
Each widget has at least two files:
• widget.xml
The manifest, describing the widget and its options (used by the Administration Console).
• widget.jsp
The actual widget logic, using JSP.
The Tag Library Descriptors (TLD) documentation is available in the following directory: <INSTALLDIR>/sdk/java-mashupui/project/doc/tld
Tip: If you have installed the Eclipse Plugin, you can open these TLDs from the Project Explorer panel. Right-click MashupUI and select CloudView Mashup > Open tag libraries documentation.
The Widget Reference documentation, which lists all available predefined widgets, is available in: <INSTALLDIR>/sdk/java-mashupui/project/doc/widget-reference/index.html
Tip: If you have installed the Eclipse Plugin, you can open the widget reference documentation from the Project Explorer panel. Right-click MashupUI and select CloudView Mashup > Open widgets documentation.
Resources
A Widget can also contain resources such as images, JavaScript, CSS and so on. These resources must be located in sub-folders of the widget directory, for example:
• images/
◦ test-image.png
• css/
◦ style.css
• js/
◦ script.js
Theses resources can be accessed through a conventional URL:
You can refer to them in your widget JSP code with a relative path, using the tag <wh:resource path="path/to/resource" />
Example:
<wh:resource path="images/test-image.png" />
Libraries
The <widgetName>/lib/ directory can contain a set of packaged JAR files. For example, you can add the jar of a controller under:
• myWidget/
◦ lib/
myController.jar
Note: This is just an example. You do not necessarily need to create a widget to embed a controller. For more information about controllers, see Create and package a controller.
Widget manifest
Let’s take a look at a simple widget in , Hello World, to understand how a widget is structured:
widget.xml
The Widget Manifest file is required to create widgets in the Mashup Builder. For example, the Hello World Widget Manifest file is as follows:
group: The widget’s group name (can be hierarchical using slashes); used to group similar widgets in the Mashup Builder.
2
Description
The widget’s description.
3
Preview
The preview can contain any text or HTML embedded using CDATA tags.
4
Includes
List of widget assets to inject in the page.
• type: The type of the asset (css or js).
• path: Path of the resource. The path can be relative to the widget (for example, css/style.css) or absolute (for example, /resources/static/css.style.css).
5
SupportWidgetsId
Defines how this widget supports sub widgets.
arity: ZERO, ZERO_OR_MANY, ONE, MANY
If you want to restrict the possibilities of sub widgets types, you can nest WidgetId tags to describe them: <WidgetId>tabContent</WidgetId>
6
SupportFeedsId
Defines how this widget supports feeds.
arity: ZERO, ZERO_OR_MANY, ONE, MANY
If you want to restrict the possibilities of feed types, you can nest FeedId tags to describe them: <FeedId>myFeed</FeedId>
7
SupportI18N
Widget internationalization support.
supported: Boolean value to enable internationalization
8
OptionsGroup
Declares an Option Group (displayed as a tab in the widget configuration).
name: Option group name
9
Option
Declares a widget Option.
• id: Internal ID of the option, to be used to retrieve the option value
• name: Displayable name of the option
• arity: ZERO, ZERO_OR_MANY, ONE, MANY
10
Description
User-friendly option description.
11
Values
Declares the option's value(s). Declaring several values will create a selection box.
12
Functions
A container to describe this Option's expected display, behavior, error checking, etc.
13
ContextMenu
Use this tag to specify the types of functions that will be available in the Value tab of the dynamic list displayed on the left of the widget properties panel:
• addContext(name, values): Appends a custom context to the dynamic list. The context is defined with names and values. For example, list ["a", "b"] or [{display:"A",value:"a_"},{display:"B",value:"b_"}]
• Aggregations(facetOptionId): Gets all facet aggregations, for example, count, score etc. Optionally you can use facetOptionId to specify the ID of the option that contains the facet aggregation you want to retrieve.
• ApiCommand(): Gets all the search API commands of all Search API configurations (see > Search API).
• ApiConfig(): Gets the names of all the Search API configurations (see Adminstration Console > Search API). For example, sapi0, sapi1, sapi2, etc.
• appendOnChange(str): A click of the user on the dynamic list, will append the specified string to the active input.
• Cookies(): Displays how to access the attributes of the dynamic list > Cookies parameters node in Mashup Expression Language. For example, the name attribute is accessed via the ${cookies['__cookieName__'].name} expression.
• DataModelClass(): Gets a list of all data model classes (see Administration Console > Classes).
• DateFacets(): Gets all Date facets from the feeds used by the widget.
• emptyOnChange(): A click of the user on the dynamic list, will remove the current value of the option before setting the clicked value.
• EntryVariables(): Displays how to access the variables of an entry in Mashup Expression Language.
• Eval(): Gets all possibilities evaluated by the widget.
• EvalCategory(): Gets all possibilities evaluated by the category.
• EvalFacet(): Gets all possibilities evaluated by the facet.
• EvalMeta(): Gets all possibilities evaluated by the meta.
• Facets(facetType, refinementPolicy): Gets all facets from the feeds used by the widget. facetType can be a string 'DATETIME' or an array ['DATETIME', 'NUMERICAL']
• Feeds(): Gets the feeds called by the widget.
• FeedVariables(): Displays how to access the variables of a feed in Mashup Expression Language.
• Fields(): Gets all the virtual fields, numerical fields and RAM-based fields from the feeds used by the widget.
• GeoFacets(refinementPolicy): Gets only Geographical facets from the feeds used by the widget.
• Hierarchical2DFacets(refinementPolicy): Gets only Hierarchical2D facets from the feeds used by the widget.
• I18N(): Displays how to access the attributes of the dynamic list > Internationalization and localization parameters node in Mashup Expression Language. For example, the code attribute is accessed via the ${i18n['__code__']} expression.
• JsKeys(): Gets a list of all the I18N jskeys available.
• Metas(): Gets all metas from the feeds used by the widget.
• MultiDimension2DFacets(refinementPolicy): Gets Multi-dimension 2D facets from the feeds used by the widget.
• MultiDimensionFacets(refinementPolicy): Gets Multi-dimension facets from the feeds used by the widget.
• NormalFacets(refinementPolicy): Gets only Category facets from the feeds used by the widget.
• NumericalFacets(refinementPolicy): Gets Numerical facets from the feeds used by the widget.
• PageParameters(parameterId): Displays how to access the attributes of the dynamic list > Page parameters node in Mashup Expression Language. For example, the lang attribute is accessed via the ${page.params['lang']} expression.
• Pages(): Gets the names of available pages.
• PageVariables(): Displays how to access the variables of a page in MEL.
• QueryPrefixes(): Gets all the query prefix handlers of the search logics (see Administration Console > Search logics > Query Language).
• Reporters(): Gets all the reporters defined in Administration Console > Reporting).
• Request(): Displays how to access the attributes of the dynamic list > Request parameters node in Mashup Expression Language. For example, the authPath attribute is accessed via the ${request.authType} expression.
• SearchLogics(): Gets a list of all Search Logics (see Administration Console > Search logics).
• SearchTargets(): Gets a list of all Search Targets (see Administration Console > Build Groups > Search targets).
• Security(): When the user is logged in, it gets all user-related information (the token, the user name and the display name).
• SecuritySources(): Gets a list of all Security Sources (see Administration Console > Security Sources).
• SelfMetas(): Gets the metas of the current feed only.
• Session(): Displays how to access the attributes of the dynamic list > Session parameters node in Mashup Expression Language. For example, the creationTime attribute is accessed via the ${session.creationTime} expression.
• Sorts(): Gets all the feed elements that can be sorted.
• SubMetas(): Gets the current subfeed metas.
• SuggestNames(): Gets the names of all the suggests and suggest dispatchers (see Administration Console > Suggest).
• SuggestServices(): Gets the complete URLs of all the suggests and suggest dispatchers (see Administration Console > Suggest).
• WUIDS(): Gets a list of this page Widget’s unique IDs.
14
Display
Use this tag to specify how the property will be displayed. For example, you can force the property to act as a select box, force it to act as an input (default is Text area), force it to act as a password input, etc.
• Code Editor: Transforms the property's input field into a code editor
• Number: Transforms the property's input field into a number input field.
• Password: Transforms the property's input field into a password input field (encrypted).
• Radio: Transforms the property's input field into a radio button.
• SetHeight: Sets the minimum height (in terms of lines) of the option's input field.
• TextEditor: Transforms the property’s input field into a rich text editor.
• TextArea: Transforms the property's input field into a text area field.
• ToggleDisplay: Shows/hides properties conditionally depending on the selected property value. For example, value1 of PropertyA will display PropertyB and PropertyD, value2 will display PropertyB and PropertyC. You need to set: * the value to match (using the valueToMatch and ifEquals attributes) * the options to hide (in hideOptions) * the options to show (in showOptions).
15
Check
Error checking functions to validate user input.
• isInteger: Checks that the value is an integer and displays an error message if not.
• isAlphanum: Checks that the value is a chain of alphanumerical characters and displays an error message if not.
• isPageName: Checks that the value is a page name and displays an error message if not.
• isEmpty: Checks that the value is NOT empty and displays an error message if it is the case.
16
Default Values
Specifies the default value of the option (one of the values specified for the "Value" element).
widget.jsp
The actual code of the widget is pretty simple too, for example:
• Import of the tiles functions (required to retrieve our widget configuration).
• Import of the widget helpers functions (useful to manipulate widgets).
• Import of the "widget" variable (our widget configuration) into the current scope.
• Retrieval of the "person" option value.
Create a widget
This section explains how to create a new widget. Read the previous sections to get information on the two main widget components, the widget.xml file and the widget.jsp file.
Create a widget manually
1. Start by creating a new directory for your widget.
2. Describe it in the widget.xml file.
3. Add the logic in the widget.jsp file.
Your widget should appear automatically after reloading the widgets in the Mashup Builder, and should be ready to be used.
Note: JSP files are compiled at the application startup. Changing a .jsp file requires restarting the searchserver.
Create a widget using the Eclipse plugin
Using the Eclipse plugin is more convenient as the widget is created with all required files at once.
1. In the Eclipse Project Explorer panel, right-click a Mashup UI project.
a. Specify a source folder. Widgets are usually stored under <project>/war/WEB-INF/jsp/widgets
b. Give it a name.
c. Specify in which widget group this widget must be filed.
5. Click Finish.
The new widget is added to the selected project in the Project Explorer panel.
6. Edit the widget file as needed.
Create a widget template
You can customize the look-and-feel of several standard widgets supporting templates (for example, the Result List and HTML widgets), by creating and referencing your own widget templates.
These templates must be JSP files, that can either include specific HTML codes or reference CSS files.
Reference a JSP file in the Result List widget
1. In Mashup Builder, go to the /search page and select the Design view.
2. Click the header of the Result List widget.
3. On the widget properties panel, go to the Hit templates tab.
4. In the Hit JSP template field, enter the absolute path of your custom JSP file.
For example: /WEB-INF/jsp/custom.jsp
Reference a JSP file in the HTML widget
1. In Mashup Builder, open a page and select the Design view.
2. Drag the HTML widget to the Design view.
3. On the widget properties panel, go to the Advanced tab.
4. In the JSP file path field, enter the absolute path of your custom JSP file.
For example: /WEB-INF/jsp/custom.jsp
Implement how to display subwidgets
You may want to include widgets within other widgets, this is what we call subwidgets.
You can choose between two modes to display subwidgets in widget containers:
• List mode (default behavior), to display subwidgets in a list, one after the other.
• Layout mode, to display subwidgets in rows and columns. For example, see the Tab and Table widgets.
Once the widget is packaged with the required code in the widget.xml and widget.jsp files, a new Edit Widget Layout entry is available in the widget menu, to let you customize the layout, exactly like a page.
<%-- Iterate and render all subwidgets --%> <render:subWidgets />
<%--Iterate and render all subwidgets for a specific entry --%> <widget:forEachSubWidget widgetContainer="${widget}" feed="${feed}" entry="${entry}"> <render:widget /> </widget:forEachSubWidget>
The $('.container') parameter shown in the following code snippets, is the starting point for all DOM lookup by the client. For performance reasons, it should be as close as possible to the widgets that will be updated. If omitted, the whole body of the page will be used.
Update all subwidgets
The widget container has the wuid jkg934f
var client = new MashupAjaxClient($('.container')); client.addWidget('jkg934f'); client.update();
Update the top widget
Here the widget at the top of the widget container has the wuid djH4dg
var client = new MashupAjaxClient($('.container')); client.addWidget('djH4dg'); client.update();
Update a specific subwidget with extra parameters
Here the subwidget has the wuid jkg934f_1_cloudview
var client = new MashupAjaxClient($('.container')); client.addWidget('jkg934f_1_cloudview'); client.addParameter('paramName', 'paramValue'); client.addParameters('paramName2', ['value1', 'value2']); client.update();
Update a specific subwidget every 5 seconds
var client = new MashupAjaxClient($('.container')); client.addWidget('jkg934f_1_cloudview'); client.updateInterval(5000);
Troubleshooting
You may encounter the following issues:
Changes in .jsp files are not taken in account
While changes to Javascript, CSS and images files are taken into account directly, JSP files are compiled by Jetty for performance reasons.
However, it is possible to switch the Jetty JSP servlet in development mode in the Mashup UIweb.xml file located in <DATADIR>/webapps/360-mashup-ui/WEB-INF/web.xml. To do so, edit the following section:
<!-- Enables development mode on JSP servlet --> <servlet> <servlet-name>jsp</servlet-name> <init-param> <param-name>development</param-name> <!-- SWITCH THIS TO TRUE TO GET YOUR JSP FILES RELOADED ON EACH REQUESTS --> <param-value>true</param-value> </init-param> </servlet>
URL/XML encoding issues
Sometimes, the default behavior of the Mashup UI does not fit your needs:
• A meta value is URL encoded where it should not be, leading to invalid links (or the opposite).
• A meta value is not XML escaped, leading to invalid HTML (or the opposite).
Having complex rules to try to determine whether we should escape the content or not would be very hard and will obviously fail at some point. Instead, a default behavior per situation that matches 90% of the cases is used. For example, when building links, as in the Hit titlelink field, meta values will be URL encoded by default.
Nevertheless, a few flags have been added to let the user invert the default behavior which allows you to control everything by yourself:
• !u: Invert URL encoding, for example: @{bi.publicurl!u}
• !x: Invert XML escaping, for example: @{bi.description!x}
• !h: Remove the highlight on metas
• You can use + or - signs after the exclamation mark to force or remove the value, for example: @{bi.publicurl!+u} or @{bi.description!-x}
You can also combine flags, for example: @{bi.name!ux}.
I can't see my new code after deploying a custom plugin
For MS Windows deployments, it may happen that you can't see your newly coded element after deploying a custom plugin (e.g. a custom widget).
The problem comes from the new version of Jetty (9.4.) which locks the files it accesses in mmap mode. For more information, see
The problem was fixed by adding the following servlet definition in the Mashup UI<DATADIR>/webapps/360-mashup-ui/WEB-INF/web.xml file: