perron 0.17.0 → 0.18.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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +25 -2
- data/app/controllers/perron/searches_controller.rb +48 -0
- data/app/helpers/perron/feeds_helper.rb +7 -0
- data/app/helpers/perron/markdown_helper.rb +3 -3
- data/app/helpers/perron/meta_tags_helper.rb +17 -0
- data/bin/release +19 -4
- data/lib/generators/perron/templates/README.md.tt +31 -7
- data/lib/generators/perron/templates/initializer.rb.tt +8 -4
- data/lib/generators/rails/content/USAGE +28 -26
- data/lib/generators/rails/content/content_generator.rb +6 -7
- data/lib/generators/rails/content/templates/controller.rb.tt +1 -5
- data/lib/generators/rails/content/templates/model.rb.tt +3 -3
- data/lib/perron/collection.rb +10 -1
- data/lib/perron/configuration.rb +9 -4
- data/lib/perron/content/data.rb +6 -2
- data/lib/perron/data_source/class_methods.rb +58 -0
- data/lib/perron/data_source/helper_context.rb +20 -0
- data/lib/perron/data_source/item.rb +37 -0
- data/lib/perron/{data → data_source}/proxy.rb +1 -1
- data/lib/perron/data_source.rb +155 -0
- data/lib/perron/engine.rb +12 -0
- data/lib/perron/html_processor/syntax_highlight.rb +2 -0
- data/lib/perron/output_server.rb +7 -2
- data/lib/perron/relation.rb +51 -0
- data/lib/perron/resource/associations.rb +2 -2
- data/lib/perron/resource/class_methods.rb +10 -0
- data/lib/perron/resource/configuration.rb +8 -11
- data/lib/perron/resource/core.rb +11 -0
- data/lib/perron/resource/related/stop_words.rb +20 -20
- data/lib/perron/resource/related.rb +73 -52
- data/lib/perron/resource/scopes.rb +29 -0
- data/lib/perron/resource/searchable.rb +19 -0
- data/lib/perron/resource/sourceable.rb +2 -2
- data/lib/perron/resource/sweeper.rb +45 -0
- data/lib/perron/resource/table_of_content.rb +0 -18
- data/lib/perron/resource.rb +30 -20
- data/lib/perron/site.rb +3 -3
- data/lib/perron/tasks/build.rake +8 -1
- data/lib/perron/version.rb +1 -1
- data/lib/perron.rb +1 -0
- data/perron.gemspec +1 -0
- metadata +28 -6
- data/app/helpers/feeds_helper.rb +0 -5
- data/app/helpers/meta_tags_helper.rb +0 -15
- data/lib/perron/data.rb +0 -180
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Perron
|
|
4
|
+
class Resource
|
|
5
|
+
module Searchable
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :search_fields_list, default: []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class_methods do
|
|
13
|
+
def search_fields(*fields)
|
|
14
|
+
self.search_fields_list = fields
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -40,7 +40,7 @@ module Perron
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def combinations
|
|
43
|
-
datasets = source_names.map { Perron::
|
|
43
|
+
datasets = source_names.map { Perron::DataSource.new(it.to_s) }
|
|
44
44
|
|
|
45
45
|
datasets.first.product(*datasets[1..])
|
|
46
46
|
end
|
|
@@ -72,7 +72,7 @@ module Perron
|
|
|
72
72
|
singular_name = name.to_s.singularize
|
|
73
73
|
identifier = frontmatter["#{singular_name}_#{primary_key}"]
|
|
74
74
|
|
|
75
|
-
hash[name] = Perron::
|
|
75
|
+
hash[name] = Perron::DataSource.new(name.to_s).find { it.public_send(primary_key).to_s == identifier.to_s }
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
Source.new(data)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Perron
|
|
4
|
+
class Resource
|
|
5
|
+
module Sweeper
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
def extracted_headings
|
|
9
|
+
extract_heading_texts(from: rendered_document)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def sweeped_content
|
|
13
|
+
ActionView::Base.full_sanitizer.sanitize(
|
|
14
|
+
rendered_document.text.gsub(/\s+/, " ").strip
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def rendered_document
|
|
21
|
+
@rendered_document ||= Nokogiri::HTML::DocumentFragment.parse(Markdown.render(content))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def extract_heading_texts(from:, levels: "h1, h2, h3, h4, h5, h6")
|
|
25
|
+
from.css(levels).map { it.text.strip }.compact_blank
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def extract_headings(from:, levels:)
|
|
29
|
+
from.css(levels).each_with_object([]) do |heading, headings|
|
|
30
|
+
heading_text = heading.text.strip
|
|
31
|
+
id = heading["id"] || heading.at("a")&.[]("id")
|
|
32
|
+
|
|
33
|
+
next if heading_text.empty? || id.blank?
|
|
34
|
+
|
|
35
|
+
headings << TableOfContent::Item.new(
|
|
36
|
+
id: id,
|
|
37
|
+
text: heading_text,
|
|
38
|
+
level: heading.name[1..].to_i,
|
|
39
|
+
children: []
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -20,24 +20,6 @@ module Perron
|
|
|
20
20
|
|
|
21
21
|
Item = ::Data.define(:id, :text, :level, :children)
|
|
22
22
|
|
|
23
|
-
def extract_headings(from:, levels:)
|
|
24
|
-
from.css(levels).each_with_object([]) do |heading, headings|
|
|
25
|
-
heading.tap do |node|
|
|
26
|
-
heading_text = node.text.strip
|
|
27
|
-
id = node["id"] || node.at("a")&.[]("id")
|
|
28
|
-
|
|
29
|
-
next if heading_text.empty? || id.blank?
|
|
30
|
-
|
|
31
|
-
headings << Item.new(
|
|
32
|
-
id: id,
|
|
33
|
-
text: heading_text,
|
|
34
|
-
level: node.name[1..].to_i,
|
|
35
|
-
children: []
|
|
36
|
-
)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
23
|
class Builder
|
|
42
24
|
def build(headings)
|
|
43
25
|
parents = {0 => {children: []}}
|
data/lib/perron/resource.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "perron/relation"
|
|
3
4
|
require "perron/resource/configuration"
|
|
4
5
|
require "perron/resource/core"
|
|
5
6
|
require "perron/resource/class_methods"
|
|
@@ -10,26 +11,30 @@ require "perron/resource/publishable"
|
|
|
10
11
|
require "perron/resource/reading_time"
|
|
11
12
|
require "perron/resource/related"
|
|
12
13
|
require "perron/resource/renderer"
|
|
14
|
+
require "perron/resource/scopes"
|
|
13
15
|
require "perron/resource/slug"
|
|
16
|
+
require "perron/resource/searchable"
|
|
14
17
|
require "perron/resource/separator"
|
|
15
18
|
require "perron/resource/sourceable"
|
|
19
|
+
require "perron/resource/sweeper"
|
|
16
20
|
require "perron/resource/table_of_content"
|
|
17
21
|
|
|
18
22
|
module Perron
|
|
19
23
|
class Resource
|
|
20
|
-
ID_LENGTH = 8
|
|
21
|
-
|
|
22
24
|
include ActiveModel::Validations
|
|
23
25
|
|
|
24
|
-
include
|
|
25
|
-
include
|
|
26
|
-
include
|
|
27
|
-
include
|
|
28
|
-
include
|
|
29
|
-
include
|
|
30
|
-
include
|
|
31
|
-
include
|
|
32
|
-
include
|
|
26
|
+
include Configuration
|
|
27
|
+
include Core
|
|
28
|
+
include ClassMethods
|
|
29
|
+
include Associations
|
|
30
|
+
include ReadingTime
|
|
31
|
+
include Searchable
|
|
32
|
+
include Sourceable
|
|
33
|
+
include Publishable
|
|
34
|
+
include Previewable
|
|
35
|
+
include Scopes
|
|
36
|
+
include Sweeper
|
|
37
|
+
include TableOfContent
|
|
33
38
|
|
|
34
39
|
attr_reader :file_path, :id
|
|
35
40
|
|
|
@@ -41,6 +46,16 @@ module Perron
|
|
|
41
46
|
raise Errors::FileNotFoundError, "No such file: #{file_path}" unless File.exist?(file_path)
|
|
42
47
|
end
|
|
43
48
|
|
|
49
|
+
def pluck(*attributes)
|
|
50
|
+
raise ArgumentError, "wrong number of arguments (given 0, expected 1+)" if attributes.empty?
|
|
51
|
+
|
|
52
|
+
if attributes.size == 1
|
|
53
|
+
public_send(attributes.first)
|
|
54
|
+
else
|
|
55
|
+
attributes.map { |attr| public_send(attr) }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
44
59
|
def filename = File.basename(@file_path)
|
|
45
60
|
|
|
46
61
|
def slug = Perron::Resource::Slug.new(self, frontmatter).create
|
|
@@ -66,15 +81,8 @@ module Perron
|
|
|
66
81
|
render_inline_erb using: page_content
|
|
67
82
|
end
|
|
68
83
|
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
def to_partial_path
|
|
72
|
-
@to_partial_path ||= begin
|
|
73
|
-
element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self.class.model_name))
|
|
74
|
-
collection = ActiveSupport::Inflector.tableize(self.class.model_name)
|
|
75
|
-
|
|
76
|
-
File.join("content", collection, element)
|
|
77
|
-
end
|
|
84
|
+
def inline(layout: "application", **options)
|
|
85
|
+
{html: content, layout: layout}.merge(options)
|
|
78
86
|
end
|
|
79
87
|
|
|
80
88
|
def collection = Collection.new(self.class.model_name.collection)
|
|
@@ -88,6 +96,8 @@ module Perron
|
|
|
88
96
|
|
|
89
97
|
private
|
|
90
98
|
|
|
99
|
+
ID_LENGTH = 8
|
|
100
|
+
|
|
91
101
|
def frontmatter
|
|
92
102
|
@frontmatter ||= Perron::Resource::Separator.new(raw_content).frontmatter
|
|
93
103
|
end
|
data/lib/perron/site.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "perron/collection"
|
|
4
|
-
require "perron/
|
|
5
|
-
require "perron/
|
|
4
|
+
require "perron/data_source"
|
|
5
|
+
require "perron/data_source/proxy"
|
|
6
6
|
require "perron/site/builder"
|
|
7
7
|
require "perron/site/validate"
|
|
8
8
|
|
|
@@ -26,7 +26,7 @@ module Perron
|
|
|
26
26
|
def data(name = nil)
|
|
27
27
|
Perron.deprecator.deprecation_warning(:data, "Use Content::Data::ClassName instead, e.g. `Content::Data::Users.all`")
|
|
28
28
|
|
|
29
|
-
(name && Perron::
|
|
29
|
+
(name && Perron::DataSource.new(name)) || Perron::DataSource::Proxy.new
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
end
|
data/lib/perron/tasks/build.rake
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
namespace :perron do
|
|
2
|
+
task :set_production_env do
|
|
3
|
+
unless ENV["RAILS_ENV"]
|
|
4
|
+
ENV["RAILS_ENV"] = "production"
|
|
5
|
+
puts "RAILS_ENV not set, defaulting to production"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
2
9
|
desc "Generate static HTML files from Perron collections"
|
|
3
|
-
task build: :environment do
|
|
10
|
+
task build: [:set_production_env, :environment] do
|
|
4
11
|
Perron::Site.build
|
|
5
12
|
end
|
|
6
13
|
end
|
data/lib/perron/version.rb
CHANGED
data/lib/perron.rb
CHANGED
data/perron.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: perron
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rails Designer Developers
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: 7.2.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mata
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.8.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.8.0
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: csv
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -78,10 +92,11 @@ files:
|
|
|
78
92
|
- Gemfile.lock
|
|
79
93
|
- README.md
|
|
80
94
|
- Rakefile
|
|
81
|
-
- app/
|
|
82
|
-
- app/helpers/meta_tags_helper.rb
|
|
95
|
+
- app/controllers/perron/searches_controller.rb
|
|
83
96
|
- app/helpers/perron/erb_helper.rb
|
|
97
|
+
- app/helpers/perron/feeds_helper.rb
|
|
84
98
|
- app/helpers/perron/markdown_helper.rb
|
|
99
|
+
- app/helpers/perron/meta_tags_helper.rb
|
|
85
100
|
- bin/console
|
|
86
101
|
- bin/rails
|
|
87
102
|
- bin/release
|
|
@@ -100,8 +115,11 @@ files:
|
|
|
100
115
|
- lib/perron/collection.rb
|
|
101
116
|
- lib/perron/configuration.rb
|
|
102
117
|
- lib/perron/content/data.rb
|
|
103
|
-
- lib/perron/
|
|
104
|
-
- lib/perron/
|
|
118
|
+
- lib/perron/data_source.rb
|
|
119
|
+
- lib/perron/data_source/class_methods.rb
|
|
120
|
+
- lib/perron/data_source/helper_context.rb
|
|
121
|
+
- lib/perron/data_source/item.rb
|
|
122
|
+
- lib/perron/data_source/proxy.rb
|
|
105
123
|
- lib/perron/deprecator.rb
|
|
106
124
|
- lib/perron/engine.rb
|
|
107
125
|
- lib/perron/errors.rb
|
|
@@ -115,6 +133,7 @@ files:
|
|
|
115
133
|
- lib/perron/metatags.rb
|
|
116
134
|
- lib/perron/output_server.rb
|
|
117
135
|
- lib/perron/refinements/delete_suffixes.rb
|
|
136
|
+
- lib/perron/relation.rb
|
|
118
137
|
- lib/perron/resource.rb
|
|
119
138
|
- lib/perron/resource/associations.rb
|
|
120
139
|
- lib/perron/resource/class_methods.rb
|
|
@@ -127,9 +146,12 @@ files:
|
|
|
127
146
|
- lib/perron/resource/related.rb
|
|
128
147
|
- lib/perron/resource/related/stop_words.rb
|
|
129
148
|
- lib/perron/resource/renderer.rb
|
|
149
|
+
- lib/perron/resource/scopes.rb
|
|
150
|
+
- lib/perron/resource/searchable.rb
|
|
130
151
|
- lib/perron/resource/separator.rb
|
|
131
152
|
- lib/perron/resource/slug.rb
|
|
132
153
|
- lib/perron/resource/sourceable.rb
|
|
154
|
+
- lib/perron/resource/sweeper.rb
|
|
133
155
|
- lib/perron/resource/table_of_content.rb
|
|
134
156
|
- lib/perron/site.rb
|
|
135
157
|
- lib/perron/site/builder.rb
|
|
@@ -170,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
170
192
|
- !ruby/object:Gem::Version
|
|
171
193
|
version: '0'
|
|
172
194
|
requirements: []
|
|
173
|
-
rubygems_version: 4.0.
|
|
195
|
+
rubygems_version: 4.0.6
|
|
174
196
|
specification_version: 4
|
|
175
197
|
summary: Rails-based static site generator
|
|
176
198
|
test_files: []
|
data/app/helpers/feeds_helper.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module MetaTagsHelper
|
|
4
|
-
def meta_tags(options = {}) = Perron::Metatags.new(resource.metadata).render(options)
|
|
5
|
-
|
|
6
|
-
private
|
|
7
|
-
|
|
8
|
-
Resource = Data.define(:path, :collection, :metadata, :published_at)
|
|
9
|
-
|
|
10
|
-
def resource
|
|
11
|
-
return Resource.new(request.path, nil, @metadata, nil) if @metadata.present?
|
|
12
|
-
|
|
13
|
-
@resource || Resource.new(request.path, nil, {}, nil)
|
|
14
|
-
end
|
|
15
|
-
end
|
data/lib/perron/data.rb
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "csv"
|
|
4
|
-
|
|
5
|
-
module Perron
|
|
6
|
-
class Data < SimpleDelegator
|
|
7
|
-
include Enumerable
|
|
8
|
-
|
|
9
|
-
def initialize(identifier)
|
|
10
|
-
@identifier = identifier
|
|
11
|
-
@file_path = self.class.path_for!(identifier)
|
|
12
|
-
@records = records
|
|
13
|
-
|
|
14
|
-
super(records)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def each(&block) = @records.each(&block)
|
|
18
|
-
|
|
19
|
-
def count = @records.count
|
|
20
|
-
|
|
21
|
-
def first(n = nil)
|
|
22
|
-
n ? @records.first(n) : @records.first
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def last = @records.last
|
|
26
|
-
|
|
27
|
-
def [](index) = @records[index]
|
|
28
|
-
|
|
29
|
-
def size = @records.size
|
|
30
|
-
alias_method :length, :size
|
|
31
|
-
|
|
32
|
-
class << self
|
|
33
|
-
def all
|
|
34
|
-
parts = name.to_s.split("::").drop(2)
|
|
35
|
-
identifier = parts.empty? ? name.demodulize.underscore : parts.map(&:underscore).join("/")
|
|
36
|
-
|
|
37
|
-
new(identifier)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def find(id)
|
|
41
|
-
all.find { it[:id] == id || it["id"] == id }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def count = all.size
|
|
45
|
-
|
|
46
|
-
def first = all.first
|
|
47
|
-
|
|
48
|
-
def second = all[1]
|
|
49
|
-
|
|
50
|
-
def third = all[2]
|
|
51
|
-
|
|
52
|
-
def fourth = all[3]
|
|
53
|
-
|
|
54
|
-
def fifth = all[4]
|
|
55
|
-
|
|
56
|
-
def forty_two = all[41]
|
|
57
|
-
|
|
58
|
-
def last = all.last
|
|
59
|
-
|
|
60
|
-
def take(n) = all.first(n)
|
|
61
|
-
|
|
62
|
-
def path_for(identifier)
|
|
63
|
-
path = Pathname.new(identifier)
|
|
64
|
-
|
|
65
|
-
return path.to_s if path.file? && path.absolute?
|
|
66
|
-
|
|
67
|
-
base_path = Rails.root.join("app", "content", "data")
|
|
68
|
-
|
|
69
|
-
SUPPORTED_EXTENSIONS.lazy.map { base_path.join("#{identifier}#{it}") }.find(&:exist?)&.to_s
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def path_for!(identifier)
|
|
73
|
-
path_for(identifier).tap do |path|
|
|
74
|
-
raise Errors::FileNotFoundError, "No data file found for `#{identifier}`" unless path
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def directory?(identifier) = Dir.exist?(Rails.root.join("app", "content", "data", identifier))
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
private
|
|
82
|
-
|
|
83
|
-
PARSER_METHODS = {
|
|
84
|
-
".yml" => :parse_yaml, ".yaml" => :parse_yaml,
|
|
85
|
-
".json" => :parse_json, ".csv" => :parse_csv
|
|
86
|
-
}.freeze
|
|
87
|
-
SUPPORTED_EXTENSIONS = PARSER_METHODS.keys
|
|
88
|
-
|
|
89
|
-
def records
|
|
90
|
-
content = rendered_from(@file_path)
|
|
91
|
-
data = parsed_from(content, @file_path)
|
|
92
|
-
|
|
93
|
-
unless data.is_a?(Array)
|
|
94
|
-
raise Errors::DataParseError, "Data in `#{@file_path}` must be an array of objects."
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
data.map { Item.new(it, identifier: @identifier) }
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def rendered_from(path)
|
|
101
|
-
raw_content = File.read(path)
|
|
102
|
-
|
|
103
|
-
render_erb(raw_content)
|
|
104
|
-
rescue NameError, ArgumentError, SyntaxError => error
|
|
105
|
-
raise Errors::DataParseError, "Failed to render ERB in `#{path}`: (#{error.class}) #{error.message}"
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def parsed_from(content, path)
|
|
109
|
-
extension = File.extname(path)
|
|
110
|
-
parser_method = PARSER_METHODS.fetch(extension) do
|
|
111
|
-
raise Errors::UnsupportedDataFormatError, "Unsupported data format: #{extension}"
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
send(parser_method, content)
|
|
115
|
-
rescue Psych::SyntaxError, JSON::ParserError, CSV::MalformedCSVError => error
|
|
116
|
-
raise Errors::DataParseError, "Failed to parse data format in `#{path}`: (#{error.class}) #{error.message}"
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def render_erb(content) = ERB.new(content).result(HelperContext.instance.get_binding)
|
|
120
|
-
|
|
121
|
-
def parse_yaml(content)
|
|
122
|
-
YAML.safe_load(content, permitted_classes: [Symbol, Time], aliases: true)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def parse_json(content)
|
|
126
|
-
JSON.parse(content, symbolize_names: true)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def parse_csv(content)
|
|
130
|
-
CSV.new(content, headers: true, header_converters: :symbol).to_a.map(&:to_h)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
class HelperContext
|
|
134
|
-
include Singleton
|
|
135
|
-
|
|
136
|
-
def initialize
|
|
137
|
-
self.class.include ActionView::Helpers::AssetUrlHelper
|
|
138
|
-
self.class.include ActionView::Helpers::DateHelper
|
|
139
|
-
self.class.include Rails.application.routes.url_helpers
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def get_binding = binding
|
|
143
|
-
|
|
144
|
-
def default_url_options = Perron.configuration.default_url_options || {}
|
|
145
|
-
end
|
|
146
|
-
private_constant :HelperContext
|
|
147
|
-
|
|
148
|
-
class Item
|
|
149
|
-
def initialize(attributes, identifier:)
|
|
150
|
-
@attributes = attributes.transform_keys(&:to_sym)
|
|
151
|
-
@identifier = identifier
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def [](key) = @attributes[key.to_sym]
|
|
155
|
-
|
|
156
|
-
def association_value(key) = self[key]
|
|
157
|
-
|
|
158
|
-
def to_partial_path
|
|
159
|
-
@to_partial_path ||= begin
|
|
160
|
-
identifier = @identifier.to_s
|
|
161
|
-
collection = File.extname(identifier).present? ? File.basename(identifier, ".*") : identifier
|
|
162
|
-
element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.singularize(File.basename(collection)))
|
|
163
|
-
|
|
164
|
-
File.join("content", collection, element)
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def method_missing(method_name, *arguments, &block)
|
|
169
|
-
return super if !@attributes.key?(method_name) || arguments.any? || block
|
|
170
|
-
|
|
171
|
-
@attributes[method_name]
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def respond_to_missing?(method_name, include_private = false)
|
|
175
|
-
@attributes.key?(method_name) || super
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
private_constant :Item
|
|
179
|
-
end
|
|
180
|
-
end
|