#69
Sep 03, 2007

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.
Tags: views plugins
Download (8.5 MB, 6:29)
alternative download for iPod & Apple TV (8.1 MB, 6:29)

Resources

script/plugin install http://code.whytheluckystiff.net/svn/markaby/trunk
# in helper
def simple_error_messages_for(object_name)
  object = instance_variable_get("@#{object_name}")
  return if object.errors.empty?
  
  markaby do
    div.error_messages! do
      h2 "#{pluralize(object.errors.count, 'error')} occurred"
      p "There were problems with the following fields:"
      ul do
        object.errors.each_full do |msg|
          li msg
        end
      end
    end
  end
end

def markaby(&block)
  Markaby::Builder.new({}, self, &block)
end

RSS Feed for Episode Comments 40 comments

1. mr_foo Sep 03, 2007 at 02:23

Thanks for screencast.


2. Vladislav Sep 03, 2007 at 02:48

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!


3. Vladislav Sep 03, 2007 at 02:57

Ok, seriously, cool screencast!


4. jc Sep 03, 2007 at 03:11

Haml also has really nice helper support.

Here's what it would look like:
http://pastie.caboo.se/93426


5. dudzjosh Sep 03, 2007 at 03:17

I was about to mention HAML as well you beat me to it :D


6. Peter Sep 03, 2007 at 05:35

ooo.. I knew Markaby would be cool to use I just never figured out a good way. This looks awesome, as usual ;)


7. schwabsauce Sep 03, 2007 at 21:54

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)?


8. Michael Voigt Sep 04, 2007 at 08:33

if i install the plugin, it is install in vendor/plugins/trunk

Is this a bug from the plugin?


9. Ryan Bates Sep 04, 2007 at 10:01

@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.


10. Paul Howson Sep 06, 2007 at 13:02

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.


11. supaspoida Sep 11, 2007 at 07:59

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?


12. Ryan Bates Sep 11, 2007 at 08:06

@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.


13. supaspoida Sep 11, 2007 at 08:19

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!


14. supaspoida Sep 11, 2007 at 09:15

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!


15. Ryan Bates Sep 11, 2007 at 09:37

@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.


16. supaspoida Sep 11, 2007 at 11:07

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.


17. Ryan Bates Sep 11, 2007 at 13:37

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.


18. supaspoida Sep 11, 2007 at 15:41

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!


19. Ryan Bates Sep 12, 2007 at 08:59

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.


20. RainChen Sep 23, 2007 at 02:01

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.


21. RainChen Sep 23, 2007 at 02:06

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.


22. Ben Curren Sep 28, 2007 at 12:22

@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.


23. Pablo Castellazzi Oct 11, 2007 at 14:12

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.


24. Eleo Oct 24, 2007 at 11:20

Nice! I really needed this.


25. Ira Phentramin Nov 02, 2007 at 17:02

I'd recommend calling capture before markaby and then setting a local variable for it. Railsforum could also be of help. Keep us updated


26. rand Nov 11, 2007 at 17:13

I will try and see how it works. The screencasts did work fine.Really Good Work!


27. bena Nov 11, 2007 at 17:16

I wonder if it would work advanced graphics. but let me try thanks anyway


28. kino May 23, 2008 at 01:52

However, our ideas have lying before them, in reference to ends, the objects in space and time.


29. Olli Jun 20, 2008 at 03:46

Since Rails 2.1 markaby doesn't work anymore :(


30. gamecube roms Jul 04, 2008 at 01:05

thanks for that post bro


31. hydrogen cars Jul 16, 2008 at 01:19

that was a helpful post there


32. rahsia internet Jul 17, 2008 at 02:23

that was an amazing post


33. sickest sites Jul 19, 2008 at 20:39

thanks


34. ab exercise equipment Jul 20, 2008 at 09:48

that was a nice post


35. Rabbit Vibrators Jul 23, 2008 at 07:04

that was a nice posting


36. crafvity Jul 27, 2008 at 02:53

that was interesting


37. Sword of the New World Gold Nov 20, 2008 at 17:59

Thanks Ryan,I think this is one of the most wonderful sites. I have great admiration for you.


38. cheap kamas Nov 21, 2008 at 21:44

 I have great admiration for you.


39. lily Nov 27, 2008 at 19:03

Thank you Ryan, your screencast is good. Please look at our URL, if necessary we can learn from each other.


40. evden eve nakliyat Dec 01, 2008 at 01:25

evden eve nakliyat

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player