Hi! I finally came up with something that I have been looking for. It might be more suitable for Wicket 1.5 because it's not very compatible (read: not very lean) with current wicket:
Wicket Without Markup ;) Well, yes there is markup for each component, but when you lay them out on the page, the markup is component-contained. So coding an application feels like a breeze for the Java developer, and the HTML developer can strictly stick to styling the (contained) components themselves. Maybe I omitted something, but here comes the example. Let me know what you think. Does it inspire any fresh ideas in you? Is this an old idea? I recall listviews having been mentioned once as a solution for producing markup-less code ... maybe I have re-invented the weel or something. HomePage.html: <html> <body> <strong>Wicket Quickstart Archetype Homepage</strong> <form wicket:id="form"> <wicket:container wicket:id="root-content-id"></wicket:container> </form> </body> </html> HomePage.java: public class HomePage extends WebPage { /** */ private static final long serialVersionUID = 1L; private final MarkupNoLongerRequiredContainer rootContainer; private final MarkupNoLongerRequiredContainer row1; private final MarkupNoLongerRequiredContainer row2; private final MarkupNoLongerRequiredContainer row3; private final Form<Void> form; /** * */ public HomePage() { add(form = new Form<Void>("form")); form.add(rootContainer = new MarkupNoLongerRequiredContainer("root-content-id")); { rootContainer.add(row1 = new MarkupNoLongerRequiredContainer()); row1.add(new Label(GID, "Hello world")); row1.add(0, new Label(GID, "<br/>").setEscapeModelStrings(false)); // Change row before row1.add(0, new Label(GID, "<br/>").setEscapeModelStrings(false)); // Change row twice before row1.add(new Label(GID, "<br/>").setEscapeModelStrings(false)); // Change row once after } { rootContainer.add(row2 = new MarkupNoLongerRequiredContainer()); row2.add(new Label(GID, "Type your name here:")); row2.add(new InputField(new TextField<String>(GID, Model.of("...")))); } { rootContainer.add(row3 = new MarkupNoLongerRequiredContainer()); row2.add(new Label(GID, "<br/>").setEscapeModelStrings(false)); // Change row before row2.add(new InputField(new Button(GID, Model.of("Clickme")) { @Override protected void onComponentTag(ComponentTag tag) { tag.put("type", "button"); super.onComponentTag(tag); } })); } } } InputField.html: <wicket:panel> <input wicket:id="generic-child-id"/> </wicket:panel> InputField.java: public class InputField extends Panel { /** */ private static final long serialVersionUID = 1L; public <InputFieldDataType, InputFieldType extends FormComponent<InputFieldDataType>> InputField(InputFieldType inputFieldType) { super(MarkupNoLongerRequiredContainer.GID); add(inputFieldType); } } MarkupNoLongerRequiredContainer.html: <wicket:panel> <wicket:container wicket:id="listview-id"> <wicket:container wicket:id="generic-child-id"> </wicket:container> </wicket:container> </wicket:panel> MarkupNoLongerRequiredContainer.java: public class MarkupNoLongerRequiredContainer extends Panel { /** */ public static final String GID = "generic-child-id"; /** */ private static final long serialVersionUID = 1L; private final List<Component> children = new ArrayList<Component>(); public MarkupNoLongerRequiredContainer() { this(GID); } @Override protected void onBeforeRender() { super.onBeforeRender(); } /** * @param id */ public MarkupNoLongerRequiredContainer(String id) { super(id); super.add(new ListView<Component>("listview-id", children) { /** */ private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem<Component> listItem) { Component component = listItem.getModelObject(); if (!component.getId().equals(GID)) { throw new IllegalStateException("Currently handles only children with id " + GID); } listItem.add(component); } }); } public boolean add(Component component) { return children.add(component); } public void add(int index, Component element) { children.add(index, element); } public boolean addAll(Collection<? extends Component> collection) { return children.addAll(collection); } public boolean addAll(int index, Collection<? extends Component> collection) { return children.addAll(index, collection); } public void clear() { children.clear(); } public boolean contains(Object o) { return children.contains(o); } public boolean containsAll(Collection<?> collection) { return children.containsAll(collection); } public int indexOf(Object o) { return children.indexOf(o); } public boolean isEmpty() { return children.isEmpty(); } public int lastIndexOf(Object o) { return children.lastIndexOf(o); } public ListIterator<Component> listIterator() { return children.listIterator(); } public ListIterator<Component> listIterator(int index) { return children.listIterator(index); } public boolean remove(Object o) { return children.remove(o); } public Component remove(int index) { return children.remove(index); } public boolean removeAll(Collection<?> collection) { return children.removeAll(collection); } public boolean retainAll(Collection<?> collection) { return children.retainAll(collection); } public Component set(int index, Component element) { return children.set(index, element); } public List<Component> subList(int fromIndex, int toIndex) { return children.subList(fromIndex, toIndex); } public Object[] toArray() { return children.toArray(); } public <T> T[] toArray(T[] a) { return children.toArray(a); } } ** Martin --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org