Skip to content

Instantly share code, notes, and snippets.

@rossmari
Last active August 29, 2015 14:16
Show Gist options
  • Save rossmari/bab9741b014ff53440db to your computer and use it in GitHub Desktop.
Save rossmari/bab9741b014ff53440db to your computer and use it in GitHub Desktop.
First DSL
-# to DRY usage of bootstrap hovered table with small font that used to SHOW model attributes was created a simple DSL
-# can assign new table with 2 columns (attribute name, attribute value)
-# can add header row/rows and content rows
= ShowTable::TableGenerator.generate_table(self) do
- add_header('Название атрибута', { width: '30%' })
- add_header('Значение атрибута')
- add_row('Имя') do
- @contact.first_name
- add_row('Фамилия') do
- @contact.second_name
class ShowTable::TableGenerator
attr_reader :headers, :rows
class << self
def table(context, &block)
@headers = []
@rows = []
# view render context
@c = context
# check if render context is defined, it's important
if @c
# we can skip this and render only empty table, this is allowed
instance_eval(&block) if block_given?
else
raise 'View Context must be defined'
end
# generate whole table with head rows and body rows
generate_table_structure
end
# add instance of header_row generators and body_row generators to array
def header(title, params = {}, &block)
@headers << HeaderCell.new(title, params, &block)
end
def row(title, params = {}, &block)
@rows << RowRenderer.new(title, params, &block)
end
end
private
class << self
# Generate whole table
# with bootstrap 3.+ small font size, and table hovered effects
def generate_table_structure
head = @c.content_tag :thead, HeaderRowRenderer.new(@headers).generate_html(@c)
body = @c.content_tag :tbody do
@c.raw( @rows.map{|header| header.generate_html(@c) }.join)
end
@c.content_tag :div, nil, class: 'small' do
@c.content_tag :table, nil, class: 'table table-hover' do
head + body
end
end
end
end
end
class RowRenderer
ROW_TAG = :tr
attr_reader :context, :title, :params, :block
def initialize(title, params = {}, &block)
@title = title
@params = params
@block = block
end
# Generate table row using view context and params
def generate_html(context)
td_title = context.content_tag(:td, context.content_tag(:b, @title))
if @block
td_content = context.content_tag(:td, context.instance_eval(&@block))
else
td_content = context.content_tag(:td, '')
end
context.content_tag(ROW_TAG , td_title + td_content, @params)
end
end
class HeaderRowRenderer
attr_reader :header_cells
def initialize(header_cells)
@header_cells = header_cells
end
def generate_html(context)
content = ''
@header_cells.each do |cell|
content << context.content_tag(:th, cell.title, cell.params)
end
return context.content_tag(:tr, context.raw(content))
end
end
class HeaderCell
attr_reader :title, :params
def initialize(title, params, &block)
@title = title
@params = params
@block = block
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment