Class: Erector::AbstractWidget

Inherits:
Object
  • Object
show all
Includes:
AfterInitialize, Attributes, Convenience, Element, Text
Defined in:
lib/erector/abstract_widget.rb

Overview

Abstract base class for Widget. This pattern allows Widget to include lots of nicely organized modules and still have proper semantics for “super” in subclasses. See the rdoc for Widget for the list of all the included modules.

Direct Known Subclasses

XMLWidget

Constant Summary collapse

@@prettyprint_default =
false
@@hyphenize_underscores =
false

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Convenience

#css, #dom_id, #javascript, #join, #to_pretty, #to_text, #url

Methods included from AfterInitialize

included

Methods included from Text

#character, #h, #nbsp, #raw, #text, #text!

Methods included from Attributes

#format_attributes, #format_sorted, #sort_attributes

Methods included from Element

#_element, #_empty_element, #element, #empty_element

Constructor Details

#initialize(assigns = {}, &block) ⇒ AbstractWidget

Returns a new instance of AbstractWidget.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/erector/abstract_widget.rb', line 60

def initialize(assigns = {}, &block)
  unless assigns.is_a? Hash
    raise ArgumentError, "Erector widgets are initialized with only a parameter hash, but you passed #{assigns.class}:#{assigns.inspect}. (Other parameters are passed to to_html, or the #widget method.)"
  end

  @_assigns = assigns

  assigns.each do |name, value|
    instance_variable_set(name.to_s[0..0] == '@' ? name : "@#{name}", value)
  end

  @_parent = eval("self", block.binding) if block
  @_block = block
end

Class Method Details

.hyphenize_underscoresObject



38
39
40
# File 'lib/erector/abstract_widget.rb', line 38

def self.hyphenize_underscores
  @@hyphenize_underscores
end

.hyphenize_underscores=(enabled) ⇒ Object



42
43
44
# File 'lib/erector/abstract_widget.rb', line 42

def self.hyphenize_underscores=(enabled)
  @@hyphenize_underscores = enabled
end

.inline(*args, &block) ⇒ Object



46
47
48
49
50
# File 'lib/erector/abstract_widget.rb', line 46

def self.inline(*args, &block)
  Class.new(self) do
    include Erector::Inline
  end.new(*args, &block)
end

.prettyprint_defaultObject



28
29
30
# File 'lib/erector/abstract_widget.rb', line 28

def self.prettyprint_default
  @@prettyprint_default
end

.prettyprint_default=(enabled) ⇒ Object



32
33
34
# File 'lib/erector/abstract_widget.rb', line 32

def self.prettyprint_default=(enabled)
  @@prettyprint_default = enabled
end

Instance Method Details

#call_blockObject

When this method is executed, the default block that was passed in to the widget’s constructor will be executed. The semantics of this block – that is, what “self” is, and whether it has access to Erector methods like “div” and “text”, and the widget’s instance variables – can be quite confusing. The rule is, most of the time the block is evaluated using “call” or “yield”, which means that its scope is that of the caller. So if that caller is not an Erector widget, it will not have access to the Erector methods, but it will have access to instance variables and methods of the calling object.

If you want this block to have access to Erector methods then use Erector::Inline#content or Erector#inline.



146
147
148
# File 'lib/erector/abstract_widget.rb', line 146

def call_block
  @_block.call(self) if @_block
end

#capture_contentObject Also known as: capture

Creates a whole new output string, executes the block, then converts the output string to a string and returns it as raw text. If at all possible you should avoid this method since it hurts performance, and use widget instead.



176
177
178
179
180
181
182
183
# File 'lib/erector/abstract_widget.rb', line 176

def capture_content
  original, @_output = output, Output.new
  yield
  original.widgets.concat(output.widgets) # todo: test!!!
  output.to_s
ensure
  @_output = original
end

#contentObject

Template method which must be overridden by all widget subclasses. Inside this method you call the magic #element methods which emit HTML and text to the output string.

If you call “super” (or don’t override content, or explicitly call “call_block”) then your widget will execute the block that was passed into its constructor. The semantics of this block are confusing; make sure to read the rdoc for Erector#call_block



130
131
132
# File 'lib/erector/abstract_widget.rb', line 130

def content
  call_block
end

#emit(options = {}) ⇒ Object

Entry point for rendering a widget (and all its children). This method creates a new output string (if necessary), calls this widget’s #content method and returns the string.

Options:

output

the string (or array, or Erector::Output) to output to. Default: a new empty string

prettyprint

whether Erector should add newlines and indentation. Default: the value of prettyprint_default (which, in turn, is false by default).

indentation

the amount of spaces to indent. Ignored unless prettyprint is true.

max_length

preferred maximum length of a line. Line wraps will only occur at space characters, so a long word may end up creating a line longer than this. If nil (default), then there is no arbitrary limit to line lengths, and only internal newline characters and prettyprinting will determine newlines in the output.

helpers

a helpers object containing utility methods. Usually this is a Rails view object.

content_method_name

in case you want to call a method other than #content, pass its name in here.



98
99
100
# File 'lib/erector/abstract_widget.rb', line 98

def emit(options = {})
  _emit(options).to_s
end

#prettyprint_defaultObject



24
25
26
# File 'lib/erector/abstract_widget.rb', line 24

def prettyprint_default
  @@prettyprint_default
end

#to_a(options = {}) ⇒ Object

Entry point for rendering a widget (and all its children). Same as #render / #to_html only it returns an array, for theoretical performance improvements when using a Rack server (like Sinatra or Rails Metal).

# Options: see #emit



117
118
119
# File 'lib/erector/abstract_widget.rb', line 117

def to_a(options = {})
  _emit(options).to_a
end

#to_s(*args) ⇒ Object

Deprecated.

Please use #emit instead

alias for #emit



104
105
106
107
108
109
110
# File 'lib/erector/abstract_widget.rb', line 104

def to_s(*args)
  unless defined? @@already_warned_to_s
    $stderr.puts "Erector::Widget#to_s is deprecated. Please use #to_html instead. Called from #{caller.first}"
    @@already_warned_to_s = true
  end
  to_html(*args)
end

#widget(target, assigns = {}, options = {}, &block) ⇒ Object

Emits a (nested) widget onto the current widget’s output stream. Accepts either a class or an instance. If the first argument is a class, then the second argument is a hash used to populate its instance variables. If the first argument is an instance then the hash must be unspecified (or empty). If a block is passed to this method, then it gets set as the emited widget’s block, and will be executed when that widget calls call_block or calls super from inside its content method.

This is the preferred way to call one widget from inside another. This method assures that the same output string is used, which gives better performance than using capture or to_html.



161
162
163
164
165
166
167
168
169
170
# File 'lib/erector/abstract_widget.rb', line 161

def widget(target, assigns = {}, options = {}, &block)
  if target.is_a? Class
    target.new(assigns, &block)._emit_via(self, options)
  else
    unless assigns.empty?
      raise "Unexpected second parameter. Did you mean to pass in assigns when you instantiated the #{target.class.to_s}?"
    end
    target._emit_via(self, options, &block)
  end
end