tipsy / j2html

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

The future of j2html #172

Open tipsy opened 3 years ago

tipsy commented 3 years ago

This issue is for disussing both the short term (next release) and long term (2.x release with API changes) to the project.

obecker commented 3 years ago

Hi, I suggest to move the current HtmlTag implementation into a new 2.x branch, since it is not compatible with the current 1.x releases (for example it is no longer a ContainerTag and behaves differently, see also https://github.com/tipsy/j2html/issues/138#issuecomment-822171574).

thomasphung commented 3 years ago

Is it currently possible to add CSS pseudo-classes to HTML elements through j2html?

sembler commented 3 years ago

You can specify your pseudo-classes in the usual style tag:

html(
    head(
        style(
            "p:first-child { color: blue; }"
        )
    ),
    body(
        p("This is some text."),
        p("This is some text.")
    )
);

Pseudo-classes and pseudo-elements cannot be declared inline on elements using the style attribute if that is what you are asking. That's due to the HTML spec., not j2html.

obecker commented 3 years ago

Hi, is there anything that prevents merging https://github.com/tipsy/j2html/pull/168 and https://github.com/tipsy/j2html/pull/152 ? Moreover, I believe some of the issues can be closed, don't you think?

tipsy commented 3 years ago

You didn't tag anyone, so I'll answer just in case. I don't think there is anything preventing them being merged (except the conflicts in #152), but I already feel like @sembler has a better overview of the project than I do, so I'm leaving it to him :)

sembler commented 3 years ago

At a glance I don't see anything wrong with those PRs. I'll review and merge shortly. Thanks!

sagesmith-wf commented 3 years ago

Hello, I am aware that this project is switching maintainers so you might not have an answer for some of these

Release Process

I am wondering if you guys have a general idea for the release process. I have a project that uses j2html pretty heavily for the UI and I am currently displaying trailing commas in several places. You guys have merged the fix #168, so I am wondering when I can expect to consume the new version now that it is merged. The last release was in 2019, so it seems like maybe there isn't any scheduled release mechanism in place yet.

Updating Dependencies

I have noticed that the latest release for this project was in 2019, which seems problematic because it means that dependencies are probably not being updated. For this to be a worthwhile dependency for consumers, it for sure needs to be up to date with all security fixes, and it is also nice if it can be running the latest versions of things where possible. Github has a mechanism called dependabot that can automatically update your dependencies that might be worth while for you guys to look into. I maintain several repos that use it and it works pretty well for me.

PR/Issue Templates

When making a PR and an Issue for this project, I noticed that you guys didn't have any templates which makes it kind of questionable what the expectation is for getting something merged. I think you guys could improve the average quality of a PR or an issue if you went ahead and added some templates that layout what you need to do in order to expect your PR to merge/Issue to be addressed. You can also add for example "please review: @tipsy @sembler" so people can at the right people. I just guessed tipsy because its on his fork and he had written most of the code.

sembler commented 3 years ago

Thanks for your input @sagesmith-wf . These are excellent ideas to move towards, and while you are right that I don't have answers for everything, here are my thoughts:

Release Process

I prefer frequent releases at regular intervals, such as a release every 2/3 months. As long as there are bug fixes or new features available to push out. Of course emergency releases for urgent bug fixes are always a possibility.

Updating Dependencies

Fortunately, from the user's perspective, j2html doesn't have any compile or runtime dependencies on other libraries; and I aim to keep it that way. I've been burned by plenty of libraries with out-of-date transitive dependencies. But, going back to the release process, keeping dependencies up-to-date every few months should be adequate. Checking for updates to the Maven plugins and testing libraries is easy enough.

PR/Issue Templates

I have not had much experience with this, but anything that helps get us clear and consistent PR sounds great to me. I'll look at the documentation you linked, and see what other projects are doing.

sagesmith-wf commented 3 years ago

New Feature Ideas

I don't know if you guys are planning any new features but here is a list of things I would use if they existed

