jekyll-contentblocks 1.1.0 → 2.0.0
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 +5 -5
- data/.github/workflows/ci.yml +110 -0
- data/.gitignore +1 -1
- data/Appraisals +50 -24
- data/Gemfile +15 -5
- data/README.md +118 -20
- data/gemfiles/jekyll_3.0.5.gemfile +15 -0
- data/gemfiles/jekyll_3.1.6.gemfile +15 -0
- data/gemfiles/jekyll_3.10.0.gemfile +16 -0
- data/gemfiles/jekyll_3.2.1.gemfile +15 -0
- data/gemfiles/jekyll_3.3.1.gemfile +15 -0
- data/gemfiles/jekyll_3.4.5.gemfile +15 -0
- data/gemfiles/jekyll_3.5.2.gemfile +15 -0
- data/gemfiles/jekyll_3.6.3.gemfile +15 -0
- data/gemfiles/jekyll_3.7.4.gemfile +15 -0
- data/gemfiles/jekyll_3.8.7.gemfile +15 -0
- data/gemfiles/jekyll_3.9.5.gemfile +16 -0
- data/gemfiles/jekyll_4.0.1.gemfile +15 -0
- data/gemfiles/jekyll_4.1.1.gemfile +15 -0
- data/gemfiles/jekyll_4.2.2.gemfile +15 -0
- data/gemfiles/jekyll_4.3.4.gemfile +15 -0
- data/gemfiles/jekyll_4.4.1.gemfile +15 -0
- data/jekyll-contentblocks.gemspec +7 -2
- data/lib/jekyll/content_blocks/content_block_tag.rb +34 -7
- data/lib/jekyll/content_blocks/pre_render_hook.rb +11 -0
- data/lib/jekyll/content_blocks/version.rb +1 -2
- data/lib/jekyll/tags/content_block.rb +2 -9
- data/lib/jekyll/tags/content_for.rb +18 -3
- data/lib/jekyll-contentblocks.rb +15 -22
- data/mise.toml +5 -0
- data/spec/jekyll_content_blocks_spec.rb +115 -55
- data/spec/spec_helper.rb +11 -12
- data/test/_layouts/default.html +14 -0
- data/test/_plugins/require.rb +1 -0
- data/test/emptyblock.md +8 -0
- data/test/page2.md +12 -0
- data/test/page3.md +27 -0
- metadata +44 -27
- data/gemfiles/jekyll_1.0.4.gemfile +0 -12
- data/gemfiles/jekyll_1.1.2.gemfile +0 -12
- data/gemfiles/jekyll_1.2.1.gemfile +0 -12
- data/gemfiles/jekyll_1.3.1.gemfile +0 -12
- data/gemfiles/jekyll_1.4.3.gemfile +0 -12
- data/gemfiles/jekyll_1.5.1.gemfile +0 -12
- data/gemfiles/jekyll_2.0.3.gemfile +0 -12
- data/gemfiles/jekyll_2.1.1.gemfile +0 -12
- data/gemfiles/jekyll_2.2.0.gemfile +0 -12
- data/gemfiles/jekyll_2.3.0.gemfile +0 -12
- data/gemfiles/jekyll_2.4.0.gemfile +0 -12
- data/gemfiles/jekyll_2.5.3.gemfile +0 -12
- data/lib/jekyll/content_blocks/convertible.rb +0 -27
- data/lib/jekyll/content_blocks/renderer.rb +0 -11
- data/test/_plugins/bundler.rb +0 -4
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "jekyll", "4.3.4"
|
|
6
|
+
gem "rexml"
|
|
7
|
+
gem "appraisal", "~> 2.5.0"
|
|
8
|
+
gem "pry"
|
|
9
|
+
gem "rspec", "~> 3.13.0"
|
|
10
|
+
gem "nokogiri"
|
|
11
|
+
gem "base64"
|
|
12
|
+
gem "bigdecimal"
|
|
13
|
+
gem "csv"
|
|
14
|
+
|
|
15
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "jekyll", "4.4.1"
|
|
6
|
+
gem "rexml"
|
|
7
|
+
gem "appraisal", "~> 2.5.0"
|
|
8
|
+
gem "pry"
|
|
9
|
+
gem "rspec", "~> 3.13.0"
|
|
10
|
+
gem "nokogiri"
|
|
11
|
+
gem "base64"
|
|
12
|
+
gem "bigdecimal"
|
|
13
|
+
gem "csv"
|
|
14
|
+
|
|
15
|
+
gemspec path: "../"
|
|
@@ -11,11 +11,16 @@ Gem::Specification.new do |gem|
|
|
|
11
11
|
gem.description = %q{Provides a mechanism for passing content up to the layout, like Rails' content_for}
|
|
12
12
|
gem.summary = %q{A Jekyll plugin kind of like Rails' content_for}
|
|
13
13
|
gem.homepage = "https://github.com/rustygeldmacher/jekyll-contentblocks"
|
|
14
|
+
gem.license = "MIT"
|
|
14
15
|
|
|
15
|
-
gem.files = `git ls-files`.split($/)
|
|
16
|
+
gem.files = `git ls-files`.split($/) - ["Gemfile.lock"]
|
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
19
|
gem.require_paths = ["lib"]
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
# Jekyll 3.0–3.7 rely on APIs removed in Ruby 3, so 2.7 is the effective floor.
|
|
22
|
+
gem.required_ruby_version = ">= 2.7.0"
|
|
23
|
+
|
|
24
|
+
# Supports the Jekyll 3.x and 4.x series; excludes the announced-breaking 5.x.
|
|
25
|
+
gem.add_dependency('jekyll', '>= 3.0', '< 5.0')
|
|
21
26
|
end
|
|
@@ -7,7 +7,7 @@ module Jekyll
|
|
|
7
7
|
def initialize(tag_name, markup, tokens)
|
|
8
8
|
super
|
|
9
9
|
parse_options(markup)
|
|
10
|
-
if content_block_name ==
|
|
10
|
+
if content_block_name == ""
|
|
11
11
|
raise SyntaxError.new("No block name given in #{tag_name} tag")
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -15,20 +15,47 @@ module Jekyll
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
17
|
def parse_options(markup)
|
|
18
|
-
options = (markup ||
|
|
18
|
+
options = (markup || "").split(" ").map(&:strip)
|
|
19
19
|
self.content_block_name = options.shift
|
|
20
20
|
self.content_block_options = options
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def block_has_content?(context)
|
|
24
|
-
|
|
25
|
-
!(block_content.nil? || block_content.empty?)
|
|
24
|
+
!raw_block_content(context).empty?
|
|
26
25
|
end
|
|
27
26
|
|
|
27
|
+
# Write accessor for the contentfor tag: returns the block's array, creating
|
|
28
|
+
# it if needed. Each stored block is a hash: "raw" (the block body), "content"
|
|
29
|
+
# (that body converted) and "data" (its own front matter). The store is
|
|
30
|
+
# exposed to layouts as contentblocks.<name> so they can be looped over.
|
|
28
31
|
def content_for_block(context)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
store = (context.environments.first["contentblocks"] ||= {})
|
|
33
|
+
store[content_block_name] ||= []
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Read-only view — does NOT create an empty entry. Reading a never-defined
|
|
37
|
+
# block therefore leaves contentblocks.<name> nil (falsy) rather than an
|
|
38
|
+
# empty array (which Liquid would treat as truthy).
|
|
39
|
+
def blocks_for(context)
|
|
40
|
+
(context.environments.first["contentblocks"] || {})[content_block_name] || []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def raw_block_content(context)
|
|
44
|
+
blocks_for(context).map { |block| block["raw"] }.join
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Convert content with the document's converters, derived from the render
|
|
48
|
+
# context (so we don't depend on the pre-render hook stashing them).
|
|
49
|
+
def converted_content(content, context)
|
|
50
|
+
Array(converters_for(context)).reduce(content) do |result, converter|
|
|
51
|
+
converter.convert(result)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def converters_for(context)
|
|
56
|
+
site = context.registers[:site]
|
|
57
|
+
extension = File.extname(context.registers[:page]["path"].to_s)
|
|
58
|
+
site.converters.select { |converter| converter.matches(extension) }
|
|
32
59
|
end
|
|
33
60
|
end
|
|
34
61
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Jekyll
|
|
2
|
+
module ContentBlocks
|
|
3
|
+
class PreRenderHook
|
|
4
|
+
def self.call(document, payload)
|
|
5
|
+
# Reset the per-document block store. Converters are derived on demand by
|
|
6
|
+
# the contentblock tag from the render context, so they aren't stashed here.
|
|
7
|
+
payload["contentblocks"] = {}
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -4,7 +4,7 @@ module Jekyll
|
|
|
4
4
|
include ::Jekyll::ContentBlocks::ContentBlockTag
|
|
5
5
|
|
|
6
6
|
def render(context)
|
|
7
|
-
block_content =
|
|
7
|
+
block_content = raw_block_content(context)
|
|
8
8
|
if convert_content?
|
|
9
9
|
converted_content(block_content, context)
|
|
10
10
|
else
|
|
@@ -15,14 +15,7 @@ module Jekyll
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
17
|
def convert_content?
|
|
18
|
-
!content_block_options.include?(
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def converted_content(block_content, context)
|
|
22
|
-
converters = context.environments.first['converters']
|
|
23
|
-
Array(converters).reduce(block_content) do |content, converter|
|
|
24
|
-
converter.convert(content)
|
|
25
|
-
end
|
|
18
|
+
!content_block_options.include?("no-convert")
|
|
26
19
|
end
|
|
27
20
|
end
|
|
28
21
|
end
|
|
@@ -5,10 +5,25 @@ module Jekyll
|
|
|
5
5
|
alias_method :render_block, :render
|
|
6
6
|
|
|
7
7
|
def render(context)
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
data, body = split_front_matter(render_block(context))
|
|
9
|
+
content_for_block(context) <<
|
|
10
|
+
{
|
|
11
|
+
"raw" => body,
|
|
12
|
+
"content" => converted_content(body, context),
|
|
13
|
+
"data" => data
|
|
14
|
+
}
|
|
15
|
+
""
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def split_front_matter(rendered)
|
|
21
|
+
if rendered.lstrip =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
|
|
22
|
+
[SafeYAML.load(Regexp.last_match(1)) || {}, $POSTMATCH]
|
|
23
|
+
else
|
|
24
|
+
[{}, rendered]
|
|
25
|
+
end
|
|
10
26
|
end
|
|
11
27
|
end
|
|
12
28
|
end
|
|
13
29
|
end
|
|
14
|
-
|
data/lib/jekyll-contentblocks.rb
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "jekyll"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
def self.version_less_than?(version)
|
|
5
|
-
Gem::Version.new(VERSION) < Gem::Version.new(version)
|
|
6
|
-
end
|
|
3
|
+
require "jekyll/content_blocks/pre_render_hook"
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
[:documents, :pages, :posts].each do |content_type|
|
|
6
|
+
Jekyll::Hooks.register(content_type, :pre_render) do |doc, payload|
|
|
7
|
+
Jekyll::ContentBlocks::PreRenderHook.call(doc, payload)
|
|
10
8
|
end
|
|
11
9
|
end
|
|
12
10
|
|
|
13
|
-
require
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
require
|
|
19
|
-
require 'jekyll/content_blocks/content_block_tag'
|
|
20
|
-
require 'jekyll/tags/content_for'
|
|
21
|
-
require 'jekyll/tags/if_has_content'
|
|
22
|
-
require 'jekyll/tags/if_not_has_content'
|
|
23
|
-
require 'jekyll/tags/content_block'
|
|
11
|
+
require "jekyll/content_blocks/version"
|
|
12
|
+
require "jekyll/content_blocks/content_block_tag"
|
|
13
|
+
require "jekyll/tags/content_for"
|
|
14
|
+
require "jekyll/tags/if_has_content"
|
|
15
|
+
require "jekyll/tags/if_not_has_content"
|
|
16
|
+
require "jekyll/tags/content_block"
|
|
24
17
|
|
|
25
|
-
Liquid::Template.register_tag(
|
|
26
|
-
Liquid::Template.register_tag(
|
|
27
|
-
Liquid::Template.register_tag(
|
|
28
|
-
Liquid::Template.register_tag(
|
|
18
|
+
Liquid::Template.register_tag("contentfor", Jekyll::Tags::ContentFor)
|
|
19
|
+
Liquid::Template.register_tag("ifhascontent", Jekyll::Tags::IfHasContent)
|
|
20
|
+
Liquid::Template.register_tag("ifnothascontent", Jekyll::Tags::IfNotHasContent)
|
|
21
|
+
Liquid::Template.register_tag("contentblock", Jekyll::Tags::ContentBlock)
|
data/mise.toml
ADDED
|
@@ -1,95 +1,155 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
describe Jekyll::ContentBlocks do
|
|
4
|
-
puts
|
|
4
|
+
puts("jekyll #{jekyll_version}")
|
|
5
5
|
|
|
6
|
-
context
|
|
6
|
+
context("against jekyll #{jekyll_version}") do
|
|
7
7
|
before(:all) do
|
|
8
|
-
expect(generate_test_site).to
|
|
8
|
+
expect(generate_test_site).to(be(true))
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
let(:index) { load_html(
|
|
11
|
+
let(:index) { load_html("index.html") }
|
|
12
12
|
|
|
13
|
-
describe
|
|
14
|
-
let(:sidebar) { index.css(
|
|
13
|
+
describe "index.html" do
|
|
14
|
+
let(:sidebar) { index.css("body > div > h2#sidebar").first }
|
|
15
15
|
|
|
16
|
-
it
|
|
17
|
-
expect(index.css(
|
|
16
|
+
it "does not render the css block" do
|
|
17
|
+
expect(index.css("style")).to(be_empty)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
it
|
|
21
|
-
expect(index.css(
|
|
22
|
-
expect(index.css(
|
|
20
|
+
it "renders the custom sidebar" do
|
|
21
|
+
expect(index.css("div.custom-sidebar")).not_to(be_empty)
|
|
22
|
+
expect(index.css("div.sidebar-default")).to(be_empty)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
it
|
|
26
|
-
expect(sidebar).not_to
|
|
27
|
-
expect(sidebar.text).to
|
|
25
|
+
it "renders the sidebar content block" do
|
|
26
|
+
expect(sidebar).not_to(be_nil)
|
|
27
|
+
expect(sidebar.text).to(eq("SIDEBAR"))
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
it
|
|
31
|
-
rendered_liquid = sidebar.css(
|
|
32
|
-
expect(rendered_liquid).not_to
|
|
33
|
-
expect(rendered_liquid.text).to
|
|
30
|
+
it "renders Liquid within a content block" do
|
|
31
|
+
rendered_liquid = sidebar.css("+ p")
|
|
32
|
+
expect(rendered_liquid).not_to(be_nil)
|
|
33
|
+
expect(rendered_liquid.text).to(eq("3"))
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
it
|
|
37
|
-
expect(index.css(
|
|
36
|
+
it "does not render a block without content" do
|
|
37
|
+
expect(index.css("head > style")).to(be_empty)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
describe
|
|
42
|
-
let(:page) { load_html(
|
|
43
|
-
let(:sidebar) { index.css('body > div > h2#sidebar').first }
|
|
41
|
+
describe "page.html" do
|
|
42
|
+
let(:page) { load_html("page.html") }
|
|
44
43
|
|
|
45
|
-
it
|
|
46
|
-
expect(page.css(
|
|
44
|
+
it "renders the css block" do
|
|
45
|
+
expect(page.css("style")).not_to(be_empty)
|
|
47
46
|
end
|
|
48
47
|
|
|
49
|
-
it
|
|
50
|
-
styles = page.css(
|
|
51
|
-
expect(styles).to
|
|
48
|
+
it "does not process Markdown in the CSS block" do
|
|
49
|
+
styles = page.css("style").text.gsub(/\s/, "")
|
|
50
|
+
expect(styles).to(eq("div{font-weight:bold;}"))
|
|
52
51
|
end
|
|
53
52
|
|
|
54
|
-
it
|
|
55
|
-
expect(page.css(
|
|
56
|
-
expect(page.css(
|
|
53
|
+
it "renders the custom footer" do
|
|
54
|
+
expect(page.css("div#footer")).to(be_empty)
|
|
55
|
+
expect(page.css("div#custom-footer")).not_to(be_empty)
|
|
57
56
|
end
|
|
58
57
|
|
|
59
|
-
it
|
|
60
|
-
expect(page.css(
|
|
61
|
-
expect(page.css(
|
|
58
|
+
it "renders the default sidebar" do
|
|
59
|
+
expect(page.css("div.sidebar-default")).not_to(be_empty)
|
|
60
|
+
expect(page.css("div.custom-sidebar")).to(be_empty)
|
|
62
61
|
end
|
|
63
62
|
end
|
|
64
63
|
|
|
65
|
-
describe
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
describe "page2.html" do
|
|
65
|
+
let(:page) { load_html("page2.html") }
|
|
66
|
+
|
|
67
|
+
it "renders only the page2 sidebar" do
|
|
68
|
+
sidebar = page.css("div.custom-sidebar")
|
|
69
|
+
expect(sidebar).not_to(be_empty)
|
|
70
|
+
expect(sidebar.text.strip).to(eq("A pretty simple sidebar."))
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "ifnothascontent" do
|
|
75
|
+
it "renders defaults when content is not supplied" do
|
|
76
|
+
expect(index.css("div#footer")).not_to(be_empty)
|
|
68
77
|
end
|
|
69
78
|
|
|
70
|
-
it
|
|
71
|
-
expect(index.css(
|
|
79
|
+
it "does not render when there is content" do
|
|
80
|
+
expect(index.css("div[class=sidebar-default]")).to(be_empty)
|
|
72
81
|
end
|
|
73
82
|
end
|
|
74
83
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
describe "content blocks in a collection" do
|
|
85
|
+
let(:item_one) { load_item_html("one") }
|
|
86
|
+
let(:item_two) { load_item_html("two") }
|
|
87
|
+
|
|
88
|
+
it "should render the content block" do
|
|
89
|
+
expect(item_one.css("div[class=sidebar-default]")).to(be_empty)
|
|
90
|
+
expect(item_one.css("div[class=custom-sidebar]")).not_to(be_empty)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should skip a content block that was not defined" do
|
|
94
|
+
expect(item_two.css("div[class=sidebar-default]")).not_to(be_empty)
|
|
95
|
+
expect(item_two.css("div[class=custom-sidebar]")).to(be_empty)
|
|
96
|
+
end
|
|
79
97
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
98
|
+
it "should process Markdown inside the content block" do
|
|
99
|
+
expect(item_one.css("div[class=custom-sidebar] ul li")).not_to(be_empty)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe "page3.html (repeated blocks and front matter)" do
|
|
104
|
+
let(:page) { load_html("page3.html") }
|
|
105
|
+
let(:testimonials) { page.css("div.testimonials div.testimonial") }
|
|
106
|
+
|
|
107
|
+
it "collects each same-named block into contentblocks" do
|
|
108
|
+
expect(testimonials.length).to(eq(3))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "exposes each block's front matter under data" do
|
|
112
|
+
expect(testimonials[0]["data-author"]).to(eq("Ada Lovelace"))
|
|
113
|
+
expect(testimonials[1]["data-author"]).to(eq("Alan Turing"))
|
|
114
|
+
end
|
|
84
115
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
116
|
+
it "leaves data empty for a block without front matter" do
|
|
117
|
+
expect(testimonials[2]["data-author"].to_s).to(eq(""))
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "converts each block's Markdown content" do
|
|
121
|
+
expect(testimonials[0].css("strong").text).to(eq("delightful"))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "does not render the section on pages without those blocks" do
|
|
125
|
+
expect(index.css("div.testimonials")).to(be_empty)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe "contentblocks variable" do
|
|
130
|
+
it "is present for a block that has content" do
|
|
131
|
+
expect(index.css("span#cb-sidebar-present")).not_to(be_empty)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "stays nil for a block referenced by tags but with no content" do
|
|
135
|
+
# page.html renders {% ifhascontent sidebar %} but never defines a sidebar,
|
|
136
|
+
# so contentblocks.sidebar must not have been created as an empty array.
|
|
137
|
+
expect(load_html("page.html").css("span#cb-sidebar-present")).to(be_empty)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "a block defined but left empty" do
|
|
142
|
+
# `{% if contentblocks.x %}` tests whether the block was defined, while
|
|
143
|
+
# `ifhascontent` tests for non-empty content — so they diverge here.
|
|
144
|
+
let(:page) { load_html("emptyblock.html") }
|
|
145
|
+
|
|
146
|
+
it "is present in contentblocks (the block was defined)" do
|
|
147
|
+
expect(page.css("span#cb-sidebar-present")).not_to(be_empty)
|
|
148
|
+
end
|
|
89
149
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
150
|
+
it "counts as no content for ifhascontent / ifnothascontent" do
|
|
151
|
+
expect(page.css("div.custom-sidebar")).to(be_empty)
|
|
152
|
+
expect(page.css("div.sidebar-default")).not_to(be_empty)
|
|
93
153
|
end
|
|
94
154
|
end
|
|
95
155
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
1
|
+
require "nokogiri"
|
|
2
|
+
require "jekyll-contentblocks"
|
|
3
|
+
require "open3"
|
|
4
4
|
|
|
5
5
|
module SpecHelpers
|
|
6
6
|
def jekyll_version
|
|
7
|
-
@jekyll_version ||= `jekyll --version`.strip.gsub(
|
|
7
|
+
@jekyll_version ||= `jekyll --version`.strip.gsub("jekyll ", "")
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def generate_test_site
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
FileUtils.rm_rf("test/_site")
|
|
12
|
+
output, status = Open3.capture2e("jekyll build -s test/ -d test/_site")
|
|
13
|
+
# Keep passing runs quiet; only surface the build log when it actually fails.
|
|
14
|
+
warn(output) unless status.success?
|
|
15
|
+
status.success?
|
|
13
16
|
end
|
|
14
17
|
|
|
15
18
|
def load_html(file)
|
|
16
19
|
path = "test/_site/#{file}"
|
|
17
|
-
if File.
|
|
20
|
+
if File.exist?(path)
|
|
18
21
|
index_html = File.read(path)
|
|
19
22
|
Nokogiri::Slop(index_html).html
|
|
20
23
|
end
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def load_item_html(item)
|
|
24
|
-
|
|
25
|
-
load_html("items/#{item}.html")
|
|
26
|
-
else
|
|
27
|
-
load_html("items/#{item}/index.html")
|
|
28
|
-
end
|
|
27
|
+
load_html("items/#{item}/index.html")
|
|
29
28
|
end
|
|
30
29
|
end
|
|
31
30
|
|
data/test/_layouts/default.html
CHANGED
|
@@ -25,6 +25,10 @@
|
|
|
25
25
|
</div>
|
|
26
26
|
{% endifnothascontent %}
|
|
27
27
|
|
|
28
|
+
{% if contentblocks.sidebar %}
|
|
29
|
+
<span id="cb-sidebar-present"></span>
|
|
30
|
+
{% endif %}
|
|
31
|
+
|
|
28
32
|
{% ifhascontent footer %}
|
|
29
33
|
{% contentblock footer %}
|
|
30
34
|
{% endifhascontent %}
|
|
@@ -34,6 +38,16 @@
|
|
|
34
38
|
This is the default footer.
|
|
35
39
|
</div>
|
|
36
40
|
{% endifnothascontent %}
|
|
41
|
+
|
|
42
|
+
{% if contentblocks.testimonial %}
|
|
43
|
+
<div class="testimonials">
|
|
44
|
+
{% for testimonial in contentblocks.testimonial %}
|
|
45
|
+
<div class="testimonial" data-author="{{ testimonial.data.author }}">
|
|
46
|
+
{{ testimonial.content }}
|
|
47
|
+
</div>
|
|
48
|
+
{% endfor %}
|
|
49
|
+
</div>
|
|
50
|
+
{% endif %}
|
|
37
51
|
</body>
|
|
38
52
|
</html>
|
|
39
53
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "jekyll-contentblocks"
|
data/test/emptyblock.md
ADDED
data/test/page2.md
ADDED
data/test/page3.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Page Three
|
|
3
|
+
layout: default
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CONTENT
|
|
7
|
+
|
|
8
|
+
This page defines several blocks with the same name, each with its own front
|
|
9
|
+
matter, and the layout loops over them.
|
|
10
|
+
|
|
11
|
+
{% contentfor testimonial %}
|
|
12
|
+
---
|
|
13
|
+
author: Ada Lovelace
|
|
14
|
+
---
|
|
15
|
+
A **delightful** plugin.
|
|
16
|
+
{% endcontentfor %}
|
|
17
|
+
|
|
18
|
+
{% contentfor testimonial %}
|
|
19
|
+
---
|
|
20
|
+
author: Alan Turing
|
|
21
|
+
---
|
|
22
|
+
Saved us hours of work.
|
|
23
|
+
{% endcontentfor %}
|
|
24
|
+
|
|
25
|
+
{% contentfor testimonial %}
|
|
26
|
+
Anonymous, but happy.
|
|
27
|
+
{% endcontentfor %}
|