bloggers bloggers

Marco Napolitano
Messaggi: 79
Stelle: 0
Data: 17/02/22
Jader Jed Francia
Messaggi: 63
Stelle: 0
Data: 18/02/21
Paolo Gambetti
Messaggi: 2
Stelle: 0
Data: 11/11/19
Katia Pazzi
Messaggi: 1
Stelle: 0
Data: 27/06/19
Ezio Lombardi
Messaggi: 11
Stelle: 0
Data: 10/04/18
Chiara Mambretti
Messaggi: 25
Stelle: 0
Data: 27/02/17
Serena Traversi
Messaggi: 3
Stelle: 0
Data: 21/07/16
Francesco Falanga
Messaggi: 8
Stelle: 0
Data: 14/06/16
Antonio Musarra
Messaggi: 2
Stelle: 0
Data: 18/11/13
Simone Celli Marchi
Messaggi: 6
Stelle: 0
Data: 09/07/13
Indietro

Aggiungere link custom alla portlet di login di Liferay 7.1

Fortunamente non ho animali mitologici da gestire come Jader, tuttavia però... ho Jader :)

Oggi voglio parlare un pò di OSGi illustrandovi una soluzione molto elegante per risolvere un problema che potrebbe capitarvi.

Il requisito iniziale, a parole, è molto semplice: rimuovere il link Password dimenticata dalla portlet di login nativa di Liferay 7.1 ed aggiungere un link custom che punti ad una pagina in cui è presente una portlet custom.

In sostanza il risultato finale deve essere il seguente (sotto al pulsante Accedi):

Soddisfare il primo requisito (rimuovere il link Password dimenticata) è semplice perchè si tratta di una configurazione da fare sull'istanza di Liferay.

Invece per aggiungere un link custom la cosa è un pochino diversa; se fossimo sulla versione 6.2 avrei già iniziato a parlare di hook della JSP di portale e sinceramente il mio approccio iniziale era di fare qualcosa di analogo anche sulla 7.1. Così ho iniziato a cercare nei sorgenti di portale il punto in cui venivano gestiti i link ed ho scoperto che... non venivamo gestiti! Non esplicitamente almeno. Cioè?!

Il file in cui vengono gestiti i link a fondo pagina nella portlet di login è il seguente:

[SRC]\modules\apps\login\login-web\src\main\resources\META-INF\resources\navigation.jspf

Ma al suo interno non ci sono link da modificare ma solamente taglib del tipo:

<liferay-util:dynamic-include key="com.liferay.login.web#/navigation.jsp#post" />

In pratica, per farla breve, tutti i link presenti vengono inclusi dinamicamente a runtime (dynamic-include per l'appunto); pertanto non bisogna modificare la portlet di login ma semplicemente realizzare un opportuno componente OSGi che venga caricato a runtime dalla taglib e si occupi di renderizzare il link custom.

Non mi soffermo oltre e vi mostro qualche riga di codice!

@Component(immediate = true, property = {
    "login.web.navigation.position=post", "service.ranking:Integer=100"
}, service = PageInclude.class)
public class MyNavigationPostPageInclude implements PageInclude {

    @Reference
    private LayoutLocalService _layoutLocalService;

    @Override
    public void include(PageContext pageContext)
        throws JspException {

        try {
            // La request serve sempre...
            HttpServletRequest request =
                (HttpServletRequest) pageContext.getRequest();

            // Sito di riferimento
            long groupId = PortalUtil.getScopeGroupId(request);

            // Recupero la pagina a cui deve puntare il link custom
            Layout layout = _layoutLocalService
                .fetchLayoutByFriendlyURL(groupId, false, "/my-friendly-url");

            if (layout != null) {
                /*
                 * Se il testo del link non è una traduzione di portale, allora
                 * è necessario recuperarla esplicitamente dal vostro bundle
                 */
                
                Locale locale = PortalUtil.getLocale(request);

                ResourceBundle resourceBundle =
                    ResourceBundleUtil.getBundle(locale, this.getClass());

                String message = LanguageUtil.get(
                    resourceBundle, "link-text-label");

                // Creazione della render URL da associare al link custom
                LiferayPortletURL myURL =
                    PortletURLFactoryUtil.create(
                        request, PortletKeys.MY_CUSTOM_PORTLET, layout,
                        PortletRequest.RENDER_PHASE);

                // Istanzio e configuro via codice la taglib aui:icon
                IconTag iconTag = new IconTag();
                iconTag.setCopyCurrentRenderParameters(false);
                iconTag.setIconCssClass("icon-undo");
                iconTag.setLocalizeMessage(false);
                iconTag.setMessage(message);
                iconTag.setUrl(myURL.toString());

                iconTag.doTag(pageContext);
            }
        }
        catch (PortalException e) {
            throw new JspException(e);
        }
    }
}
Non so voi, ma io la trovo una soluzione estremamente elegante che evita di mettere mano ai sorgenti di portale.
Commenti
Aggiungi Commento
mmm
Since overriding a JSP using an OSGi fragment or a Custom JSP Bag is not based on APIs there’s no way to guarantee that they’ll fail gracefully. Instead, if your customization is buggy (because of your code or because of a change in Liferay), you are most likely to find out at runtime, where functionality breaks and nasty log errors greet you. These approaches should only be used as a last resort.
Inviato il 28/01/20 11.10.