Templated HTML

I would like to be able to do something like Django but with the built in type safety of java. It'd be nice to be able to stub out the static parts of the html and only have code for what is going to change depending on the input instead of having to visualize the entire html doc through chained method calls

Style methods off of the dom objects

It would be nice if the for example body() call allowed me to set attributes directly through it and provided type safety instead of relying on .style() which takes a String. Ex:

body(
    // other dom content)
    .color(Color.fromHex("#FF0000")
    .font(Font.fromFile("some path"))
    //etc     

Default subroutines for certain dom content

A lot of what I am doing which this library is displaying various data structures in some fashion. It would be pretty neat to make some of the methods able to handle some of the common usecases ex:

Displaying a list
List<String> myList = List.of("1", "2", "3", "4");
ul(myList);
Map<String, List<String>> myMap = Map.of(
         "1", List.of("a", "b", "c"),
         "2", List.of("d"),
         "3", List.of("e", "f")
         "4", List.of());
ul(myMap);

Rendering HTML

The render function being chained to the actual dom content calls feels a bit unexpected when using this library. I feel like it makes this library a lot less discoverable than simply funneling everyone in through some entrypoint . Maybe something like:

HTMLWriter.write(OutputStream out, DomContent content);

Custom Dataobjects

It'd be really handy to be able to just pass a data object for some of these things and have single reusable object that you can just set the data for. This becomes really useful when it gets really deeply nested structures that you need to swap out the data for and you don't want to think about the output. Ex:

Template template = ul("k", li("k2"));
template.render(Map.of(
      "k", List.of(1, 2),
      "k2", List.of(a, b));

You can take this concept really far and do the whole jackson getter thing to if you want, so something like:

class MyPojo {
      private String k;

      public String getK() {
           return k;
      }
}

Template template = ul("k");
MyPojo p = new Pojo("1);
template.render(p);

Simple WebServer

I don't think this is super necessary for the core library, but something that brought in for example jetty that made it super easy to get a functioning server running with this code I think this would have a chance at being a pretty widely used library.

obecker commented 3 years ago

Hi @sagesmith-wf, I think the cool thing about j2html is that it is both simple and extensible.

So, concerning (some of) your ideas:

Style methods

Actually, I would always use an inline css <style> sheet and add classes to the HTML tags. However, one could easily create some sort of StyleBuilder class that has all the convenience methods you need and use it like this:

div().withStyle(Style.builder().color("#FF0000").font("...").build())

And this StyleBuilder doesn't necessarily have to be part of j2html (but of course it could, if others find it useful).

Default subroutines for certain dom content

Same here - I wouldn't add these methods to j2html (to keep the j2html API rather compact), but nothing is stopping you from defining your own static methods in your project that do all the things you need. This is what I mean with extensible. At least I have such methods in my project that uses j2html. 😉

Nevertheless, I also miss some basic method like

Custom Data objects

I wonder if we can use the renderModel method that is already there. The only thing to do is to create some custom DomContent class that will access the given model during rendering. Something like new ParsedText("Hello ${name}") that will parse the given string and accesses the model object to find the value for name. In any case, this should be something that is explicitly "activated" (can't find a better term) to keep the fast rendering for users that don't need this functionality.

Simple webserver

Sounds to me as this could be a separate project/module. (I can't comment on the Django suggestion as I don't know what it is exactly doing ...)

Just my 2 cents ...

obecker commented 3 years ago

By the way, something that I am thinking about is to use/extend j2html to create SVG. With the current 1.4.0 version I would just create a lot of static methods that create ContainerTag instances with the proper SVG tag names. The latest changes would probably require creating a lot of specific classes ... However, I wonder if this is something worth to share, i.e. have it as a separate library. In that case it probably makes sense to split j2html in a base library (j2markup) and a HTML library (j2html), so that j2svg would depend on j2markup, but not necessarily on j2html. What do you guys think?

sembler commented 3 years ago

Between the suggestions here and some of my own thoughts lately, I'm seeing that making a new release should be our first priority. This month if possible @tipsy.

Following that I'd like to suggest something painful and mundane... we update the documentation and website. As not-fun as that might be, I've come to realize that we need to more clearly communicate the nuances and capabilities of this library. The example page is a good overview, but doesn't fully explain many of the design ideas behind the API (or warn against the wrong way to do things, as we so often see in the project issues page) and doesn't even touch on the deeper features like custom DomContent and using model objects during rendering.

But don't let that put you off from adding more suggestions! Let's consider them to be part of v2.0 (because they'll probably involve breaking changes) and keep exploring possibilities. Some of the smaller changes like helper methods should be possible to integrate before v2.0.

tipsy commented 3 years ago

Just ping me when you want me to release. Is the master branch back to being non breaking now?

obecker commented 3 years ago

There is still the special HtmlTag class that behaves differently. Adjusting existing code should be not that difficult, however, it's a breaking change.

obecker commented 3 years ago

One more thought for @sagesmith-wf ...

Release Process

I am wondering if you guys have a general idea for the release process. I have a project that uses j2html pretty heavily for the UI and I am currently displaying trailing commas in several places. You guys have merged the fix #168, so I am wondering when I can expect to consume the new version now that it is merged. The last release was in 2019, so it seems like maybe there isn't any scheduled release mechanism in place yet.

I strongly agree that there should be a new release pretty soon, but do you realize, that you can temporarily fix the trailing comma behavior in your own code? It's a static method that contained this bug, all you have to do is to create your own version of this method and use it instead of the j2html version. ✌️

obecker commented 3 years ago

I've opened a new issue to discuss the HtmlTag problem: https://github.com/tipsy/j2html/issues/185

tipsy commented 3 years ago

@obecker @sembler say the word and I'll release 1.5.0.

obecker commented 3 years ago

sembler commented 3 years ago

I'd like to drop one last PR in a few minutes. But after that, YES!

tipsy commented 3 years ago

I ran into POM file pom.xml specified the -f/--file command-line argument does not exist when trying to release, I guess it's related to moving the library into a subdir.

Edit: http://maven.40175.n5.nabble.com/Release-plugin-release-project-from-within-subdirectory-td126661.html 🤔

Edit2: This is probably more accurate: https://stackoverflow.com/a/17639344/7916291

Edit3: Seems to be fixed!

Edit4: Getting Unauthorized now, not sure if related to subdir or something else.

Edit5: Something funky is going on with the release plugin.

Edit6: 14th time's the charm!

tipsy commented 3 years ago

@sembler @obecker 1.5.0 is out, great job both of you!

I found one small breaking change when updating the website to 1.5.0:

image

sembler commented 3 years ago

Awesome! Big thanks to you and Oliver!

That's a small surprise to round off the day. I hadn't considered method references that much before, but we can take them into account going forward.

Ordiel commented 2 years ago

Adding my 2 cents, is there any consideration for the handling of WebComponents which would require defining custom HTML Tags?

sembler commented 2 years ago

@Ordiel Yes there is. At the moment defining your own HTML tags is easy enough using TagCreator.tag() and TagCreator.emptyTag(). That is a shallow representation of tagging that provides no further support towards web components. I'm preparing a new release soon to add support for <template> and <slot>, but what else would benefit you when working with web components?

Ordiel commented 2 years ago

Sorry I didn't noticed this on my notifications, I'll have to play around a bit more with whats already there to find out its current limitations, I'll be sure to add my comments here, I've been a lurker of j2html for a while and I just got myself to put it to use a few weeks back (with the intent of creating the content of a library intended to dynamically create web components) so far it has been great yet I as you mentioned I noticed the lack of those two tags. I'll do my homework and provide feedback

sembler commented 2 years ago

That sounds great @Ordiel ! The tags and global attributes have been added in 1.6.0 so you should be good to start.