Class: Fragmentary::WidgetParser

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers::JavaScriptHelper
Defined in:
lib/fragmentary/widget_parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template) ⇒ WidgetParser

Returns a new instance of WidgetParser.



9
10
11
12
# File 'lib/fragmentary/widget_parser.rb', line 9

def initialize(template)
  @template = template
  @widget_container = {:'' => 'Empty widget specification detected'}
end

Instance Attribute Details

#templateObject (readonly)

Returns the value of attribute template.



7
8
9
# File 'lib/fragmentary/widget_parser.rb', line 7

def template
  @template
end

#widget_containerObject (readonly)

Returns the value of attribute widget_container.



7
8
9
# File 'lib/fragmentary/widget_parser.rb', line 7

def widget_container
  @widget_container
end

Instance Method Details

#parse_buffer(options = {}) ⇒ Object

This method returns a new OutputBuffer instance that can be used to overwrite the existing template’s output_buffer with a copy that has its widget specifications expanded. It is usually called from cache_fragment to insert widgets into a cached root fragment. However when an ajax request inserts a non-root fragment into a page it can be invoked from CacheBuilder#cache_child if that method is called with the :insert_widgets option set to true. Alternatively if an ajax request inserts content containing a widget without a fragment context, i.e. in order to modify content within a fragment, a WidgetParser can be instantiated separately using erb at the end of the view template. This can be done either in an html template if the client is loading html by ajax (e.g. jQuery.load) or in a js(.coffee) script if the ajax request loads javascript.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/fragmentary/widget_parser.rb', line 24

def parse_buffer(options = {})
  template.output_buffer.scan(/%{([^}]+)}/) do |spec|
    widget_key = spec[0]; widget = nil
    widget_container[widget_key.to_sym] = if Widget.subclasses.find{|klass| (widget = klass.new(template, widget_key)).match}
      if options[:javascript] or options[:js]
        escape_javascript(widget._content)
      else
        widget._content
      end
    else
      "Oops! Widget for #{widget_key} not found."
    end
  end
  # The gsub replaces instances of '%' that aren't part of widget specifications with '%%', preventing
  # those characters from making the buffer an invalid format specification. The substitution operation
  # restores them to single characters. The new OutputBuffer is needed because gsub returns a string.
  # (Although gsub! would return an OutputBuffer if a substitution occurs, it returns nil otherwise,
  # so isn't suitable here.)
  ActionView::OutputBuffer.new(template.output_buffer.gsub(/%(?!{)/,'%%') % widget_container)
end