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



113
114
115
116
117
# File 'lib/effigy/view.rb', line 113

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



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

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



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

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.



144
145
146
# File 'lib/effigy/view.rb', line 144

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



101
102
103
# File 'lib/effigy/view.rb', line 101

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



129
130
131
132
133
# File 'lib/effigy/view.rb', line 129

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



87
88
89
90
91
92
# File 'lib/effigy/view.rb', line 87

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



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

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.



156
157
158
# File 'lib/effigy/view.rb', line 156

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



35
36
37
# File 'lib/effigy/view.rb', line 35

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


209
210
# File 'lib/effigy/view.rb', line 209

def transform
end