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

Use go templ instead of go template #75

Open
nithin-bose opened this issue Aug 18, 2024 · 19 comments
Open

Use go templ instead of go template #75

nithin-bose opened this issue Aug 18, 2024 · 19 comments
Labels
enhancement New feature or request

Comments

@nithin-bose
Copy link

Go Templ is an alternate templating engine that can compile templates down to go code. I find the added compiler support to be really helpful for medium to large projects.

Is it possible to integrate it?

@mikestefanello
Copy link
Owner

Hi - great question. I am familiar with the project but I haven't yet given it a full try, especially within the scope of this. The last time I tried it out, which was a while ago, the Goland integration and tooling was lacking too much for me to feel comfortable considering it as a default for this project. I do need to try that again. Which IDE are you using and how has your experience been?

When I first came across templ, I was definitely impressed and completely onboard with the concept. Adding type-safety to that layer is a huge gain; not to mention other short-comings with standard templates. However, I was a bit hesitant to include it as a default here because it's quite a heavy dependency, requires you to know the language, patterns, add an IDE plugin, build step(s), etc. I'm not sure which is easier: moving to that or moving away from it.

There's nothing stopping you from using templ within pagoda. I can't say how much work that would be, but it will get pretty tricky, given that there's a lot of functionality baked in to the template renderer, everything else tied to the templates, and how they are built, parsed, and rendered, etc. If you do go down this path, please share your experience along the way. I will also be trying this out somewhat soon, if time permits, so I can evaluate it again and reconsider it being part of this.

@nithin-bose
Copy link
Author

Hi @mikestefanello,

I am also just getting used to Templ. I used it in a couple small projects before and am planning to use it in a new project which is when I stumbled upon Pagoda. Pagoda has most of everything I need except for templ. Thanks for the time and effort you have put into Pagoda.

I am on VS Code with the templ plugin installed. It has autocomplete and validations. Yes, it leaves a lot to be desired, but its serving my needs so far. I am a huge fan of devcontainers so having the dependencies and IDE plugins installed is sorted. I agree with the rest of your points. There is a significant barrier to entry for go-templ. That said IMHO, learning go-templates or go-templ seems to have the same effort, especially considering that go-templ lets me use go in the template itself and most of the "magic" in the template renderer in pagoda might just go away.

I did start integrating templ into pagoda. I haven't got it working yet. So far, the following is my progress:

  • Made template renderer an interface
  • Created templ renderer
  • Moved page cache out of template renderer so that both the template renderer and templ renderer can use it

As of now I am converting all gohtml files to templ files trying to keep the current structure as much as possible. Seems like I might have to change all the handlers as well and make some changes to the page module.

I am trying to keep the current template renderer and the templ renderer together. But as I am progressing I feel that just replacing the current template renderer with the templ renderer might be easier. I would love to know your thoughts about this.

I was planning to give a PR once I get this working, but if you are interested in the changes, I can keep in on a branch in my fork. Let me know.

@mikestefanello
Copy link
Owner

You're very welcome - I'm glad to hear that you're finding it useful.

I've been a bit busy lately, and I still need to wrap up the final cleanup of backlite so that's in a sufficient state (especially now that pagoda uses it). After that, I do intend to devote a good amount of time to re-investigating templ and seeing if it makes sense to incorporate it. I will certainly keep an eye on your branch but please also update this thread as you make progress and let me know what's working and what's not.

Thanks

@nithin-bose
Copy link
Author

nithin-bose commented Aug 25, 2024

I am working on the go-templ branch in my fork.

As for the progress:

  • I removed the go html renderer and replaced it with the templ renderer thereby making things a lot let complicated. I also removed the template renderer interface as it was no longer needed.
  • Page cache is still outside the template renderer
  • Since layout, pages and data in the page behave like function and function parameters in templ, the fields related to go html layout and Data in the page struct was removed in favor of a new templComponent field. I would like to remove this field and Title to somewhere else but haven't figured out where yet
  • Converted all gohtml files to templ files
  • The forms and data structs which were defined in the handlers packge was causing a circular dependency error when used from go-templ files. So moved them to a helpers package for the time being. I am looking for a better solution, suggestions are welcome
  • Made changes to the Makefile to generate templ files on run

I am yet to re-implement the functions in funcMap so things like urls and images are broken or rather nothing other than rendering works as of now.

If you get time, do take a look at my branch and let me know if you have any suggestions. This rabbit hole is turning out to be a lot deeper than I thought.

@nithin-bose
Copy link
Author

