bridgetown-builder 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +17 -0
- data/Rakefile +11 -0
- data/bridgetown-builder.gemspec +18 -0
- data/lib/bridgetown-builder.rb +41 -0
- data/lib/bridgetown-builder/builder.rb +45 -0
- data/lib/bridgetown-builder/document.rb +63 -0
- data/lib/bridgetown-builder/documents_generator.rb +31 -0
- data/lib/bridgetown-builder/dsl/generators.rb +34 -0
- data/lib/bridgetown-builder/dsl/hooks.rb +28 -0
- data/lib/bridgetown-builder/dsl/http.rb +36 -0
- data/lib/bridgetown-builder/dsl/liquid.rb +45 -0
- data/lib/bridgetown-builder/plugin.rb +40 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d55403ba9988ba7ef4f805e8f46f9bb1f3b6f5bf5571ba442372938fe11c3b7e
|
4
|
+
data.tar.gz: faf5ad6c2a5767522c00bf4618a8e3ff330f3b393cff018059e6fbf8bada5022
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 286318aa0554d4e905bbea42ba651f0293378dfc3c0c0ae978b54428d62dcae1aa1fc3e07e58221e5b2a91609c0c0b4b58845d0428ecabdc1e60733f3f504278
|
7
|
+
data.tar.gz: cdb633657736552e5a7a1691019dca4788895fa8b148c4ab52ba45b7d93d621e72b8a82950a8cad75ee86d7eb70f42876788576dfd473ee91232fd36745c59bc
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
inherit_from: ../.rubocop.yml
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
Include:
|
6
|
+
- lib/**/*.rb
|
7
|
+
- spec/**/*.rb
|
8
|
+
|
9
|
+
Metrics/AbcSize:
|
10
|
+
Exclude:
|
11
|
+
- lib/bridgetown-builder/dsl/*
|
12
|
+
Metrics/MethodLength:
|
13
|
+
Exclude:
|
14
|
+
- lib/bridgetown-builder/dsl/*
|
15
|
+
Metrics/ParameterLists:
|
16
|
+
Exclude:
|
17
|
+
- lib/bridgetown-builder/dsl/hooks.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../bridgetown-core/lib/bridgetown-core/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "bridgetown-builder"
|
7
|
+
spec.version = Bridgetown::VERSION
|
8
|
+
spec.author = "Bridgetown Team"
|
9
|
+
spec.email = "maintainers@bridgetownrb.com"
|
10
|
+
spec.summary = "A Bridgetown plugin to provide a sophisticated DSL for writing plugins at a higher level of abstraction."
|
11
|
+
spec.homepage = "https://github.com/bridgetownrb/bridgetown/tree/master/bridgetown-builder"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|script|spec|features)/!) }
|
15
|
+
spec.require_paths = ["lib"]
|
16
|
+
|
17
|
+
spec.add_dependency("bridgetown-core", Bridgetown::VERSION)
|
18
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bridgetown-core"
|
4
|
+
require "bridgetown-core/version"
|
5
|
+
|
6
|
+
module Bridgetown
|
7
|
+
module Builders
|
8
|
+
autoload :PluginBuilder, "bridgetown-builder/plugin"
|
9
|
+
autoload :DocumentBuilder, "bridgetown-builder/document"
|
10
|
+
autoload :DocumentsGenerator, "bridgetown-builder/documents_generator"
|
11
|
+
end
|
12
|
+
|
13
|
+
autoload :Builder, "bridgetown-builder/builder"
|
14
|
+
end
|
15
|
+
|
16
|
+
Bridgetown::Hooks.register_one :site, :pre_read, priority: :low, reloadable: false do |site|
|
17
|
+
# SiteBuilder is the superclass sites can subclass to create any number of
|
18
|
+
# builders, but if the site hasn't defined it explicitly, this is a no-op
|
19
|
+
if defined?(SiteBuilder)
|
20
|
+
SiteBuilder.descendants.map do |c|
|
21
|
+
c.new(c.name, site)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# If the documents generator is in use, we need to add it at the top of the
|
26
|
+
# list so the site runs the generator before any others
|
27
|
+
if Bridgetown::Builders.autoload?(:DocumentsGenerator).nil? &&
|
28
|
+
!site.generators.first.is_a?(Bridgetown::Builders::DocumentsGenerator)
|
29
|
+
site.generators.unshift Bridgetown::Builders::DocumentsGenerator.new(site.config)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Bridgetown::Hooks.register_one :site, :pre_reload, reloadable: false do |site|
|
34
|
+
# Remove all anonymous generator classes so they can later get reloaded
|
35
|
+
site.converters.delete_if { |generator| generator.class.name.nil? }
|
36
|
+
site.generators.delete_if { |generator| generator.class.name.nil? }
|
37
|
+
|
38
|
+
unless Bridgetown::Builders.autoload? :DocumentsGenerator
|
39
|
+
Bridgetown::Builders::DocumentsGenerator.clear_documents_to_generate
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
# Superclass for a website's SiteBuilder abstract class
|
5
|
+
class Builder < Bridgetown::Builders::PluginBuilder
|
6
|
+
class << self
|
7
|
+
def register
|
8
|
+
Bridgetown::Hooks.register_one :site, :pre_read, reloadable: false do |site|
|
9
|
+
new(name, site)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Subclass is expected to implement #build
|
15
|
+
def initialize(name, current_site = nil)
|
16
|
+
super(name, current_site)
|
17
|
+
build
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
name
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.inherited(const)
|
25
|
+
(@children ||= Set.new).add const
|
26
|
+
catch_inheritance(const) do |const_|
|
27
|
+
catch_inheritance(const_)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.catch_inheritance(const)
|
32
|
+
const.define_singleton_method :inherited do |const_|
|
33
|
+
(@children ||= Set.new).add const_
|
34
|
+
yield const_ if block_given?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.descendants
|
39
|
+
@children ||= Set.new
|
40
|
+
out = @children.map(&:descendants)
|
41
|
+
out << self unless ["SiteBuilder", "Bridgetown::Builder"].include?(name)
|
42
|
+
Set.new(out).flatten
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Builders
|
5
|
+
class DocumentBuilder
|
6
|
+
attr_reader :site
|
7
|
+
|
8
|
+
def initialize(site, path)
|
9
|
+
@site = site
|
10
|
+
@path = path
|
11
|
+
@data = ActiveSupport::HashWithIndifferentAccess.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def front_matter(data)
|
15
|
+
@data.merge!(data)
|
16
|
+
end
|
17
|
+
|
18
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
19
|
+
def _add_document_to_site
|
20
|
+
@collection = (@data[:collection] || :posts).to_s
|
21
|
+
collection = @site.collections[@collection]
|
22
|
+
unless collection
|
23
|
+
collection = Collection.new(@site, @collection)
|
24
|
+
collection.metadata["output"] = true
|
25
|
+
@site.collections[@collection] = collection
|
26
|
+
end
|
27
|
+
|
28
|
+
doc = Document.new(
|
29
|
+
File.join(collection.directory, @path),
|
30
|
+
site: @site,
|
31
|
+
collection: collection
|
32
|
+
)
|
33
|
+
doc.send(:merge_defaults)
|
34
|
+
doc.content = @data[:content]
|
35
|
+
@data.delete(:content)
|
36
|
+
|
37
|
+
if @path.start_with?("/")
|
38
|
+
pathname = Pathname.new(@path)
|
39
|
+
@data[:permalink] = File.join(
|
40
|
+
pathname.dirname,
|
41
|
+
pathname.basename.sub(pathname.extname, "")
|
42
|
+
) + "/"
|
43
|
+
end
|
44
|
+
|
45
|
+
doc.merge_data!(@data)
|
46
|
+
doc.send(:read_post_data)
|
47
|
+
|
48
|
+
collection.docs << doc
|
49
|
+
end
|
50
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
51
|
+
|
52
|
+
# rubocop:disable Style/MissingRespondToMissing
|
53
|
+
def method_missing(key, value = nil)
|
54
|
+
if respond_to?(key)
|
55
|
+
super
|
56
|
+
else
|
57
|
+
@data[key] = value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# rubocop:enable Style/MissingRespondToMissing
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Builders
|
5
|
+
class DocumentsGenerator < Bridgetown::Generator
|
6
|
+
priority :high
|
7
|
+
|
8
|
+
def self.add(path, block)
|
9
|
+
@documents_to_generate ||= []
|
10
|
+
@documents_to_generate << [path, block]
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_reader :documents_to_generate
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.clear_documents_to_generate
|
18
|
+
@documents_to_generate = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate(site)
|
22
|
+
self.class.documents_to_generate&.each do |doc_block|
|
23
|
+
path, block = doc_block
|
24
|
+
doc_builder = DocumentBuilder.new(site, path)
|
25
|
+
doc_builder.instance_exec(&block)
|
26
|
+
doc_builder._add_document_to_site
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Builders
|
5
|
+
module DSL
|
6
|
+
module Generators
|
7
|
+
def generator(method_name = nil, &block)
|
8
|
+
block = method(method_name) if method_name.is_a?(Symbol)
|
9
|
+
local_name = name # pull the name method into a local variable
|
10
|
+
|
11
|
+
new_gen = Class.new(Bridgetown::Generator) do
|
12
|
+
define_method(:_builder_block) { block }
|
13
|
+
define_singleton_method(:custom_name) { local_name }
|
14
|
+
|
15
|
+
attr_reader :site
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"#{self.class.custom_name} (Generator)"
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate(_site)
|
22
|
+
_builder_block.call
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
first_low_priority_index = site.generators.find_index { |gen| gen.class.priority == :low }
|
27
|
+
site.generators.insert(first_low_priority_index || 0, new_gen.new(site.config))
|
28
|
+
|
29
|
+
functions << { name: name, generator: new_gen }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Builders
|
5
|
+
module DSL
|
6
|
+
module Hooks
|
7
|
+
def hook(
|
8
|
+
owner,
|
9
|
+
event,
|
10
|
+
method_name = nil,
|
11
|
+
priority: Bridgetown::Hooks::DEFAULT_PRIORITY,
|
12
|
+
&block
|
13
|
+
)
|
14
|
+
block = method(method_name) if method_name.is_a?(Symbol)
|
15
|
+
|
16
|
+
hook_block = Bridgetown::Hooks.register_one(owner, event, priority: priority, &block)
|
17
|
+
functions << { name: name, hook: [owner, event, priority, hook_block] }
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_data(data_key)
|
21
|
+
hook(:site, :post_read) do
|
22
|
+
site.data[data_key] = yield
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday_middleware/redirect_limit_reached"
|
4
|
+
require "faraday_middleware/response/follow_redirects"
|
5
|
+
require "faraday_middleware/response/parse_json"
|
6
|
+
|
7
|
+
module Bridgetown
|
8
|
+
module Builders
|
9
|
+
module DSL
|
10
|
+
module HTTP
|
11
|
+
def get(url, headers: {}, parse_json: true)
|
12
|
+
body = begin
|
13
|
+
connection(parse_json: parse_json).get(url, headers: headers).body
|
14
|
+
rescue Faraday::ParsingError
|
15
|
+
Bridgetown.logger.error(
|
16
|
+
"Faraday::ParsingError",
|
17
|
+
"The response from #{url} did not contain valid JSON"
|
18
|
+
)
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
yield body
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection(headers: {}, parse_json: true)
|
25
|
+
headers["Content-Type"] = "application/json" if parse_json
|
26
|
+
|
27
|
+
Faraday.new(headers: headers) do |faraday|
|
28
|
+
faraday.use FaradayMiddleware::FollowRedirects
|
29
|
+
faraday.use FaradayMiddleware::ParseJson if parse_json
|
30
|
+
yield faraday if block_given?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Builders
|
5
|
+
module DSL
|
6
|
+
module Liquid
|
7
|
+
def liquid_filter(filter_name, method_name = nil, &block)
|
8
|
+
block = method(method_name) if method_name.is_a?(Symbol)
|
9
|
+
|
10
|
+
m = Module.new
|
11
|
+
m.send(:define_method, filter_name, &block)
|
12
|
+
::Liquid::Template.register_filter(m)
|
13
|
+
|
14
|
+
functions << { name: name, filter: m }
|
15
|
+
end
|
16
|
+
|
17
|
+
def liquid_tag(tag_name, method_name = nil, as_block: false, &block)
|
18
|
+
block = method(method_name) if method_name.is_a?(Symbol)
|
19
|
+
local_name = name # pull the name method into a local variable
|
20
|
+
|
21
|
+
tag_class = as_block ? ::Liquid::Block : ::Liquid::Tag
|
22
|
+
tag = Class.new(tag_class) do
|
23
|
+
define_method(:_builder_block) { block }
|
24
|
+
define_singleton_method(:custom_name) { local_name }
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
"#{self.class.custom_name} (Liquid Tag)"
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :content, :context
|
31
|
+
|
32
|
+
def render(context)
|
33
|
+
@context = context
|
34
|
+
@content = super if is_a?(::Liquid::Block)
|
35
|
+
_builder_block.call(@markup.strip, self)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
::Liquid::Template.register_tag tag_name, tag
|
40
|
+
functions << { name: name, tag: [tag_name, tag] }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bridgetown-builder/dsl/generators"
|
4
|
+
require "bridgetown-builder/dsl/hooks"
|
5
|
+
require "bridgetown-builder/dsl/http"
|
6
|
+
require "bridgetown-builder/dsl/liquid"
|
7
|
+
module Bridgetown
|
8
|
+
module Builders
|
9
|
+
class PluginBuilder
|
10
|
+
include DSL::Generators
|
11
|
+
include DSL::Hooks
|
12
|
+
include DSL::HTTP
|
13
|
+
include DSL::Liquid
|
14
|
+
|
15
|
+
attr_accessor :functions, :name, :site, :config
|
16
|
+
|
17
|
+
def initialize(name, current_site = nil)
|
18
|
+
self.functions = Set.new
|
19
|
+
self.name = name
|
20
|
+
self.site = current_site || Bridgetown.sites.first
|
21
|
+
|
22
|
+
self.config = if defined?(self.class::CONFIG_DEFAULTS)
|
23
|
+
Bridgetown::Utils.deep_merge_hashes(
|
24
|
+
self.class::CONFIG_DEFAULTS.with_indifferent_access, site.config
|
25
|
+
)
|
26
|
+
else
|
27
|
+
site.config
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
"#{name} (Hook)"
|
33
|
+
end
|
34
|
+
|
35
|
+
def doc(path, &block)
|
36
|
+
DocumentsGenerator.add(path, block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bridgetown-builder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.14.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bridgetown Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bridgetown-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.14.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.14.0
|
27
|
+
description:
|
28
|
+
email: maintainers@bridgetownrb.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- ".rubocop.yml"
|
34
|
+
- Rakefile
|
35
|
+
- bridgetown-builder.gemspec
|
36
|
+
- lib/bridgetown-builder.rb
|
37
|
+
- lib/bridgetown-builder/builder.rb
|
38
|
+
- lib/bridgetown-builder/document.rb
|
39
|
+
- lib/bridgetown-builder/documents_generator.rb
|
40
|
+
- lib/bridgetown-builder/dsl/generators.rb
|
41
|
+
- lib/bridgetown-builder/dsl/hooks.rb
|
42
|
+
- lib/bridgetown-builder/dsl/http.rb
|
43
|
+
- lib/bridgetown-builder/dsl/liquid.rb
|
44
|
+
- lib/bridgetown-builder/plugin.rb
|
45
|
+
homepage: https://github.com/bridgetownrb/bridgetown/tree/master/bridgetown-builder
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubygems_version: 3.0.6
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: A Bridgetown plugin to provide a sophisticated DSL for writing plugins at
|
68
|
+
a higher level of abstraction.
|
69
|
+
test_files: []
|