Class: Effigy::View

Inherits:
Object show all
Defined in:
lib/effigy/view.rb

Overview

Accepts a template to be transformed.

For most common cases, creating a subclass makes the most sense, but this class can be used directly by passing a block to #render.

view = Effigy::View.new view.render(template) do

view.find('h1').text('the title')

end

See Also:

Direct Known Subclasses

Rails::View

Instance Method Summary collapse

Instance Method Details

#add_class(selector, *class_names) ⇒ Object

Adds the given class names to the selected element.

Examples:

add_class('a#home', 'selected')
find('a#home').add_class('selected')

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • class_names (String)

    a CSS class name that should be added



111
112
113
114
115
# File 'lib/effigy/view.rb', line 111

def add_class(selector, *class_names)
  element = select(selector)
  class_list = ClassList.new(element)
  class_names.each { |class_name| class_list << class_name }
end

#attr(selector, attributes_or_attribute_name, value = nil) ⇒ Object

Adds or updates the given attribute or attributes of the selected element.

Examples:

attr('p', :id => 'an_id', :style => 'display: none')
attr('p', :id, 'an_id')
find('p').attr(:id, 'an_id')

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • attributes_or_attribute_name (String, Hash)

    if a String, replaces that attribute with the given value. If a Hash, uses the keys as attribute names and values as attribute values

  • value (String) (defaults to: nil)

    the value for the replaced attribute. Used only if attributes_or_attribute_name is a String



50
51
52
53
54
55
56
# File 'lib/effigy/view.rb', line 50

def attr(selector, attributes_or_attribute_name, value = nil)
  element = select(selector)
  attributes = attributes_or_attribute_name.to_effigy_attributes(value)
  attributes.each do |attribute, value|
    element[attribute.to_s] = value
  end
end

#find(selector) ⇒ Selection Also known as: f

Selects an element or elements for chained transformation.

If given a block, the selection will be in effect during the block.

If not given a block, a Selection will be returned on which transformation methods can be called. Any methods called on the Selection will be delegated back to the view with the selector inserted into the parameter list.

Examples:

find('.post') do
  text('h1', post.title)
  text('p', post.body)
end
find('h1').text(post.title).add_class('active')

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

Returns:

  • (Selection)

    a proxy object on which transformation methods can be called



177
178
179
180
181
182
183
184
185
186
# File 'lib/effigy/view.rb', line 177

def find(selector)
  if block_given?
    old_context = @current_context
    @current_context = select(selector)
    yield
    @current_context = old_context
  else
    Selection.new(self, selector)
  end
end

#html(selector, xml) ⇒ Object

Replaces the contents of the selected element with live markup.

Examples:

html('p', '<b>Welcome!</b>')
find('p').html('<b>Welcome!</b>')

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • xml (String)

    the new contents of the selected element. Markup is not escaped.



142
143
144
# File 'lib/effigy/view.rb', line 142

def html(selector, xml)
  select(selector).inner_html = xml
end

#remove(selector) ⇒ Object

Removes the selected elements from the template.

Examples:

remove('.post')
find('.post').remove

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform



99
100
101
# File 'lib/effigy/view.rb', line 99

def remove(selector)
  select_all(selector).each { |element| element.unlink }
end

#remove_class(selector, *class_names) ⇒ Object

Removes the given class names from the selected element.

Ignores class names that are not present.

Examples:

remove_class('a#home', 'selected')
find('a#home').remove_class('selected')

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • class_names (String)

    a CSS class name that should be removed



127
128
129
130
131
# File 'lib/effigy/view.rb', line 127

def remove_class(selector, *class_names)
  element = select(selector)
  class_list = ClassList.new(element)
  class_names.each { |class_name| class_list.remove(class_name) }
end

#render(template) { ... } ⇒ String

Perform transformations on the given template.

Yields:

  • inside the given block, transformation methods such as #text and #html can be used on the template. Using a subclass, you can instead override the #transform method, which is the preferred approach.

Returns:

  • (String)

    the resulting document



85
86
87
88
89
90
# File 'lib/effigy/view.rb', line 85

def render(template)
  @current_context = Nokogiri::XML.parse(template)
  yield if block_given?
  transform
  output
end

#replace_each(selector, collection, &block) ⇒ Object

Replaces the selected element with a clone for each item in the collection.

Examples:

titles = %w(one two three)
find('.post').replace_each(titles) do |title|
  text('h1', title)
end

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • collection (Enumerable)

    the items that are the base for each cloned element



69
70
71
72
73
74
75
76
# File 'lib/effigy/view.rb', line 69

def replace_each(selector, collection, &block)
  original_element = select(selector)
  collection.inject(original_element) do |sibling, item|
    item_element = clone_element_with_item(original_element, item, &block)
    sibling.add_next_sibling(item_element)
  end
  original_element.unlink
end

#replace_with(selector, xml) ⇒ Object

Replaces the selected element with live markup.

The “outer HTML” for the selected tag itself is also replaced.

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • xml (String)

    the new markup to replace the selected element. Markup is not escaped.



154
155
156
# File 'lib/effigy/view.rb', line 154

def replace_with(selector, xml)
  select(selector).after(xml).unlink
end

#text(selector, content) ⇒ Object

Replaces the text content of the selected element.

Markup in the given content is escaped. Use #html if you want to replace the contents with live markup.

Examples:

text('h1', 'a title')
find('h1').text('a title')
text('p', '<b>title</b>') # <p>&lt;b&gt;title&lt;/title&gt;</p>

Parameters:

  • selector (String)

    a CSS or XPath string describing the element to transform

  • content (String)

    the text that should be the new element contents



33
34
35
# File 'lib/effigy/view.rb', line 33

def text(selector, content)
  select(selector).content = content
end

#transformObject

Called by #render to perform transformations on the source template.

Override this method in subclasses to perform the transformations specific to your view.

Examples:

class PostView < Effigy::View
  def initialize(post)
    @post = post
  end

  def transform
    find('.post') do
      find('h2').text(post.title)
      find('p').text(post.body)
    end
  end
end


207
208
# File 'lib/effigy/view.rb', line 207

def transform
end