Coder Social home page Coder Social logo

Comments (10)

saurori avatar saurori commented on July 1, 2024 3

@mikestefanello I made an initial pass at trying templ and converting the codebase to use it. Check it out at this branch if you're interested. My initial impressions of templ are mostly positive, but there were some gotchas:

  1. I was expecting to use "plain Go" in the template functions but that's not exactly how it works. For example, you can't build variables inside a templ function such as allNames := append(names, "John"), so you need to sometimes approach writing the template differently, or call plain Go functions from the templ function.
  2. There is a question of which strategy to use for passing data into the template (see prop drilling). I opted for "Coupling" and passing in the Page struct
  3. It's an advantage to have everything type safe in the template but that means operating on data passed as any requires casting in the templ function such as if form, ok := page.Form.(*types.LoginForm); ok {.

I think I would need to build a real app to see if there are any sharp edges with this implementation.

from pagoda.

leomorpho avatar leomorpho commented on July 1, 2024 2

Thanks for your awesome work @mikestefanello, this is truly a fantastic starter for anyone wanting to use Go/HTMX. @saurori thanks for your work on templ integration too. I used your branch to start a few projects now and I must say I love the Pagoda setup even more now, templ truly makes the dev experience fantastic compared to the default html package. Not sure if it's useful, but my branch lives here. I meant to keep it clean but it's got a lot of extra changes I use by default in my projects...perhaps it will be useful.

from pagoda.

mikestefanello avatar mikestefanello commented on July 1, 2024 1

I would expect that too. Thanks for the detailed steps. I am able to reproduce. I'll have to look in to it. I don't understand why the middleware is being executed if there's no match for the route.

from pagoda.

mikestefanello avatar mikestefanello commented on July 1, 2024 1

Thinking about this some more, the middleware should definitely be executing even if there's no match found. I don't see anyway for the cache middleware to know that it's a 404 at that point. I don't think Echo exposes that in any way, unfortunately. I think you'll just have to clear the cache if you're making a change like this. I added a cache-clear command to the Makefile to make this easier. I also included stop and down.

from pagoda.

mikestefanello avatar mikestefanello commented on July 1, 2024

You're welcome. I'm glad to hear that you're finding it useful. Keep me posted on your experience with templ. I've been looking at it recently and it looks very promising. I'm waiting for the Goland plugin to be done so I can really dive in. While the std lib templates are quite powerful and flexible, they do leave a lot to be desired, and it was not easy to provide the solution that I did; and I'm not too thrilled with how some of the function and nested templates calls came out.

  1. I'm a little confused with the example that you outlined. Those would be separate routes so one should not affect the other. Can you elaborate a little further? By default, nothing will be cached. If you set your Page's Cache.Enabled to true, the output will be cached. The cache middleware will currently only serve from the cache if it's a GET request and the user is not logged in. You can, of course, alter that behavior to fit your needs though. As I'm writing this I think I realize what you meant - by change do you mean in the browser or the route definition? I guess you mean the latter (I assumed the former at first). Did you restart the application after making that change? I haven't tested this but I assume you would get a 404 if there is no /about route registered any more. I don't think the middleware would even get executed.
  2. Yes, that would work. I used the same trick to get the templates directory. I was hoping by now there would be a better/standardized way of doing that, but it looks like there's not. I used the solution I have now because it's not too uncommon that your build process includes the config at the root when building an image, for example. So with the multiple paths, it allows there to be some flexibility and preference.
  3. I agree. I can add that in quickly.

from pagoda.

saurori avatar saurori commented on July 1, 2024

Regarding Number 1:

Steps to reproduce:

  1. run make up
  2. run make run
  3. In a browser, visit localhost:8000/about
  4. Kill the app
  5. Change this line in the router to g.GET("/about-us", about.Get).Name = "about-us"
  6. run make run
  7. In a browser, visit localhost:8000/about

I would expect a 404, but the page renders 200

from pagoda.

saurori avatar saurori commented on July 1, 2024

Well that's unfortunate. It might be useful to put a warning about that in the README. Thanks for looking into that and adding those additional commands.

from pagoda.

mikestefanello avatar mikestefanello commented on July 1, 2024

It looks like you made some really great progress. I like the approach that you took. My initial thought when I saw templ and considered using it with this project was dealing with potential import cycle problems between the templates package and either the controller or routes package, but it looks like you avoided that nicely (though as you pointed out in the 3rd point, maybe this will become an issue). I also think the coupling approach is superior to context for the templates. And your last point about using this in a real app was another concern of mine.. it may seem nice in a simple example but a real problem in a more complex one.

from pagoda.

saurori avatar saurori commented on July 1, 2024

Funny you mention it, I did hit an import cycle problem but found a way around it. It was an issue in controller tests but I changed those tests to use package controller_test to avoid.

I think the coupling approach is the way to go. For number 3, you could get around type casting by passing additional structs to a template such as page.Component = pages.Contact(&page, &contactForm) and not set the page.Form. I was trying to stick to the original design choices and change less, but looking at it now I think setting less any types on Page is a better approach.

from pagoda.

mikestefanello avatar mikestefanello commented on July 1, 2024

@leomorpho Thank you! I'm very glad this project turned out to be useful for you. Please feel free to share any feedback about this and templ. Maybe at some point I'll bring templ in. I haven't yet given it a real try yet but I plan to.

from pagoda.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.