Skip to main content

Release 4.0 Support for Asynchronous Models

· 2 min read
Miguel Gamboa
HtmlFlow Author

This release introduces the following changes when migrating from HtmlFlow 3.x to 4.x:

  • DynamicHtml and StaticHtml are replaced by HtmlView and HtmlDoc, respectively. Both inherit from the new HtmlPage type.
  • The factory methods DynamicHtml.view() and StaticHtml.view() have been moved to the HtmlFlow class, becoming HtmlFlow.view() and HtmlFlow.doc().
  • The HtmlWriter interface, which previously defined standard methods (write and render) for all HTML pages, has been removed. With the dynamic nature of HtmlView (formerly DynamicHtml), render(model) and write(model) now require a model argument. These methods are not applicable to HtmlDoc (formerly StaticHtml), leading to the removal of HtmlWriter. The base class HtmlPage no longer defines write or render methods.
  • HtmlPage, HtmlView, and HtmlDoc are no longer parameterized with the model type. The model is now parameterized only when using the builder <M> dynamic(BiConsumer<E, M> consumer), where E is the parent HTML element and M is the model type.
  • The model object is now passed directly as a parameter to the consumer of a dynamic block (e.g., calling .dynamic((elem, model) -> ...)), eliminating the need for closures to capture the model object.

For example, the dynamic blocks approach has been simplified:

New 4.x approach
public void template(HtmlPage view) {
view.div().h2().<Pet>dynamic((h2, pet) -> pet.getName()).....
...
  • Partials are now the only place where closures can capture a model object of a different type than the enclosing template. When doing so, you must use a dynamic() block to prevent the partial from being stored as static HTML and ensure it renders whenever called with a model. If the partial uses the same model as its container, avoid the closure and instead use the model provided to the dynamic(cons) builder.
  • The addPartial() builder has been removed. A partial is now simply a consumer function of an HTML element (Consumer<E extends Element>). You can combine partials using higher-order function composition. The element serves as the parent HTML where HtmlFlow continues to emit code. Additional arguments corresponding to context models can also be passed to partial views.