Ciao a tutti!
Il post di quest'oggi tocca un argomento che prima o poi tutti devono affrontare: vogliamo salvare delle piccole preferenze utente e renderle "persistenti" senza magari scomodare delle tabelle di dominio.
Aggiungo a questo che le preferenze di cui parliamo non le vogliamo "per portlet", come solitamente fareste quando si parla di preferences, ma le vogliamo "cross portlet", quindi a livello di portale.
In più, potrebbe essere comodo farlo utilizzando una funzionalità javascript, in modo da poter notificare al server, in tempo reale, i parametri che vogliamo rendere persistenti nelle preferenze dell'utente.
Qui ognuno di noi, di solito, si mette a pensare alla via più (elegante | facile | veloce | generica) per farlo.. Senza considerare che in Liferay magari il lavoro è già stato fatto per voi e dovete solo riusarlo! ;)
Ed ecco che entrano in scena due funzionalità out-of-the-box: Liferay.Store()
(da usare in pagina via javascript) e la classe SessionClicks
per leggerne i valori.
Ma vediamo un po' di codice! :)
In pagina prepariamo il campo per leggere il valore inserito dall'utente e salvarlo lato server:
...
<aui:select id="myPref" name="<portlet:namespace/>myPref" label="my-pref">
<aui:option value="first-message">
<liferay-ui:message key="first-message"/>
</aui:option>
<aui:option value="second-message">
<liferay-ui:message key="second-message"/>
</aui:option>
<aui:option value="third-message">
<liferay-ui:message key="third-message"/>
</aui:option>
</aui:select>
...
<aui:script use="liferay-store">
var node = A.one('#<portlet:namespace/>myPref');
node.on(
'change',
function(event) {
var instance = this;
// Qui accade la magia..
Liferay.Store('<portlet:namespace/>myPref', instance.val());
}
);
</aui:script>
In pratica, ogni volta che viene selezionato un nuovo valore dal menù a tendina, viene invocata la chiamata a Liferay.Store() che, come potete ben immaginare, altro non fa che chiamare una funzionalità lato server che salva la preferenza dell'utente a livello di portale.
Eggià, perché la novità rispetto alla preferenze che usate di solito è che questa funzionalità salva i valori a livello di portale; li rende quindi disponibili cross sessione e li potete accedere da ogni punto del vostro codice java..
Ma come fa a fare questa magia? :)
Se attivate il monitor delle connessioni HTTP sul vostro browser di fiducia, noterete che al cambio del valore del menù a tendina viene effettuata una post a questa servlet:
/c/portal/session_click
che, se cercate nei sorgenti di portale, troverete mappata sulla "Main Servlet" (ovvero:com.liferay.portal.servlet.MainServlet
) che utilizza delle simpatiche action di Struts per eseguire i comandi che le vengono mappati sul percorso '/c/
'.
Quindi la magia accade nella Struts Action com.liferay.portal.action.SessionClickAction
che altro non fa, se guardate il sorgente, che leggere i parametri di request e inserirli nel db usando la classe SessionClicks
.
A questo punto il nostro lavoro è finito!
Adesso, tutto quello che dovete fare, è leggere questo valore lato server. Questa chiamata fa esattamente quello che vi aspettate:
String myValue = SessionClicks.get(request,
renderResponse.getNamespace() + "myPref", "");
Aggiungo a questo che potete utilizzare la SessionClicks
anche all'interno del vostro codice java per salvare preferenze che volete rendere persistenti. Attenti però: come quando lavorate con la sessione, il problema della concorrenza è sempre in agguato, quindi comportatevi bene! ;)
Infine, concludo dicendo che è sempre possibile utilizzare l'oggetto Liferay.Store() anche per leggere le proprietà che avete impostato:
Liferay.Store.get('myId', callback)
Liferay.Store.getAll('myId', callback)
La differenza è che 'get' ritorna il valore della preference mentre il 'getAll' ritorna un oggetto JSON che mappa la hash di valori ritornati. Ancora, maggiori dettagli nel codice della classecom.liferay.portal.action.SessionClickAction.
Un piccolo addendum, prima di concludere!
Ma questa SessionClicks
come fa a rendere persistenti a livello di portale queste preferenze?
Anche qui la magia è presto svelata:
PortalPreferences preferences =
PortletPreferencesFactoryUtil.getPortalPreferences(request);
Attraverso questa interfaccia gli oggetti che passate arrivano ad essere salvati nella tabella di db 'portalpreferences
' attraverso la PortalPreferencesLocalServiceUtil
.. E qui il giro vi dovrebbe essere già chiaro.. ;)
Spero che questo post vi sia d'aiuto! ;)
Buona Pasqua a tutti!!! :)
P.S. Se volete il codice della portlet, abbiamo inaugurato l'account D'vel su GitHub; qui trovate la portlet di POC per questa roba:
Se invece cercate le portlet open source che rilasciamo, qui trovate il repository aziendale: