judofyr / tubby

HTML templates as Ruby
Other
49 stars 3 forks source link

A few questions about this project I've found no answers to #2

Open alfuken opened 3 years ago

alfuken commented 3 years ago

I've stumbled upon this project in search of a decent Markaby implementation, and while it's not just it, it's still pretty close.. hence the curiosity:

judofyr commented 3 years ago
  • Is it production ready?

I'm using it in production, so yes.

  • How it performs compared to, say, Parkaby, Erubi, Slim, Haml, and plain old Rails helpers?

I haven't done any extensive benchmarks, but I would imagine that it's slower than Erubi/Slim/Haml, on-par with Rails helpers, and faster than Markaby.

However, in practice I've found that performance is not a big problem. Due to the way you end structure components it's often easy to use caching which also bypasses the database.

Here's a typical example of caching:

class Cached
  def initialize(*keys, &blk)
    @keys = keys
    @code = blk
  end

  def to_html
    Rails.cache.fetch(*keys) do
      target = String.new
      t = Tubby::Renderer.new(target)
      t << @code.call
      target
    end
  end
end

## Usage:

class UserPage
  def initialize(user)
    @user = user

  def posts
    @user.posts
  end

  def to_tubby
    Tubby.new { |t|
      posts.each do |post|
        t.h2(post.title)
      end
    }
  end
end

# And then we can use it somewhere else like this:
class Foo
  def to_tubby
    Tubby.new { |t|
      t << Cached.new("user-page", user.id) { UserPage.new(user) }
    }
  end
end

If you find that a component is slow to render, you can always replace to_tubby with a to_html where you can do whatever you want in there.

  • Have you tried reimplementing Parkaby/Markaby with Temple, btw? I'd love to give it a try!

I have not :)

  • Can it be used as a template within Rails? Is there a Tilt adapter?

There's no Tilt adapter, but it doesn't make much sense to have them as separate "template files". I've ended up creating app/components, add it to the autoload path, and then create plain classes inside there.

  • Is it complicated to add a support of writing tags without that t. prefix? It'd really sweeten up the syntax.

It might look nicer, but I'd argue against it. The t. prefix is quite important for making it easier to understand:

class UserPage
  def initialize(user)
    @user = user

  def posts
    @user.posts
  end

  def category_box(t, category)
    t.div(class: "category active") {
      t.a(category.name, href: "/categories/#{category.slug}")
      if category.description
        t << ": "
        t.span(category.description, class: "category-desc")
      end
    }
  end

  def to_tubby
    Tubby.new { |t|
      posts.each do |post|
        t.h2(post.title)
        post.categories.each do |category|
          category_box(t, category)
        end
      end
    }
  end
end

This has the following advantages:

alfuken commented 3 years ago

Oh, so do I understand it correctly, that it's not a template engine per se, but a tool for generating components and chunks of html, akin to Rails helpers?

I have not :)

That is rather a pity :(

judofyr commented 3 years ago

Oh, so do I understand it correctly, that it's not a template engine per se, but a tool for generating components and chunks of html, akin to Rails helpers?

Yes, that is a more accurate description. You can either use it for some components (and still use ERB/Slim views) or you can build your entire applications (include the layout!) out of Tubby components. I've quite successfully developed Tubby-only applications (e.g. no traditional templates used).

alfuken commented 3 years ago

I see... Though I'd still love to see a Markaby by you ;)