flutterby 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6f25431bf9e8f2dafc67f58b966c2fde5a368055
4
- data.tar.gz: f32e383638dfc175617f1f5a3af8eff54ca288e9
3
+ metadata.gz: 912db5fb0467b2ea17535d27a16f7d5cae9c4844
4
+ data.tar.gz: bc120fb8c0db94fe25f9894183c2ac784c8c7723
5
5
  SHA512:
6
- metadata.gz: 59134f58f623e20cc2e168671e43dfa7012577c90108db6f6bb0bb92af52a990f2f2629a6cd00a55da4aa43aff5c86155572e5f9d3c81c0804419f256b4f1f72
7
- data.tar.gz: 7900512a1c3d2cf8d193c3c427d6c4f06d16cef75c5b3be817f7db3bf658685e15654894a6f2cbf352a96922b12e6dd2e28f260a972fdafbd80732dcc1cc3109
6
+ metadata.gz: 2f00d281c3fc731e97877ee6c091d38a5589ed3ff6bcddc0301f6b5b4a78a1b6357585af2facbbe314c2134233e2e349108d789e34c75e11f502e9617d5a58f2
7
+ data.tar.gz: 2c054331bd42b2c1fc898694ec1b9446d8fa04d8e53f728feaff8ba13885c27e6ac0d22e738f9191998e47619c46309e8820deccf53c40b2e08c9d4ae80f4d9d
data/CHANGES.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # Version History
2
2
 
3
- ### HEAD
3
+ ### 0.5.2 (2017-01-25)
4
+
5
+ - **NEW:** Just like `find`, there is now also a `find!` that will raise an exception when the specified node could not be found.
6
+ - **NEW:** Nodes can now control the layout(s) that will be applied to them in their front matter through the `layout` keyword.
7
+
8
+
9
+ ### 0.5.1 (2017-01-24)
4
10
 
5
11
  - **NEW:** Views now provide an `extend_view` method that you can (and should) use in `_view.rb` extensions.
6
12
  - **NEW:** Improved log output, especially when using `--debug`.
@@ -8,19 +8,18 @@ require 'flutterby/markdown_formatter'
8
8
 
9
9
  module Flutterby
10
10
  module Filters
11
- def self.apply!(view)
12
- view._body = view.source.try(:html_safe)
13
-
11
+ def self.apply!(input, view:)
14
12
  # Apply all filters
15
- view.node.filters.each do |filter|
13
+ view.node.filters.inject(input) do |body, filter|
16
14
  meth = "process_#{filter}!"
17
15
 
18
16
  if Filters.respond_to?(meth)
19
- Filters.send(meth, view)
20
- elsif template = tilt(filter, view._body)
21
- view._body = template.render(view).html_safe
17
+ Filters.send(meth, body, view: view)
18
+ elsif template = tilt(filter, body)
19
+ template.render(view).html_safe
22
20
  else
23
21
  Flutterby.logger.warn "Unsupported filter '#{filter}' for #{view.node.url}"
22
+ body
24
23
  end
25
24
  end
26
25
  end
@@ -43,15 +42,15 @@ module Flutterby
43
42
  end
44
43
  end
45
44
 
46
- Flutterby::Filters.add("rb") do |view|
47
- view._body = view.instance_eval(view._body)
45
+ Flutterby::Filters.add("rb") do |input, view:|
46
+ view.instance_eval(input)
48
47
  end
49
48
 
50
- Flutterby::Filters.add(["md", "markdown"]) do |view|
51
- view._body = Flutterby::MarkdownFormatter.new(view._body).complete.to_s.html_safe
49
+ Flutterby::Filters.add(["md", "markdown"]) do |input, view:|
50
+ Flutterby::MarkdownFormatter.new(input).complete.to_s.html_safe
52
51
  end
53
52
 
