#69 Markaby in Helper
Do you ever need to generate HTML code in a helper method? Placing it directly in Ruby strings is not very pretty. Learn a great way to generate HTML through Markaby in this episode.
- Download:
- mp4Full Size H.264 Video (9.49 MB)
- m4vSmaller H.264 Video (6.59 MB)
- webmFull Size VP8 Video (22.7 MB)
- ogvFull Size Theora Video (15 MB)
Thanks for screencast.
I personally believe, that... screencasts, such as... Railscasts, PeepCode and so on... will help the US, will help the South Africa, will help Iraq and Asian Countries with educations... for th future of our children!
Ok, seriously, cool screencast!
Haml also has really nice helper support.
Here's what it would look like:
http://pastie.caboo.se/93426
I was about to mention HAML as well you beat me to it :D
ooo.. I knew Markaby would be cool to use I just never figured out a good way. This looks awesome, as usual ;)
Teaching us that one line that goes in the "markaby" method is just what a lot of us need. It is very simple and well documented but don't underestimate how helpful a video like this can be. It boosts your confidence in the question of whether you're missing anything. There are a lot more libraries that could be introduced almost as simply. Great to have you on board, Ryan. Is anyone else publishing screencasts (besides Geoffrey)?
if i install the plugin, it is install in vendor/plugins/trunk
Is this a bug from the plugin?
@Michael, good catch. I didn't even notice that. Strangely enough, if you use the "-x" option to make it an svn external (which is what I normally do), it is smart enough to call it markaby.
Anyway, I recommend renaming the folder to "markaby" so it is correct. Hopefully this will be fixed in a future version of Rails.
It seems HAML is efficient for templates, but not quite as much in helpers. The Markaby in this helper example has less noise than the HAML equivalent.
I am very interested in using this technique, but started reading up on markaby and it seems that fragment caching is broken. Is this still the case? There is a ticket on the markaby site that says someone discovered a solution, but is it committed to the plugin yet? Does HAML suffer from this same issue?
@supaspoida, fragment caching should work fine with this technique as long as you put the "cache" block outside of the method call. This way caching is still handled on the ERB side of things. Where it becomes a problem is when you're using Markaby for a complete ERB replacement. I'm not sure if HAML has the same issues or not.
Thanks for the prompt response! We are going to give it a try here and see how it goes. Once again your screencasts have helped tremendously, keep up the good work!
One other question. I am trying to use this to create a content box helper method, and want to pass the id and class as options to the helper method. Is there any way to only add these variables if they exist? And can you attach multiple classes? Thanks again!
@supaspoida, if you want to pass a parameter as a class or id, then it's probably best to use the hash instead of the method call, like this:
div :id => foo, :class => bar
And then you're just passing a string so it can be anything you want.
Regarding attaching multiple classes, you can also do this:
div.item.row
That will make two classes (item and row) I believe.
That's exactly what I needed, thanks!
Stumbled across another issue that I am having trouble with though. I want to pass a block to the helper method, like so (very simplified example):
<% content_box do %>
<p>does content for layout work?</p>
<% end %>
With the helper looking something like:
def content_box(&block)
markaby do
div.class do
yield
end
end
end
However when I do it like that only the yield shows up and none of the markaby template. I have read that yield does not work with markaby, and to use content_for but I'm not sure how to implement it.
Thanks once again for your patience on this! If I can get this working it will improve my productivity quite a bit.
Blocks are handled strangely in views. You'll need to use a combination of concat and capture. See this episode for details:
http://railscasts.com/episodes/40
However, considering that it's in a block already I don't know if it will work.
Sorry to fill up your comments like this, if you would like me to move this to the ruby-forum or email I can do so, but I figured this will likely be good reference material for others if we can work it out. I feel like we are very close.
Messing around with concat and capture I am able to get it to output both the block and the helper html. However, the block appears before the helper, not within it. I am wondering if there is a way to concat/capture the block in a variable then feed it to the markaby block w/in the helper? Here is what I've got now:
def new_box(&block)
b = markaby do
div.default.box do
h2 "Testing Markaby Helper"
p "testing"
capture(&block)
end
end
concat b.to_s, block.binding
end
Once again, thank you for your time!
You can try calling capture near the beginning (before markaby) and setting it in a local variable. This might work better but I don't know. I recommend moving this to railsforum.com where it's easier to post code snippets and details. You can then link to it from here for those following along.
I don't think we need to install a new plugin, the XmlMarkup is a good enough as a markup builter :
xml = Builder::XmlMarkup.new
xml.div("id" => "error_message") do
xml.h2 "#{pluralize(object.errors.count, 'error')} occurred"
xml.p "There were problems with the following fields:"
xml.ul do
object.errors.each_full do |msg|
xml.li msg
end
end
end
though it is not so "sexy" as markaby,but it's good enough for this situation.
oops, sorry for the formating.repost here:
http://pastie.caboo.se/99835
btw: suggest add a "remember me" option for the comment for auto refill the form options.
@Michael
The following will make sure the plugin gets installed in a directory named markaby. I believe script/plugin in this case is just wrapping svn co since this is exactly how svn works as well.
script/plugin install http://code.whytheluckystiff.net/svn/markaby/trunk markaby
Notice the last parameter. Hope that helps.
Its better to use a "markaby" helper like this.
def markaby(&block)
Markaby::Rails::Builder.new({}, self, &block)
end
If you use Markaby::Builder you will get problems like "method not found _erbout" of "method not found length". if you use other rails helpers like form_tag, form_for, etc.
I'd recommend calling capture before markaby and then setting a local variable for it. Railsforum could also be of help. Keep us updated
I will try and see how it works. The screencasts did work fine.Really Good Work!
I wonder if it would work advanced graphics. but let me try thanks anyway
Since Rails 2.1 markaby doesn't work anymore :(
Markaby works great except for one minor problem:
I need to user a form_remote_for call inside of the markaby block. This doesn't work at all, and I have tried many different angles on it.
Is there anyway to get a form_remote_for block inside of a markaby block and have it output correctly, or is this entirely impossible?
I believe script/plugin in this case is just wrapping svn co since this is exactly how svn works as well.
Just for comparison (the same markup with rails content_tag helper):
content_tag :div, nil, :class => 'error_messages' do
content = content_tag(:h2, "... errors occurred")
content << content_tag(:p, "There were problems...:")
content << content_tag(:ul) do
object.errors.to_a.map do |msg|
content_tag :li, msg
end.join.html_safe
end
end