> Docs > Html Builder > Custom Builder
HtmlPiece
is the most basic type for html builders. An html document is a tree of HtmlPiece
nodes.
The HtmlPiece
interface has a single abstract method render(indent, out)
which renders the piece as a sequence of chars as the piece would appear in an HTML document.
An html builder interface contains nested subtypes of HtmlPiece
, and builder methods that build such pieces. The builder methods should be default
methods; the interface should have no abstract methods. App can access members of the interface simply by inheritance.
For example, the standard builder Html5
contains element types like Html5.DIV
and builder methods like Html5._div()
. Subclasses of Html5Doc
(which implements Html5
) access DIV
and _div()
through inheritance .
A custom builder interface follows the same pattern, for example
import static bayou.html.Html5.*; public interface HtmlMisc { public static final HtmlMisc misc = new HtmlMisc(){}; default public A _url(String url) // do not use stand element names like _a(), _link() { return html5._a(url).href(url); }
This builder can be reused by different projects and teams. User code simply extends/implements HtmlMisc
to access its members.
An instance of HtmlMisc
is also provided (as HtmlMisc.misc
) in case inheritance is not suitable in some situations. Actually here in the body of _url()
method, we access Html5
builder methods through the Html5.html5
instance.
You may also consider static builder methods, if that's more convenient; e.g. CsrfToken._input()
.
The _url()
example is just a syntax sugar to build a standard piece. Next, let's try creating some custom pieces.
Let's start with a simple custom piece, Hex
, which simply renders an integer in hex format. Not very exciting.
public interface HtmlMisc { ... public class Hex implements HtmlPiece { int x; public Hex(int x) { this.x = x; } @Override public void render(int indent, Consumer<CharSequence> out) { out.accept("0x"); out.accept(Integer.toHexString(x)); } } default public Hex _hex(int x) { return ContextParent.add(new Hex(x)); }
The builder method _hex()
creates a Hex
piece and adds it to the context parent.
public class TestHtml extends Html5Doc implements HtmlMisc { ... _p("The value is ", _hex(47806));
As a more complex example, let's build a bar chart. The chart contains a list of integers; its color can be configured; its caption can contain arbitrary html pieces. The API should look like:
public class TestDoc extends Html5Doc implements HtmlMisc { ... _barChart(100, 150, 200).color("red").caption( "Much Data", _br(), _url("http://example.com") );
We'll need a BarChart
class, with a color(String)
method, and a caption(Object...)
method. It'll be rendered as a list of <div>
elements with varying lengths.
default public BarChart _barChart(int... data) { return ContextParent.add(new BarChart(data)); } public class BarChart implements HtmlPiece { int[] data; public BarChart(int... data) { this.data = data; } String color="#777"; public BarChart color(String color) { this.color = color; return this; } DIV caption = new DIV().style("text-align:center"); public BarChart caption(Object... children) { caption.add(children); return this; } @Override public void render(int indent, Consumer<CharSequence> out) { DIV div = new DIV().style("border:1px solid black; width:300px;"); for(int x : data) div.add( new DIV().add(x).style(String.format( "width:%dpx; background-color:%s; margin:5px;", x, color))); div.add(caption); div.render(indent, out); } }