Velocity engine
A JIRA pluginok funkcióinak megjelenítését a Velocity template engine végzi, amely a velocity context-be bepakolt változókhoz nyújt hozzáférést a megjelenítési (view) részen. A működése a JSP/JSTL-hez hasonló, HTML kódba ágyazott velocity kód kerül a vm fájlokba, amiből tetszőleges kimenet nyerhető (itt *.jspa kiterjesztésű HTML). A szintaktika egyszerű: a változók előtt $ karaktert, a tulajdonságok minősítésére pontot, a vezérlési szerkezetek kelölésére # karaktert kell használnunk (pl: #if($authcontext.loggedInUser)...). A getter-ek a BSH-hoz és a Groovy-hoz hasonlóan elérhetők kompakt hivatkozással is, így a getLoggedInUser() helyett elég a loggedInUser is.
Veloeclipse
Az Eclipse a vm fájloknál nem emeli ki a kódot, így nehezen választható szét a html és a velocity szintaktika. Hozzárendelhetjük a vm fájlokhoz a beépített html editort, de akkor a velocity minden eleme egyszínű (fekete) lesz. Egy fokkal jobb megoldás a veloeclipse plugin telepítése az Eclipse-hez. Sajnos kódkiegészítést nem tud, de kiemeli a velocity vezérlést és változókat.
Velocity context
A JIRA nagy segítséget ad a context-be előre bepakolt utils osztályokkal, de sajnos 3 különböző dokumentáció 3 eltérő halmazt ad meg. A régebbi verzióknál elérhető volt a ctx változó a vm fájlokból, de az 5-ös verziótól felfelé már trükközni kell, hogy a teljes és friss listát megnézhessük (lásd lentebb).
HelloAction.java
package hu.lacimol.tutorial.webwork; import java.util.Map; import java.util.TreeMap; import com.atlassian.crowd.embedded.api.User; import com.atlassian.jira.component.ComponentAccessor; import com.atlassian.jira.user.UserUtils; import com.atlassian.jira.web.action.JiraWebActionSupport; public class HelloAction extends JiraWebActionSupport { private static final long serialVersionUID = 6545090412954507661L; private String userName; @Override protected String doExecute() throws Exception { log.debug("Entering doExecute"); String loggedUserName = getLoggedUserName(); User admin = UserUtils.getUser("admin"); userName = loggedUserName != null ? loggedUserName : admin.getDisplayName(); return SUCCESS; } public String getUserName() { return userName; } public String getLoggedUserName() { User loggedInUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(); return loggedInUser == null ? null : loggedInUser.getDisplayName(); } public Map<String, Object> getCtx() { // rendezett velocity paraméterek return new TreeMap<String, Object>(ComponentAccessor.getVelocityParamFactory().getDefaultVelocityParams()); } }
succes.vm
<html> <head> <title>HelloAction Success</title> </head> <body> <div style="background: #FFFFFF"> <h3>Velocity context examples</h3> <table> <tr> <td>action.userName:</td> <td>$action.userName</td></tr> <tr> <td>userutils.getUser("admin"):</td> <td>$userutils.getUser("admin")</td></tr> <tr> <td>authcontext.loggedInUser.displayName:</td> ## Feltétel <td>#if($authcontext.loggedInUser) $authcontext.loggedInUser.displayName #else Unknown #end</td></tr> <tr> <td>i18n.getText("lacimol.description"):</td> <td>$i18n.getText("lacimol.description")</td></tr> </table> <h3>Velocity context parameters ($ctx.size())</h3> <table> <tr> <td>Parameter</td> <td>Class</td> </tr> ## ciklus #foreach($param in $ctx.entrySet()) <tr> <td>$param.key</td> <td>$param.value.class</td> </tr> #end </table> </div> </body> </html>
Az eredmény
A lenti képen látható, hogy a context-ben lévő változók hogyan használhatók. Például az action.userName a HelloAction getUserName() metódusát hívja és jeleníti meg a kapott Stringet. A userutils-szal elkérhetjük egy adott felhasználó adatait, az authcontext-ből kivehetjük az aktuálisan belépett usert, és az i18n-nel pedig az aktuális nyelvnek megfelelő szöveget jeleníthetjük meg.
A fenti módosítások letölthetők SVN-en keresztül és becsomagolva a blog GoogleCode oldaláról a JiraDevTutor projektből.