Skip to content

Instantly share code, notes, and snippets.

@lev
Last active August 29, 2015 14:20
Show Gist options
  • Select an option

  • Save lev/3793596e0769ff9d306b to your computer and use it in GitHub Desktop.

Select an option

Save lev/3793596e0769ff9d306b to your computer and use it in GitHub Desktop.
Toronto Ruby Brigade - Leigh Halliday's DSL workshop
# based on: http://www.leighhalliday.com/creating-ruby-dsl
class FancyMarkup
def initialize
@markup = ''
end
# the args array should capture any number of arguments, from zero to many
# maybe useful: https://endofline.wordpress.com/2011/01/21/the-strange-ruby-splat/
def method_missing(name, *args, &block)
# assume that the content is the first string in args, or nil if none found
content = args.select { |a| a.class == String }.first || nil
# assume that attr is the first hash in args, or empty hash if none found
attr = args.select { |a| a.class == Hash }.first || {}
@markup << "<#{name}#{flatten(attr)}>\n"
@markup << "#{content}\n" if content
instance_eval(&block) if block_given?
@markup << "</#{name}>\n"
end
def flatten(h)
h.keys.inject('') { |flat, k| flat << %Q{ #{k}="#{h[k]}"} }
end
end
markup = FancyMarkup.new.html do
body do
div id: "container" do
ul class: "pretty" do
li "Item 1", class: :active
li "Item 2"
end
article class: 'foo', id: 'foofoo' do
foobar id: 'bar' do
hr
end
end
end
end
end
puts markup
# p FancyMarkup.instance_methods false
# output:
# <html>
# <body>
# <div id="container">
# <ul class="pretty">
# <li class="active">
# Item 1
# </li>
# <li>
# Item 2
# </li>
# </ul>
# <article class="foo" id="foofoo">
# <foobar id="bar">
# </foobar>
# </article>
# </div>
# </body>
# </html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment