• petepete 5 days ago

    Rails gives you the tools to do much of this already.

    For example, this:

        html_slice :stuff do
          h1 'hello world' # @html_slice[:default] << '<h1>hello world</h1>'
          text # @html_slice[:default] << '<p>Lorem ipsum dolor sit amet</p>'
          div do
            _ '<b> some raw html </b>'
          end
        end
    
    Could be written in a helper like this:

        safe_join([
          tag.h1('Hello world'),
          tag.p('Lorem ipsum dolor sit amet'),
          tag.div(<<~RAW.html_safe)
            <b>some raw html</b>
          RAW
        ])
  • judofyr 5 days ago

    I've written a similar library and I can heavily recommend the approach: https://github.com/judofyr/tubby. The main difference between this and the other approaches (HTML_slice, Phlex) is that Tubby doesn't depend on inheritance or module inclusion. This means that it's slightly more verbose (you need to add "t." to each tag), but there's never any confusion of what `self` is nor any method collision. (For instance, looking at HTML_slice it appears that if you class defines the instance variable "@html_slice" weird things will happen.)

    If you have a server-side rendered Ruby application with complicated view logic I can 100% recommend this approach (either Tubby, HTML_slice or Phlex). It's a super powerful way of structuring logic. You can create standalone classes which represents concepts (e.g. I've created a "ResourceCalendar" which renders a calendar view showing which resources are available for a given day), add methods which act on these, and finally make them renderable. It's heavily composable. It's very similar to React components, but here you also have the power of defining separate methods instead of having everything be hooks (with weird limitations) at the top of the component.

    I also wrote a longer article here describing the different types of components you can build using Tubby: https://github.com/judofyr/timeless/blob/master/posts/compos.... I think this would also apply to HTML_slice and Phlex.

    • baggy_trough 5 days ago

      Personally I like to have little snippets like these as Slim/ERB templates and render them like partials (I have a utility class to actually do the rendering to avoid excess logging and make it easier to pass arguments and blocks to them.)

      I just never liked "rendering" html elements directly in a ruby method. Feels weird, man.

      • xutopia 5 days ago

        I’m seeing tons of explorations around ways to do things happen today in the Ruby world. Starting to feel like 2008 again with an explosion of cool fun projects.

        • nine_k 5 days ago

          Oh yes, cool fun projects, not (only) buttoned-up necktie-wearing moneymaking projects. Cool fun projects have a higher chance to discover some new gold (among reams and heaps of underbaked fluff, of course), while strictly-moneymaking projects quite rationally choose to play it safe and only use time-proven stuff.

        • bandrami 5 days ago

          Every so often, html injection is re-invented. It's particularly funny when it's Ruby, which came to prominence because of a framework that promised to end html injection forever. But the cycle of life continues.

          • block_dagger 5 days ago

            Reacting to the example in the Readme: Rails controllers are not the place to put view logic. That’s what the view layer is for. I suggest showing a view helper as an example instead.

            • caiusdurling 5 days ago

              Looks similar to https://www.phlex.fun/ at first glance

              • dominicrose 5 days ago

                > The Nav menu above could be refactored into a Ruby class to allow developers to add items to the menu without needing to understand the underlying HTML.

                Either you do SSR and you have to understand HTML or you don't and you can just build a Typescript front-end that calls a ruby server that doesn't generate HTML.

                Lets say you do SSR and don't want to understand the HTML, then you can separate the project in two parts and give one part to someone else, but I still don't see how mixing classes and HTML helps.

                Functions or templates are enough for SSR, lets be honest this is just about doing OOP everywhere and it creates coupling which IMO is no good.

              • quechimba 5 days ago

                I did a similar thing using another approach (unpublished) where I use blocking fibers and fiber locals [1] instead of instance variables so you don't have to wrap anything in a `html_slice`-block or keep track of ids. Maybe I should open a PR.

                I did this as an experiment for my own web framework [2] but I decided to use Haml for templating instead.

                [1] https://docs.ruby-lang.org/en/3.4/Fiber.html#method-c-5B-5D

                [2] https://github.com/mayu-live/framework

                • burlesona 5 days ago

                  Neat! I made a library very similar to this once, and I know there are others. Must be one of those itches that’s fun to scratch.

                  https://github.com/burlesona/html_rb

                  • kissgyorgy 5 days ago

                    Here is another component library for Python: https://compone.kissgyorgy.me

                    • tekknolagi 5 days ago

                      Why do you use a combination of `__class_getitem__` and `__getitem__`?

                      • kissgyorgy 9 hours ago

                        so these both work: html.Div["content"] and html.Div(class_="red")["content"]

                    • null_investor 5 days ago

                      The author could collaborate on developing further phlex!