# eigene taglib für jsf 2.0 schreiben



## JanHH (16. Jan 2013)

Hallo,

brauche für meine JSF 2.0-Anwendung ein eigenes Tag (bzw. eine eigene Taglib). Wie ich das bei JSF 1.2 mache, weiss ich (hab ja das schlaue Buch, Core Java Server Faces, da stehts drin). Geht das nun bei 2.0 genauso, kann ich verfahren wie im Buch / bei 1.2? Oder gibts da auch Änderungen? Was muss ich zusätzlich beachten?

Ich brauche keine dieser neuen "composit components", sondern eine ganz klassische eigene Komponente.

Gruß+Danke
Jan


----------



## Sym (16. Jan 2013)

Funktioniert in JSF 2 noch genau so wie in JSF 1.x.

Du möchtest aber eine echte Java-Komponente referenzieren und kein xhtml-Template, oder? Bei letzterem wäre ein composite component nämlich das richtige.


----------



## Nogothrim (16. Jan 2013)

Was spricht denn gegen eine composite component bzw. was hast du vor? Wir haben damit recht gute Erfahrungen gemacht und der Aufwand ist gegenüber einer klassischen taglib Komponente schon extrem niedriger.


----------



## JanHH (16. Jan 2013)

Danke.

Hm, will halt ziemlich individuelles Zeug rendern, welches definitiv nicht mit den normalen jsf-Tags zu realisieren ist, und dessen Erscheinungsbild auch sehr stark vom dahinterliegenden Datenmodell abhängt. Denke nicht das so eine composite Komponente mir da weiterhilft.

Ich kann/will das nicht so detailliert beschreiben weil es in Richtung "Geschäftsgeheimnis" geht, hoffe ihr akzeptiert das.

Aber wenn ichs einfach so wie in 1.2 machen kann reicht das eigentlich auch aus.. damit komm ich schon klar.


----------



## sence (17. Jan 2013)

Hallo JanHH,

was einer Taglib in jsf 2.0 recht ähnlich kommt ist panelGroup-Binding.


```
private HtmlPanelGroup buildGetPagination() {
		HtmlPanelGroup menu = new HtmlPanelGroup();
               
                HtmlOutputText outText = new HtmlOutputText(); 
		outText.setValue("ich bin ein Text<br/>");
		outText.setEscape(false);
               menu.getChildren().add(outText);

                HtmlOutputText outText2 = new HtmlOutputText(); 
		outText2.setValue("ich bin auch ein Text<br/>");
		outText2.setEscape(false);
               menu.getChildren().add(outText2);

               HtmlOutcomeTargetLink link = new HtmlOutcomeTargetLink();
               link.setValue("Edit");
               link.setOutcome("edit");
               UIParameter param = new UIParameter();
               param.setName("id");
               param.setValue("500");
               link.getChildren().add(param);
 
              menu.getChildren().add(link);
return menu;
```

usw.. du kannst innerhalb der Implementierungsfunktion, auf jede JSF2 Komponente zugreifen und diese Verwenden.
HtmlOutputLink, HtmlCommandButton usw, diese werden dann entsprechend in der View gerendert.

Ein Vorteil zum Beispiel:
die selbst geschriebenen Komponente h:commandLink, soll z.B. automatisch alle Viewparameter includieren (includeViewParam=true)
das geht hier z.B. recht einfach.

grüße


----------



## JanHH (17. Jan 2013)

Danke, sieht interessant aus, mal anschauen.


----------



## Sym (18. Jan 2013)

Da Du leider nicht mehr zeigen kannst, ist es schwierig, hier vernünftige Hilfe zu geben. Ich habe bisher wenig gesehen, was nicht auch elegant mit einem CC umgesetzt werden könnte. Ich finde diese JSF-Neuerung ziemlich gelungen.


----------



## JanHH (19. Jan 2013)

Ja, sorry..

aber mir reicht an sich auch schon die Info, das ich das einfach wie bei JSF 1.2 machen kann.


----------



## JanHH (19. Jan 2013)

Wobei..

kann man bei Composite Components auch z.B. taglibs wie rich und prime faces benutzen? Das würde evtl. helfen.


----------



## sence (19. Jan 2013)

du meinst einen eigenen Namensraum ?
-> ja


----------



## Sym (20. Jan 2013)

Der Unterschied zwischen einem CC und einer taglib ist eigentlich nur, dass Du in einem CC die Variablen, die Du an das Template übergeben möchtest, deklarieren kannst. Damit weiß jeder Nutzer Deines Templates direkt, welche Möglichkeiten er/sie hat. Bei taglib-Templates ist dies nicht möglich, was bisher immer ein Manko war. Innerhalt eines CC kannst Du sonst genau dieselben Dinge tun, wie in einem taglib-Template.


----------



## JanHH (21. Jan 2013)

Hm, probier grad rum, nun zum "wie"..

also ich hab:

- eine UIMeineComponent-Klasse
- eine MeineComponentTag-Klasse
- eine MeineComponent.tld-Datei (in WEB-INF)

reicht dat? Oder noch was vergessen?

Denn.. funktionieren tuts bisher nicht..

Hab das wie in meinem JSF1.2-Buch beschrieben gemacht.


----------



## sence (21. Jan 2013)

im Ordner "resources" zwei Ordner anlegen (einer geht auch, wenn es überschaubar ist)
z.B. myComposites/outputComp

darin die CC erstellen "test.xhtml":


```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
         xmlns:composite="http://java.sun.com/jsf/composite">
<head>
</head>
<body>
<composite:interface>
    <composite:attribute name="actionLabel required="false" default="#{msgs.actionLabel}"/> 
</composite:interface>
<composite:implementation>
 /* Deine Inhalte z.B.*/
   <h:commandButton action="#{myBean.action()}" value="#{cc.attrs.actionLabel}"/>

     <composite:insertChildren/>
</composite:implementation>
</body>
</html>
```

in der .xhtml Datei, wo du die Composite Componente verwenden möchtest:
folgendes einbinden

```
<html .............
      xmlns:outComp="http://java.sun.com/jsf/composite/myComposites/outputComp">

<!-- jetzt wird auf die CC zugegriffen -->
<outComp:test actionLabel="meinLabelAlsParameterDerComposite">
Alles was hier steht, wird dort eingefügt, wo in deiner CompositeComponente das Tag: <composite:insertChildren/> steht
</outComp:test>
```

der CompositeComponente kann alles mögliche als Parameter übergeben werden.
z.B.:
- einfache Datentypen-Werte: String / int usw.
- EL Expressions
- Beans usw


----------



## JanHH (21. Jan 2013)

Danke aber ich will keine CC sondern eine gute alte handgebaute java-Komponente


----------



## JanHH (21. Jan 2013)

Ausserdem werd ich grad sauer. Alles was google liefert ist unübersichtlich und hilft kaum weiter.

Offenbar braucht man in JSF 2.0 keine UIComponent-Klasse mehr sondern die TagHandler-Klasse reicht aus und darf auch direkt rendern?

Und das TLD-File braucht man wohl nicht mehr?

Dafür aber meine.taglib.xml?

Kann mir nicht jemand mal einfach einen Link zu einem Tutorial schicken wie man sowas mit JSF 2.0 "standardmässig" macht? ich finde zwar viel aber nix hilft so richtig.


----------



## JanHH (21. Jan 2013)

Schritt für Schritt..

neue Erkenntnisse:

- ich brauche nur die UIComponent-Klasse, keine TagHandler-Klasse mehr
- ich brauche auch kein tld-File sondern nur my.taglib.xml
- die Komponente braucht auch nicht in der faces-config konfiguriert zu werden, sondern annotieren mit @FacesComponent reicht aus

Muss die my.taglib.xml ins WEB-INF oder ins META-INF Verzeichnis?

Und stimmen meine Hypothesen?


----------



## JanHH (21. Jan 2013)

Funktionert nicht, *resignier

Ich poste mal den Code, wäre schön wenn jemand mir sagt was da falsch ist..

Komponenten-Klasse:


```
@FacesComponent("de.abc.render.ABC")
public class UIABC extends UIPanel
{
	public static final String COMPONENT_TYPE = "de.abc.render.ABC";
	
	public UIABC()
	{
		this.setRendererType(null);
	}
	
	public void encodeBegin(FacesContext context) throws IOException
	{
		ResponseWriter writer=context.getResponseWriter();
		writer.writeText("Hallo HTML", null);
	}
}
```

my.taglib.xml:


```
<?xml version="1.0" encoding="UTF-8"?>
<!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://www.abc.de/abc</namespace>
    <tag>
	<tag-name>abctest</tag-name>
        <component>
            <component-type>de.abc.render.ABC</component-type>
        </component>        
    </tag>
</facelet-taglib>
```

jsf-Seite:


```
<?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:fn="http://java.sun.com/jsp/jstl/functions"
	template="/WEB-INF/templates/template.xhtml"
	xmlns:rich="http://richfaces.org/rich"
   xmlns:abc="http://www.abc.de/abc">
	<ui:define name="content">
	
	   <abc:abctest />
	</ui:define>
</ui:composition>
```


----------



## Sym (22. Jan 2013)

Hast Du Deine taglib auch in der web.xml eingetragen?

[xml]<context-param>
	<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
	<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>[/xml]


----------



## JanHH (22. Jan 2013)

Nee, muss man das? Wieso sagt mein schlaues Buch das nicht? Grummel. Ausprobier. Danke.


----------



## JanHH (22. Jan 2013)

Man glaubt es kaum, nu gehts! Danke!


----------



## Sym (22. Jan 2013)

Kein Ding. Immer gerne


----------



## JanHH (22. Jan 2013)




----------

