Class: Flutterby::View

Inherits:
Object
  • Object
show all
Includes:
ERB::Util
Defined in:
lib/flutterby/view.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, locals: {}) ⇒ View

Returns a new instance of View.



16
17
18
19
# File 'lib/flutterby/view.rb', line 16

def initialize(node, locals: {})
  @node = node
  @locals = locals
end

Instance Attribute Details

#localsObject (readonly)

Returns the value of attribute locals.



6
7
8
# File 'lib/flutterby/view.rb', line 6

def locals
  @locals
end

#nodeObject (readonly) Also known as: page

Returns the value of attribute node.



6
7
8
# File 'lib/flutterby/view.rb', line 6

def node
  @node
end

Class Method Details

.for(node, *args) ⇒ Object

Factory method that returns a newly created view for the given node. It also makes sure all available _view.rb extensions are loaded.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/flutterby/view.rb', line 97

def for(node, *args)
  # create a new view instance
  view = new(node, *args)

  # walk the tree up to dynamically extend the view
  TreeWalker.walk_down(node) do |e|
    if view_node = e.sibling("_view.rb")
      case view_node.ext
      when "rb" then
        view.instance_eval(view_node.source)
      else
        raise "Unknown view extension #{view_node.full_name}"
      end
    end
  end

  # return the finished view object
  view
end

Instance Method Details

#date_format(date, fmt) ⇒ Object



21
22
23
# File 'lib/flutterby/view.rb', line 21

def date_format(date, fmt)
  date.strftime(fmt)
end

#debug(obj) ⇒ Object



75
76
77
# File 'lib/flutterby/view.rb', line 75

def debug(obj)
  tag(:pre, class: "debug") { h obj.to_yaml }
end

#extend_view(*mods, &blk) ⇒ Object



79
80
81
82
83
84
85
# File 'lib/flutterby/view.rb', line 79

def extend_view(*mods, &blk)
  if block_given?
    mods << Module.new(&blk)
  end

  extend(*mods)
end

#find(*args) ⇒ Object



41
42
43
# File 'lib/flutterby/view.rb', line 41

def find(*args)
  node.find(*args)
end

#find!(*args) ⇒ Object



45
46
47
# File 'lib/flutterby/view.rb', line 45

def find!(*args)
  node.find!(*args)
end


66
67
68
69
70
71
72
73
# File 'lib/flutterby/view.rb', line 66

def link_to(text, target, attrs = {})
  href = case target
  when Flutterby::Node then target.url
  else target.to_s
  end

  tag(:a, attrs.merge(href: href)) { text }
end

#raw(str) ⇒ Object



25
26
27
# File 'lib/flutterby/view.rb', line 25

def raw(str)
  str.html_safe
end

#render(expr, as: nil, locals: {}, **args) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/flutterby/view.rb', line 29

def render(expr, as: nil, locals: {}, **args)
  node = expr.is_a?(Node) ? expr : find(expr)

  # Resolve rendering "as" specific things
  if as
    locals[as] = node
    node = node.find!("./_#{as}.#{self.node.ext}")
  end

  node.render(**args, locals: locals.with_indifferent_access, **args)
end

#siblings(*args) ⇒ Object



49
50
51
# File 'lib/flutterby/view.rb', line 49

def siblings(*args)
  node.siblings(*args)
end

#tag(name, attributes = {}) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/flutterby/view.rb', line 53

def tag(name, attributes = {})
  ActiveSupport::SafeBuffer.new.tap do |output|
    attributes_str = attributes.keys.sort.map do |k|
      %{#{h k}="#{h attributes[k]}"}
    end.join(" ")

    opening_tag = "#{h name.downcase} #{attributes_str}".strip
    output << "<#{opening_tag}>".html_safe
    output << yield if block_given?
    output << "</#{h name}>".html_safe
  end
end