Oto kilka przykładów, gdzie moim zdaniem warto się zastanowić nad stworzeniem własnego taga:
- komponent pojawia się w wielu miejscach w systemie (np. inputy formularza, panele ze zdefiniowanym nagłówkiem, popup'y, itp.)
- zestaw kontrolek do obsługi ValueObject tj. MoneyVO, PeselVO, PostCodeVO, itd.
- bardzo złożony fragment kodu, który może i teoretycznie nie wymaga stworzenia własnego tag'a, ale dzięki czemu nasz kod stanie się o wiele bardziej czytelny
Jak stworzyć własny tag
Zaczynamy od stworzenia pliku, który będzie naszym szablonem. Definiujemy w nim wszystkie komponenty, które będą tworzyły nasz komponent.
Ważne fragmenty:
- <ui:param> czyli możliwość definiowania własnych parametrów, dzięki którym nasz kod jest bardziej czytelny
- <ui:insert> tag, który definiuje nam pewną sekcję, którą możemy wykorzystać/zastąpić w momencie wykorzystania naszego taga. Atrybut name defiuje nazwę sekcji.
- #{name} zmienna name, która może zostać ustawiona w momencie wykorzystania taga
<?xml version="1.0" encoding="UTF-8"?> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <ui:param name="labelMsg" value="#{not empty labelMsg ? labelMsg : 'defaultLabel'}" /> <div> <ui:insert name="label"> <div style="width: 150px; float:left;"> <h:outputText id="#{name}_label" value="#{labelMsg}" /> </div> </ui:insert> <h:inputText id="#{name}_inputText" value="#{value}" /> </div> </ui:composition>Następnym krokiem jest stworzenie facletowego tagliba, w którym definiujemy:
- namespace,
- miejsce położenia naszych tagów.
<?xml version="1.0"?> <!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"> <facelet-taglib> <namespace>http://mkorwel.blogspot.com/components</namespace> <tag> <tag-name>formInputText</tag-name> <source>tags/com/blogspot/mkorwel/formInputText.xhtml</source> </tag> </facelet-taglib>Ostatnim krokiem jest zarejestrowanie naszego tagliba w web.xml.
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <context-param> <param-name>facelets.LIBRARIES</param-name> <param-value>/WEB-INF/my.taglib.xml</param-value> </context-param> </web-app>U mnie struktura plików wygląda następująco:
Wykorzytanie
Poniżej krótki fragment kodu, który przedstawia przykładowe wykorzystanie tagu formInputText.
Ważne fragmenty:
- <ui:define> możliwość nadpisania sekcji <ui:insert> zdefiniowanej wewnątrz tagu. Atrybut name wskazuje którą sekcję chcemy nadpisać.
<?xml version="1.0" encoding="UTF-8"?> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:my="http://mkorwel.blogspot.com/components" template="/WEB-INF/templates/default.xhtml"> <ui:define name="content"> <h:form> <my:formInputText name="example1" labelMsg="Example1: " value="#{myFormController.example1}" /> <my:formInputText name="example2" labelMsg="Example2: " value="#{myFormController.example2}" /> <my:formInputText name="example3" value="#{myFormController.example3}" /> <my:formInputText name="example4" value="#{myFormController.example4}"> <ui:define name="label"><div>My custom label:</div></ui:define> </my:formInputText> </h:form> </ui:define> </ui:composition>
Dokumentacja
Kiedy komponent/tag jest już gotowy, to warto go opisać. Dokumentacja jak wiadomo jest bardzo ważna, czasami ważniejsza od samego kodu, dlatego należy zadbać o ten punkt niezwykle starannie. Do tej pory nasz komponent jest widoczny przez nasze IDE, ale niestety nie podpowiada nam co możemy z nim zrobić. Aby to się zmieniło wystarczy stworzyć plik TLD (Tag Library Descriptor) w którym starannie opisujemy nasz tag oraz każdy atrybut, jaki w nim występuje. Do opisu możemy używać znaczników html, dzięki czemu nasz opis będzie bardziej przyjemny.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.2</tlib-version> <jsp-version>2.0</jsp-version> <short-name>mir</short-name> <uri>http://mkorwel.blogspot.com/components</uri> <display-name>mkorwel</display-name> <description>My Components</description> <tag> <name>formInputText</name> <tag-class /> <body-content>empty</body-content> <description>Pole formularza renderowane wraz z etykietą.</description> <attribute> <name>name</name> <required>true</required> <type>java.lang.String</type> <description>Nazwa pola. Na podstawie tego atrybutu generowane jest id komponentów.</description> </attribute> <attribute> <name>value</name> <required>true</required> <type>java.lang.String</type> <description>Wartość pola tekstowego.</description> </attribute> <attribute> <name>labelMsg</name> <type>java.lang.String</type> <description>Etykieta pola</description> </attribute> </tag> </taglib>