I have created a custom JSF component with the following code:
@FacesComponent("MainMenu")
public class MenuComponent extends UIComponentBase {
private List<MenuItem> items;
private String title;
public MenuComponent() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<MenuItem> getItems() {
return items;
}
public void setItems(List<MenuItem> items) {
this.items = items;
}
public String getFamily() {
return UI.FAMILY;
}
}
Then I added a renderer for component:
@FacesRenderer(componentFamily = UI.FAMILY, rendererType = "MainMenuRenderer")
public class MenuComponentRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
MenuComponent menuComponent = (MenuComponent) component;
ResponseWriter responseWriter = context.getResponseWriter();
responseWriter.startElement("ul", menuComponent);
responseWriter.writeAttribute("class", "sidebar-menu", "");
// заголовок
responseWriter.startElement("li", menuComponent);
responseWriter.writeAttribute("class", "header", "");
responseWriter.write(menuComponent.getTitle());
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
MenuComponent menuComponent = (MenuComponent) component;
ResponseWriter responseWriter = context.getResponseWriter();
responseWriter.endElement("ul");
// title
responseWriter.endElement("li");
// menu items
for (MenuItem menuItem : menuComponent.getItems()) {
responseWriter.startElement("li", menuComponent);
}
}
}
Then registered component in taglib.xml:
<tag>
<tag-name>mainMenu</tag-name>
<component>
<component-type>MainMenu</component-type>
<renderer-type>MainMenuRenderer</renderer-type>
</component>
<attribute>
<name>items</name>
<required>true</required>
</attribute>
<attribute>
<name>title</name>
<required>true</required>
</attribute>
</tag>
In JSF page I used it in the following way:
<mds:mainMenu items="${sidebar.menuItems}" title="Главное меню"</mds:mainMenu>
Tag is related with sidebar managed bean, bean is simple as possible:
@ManagedBean(name = "sidebar", eager = true)
@RequestScoped
public class Sidebar {
@Inject
private MenuService menuService;
private List<MenuItem> menuItems;
public Sidebar() {
System.out.println("Hello, world!");
}
@PostConstruct
public void init(){
setMenuItems(menuService.getMainMenu());
}
public List<MenuItem> getMenuItems() {
return menuItems;
}
public void setMenuItems(List<MenuItem> menuItems) {
this.menuItems = menuItems;
}
}
But! I have value of "title" attribute in my renderer, but not "items"! How to pass "items" attibute value to my component? When I debug, there is no call to "Sidebar" bean. What is wrong in my code?