eigene taglib für jsf 2.0 schreiben

JanHH

Top Contributor
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
 
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.
 
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.
 
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.
 
Hallo JanHH,

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

Java:
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
 
Zuletzt bearbeitet:
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.
 
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.
 
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.
 
im Ordner "resources" zwei Ordner anlegen (einer geht auch, wenn es überschaubar ist)
z.B. myComposites/outputComp

darin die CC erstellen "test.xhtml":

Java:
<?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
Java:
<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
 
Zuletzt bearbeitet:
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.
 
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?
 
Funktionert nicht, *resignier

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

Komponenten-Klasse:

Java:
@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:

Java:
<?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:

Java:
<?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>
 
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]
 

Neue Themen


Zurück
Oben