Open alfuken opened 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:
self
. self
is always the object itself and you can safely use instance variables and whatnot. There's no "magic" as in Markaby.to_tubby
method you easily distinguish between plain tags (t.div
), non-rendering helper methods (posts
) and rendering helper methods (category_box(t)
).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 :(
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).
I see... Though I'd still love to see a Markaby by you ;)
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:
t.
prefix? It'd really sweeten up the syntax.