flutterby 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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