Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View with dynamic and static attribute / Placement of dynamic() block #100

Open
shimikano opened this issue Dec 7, 2023 · 6 comments
Open

Comments

@shimikano
Copy link

The following test creates a view, adds an attribute to a div() in a dynamic() block, and then adds a static attribute.

  @Test
  public void dynamicAttribute() {
    var view = HtmlFlow.view(page -> {
      page
        .div()
          .<String>dynamic((div, model) ->
            div.addAttr("dynamic-attribute", model)
          )
          .addAttr("static-attribute", "world")
        .__();
    });

    var actual = view.render("hello");

    var expected = """
      <div dynamic-attribute="hello" static-attribute="world">
      </div>""";

    assertEquals(expected, actual);
  }

The rendered string is:

<div dynamic-attribute="hello">
static-attribute="world"
</div>

As opposed to the expected:

<div dynamic-attribute="hello" static-attribute="world">
</div>

If I move the static-attribute line into the dynamic() block, the test passes.

So I wonder if this is a bug or if dynamic() is not supposed to be used like this.

Using HtmlFlow 4.1.

@fmcarvalho
Copy link
Member

That is an issue that we were not able to solve.

In that kind of HtmlFlow view we are evaluating the static blocks before-hand without running the continuations of dynamic blocks. Thus, we have no way to know whether a dynamic block is closing (i.e. <div>) or leaving the tag opened (i.e. <div). We had to take a decision, and we assumed that is better to presume that a dynamic block always kept the tags closed.

That’s the reason of that behavior observed on your test.

Since, we do not have immediate solution for this we suggest that you move your static attribute into the dynamic block as you proposed in your work-around.

There will not be any significant overhead of processing a further attribute in dynamic.

Thank you

@shimikano
Copy link
Author

Dear Fernando

I understand, thank you very much for your swift reply and explanation.

Best regards

@shimikano
Copy link
Author

Sure thing, I'm happy to do so.

Off-topic, but I'm experimenting with HtmlFlow as a replacement for Thymeleaf. So far I'm happy with the reduced complexity and not having to deal with limitations of the external Thymeleaf DSL. For example, adding the CSRF token to the view? - Just do it yourself in Java (or Kotlin) instead of having to rely on Thymeleaf-provided magic (${_csrf.token}). This is quite liberating. The better performance is also a big plus, of course.

Disadvantages are the poorer readability compared to HTML-like templates, the inability to easily copy-paste existing HTML into your templates (sure, Flowifier may help, but it's an extra step), and the poor formatting/indenting support of IDEs (cf. #91). For the latter, Kotlin extension functions help BTW.

I'll report on further findings later on.

@changchengqin
Copy link

I have developed a rudimentary plugin that serves its purpose, but it hasn't been submitted to the IntelliJ Marketplace. You'll need to manually install the plugin JAR file. I hope it proves useful to everyone.
@shimikano
https://github.com/changchengqin/indent-folder

@shimikano
Copy link
Author

Thank you @changchengqin.

I'm using Kotlin extension functions to create a mini DSL with proper scoping using the language-level blocks ({ and }), e.g.:

htmlFlowDoc {
  table {
    thead {
      tr {
        th { t("Sample th 1") }
        th { t("Sample th 2") }
      }
    }
    tbody {
      tr {
        td { t("Sample td 1") }
        td { t("Sample td 2") }
      }
    }
  }
}

This has helped a lot when authoring HtmlFlow templates.

@fmcarvalho fmcarvalho reopened this Apr 9, 2024
@fmcarvalho
Copy link
Member

Just to let you know that we have just released HtmlFlow 4.6 with full compatible API for Kotlin builder with function literals with receivers that are fully compatible with the already exiting Java API. In truth you can mixed both.

All examples are updated here https://htmlflow.org/features and snippets include a tab for Kotlin. Now you can write as bellow:

System.out.doc {
  html {
    head {
      title { text("HtmlFlow") }
    }
    body  {
      div {
        attrClass("container")
        h1 { text("My first HtmlFlow page") }
        img { attrSrc("http://bit.ly/2MoHwrU") }
        p { text("Typesafe is awesome! :-)") }
      }
    }// body
  } //html
} // doc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants