tipsy / j2html

Java to HTML generator. Enjoy typesafe HTML generation.
https://j2html.com/
Apache License 2.0
765 stars 136 forks source link

Rendering multiple elements in one go without parent element #136

Open ijabz opened 5 years ago

ijabz commented 5 years ago

Typically I can not create the whole html file in one go, typically I may have to create the header and main contents of the file at one point, but then finish the file creation at later date. So often this means I cannot use j2html to create the tag, because I will add the closing at a later point, this is fine but then if I have multiple elements that should attach directly to body rather than to an intermediate element I have to make multiple calls to render(), it would be nice if I could do once.

i.e I want output to be

<body>
<h1>..</h1>
<h2>..</h2>
....

so I have to render h1 and h2 separately

Alternatively I could output

<body>
<div>
<h1>..</h1>
<h2>..<./h2>
</div>

and then I could just render div, but now I am modifying my html just to suit j2html

Would be nice if I could render i one go/store the elements as a special list that j2html could render accordingly

Real code extract

StringBuilder sb = new StringBuilder();
            sb.append(BootstrapReports.getReportPageSongChangesFilesStart(FixSongsController.isPreview(), InfoMessage.MSG_FIX_SONGS_REPORT_TITLE.getMsg(), FixSongsReport.getInstance().getMenuItems()));
            sb.append(DIV_CLASS_CARD_STYLE_BORDER_0_DIV_CLASS_CARD_BODY);

sb.append(h1(InfoMessage.MSG_FIX_SONGS_REPORT_TITLE.getMsg() + " " + currentReportId).renderFormatted());
sb.append(h2(title + ": " + artistCredit).renderFormatted());
pointbazaar commented 4 years ago

You do not need multiple calls to .render(), even when you build your html in increments.

You just need to reverse the order of creating the elements. The innermost elements have to be created first, then the outermost elements, and then you can render it all in one call.

Example:

var t1 = h1(InfoMessage....);
var t2 = h2(title + ": "+ artistCredit);

return body(t1,t2).render()

This way you avoid using StringBuilder and also avoid the extra <div>.

Alternative (using Array to store elements):

var arr = new ContainerTag[]{h1(...), h2(...)};
return body(arr).render()