Updates:

  • re-implemented the funcMap module, renamed it to funcs as there is no map anymore
  • removed sprig as a direct dependency
  • Updated link/url/file functions in templates

Everything seem to work fine now. Would be great if you can give it a try, in case I missed something

@mikestefanello
Copy link
Owner

Looks like great progress so far. I've only done a very quick review, but I will dig in more once I get some time to.

Circular dependencies was the first potential problem I thought of when I initially considered templ. I haven't put any though towards a solution yet, but as you mentioned, we'd definitely need a good pattern for it (something other than helpers, etc).

Some quick thoughts/observations:

  • A noticed a few bugs clicking around the UI (paging is broken, the link on the error page is broken, the About link is broken).
  • It would be nice to use consts for the route names in the components (they currently exist in handlers but can be moved).
  • Maybe the Page concept doesn't quite fit any more, and something else should be considered? Not sure, just noting that we're not locked in to using it.
  • Can the Funcs just be moved to templates so they can be called directly?
  • Thinking (way) further ahead, I wonder if the form templates can be improved (ie, reusable element components, easier way to add the inline validation stuff, etc)
  • Also thinking ahead, it feels like there should be a way to bake in the HTMX integration in a more seamless manner.

Big problem, for me, is it seems like the Goland plugin does not work at all.

@mikestefanello mikestefanello added the enhancement New feature or request label Aug 27, 2024
@mikestefanello
Copy link
Owner

I've never tried gomponents and had a very negative reaction when I initially saw it, but I was curious if you've tried it out, since it seems to try to accomplish similar things as templ.

@nithin-bose
Copy link
Author

Fixed the following:

  • paging
  • the link on the error page
  • About link

Circular dependencies was the first potential problem I thought of when I initially considered templ. I haven't put any though towards a solution yet, but as you mentioned, we'd definitely need a good pattern for it (something other than helpers, etc).

I totally agree. helpers is too generic and has a tendency for eventually becoming a "dump all" package. A good pattern will need some thought and I would rather do it properly, if we are doing it at all. It'll be a major structure change anyways.

It would be nice to use consts for the route names in the components (they currently exist in handlers but can be moved).
Yes, I was thinking of making the routeNames an explicit type. In fact I had given it a try but had the following problems:

  • Calling it from handlers in the templ files causes a circular dependency so it has to be moved out of handlers, if so where to move it?
  • If we move to a different package, add a route will require changes in two packages handlers and the new package where we are moving the route names to. IMHO changing multiple is a hassle.

Maybe the Page concept doesn't quite fit any more, and something else should be considered? Not sure, just noting that we're not locked in to using it.

Maybe moving the layout, component, title and pagination to a different rendering struct might be a good idea since rest of the fields are project level or request level and can be populated from something like a middleware and added to the context, which will avoid passing around page everywhere. What do you think?

Can the Funcs just be moved to templates so they can be called directly?

Yes it can be, but since the module requires web *echo.Echo which is not available in templates, it will have to be initialized in template_renderer anyways, so I didn't think it made much difference. But If think putting it in templates is better, it can be done.

Thinking (way) further ahead, I wonder if the form templates can be improved (ie, reusable element components, easier way to add the inline validation stuff, etc)
Also thinking ahead, it feels like there should be a way to bake in the HTMX integration in a more seamless manner.

Yes agreed

I've never tried gomponents and had a very negative reaction when I initially saw it, but I was curious if you've tried it out, since it seems to try to accomplish similar things as templ.

I had the same negative reaction as you did. IMHO I am not sold on it

  • html support is far more mature in IDEs etc
  • It looks tedious (using Raw) if you have a lot of custom html attributes like if you use htmx, alpine or anything these days. Kind of beats the purpose IMHO
  • Not sure how well and how many custom attributes can be supported if all they ever will be
  • Personally, even though I try to avoid JS as much as possible unless the business needs an SPA or something, my background is HTML/JS and am more comfortable with them. This could change in the future though.

I haven't paid for an IDE yet, maybe I should :)

@mikestefanello
Copy link
Owner

Without IDE support, I really have a hard time taking templ seriously for this project. That's just such a blocker in my mind. Not to mention, all of the other various issues we've discussed. I do like the concept and objective of templ, and I certainly understand that standard Go templates leave a ton to be desired, but perhaps it's just not ready yet.

Are there any other libraries or approaches to consider and try out?

@nithin-bose
Copy link
Author

Not at the moment.