54
- Flutterby::Filters.add("scss") do |view|
53
+ Flutterby::Filters.add("scss") do |input, view:|
55
54
  sass_options = {
56
55
  syntax: :scss,
57
56
  load_paths: []
@@ -61,5 +60,5 @@ Flutterby::Filters.add("scss") do |view|
61
60
  sass_options[:load_paths] << File.dirname(view.node.fs_path)
62
61
  end
63
62
 
64
- view._body = Sass::Engine.new(view._body, sass_options).render
63
+ Sass::Engine.new(input, sass_options).render
65
64
  end
@@ -0,0 +1,49 @@
1
+ module Flutterby
2
+ module Layout
3
+ extend self
4
+
5
+ # Determines which layouts should be applied to the view object (based on
6
+ # the node it is rendering), and then applies each of these layouts in order,
7
+ # modifying the view in place.
8
+ #
9
+ def apply!(body, view:)
10
+ collect_layouts(view).inject(body) do |acc, layout|
11
+ tilt = Flutterby::Filters.tilt(layout.ext, layout.source)
12
+ tilt.render(view) { acc }.html_safe
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def collect_layouts(view)
19
+ layouts = []
20
+
21
+ # Collect layouts explicitly configured for node
22
+ if defined? view.node.layout
23
+ Array(view.node.layout).each do |sel|
24
+ # If a false is explicity specified, that's all the layouts
25
+ # we're expected to render
26
+ return layouts if sel == false
27
+
28
+ if layout = view.node.find(sel)
29
+ layouts << layout
30
+ else
31
+ raise "No layout found for path expression '#{sel}'"
32
+ end
33
+ end
34
+ end
35
+
36
+ # Decide on a starting node for walking the tree upwards
37
+ start = layouts.any? ? layouts.last.parent : view.node
38
+
39
+ # Walk the tree up, collecting any layout files found on our way
40
+ TreeWalker.walk_up(start) do |node|
41
+ if layout = node.sibling("_layout")
42
+ layouts << layout
43
+ end
44
+ end
45
+
46
+ layouts
47
+ end
48
+ end
49
+ end
@@ -121,6 +121,13 @@ module Flutterby
121
121
  Node.new(name.to_s, **args)
122
122
  end
123
123
 
124
+ # Like {find}, but raises an exception when the specified node could not
125
+ # be found.
126
+ #
127
+ def find!(path, *args)
128
+ find(path, *args) || raise("Could not find node for path expression '#{path}'")
129
+ end
130
+
124
131
  def find(path, opts = {})
125
132
  path = path.to_s
126
133
  return self if path.empty?
@@ -223,8 +230,6 @@ module Flutterby
223
230
  end
224
231
 
225
232
  def extract_frontmatter!
226
- @data || {}
227
-
228
233
  if @source
229
234
  # YAML Front Matter
230
235
  if @source.sub!(/\A\-\-\-\n(.+)\n\-\-\-\n/m, "")
@@ -325,17 +330,11 @@ module Flutterby
325
330
 
326
331
 
327
332
  module Rendering
328
- # Returns a freshly created {View} instance for this node.
329
- #
330
- def view(opts = {})
331
- View.for(self, opts)
332
- end
333
-
334
- # Creates a new {View} instance through {#view} and uses it to
333
+ # Creates a new {View} instance and uses it to
335
334
  # render this node. Returns the rendered page as a string.
336
335
  #
337
336
  def render(opts = {})
338
- view(opts).render!
337
+ View.for(self, opts).render!
339
338
  end
340
339
  end
341
340
 
@@ -356,6 +355,13 @@ module Flutterby
356
355
  data[:title] || slug.try(:titleize)
357
356
  end
358
357
 
358
+ # Returns the layout(s) configured for this node. This is sourced from
359
+ # the node's {data} attribute, so it can be set from front matter.
360
+ #
361
+ def layout
362
+ data[:layout]
363
+ end
364
+
359
365
  def to_s
360
366
  "<#{self.class} #{self.url}>"
361
367
  end
@@ -1,3 +1,3 @@
1
1
  module Flutterby
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
@@ -1,9 +1,9 @@
1
1
  require 'benchmark'
2
+ require 'flutterby/layout'
2
3
 
3
4
  module Flutterby
4
5
  class View
5
- attr_reader :node, :opts, :source
6
- attr_accessor :_body
6
+ attr_reader :node, :opts
7
7
  alias_method :page, :node
8
8
 
9
9
  # Include ERB::Util from ActiveSupport. This will provide
@@ -16,17 +16,17 @@ module Flutterby
16
16
  def initialize(node, opts = {})
17
17
  @node = node
18
18
  @opts = opts
19
- @source = node.source
20
- @_body = nil
21
19
  end
22
20
 
23
21
  def render!
22
+ output = node.source.try(:html_safe)
23
+
24
24
  time = Benchmark.realtime do
25
- Filters.apply!(self)
25
+ output = Filters.apply!(output, view: self)
26
26
 
27
27
  # Apply layouts
28
28
  if opts[:layout] && node.page?
29
- @_body = apply_layout!(@_body)
29
+ output = Layout.apply!(output, view: self)
30
30
  end
31
31
  end
32
32
 
@@ -41,22 +41,7 @@ module Flutterby
41
41
 
42
42
  logger.debug "Rendered #{node.url.colorize(:blue)} in #{sprintf("%.1fms", time * 1000).colorize(color)}"
43
43
 
44
- @_body
45
- end
46
-
47
- def apply_layout!(input)
48
- TreeWalker.walk_up(node, input) do |node, current|
49
- if layout = node.sibling("_layout")
50
- tilt = Flutterby::Filters.tilt(layout.ext, layout.source)
51
- tilt.render(self) { current }.html_safe
52
- else
53
- current
54
- end
55
- end
56
- end
57
-
58
- def to_s
59
- @_body ||= render!
44
+ output
60
45
  end
61
46
 
62
47
  def date_format(date, fmt)
@@ -76,7 +61,11 @@ module Flutterby
76
61
  end
77
62
 
78
63
  def find(*args)
79
- node.find(*args) or raise "No node found for #{args}"
64
+ node.find(*args)
65
+ end
66
+
67
+ def find!(*args)
68
+ node.find!(*args)
80
69
  end
81
70
 
82
71
  def siblings(*args)
@@ -117,6 +106,8 @@ module Flutterby
117
106
  extend(*mods)
118
107
  end
119
108
 
109
+ private
110
+
120
111
  def logger
121
112
  @logger ||= Flutterby.logger
122
113
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flutterby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hendrik Mans
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-24 00:00:00.000000000 Z
11
+ date: 2017-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -391,6 +391,7 @@ files:
391
391
  - lib/flutterby/dotaccess.rb
392
392
  - lib/flutterby/exporter.rb
393
393
  - lib/flutterby/filters.rb
394
+ - lib/flutterby/layout.rb
394
395
  - lib/flutterby/markdown_formatter.rb
395
396
  - lib/flutterby/node.rb
396
397
  - lib/flutterby/node_extension.rb