# Widgets via JSP
You can implement a widget in a JSP if it should be visible in an article page, independently of the extraction. This technique relies on shadowing an existing template, and this article explains the steps to follow.
Use this technique if:
- A widget appears at different places in Desktop, and should always be visible in the same position in Marfeel.
- With MarfeelPress sites where the widget might not be rendered at extraction-time.
# Create the widget
- Create the widget as any other, in the
widgets.json
, with the corresponding provider implementation for an XPLib tenant, or 3pi for a legacy tenant.
TIP
If the widget is not in the article pages where it should appear, use id
instead of selector
in the widgets.json
.
# Shadow a template
- Search in MarfeelXP for the best JSP to import your widget.
WARNING
The JSP must be empty to be shadowed. Marfeel highly discourages shadowing JSPs with content, as you would lose backward compatibility.
If you can't find a suitable jsp, speak to your tech lead: it is possible to create a new empty jsp and inject it in the right place.
- Shadow the template in the tenant's site repository.
TIP
Test the newly created template without the widget first, to make sure it works independently of the widget's implementation.
- Create a new, different JSP file named after the widget in the tenant's
/themes/layouts/
folder.
example.com/themes/layouts/youtubeWidget.jsp
- Inject this widget's JSP in the shadowed template:
<%@taglib prefix="dali" uri="http://dev.marfeel.com/jsp/mrf/dali" %> <!-- dali tag library -->
<dali:importThemePart url="layouts/youtubeWidget.jsp" />
# Fill the Widget template
This cascading JSP logic makes it 100% clear to other developers why the original template was shadowed.
- Add the widget logic to the Widget JSP:
<%@taglib prefix="dali" uri="http://dev.marfeel.com/jsp/mrf/dali" %> <!-- dali tag library -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!-- c tag library -->
<%@page pageEncoding="UTF-8" %> <!-- language code -->
<c:forEach items="${item.detailItem.widgets}" var="widget">
<c:if test="${widget.src.contains('your-widget-src')}"> <!-- Look for id instead of src if providers -->
<dali:detailsWidgetGenerator element="${widget}" articleUri="${item.uri}">
</dali:detailsWidgetGenerator>
</c:if>
</c:forEach>
TIP
This example uses the widget src
attribute to make sure it exists.
As Widget Providers don't have the src
attribute, look for the id
instead:
<c:if test="${widget.src.contains('your-widget-src')}"> <!-- For 3pi -->
<c:if test="${widget.id.contains('your-widget-id')}"> <!-- For provider -->
WARNING
detailsWidgetGenerator
can only be used with a widget that has a selector
.
If your widget has no selector
in the widgets.json
file, you can't use the dali
tag.
This is common for MarfeelPress sites.
In this case, you must display the widget manually instead of relying on the dali
tag to inject it.
# Debugging
TIP
No compilation is required to see a JSP update, you can simply refresh the page.
If the widget does not appear:
- Make sure the imports are correct
- You can print variables directly to see their value, with
${item}
for example. - Debug the widget's implementation with breakpoints in the TypeScript source code
JSP debugging example:
<%@taglib prefix="dali" uri="http://dev.marfeel.com/jsp/mrf/dali" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page pageEncoding="UTF-8" %>
${item} <!-- Prints the entire item information -->
<c:forEach items="${item.detailItem.widgets}" var="widget">
<c:if test="${widget.src.contains('your-widget-src')}">
<dali:detailsWidgetGenerator element="${widget}" articleUri="${item.uri}">
</dali:detailsWidgetGenerator>
</c:if>
<c:else>
${widget.src} <!-- Prints the source if different -->
</c:else>
</c:forEach>