-
-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Programmatically creating facelets with @View doesn't work #444
Comments
I wonder if nobody has tried this yet and the Quarkus MyFaces extension is not scanning for |
Standalone Jetty runnner of the example above just so i could make sure it works outside of Quarkus.
|
I opened a MyFaces Quarkus Extension ticket: https://issues.apache.org/jira/browse/MYFACES-4668 |
Also opened this: https://issues.apache.org/jira/browse/MYFACES-4669 |
I have a fix for Quarkus but waiting to hear back on the escaping issue with the UIOutput |
ok for MyFaces I had to update your example to be this using package org.primefaces.test;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.faces.annotation.View;
import jakarta.faces.application.StateManager;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.html.HtmlBody;
import jakarta.faces.component.html.HtmlCommandButton;
import jakarta.faces.component.html.HtmlDoctype;
import jakarta.faces.component.html.HtmlForm;
import jakarta.faces.component.html.HtmlOutputText;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.facelets.Facelet;
@View("/facelet.xhtml")
@ApplicationScoped
public class FaceletView extends Facelet {
@Override
public void apply(FacesContext facesContext, UIComponent parent) {
if (!facesContext.getAttributes().containsKey(StateManager.IS_BUILDING_INITIAL_STATE)) {
return;
}
var components = new ComponentBuilder(facesContext);
var rootChildren = parent.getChildren();
var htmlDoctype = new HtmlDoctype();
htmlDoctype.setRootElement("html");
rootChildren.add(htmlDoctype);
HtmlBody body = components.create(HtmlBody.COMPONENT_TYPE);
rootChildren.add(body);
HtmlForm form = components.create(HtmlForm.COMPONENT_TYPE);
form.setId("form");
body.getChildren().add(form);
HtmlOutputText message = components.create(HtmlOutputText.COMPONENT_TYPE);
message.setId("message");
HtmlCommandButton actionButton = components.create(HtmlCommandButton.COMPONENT_TYPE);
actionButton.setId("button");
actionButton.addActionListener(
e -> message.setValue("Hello, World! Welcome to Faces 4.0 on Jakarta EE 10"));
actionButton.setValue("Greet");
form.getChildren().add(actionButton);
body.getChildren().add(message);
}
private static class ComponentBuilder {
FacesContext facesContext;
ComponentBuilder(FacesContext facesContext) {
this.facesContext = facesContext;
}
@SuppressWarnings("unchecked")
<T> T create(String componentType) {
try {
return (T) facesContext.getApplication().createComponent(componentType);
} catch (ClassCastException e) {
throw new IllegalArgumentException("Component type " + componentType + " is not valid.", e);
}
}
}
} |
I also asked on Mojarra which is the correct behavior eclipse-ee4j/mojarra#5452 |
Got to the bottom of it. Mojarra is wrong and Myfaces is correct: jakartaee/faces#1796 To do it correctly package org.primefaces.test;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.faces.annotation.View;
import jakarta.faces.application.StateManager;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.UIOutput;
import jakarta.faces.component.html.HtmlBody;
import jakarta.faces.component.html.HtmlCommandButton;
import jakarta.faces.component.html.HtmlDoctype;
import jakarta.faces.component.html.HtmlForm;
import jakarta.faces.component.html.HtmlOutputText;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.facelets.Facelet;
@View("/facelet.xhtml")
@ApplicationScoped
public class FaceletView extends Facelet {
@Override
public void apply(FacesContext facesContext, UIComponent parent) {
if (!facesContext.getAttributes().containsKey(StateManager.IS_BUILDING_INITIAL_STATE)) {
return;
}
var components = new ComponentBuilder(facesContext);
var rootChildren = parent.getChildren();
var htmlDoctype = new HtmlDoctype();
htmlDoctype.setRootElement("html");
rootChildren.add(htmlDoctype);
UIOutput output = new UIOutput();
output.setValue("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
output.getAttributes().put("escape", false);
rootChildren.add(output);
HtmlBody body = components.create(HtmlBody.COMPONENT_TYPE);
rootChildren.add(body);
HtmlForm form = components.create(HtmlForm.COMPONENT_TYPE);
form.setId("form");
body.getChildren().add(form);
HtmlOutputText message = components.create(HtmlOutputText.COMPONENT_TYPE);
message.setId("message");
HtmlCommandButton actionButton = components.create(HtmlCommandButton.COMPONENT_TYPE);
actionButton.setId("button");
actionButton.addActionListener(
e -> message.setValue("Hello, World! Welcome to Faces 4.0 on Jakarta EE 10"));
actionButton.setValue("Greet");
form.getChildren().add(actionButton);
body.getChildren().add(message);
output = new UIOutput();
output.setValue("</html>");
output.getAttributes().put("escape", false);
rootChildren.add(output);
}
private static class ComponentBuilder {
FacesContext facesContext;
ComponentBuilder(FacesContext facesContext) {
this.facesContext = facesContext;
}
@SuppressWarnings("unchecked")
<T> T create(String componentType) {
try {
return (T) facesContext.getApplication().createComponent(componentType);
} catch (ClassCastException e) {
throw new IllegalArgumentException("Component type " + componentType + " is not valid.", e);
}
}
}
} |
@simasch i added this fix in Quarkus PrimeFaces 3.14.6.1 so we don't have to wait for a MyFaces release: https://github.com/quarkiverse/quarkus-primefaces/blob/804d53a3bd56d88c6077775f36db145d22377ba9/quarkus-primefaces/deployment/src/main/java/io/quarkiverse/primefaces/deployment/PrimefacesProcessor.java#L177-L197 |
Thank you @melloware |
I tried to add a programmatic view with the
@View
annotation, but when I access http://localhost:8080/facelet.xhml it returns 404The text was updated successfully, but these errors were encountered: