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, opts = {}) ⇒ View

Returns a new instance of View.



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

def initialize(node, opts = {})
  @node = node
  @opts = opts
end

Instance Attribute Details

#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

#optsObject (readonly)

Returns the value of attribute opts.



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

def opts
  @opts
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.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/flutterby/view.rb', line 119

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



47
48
49
# File 'lib/flutterby/view.rb', line 47

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

#debug(obj) ⇒ Object



97
98
99
# File 'lib/flutterby/view.rb', line 97

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

#extend_view(*mods, &blk) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/flutterby/view.rb', line 101

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

  extend(*mods)
end

#find(*args) ⇒ Object



63
64
65
# File 'lib/flutterby/view.rb', line 63

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

#find!(*args) ⇒ Object



67
68
69
# File 'lib/flutterby/view.rb', line 67

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


88
89
90
91
92
93
94
95
# File 'lib/flutterby/view.rb', line 88

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



51
52
53
# File 'lib/flutterby/view.rb', line 51

def raw(str)
  str.html_safe
end

#render(expr, *args) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/flutterby/view.rb', line 55

def render(expr, *args)
  if expr.is_a?(Node)
    expr.render(*args)
  else
    find(expr).render(*args)
  end
end

#render!Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/flutterby/view.rb', line 21

def render!
  output = node.source.try(:html_safe)

  time = Benchmark.realtime do
    output = Filters.apply!(output, view: self)

    # Apply layouts
    if opts[:layout] && node.page?
      output = Layout.apply!(output, view: self)
    end
  end

  # Log rendering times using different colors based on duration
  color = if time > 1
    :red
  elsif time > 0.25
    :yellow
  else
    :green
  end

  logger.debug "Rendered #{node.url.colorize(:blue)} in #{sprintf("%.1fms", time * 1000).colorize(color)}"

  output
end

#siblings(*args) ⇒ Object



71
72
73
# File 'lib/flutterby/view.rb', line 71

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

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



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/flutterby/view.rb', line 75

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