I am planning to use pagoda with templ in my future projects. If I make any further changes, I'll push it to the branch and update here.

@leomorpho
Copy link

leomorpho commented Sep 10, 2024

For anyone interested, I have a heavily modified fork that uses Templ instead of gotemplates. I personally haven't looked back. I trust my code so much more than back when I had to pass maps to components. I love the static typing, and it's got some quite fantastic template composition syntax. It's OSS: https://github.com/leomorpho/GoShip
I'd be happy to merge some things back into Pagoda, but it's just gotten quite off-road from my initial pagoda fork...

@mikestefanello
Copy link
Owner

Looks great, thanks for sharing. I'll be sure to dig in and try it out once I have some time available. I'm sure I'll have some templ questions when I start exploring it more.

@PraveenGandhi
Copy link

My fork: PraveenGandhi/pagoda on top of @nithin-bose 's fork.

I am trying to replace Ent with SQLc. Hope it is a reference for anyone who wants.

Thank you @mikestefanello. As pagoda is well thought through and well organized, it is not much complicated to replace Ent with SQLc.

Disclimer:

  1. I am not proficient in Go, hence there is room for improvement.
  2. Not concentrated on Unit testing.

Thank you.

@PraveenGandhi
Copy link

I've never tried gomponents and had a very negative reaction when I initially saw it, but I was curious if you've tried it out, since it seems to try to accomplish similar things as templ.

I understand your thoughts,
but I have seen similar thing in Python: FastHtml and python community loves it.

As far as I have understood it, it is general server rendered web framework. At the same time it has opiniated way with Pico CSS and HTMX

Other referrences:
FastHtml Foundation
FastHtml Tech Stack
FastHtml Components Example

https://github.com/guettli/frow--fragments-over-the-wire
HOTWIRE (HTML over the wire)

@mikestefanello
Copy link
Owner

@PraveenGandhi You're very welcome. Thanks for the kind words. Out of curiosity, why did you prefer SQLc over Ent? Are you planning to use Gomponents? Have you worked with it enough to be able to share your experience/feedback, etc? I have never really given it a try but I intend to at some point just to see.

@mikestefanello
Copy link
Owner

mikestefanello commented Oct 8, 2024

htmgo is another interesting (early) project that's similar to gomponents but looks like it has htmx baked in.

edit: I see that gomponents has some htmx support as well.

@nithin-bose
Copy link
Author

nithin-bose commented Oct 8, 2024

My problem with libraries like htmgo is the whole write html in go thing.

In my experience when working on small or indie projects, I usually integrate prebuilt html themes (open source or even purchase from someone) which are mostly in html/css/js.

As for medium to large projects, I have generally had front end developer(s) create the themes also usually in html/css/js. Or go full out with a client side rendered framework like react, in which case go would only expose APIs.

In both of the cases above, converting html to go for the additional compiler support seems unnecessary, tedious and slow. Also something like templ seems like a good midway in both the cases, where I get compiler support in places where I interfere with front end code. I am really having trouble understanding who libraries like htmgo or gomponents are catering to. IMHO its more of a niche unless I am missing something.

Edit: I have used Streamlit in python for quick and dirty visualisations in internal dashboards but I dont think I will ever use it for anything customer facing (IMHO not too flexible) .

Just my 2 cents, please take it with a sack of salt 😄

@mikestefanello
Copy link
Owner

I do agree, just like I originally did. I was just trying to keep an open mind and compile a running list of all options/alternatives to consider. It's interesting to see how each project approached the problem and perhaps we can see what each of them do well. I did give gomponents a serious try recently and I just don't see how it's practical or appealing. Maybe for very simple use-cases it can be, but I'm not sure. I imagine I would feel very much the same if I tried htmgo.

@PraveenGandhi
Copy link

PraveenGandhi commented Oct 10, 2024

why did you prefer SQLc over Ent?

I am new to GO ecosystem, I found SQLc simple to use, I have no opinoin about Ent, but in general I do not like full blown ORMs and prefer to use SQL and some kind of DSL like jOOQ, ExposedSQL

Are you planning to use Gomponents?

At the moment, I don't have any immediate plans to use Gomponents, but I'm open to exploring it in the future.

htmgo is another interesting (early) project that's similar to gomponents but looks like it has htmx baked in.

Thanks for the suggestion! I did notice that the development feedback loop with htmgo seems a bit slower compared to Pagoda, in terms of seeing changes reflected in the browser. However, I plan to give it another try and explore it further down the line.

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

No branches or pull requests

4 participants