Migrating from HtmlFlow 3.x to 4.x

  • Replace DynamicHtml and StaticHtml by new HtmlView and HtmlDoc. Both inherit from new HtmlPage type.

  • The factory methods DynamicHtml.view() and StaticHtml.view() are now part of the class HtmlFlow corresponding to its methods HtmlFlow.view() and HtmlFlow.doc().

  • Removed the HtmlWriter interface which defined the standard API (methods write and render) to any kind of HTML page in the context of HtmlFlow. Given the dynamic requirements of DynamicHtml (now called HtmlView) we need an argument model on render(model) and write(model) methods. Yet, those methods were illegal for StaticHtml (now called HtmlDoc) which does not depend on a model object given its static nature. So, the HtmlWriter disappeared and the new HtmlPage base class does not define any write/render method.

  • HtmlPage, HtmlView and HtmlDoc, are no longer parametrized (generic) with the type of the model. Now the model is only parametrized on the use of the builder <M> dynamic(BiConsumer<E, M> consumer), where E is the parent HTML element and M is the type of the model.

  • The model object is now passed as parameter of the consumer of a dynamic block (i.e. calling the builder .dynamic((elem, model) -> ...)). There is no more use of closures to capture the model object. Thus, the former 3.x style of dynamic block, such as:

    public void template(DynamicHtml<Pet> view, Pet pet) {
      view.div().h2().dynamic(h2 -> pet.getName()).....
      ...
    

Is now on API 4.x:

public void template(HtmlPage view) {
    view.div().h2().<Pet>dynamic((h2, pet) -> pet.getName()).....
    ...
  • Partial (aka fragment) are the only place where we may use closure to capture a model object that has a different type from the enclosure template. In that case, remember when including that partial to use a dynamic() block to avoid storing it internally as a static HTML block and make it render whenever you call it with a model. Yet, if the partial use the same model as its container, then it should avoid the closure and use the model received on the consumer of its dynamic(cons) builder. For example, for views used inside a layout view.

  • Removed the addPartial() builder. A partial (aka fragment) is only a consumer function of an HTML element, i.e. Consumer<E extends Element>. Thus, you may simply combine partials through higher-order functions composition. The element is the parent HTML where HtmlFlow will continue to emit HTML. We may also use consumers with additional arguments corresponding to models (i.e. context objects) used in the partial view (i.e. HTML fragment).