perron 0.7.0 → 0.8.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.lock +1 -1
- data/README.md +51 -5
- data/app/helpers/perron/markdown_helper.rb +5 -1
- data/lib/generators/perron/templates/README.md.tt +4 -4
- data/lib/perron/configuration.rb +6 -5
- data/lib/perron/errors.rb +4 -0
- data/lib/perron/html_processor/base.rb +15 -0
- data/lib/perron/html_processor/lazy_load_images.rb +13 -0
- data/lib/perron/html_processor/target_blank.rb +4 -8
- data/lib/perron/html_processor.rb +30 -8
- data/lib/perron/markdown.rb +2 -2
- data/lib/perron/metatags.rb +12 -6
- data/lib/perron/site/builder/sitemap.rb +58 -0
- data/lib/perron/site/builder.rb +4 -0
- data/lib/perron/site/collection.rb +6 -1
- data/lib/perron/site/data/proxy.rb +17 -0
- data/lib/perron/site/resource/configuration.rb +50 -0
- data/lib/perron/site/resource.rb +3 -1
- data/lib/perron/site.rb +4 -2
- data/lib/perron/version.rb +1 -1
- data/perron.gemspec +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9605385eb10b149f1f679d423a2367ed7f35684d381699692d329a1d05a2f6ea
|
4
|
+
data.tar.gz: e3803d65512af0de01c0cee99afdbbd2a8fed6d54afb823a9b64716469ea0fc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '090e644895f9f3fabb0b1ca3839592838864c5c6cb0a1c31acd83dbe2ef8c0ee2cbad5a13308e8986928f660d54c342f494858fcd7eb33038dc57d32834b03f8'
|
7
|
+
data.tar.gz: 1647b01aed3aa31f8aaac047ffe7880f58fe47530d81445077652c15635efdc99eeaedfdc7e12af87ab914ae3e4e80edda0eeec42404bdb5d50813527ac642a0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -17,11 +17,17 @@ A Rails-based static site generator.
|
|
17
17
|
|
18
18
|
### Installation
|
19
19
|
|
20
|
-
Start by
|
20
|
+
Start by adding Perron:
|
21
|
+
```bash
|
22
|
+
bundle add perron
|
23
|
+
```
|
24
|
+
|
25
|
+
Then generate the initializer:
|
21
26
|
```bash
|
22
27
|
rails generate perron:install
|
23
28
|
```
|
24
29
|
|
30
|
+
|
25
31
|
This creates an initializer:
|
26
32
|
```ruby
|
27
33
|
Perron.configure do |config|
|
@@ -85,6 +91,46 @@ bundle add {commonmarker,kramdown,redcarpet}
|
|
85
91
|
```
|
86
92
|
|
87
93
|
|
94
|
+
## HTML Transformations
|
95
|
+
|
96
|
+
Perron can post-process the HTML generated from your Markdown content.
|
97
|
+
|
98
|
+
|
99
|
+
### Usage
|
100
|
+
|
101
|
+
Apply transformations by passing an array of processor names or classes to the `markdownify` helper via the `process` option.
|
102
|
+
```erb
|
103
|
+
<%= markdownify @resource.content, process: %w[target_blank lazy_load_images] %>
|
104
|
+
```
|
105
|
+
|
106
|
+
|
107
|
+
### Available Processors
|
108
|
+
|
109
|
+
The following processors are built-in and can be activated by passing their string name:
|
110
|
+
|
111
|
+
- `target_blank`: Adds `target="_blank"` to all external links;
|
112
|
+
- `lazy_load_images`: Adds `loading="lazy"` to all `<img>` tags.
|
113
|
+
|
114
|
+
|
115
|
+
### Creating Your Own
|
116
|
+
|
117
|
+
You can create your own processor by defining a class that inherits from `Perron::HtmlProcessor::Base` and implements a `process` method.
|
118
|
+
Then, pass the class constant directly in the `process` array.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
# app/processors/add_nofollow_processor.rb
|
122
|
+
class AddNofollowProcessor < Perron::HtmlProcessor::Base
|
123
|
+
def process
|
124
|
+
@html.css("a[target=_blank]").each { it["rel"] = "nofollow" }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
```erb
|
130
|
+
<%= markdownify @resource.content, process: ["target_blank", AddNofollowProcessor] %>
|
131
|
+
```
|
132
|
+
|
133
|
+
|
88
134
|
## Data Files
|
89
135
|
|
90
136
|
Perron can consume structured data from YML, JSON, or CSV files, making them available within your templates.
|
@@ -92,9 +138,9 @@ This is useful for populating features, team members, or any other repeated data
|
|
92
138
|
|
93
139
|
### Usage
|
94
140
|
|
95
|
-
To use a data file, instantiate `Perron::
|
141
|
+
To use a data file, instantiate `Perron::Site.data` with the basename of the file and iterate over the result.
|
96
142
|
```erb
|
97
|
-
<% Perron::
|
143
|
+
<% Perron::Site.data.features.each do |feature| %>
|
98
144
|
<h4><%= feature.name %></h4>
|
99
145
|
<p><%= feature.description %></p>
|
100
146
|
<% end %>
|
@@ -103,7 +149,7 @@ To use a data file, instantiate `Perron::Data` with the basename of the file and
|
|
103
149
|
### File Location and Formats
|
104
150
|
|
105
151
|
By default, Perron looks up `app/content/data/` for files with a `.yml`, `.json`, or `.csv` extension.
|
106
|
-
For a `
|
152
|
+
For a `features` call, it would find `features.yml`, `features.json`, or `features.csv`. You can also provide a path to any data file, via `Perron::Data.new("path/to/data.json")`.
|
107
153
|
|
108
154
|
### Accessing Data
|
109
155
|
|
@@ -118,7 +164,6 @@ feature[:name]
|
|
118
164
|
|
119
165
|
The `meta_tags` helper automatically generates SEO and social sharing meta tags for your pages.
|
120
166
|
|
121
|
-
|
122
167
|
### Usage
|
123
168
|
|
124
169
|
In your layout (e.g., `app/views/layouts/application.html.erb`), add the helper to the `<head>` section:
|
@@ -207,6 +252,7 @@ Sites that use Perron.
|
|
207
252
|
### Integrated (part of a Rails app)
|
208
253
|
- [Rails Designers (private community for Rails UI engineers](https://railsdesigners.com)
|
209
254
|
|
255
|
+
|
210
256
|
## Contributing
|
211
257
|
|
212
258
|
This project uses [Standard](https://github.com/testdouble/standard) for formatting Ruby code. Please run `be standardrb` before submitting pull requests. Run tests with `rails test`.
|
@@ -4,6 +4,10 @@ require "perron/markdown"
|
|
4
4
|
|
5
5
|
module Perron
|
6
6
|
module MarkdownHelper
|
7
|
-
def markdownify(content = nil,
|
7
|
+
def markdownify(content = nil, options = {}, &block)
|
8
|
+
processors = options.fetch(:process, [])
|
9
|
+
|
10
|
+
Perron::Markdown.render(content || capture(&block).strip_heredoc, processors: processors)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
@@ -8,11 +8,11 @@ This is useful for populating features, team members, or any other repeated data
|
|
8
8
|
|
9
9
|
To use a data file, instantiate `Perron::Data` with the basename of the file and iterate over the result.
|
10
10
|
```erb
|
11
|
-
|
12
|
-
<h4
|
11
|
+
<%% Perron::Data.new("features").each do |feature| %>
|
12
|
+
<h4><%%= feature.name %></h4>
|
13
13
|
|
14
|
-
<p
|
15
|
-
|
14
|
+
<p><%%= feature.description %></p>
|
15
|
+
<%% end %>
|
16
16
|
```
|
17
17
|
|
18
18
|
## File Location and Formats
|
data/lib/perron/configuration.rb
CHANGED
@@ -9,10 +9,6 @@ module Perron
|
|
9
9
|
yield(configuration)
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.reset_configuration!
|
13
|
-
@configuration = Configuration.new
|
14
|
-
end
|
15
|
-
|
16
12
|
class Configuration
|
17
13
|
def initialize
|
18
14
|
@config = ActiveSupport::OrderedOptions.new
|
@@ -34,11 +30,16 @@ module Perron
|
|
34
30
|
trailing_slash: ENV.fetch("PERRON_TRAILING_SLASH", "true") == "true"
|
35
31
|
}
|
36
32
|
|
33
|
+
@config.sitemap = ActiveSupport::OrderedOptions.new
|
34
|
+
@config.sitemap.enabled = false
|
35
|
+
@config.sitemap.priority = 0.5
|
36
|
+
@config.sitemap.change_frequency = :monthly
|
37
|
+
|
37
38
|
@config.metadata = ActiveSupport::OrderedOptions.new
|
38
39
|
@config.metadata.title_separator = " — "
|
39
40
|
end
|
40
41
|
|
41
|
-
def input = "app
|
42
|
+
def input = Rails.root.join("app", "content")
|
42
43
|
|
43
44
|
def output
|
44
45
|
mode.integrated? ? "public" : @config.output
|
data/lib/perron/errors.rb
CHANGED
@@ -1,21 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "perron/html_processor/base"
|
4
|
+
|
3
5
|
module Perron
|
4
6
|
class HtmlProcessor
|
5
|
-
class TargetBlank
|
6
|
-
def initialize(html)
|
7
|
-
@html = html
|
8
|
-
end
|
9
|
-
|
7
|
+
class TargetBlank < HtmlProcessor::Base
|
10
8
|
def process
|
11
9
|
@html.css("a").each do |link|
|
12
10
|
href = link["href"]
|
13
11
|
|
14
|
-
next
|
15
|
-
next if href.start_with?("/", "#", "mailto:")
|
12
|
+
next if href.blank? || href.start_with?("/", "#", "mailto:")
|
16
13
|
|
17
14
|
link["target"] = "_blank"
|
18
|
-
link["rel"] = "noopener"
|
19
15
|
end
|
20
16
|
end
|
21
17
|
end
|
@@ -1,28 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "perron/html_processor/target_blank"
|
4
|
+
require "perron/html_processor/lazy_load_images"
|
4
5
|
|
5
6
|
module Perron
|
6
7
|
class HtmlProcessor
|
7
|
-
def initialize(html)
|
8
|
+
def initialize(html, processors: [])
|
8
9
|
@html = html
|
10
|
+
@processors = processors.map { find_by(it) }
|
9
11
|
end
|
10
12
|
|
11
13
|
def process
|
12
14
|
document = Nokogiri::HTML::DocumentFragment.parse(@html)
|
13
15
|
|
14
|
-
|
15
|
-
processor.new(document).process
|
16
|
-
end
|
16
|
+
@processors.each { it.new(document).process }
|
17
17
|
|
18
18
|
document.to_html
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
Perron::HtmlProcessor::
|
26
|
-
|
23
|
+
BUILT_IN = {
|
24
|
+
"target_blank" => Perron::HtmlProcessor::TargetBlank,
|
25
|
+
"lazy_load_images" => Perron::HtmlProcessor::LazyLoadImages
|
26
|
+
}
|
27
|
+
|
28
|
+
def find_by(identifier)
|
29
|
+
case identifier
|
30
|
+
when String, Symbol
|
31
|
+
key = identifier.to_s
|
32
|
+
|
33
|
+
BUILT_IN[key] || find_class_by(key)
|
34
|
+
when Class
|
35
|
+
identifier
|
36
|
+
else
|
37
|
+
raise Perron::Errors::InvalidProcessorError, "Processor must be a String, Symbol, or Class, but got #{identifier.class.name}."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_class_by(name)
|
42
|
+
processor = name.camelize.safe_constantize
|
43
|
+
|
44
|
+
return processor if processor
|
45
|
+
|
46
|
+
raise Perron::Errors::ProcessorNotFoundError,
|
47
|
+
"Could not find processor `#{name}`. It is not a Perron-included processor and the constant `#{name.camelize}` could not be found."
|
48
|
+
end
|
27
49
|
end
|
28
50
|
end
|
data/lib/perron/markdown.rb
CHANGED
@@ -5,9 +5,9 @@ require "perron/html_processor"
|
|
5
5
|
module Perron
|
6
6
|
class Markdown
|
7
7
|
class << self
|
8
|
-
def render(text)
|
8
|
+
def render(text, processors: [])
|
9
9
|
parser.parse(text)
|
10
|
-
.then { Perron::HtmlProcessor.new(it).process }
|
10
|
+
.then { Perron::HtmlProcessor.new(it, processors: processors).process }
|
11
11
|
.html_safe
|
12
12
|
end
|
13
13
|
|
data/lib/perron/metatags.rb
CHANGED
@@ -20,6 +20,7 @@ module Perron
|
|
20
20
|
private
|
21
21
|
|
22
22
|
FRONTMATTER_KEY_MAP = {
|
23
|
+
"locale" => %w[og:locale],
|
23
24
|
"image" => %w[og:image twitter:image],
|
24
25
|
"author" => %w[og:author]
|
25
26
|
}.freeze
|
@@ -30,30 +31,35 @@ module Perron
|
|
30
31
|
defaults = @config.metadata
|
31
32
|
|
32
33
|
title = frontmatter["title"] || defaults["title"] || @config.site_name || Rails.application.name.underscore.camelize
|
34
|
+
type = frontmatter["type"] || defaults["type"]
|
33
35
|
description = frontmatter["description"] || defaults["description"]
|
36
|
+
logo = frontmatter["logo"] || defaults["logo"]
|
34
37
|
author = frontmatter["author"] || defaults["author"]
|
35
38
|
image = frontmatter["image"] || defaults["image"]
|
39
|
+
locale = frontmatter["locale"] || defaults["locale"]
|
36
40
|
og_image = frontmatter["og:image"] || image
|
37
41
|
twitter_image = frontmatter["twitter:image"] || og_image
|
38
42
|
|
39
43
|
{
|
40
44
|
title: title_tag(title),
|
41
45
|
description: meta_tag(name: "description", content: description),
|
46
|
+
article_published: meta_tag(property: "article:published_time", content: @resource&.published_at),
|
42
47
|
|
43
|
-
og_type: meta_tag(property: "og:type", content: frontmatter["og:type"] || "article"),
|
44
48
|
og_title: meta_tag(property: "og:title", content: frontmatter["og:title"] || title),
|
49
|
+
og_type: meta_tag(property: "og:type", content: frontmatter["og:type"] || type),
|
50
|
+
og_url: meta_tag(property: "og:url", content: canonical_url),
|
51
|
+
og_image: meta_tag(property: "og:image", content: og_image),
|
52
|
+
|
45
53
|
og_description: meta_tag(property: "og:description", content: frontmatter["og:description"] || description),
|
46
54
|
og_site_name: meta_tag(property: "og:site_name", content: @config.site_name),
|
47
|
-
|
55
|
+
og_logo: meta_tag(property: "og:logo", content: frontmatter["og:logo"] || logo),
|
48
56
|
og_author: meta_tag(property: "og:author", content: frontmatter["og:author"] || author),
|
57
|
+
og_locale: meta_tag(property: "og:locale", content: frontmatter["og:locale"] || locale),
|
49
58
|
|
50
59
|
twitter_card: meta_tag(name: "twitter:card", content: frontmatter["twitter:card"] || "summary_large_image"),
|
51
60
|
twitter_title: meta_tag(name: "twitter:title", content: frontmatter["twitter:title"] || title),
|
52
61
|
twitter_description: meta_tag(name: "twitter:description", content: frontmatter["twitter:description"] || description),
|
53
|
-
twitter_image: meta_tag(name: "twitter:image", content: twitter_image)
|
54
|
-
article_published: meta_tag(property: "article:published_time", content: @resource&.published_at),
|
55
|
-
|
56
|
-
og_url: meta_tag(property: "og:url", content: canonical_url)
|
62
|
+
twitter_image: meta_tag(name: "twitter:image", content: twitter_image)
|
57
63
|
}
|
58
64
|
end
|
59
65
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perron
|
4
|
+
module Site
|
5
|
+
class Builder
|
6
|
+
class Sitemap
|
7
|
+
def initialize(output_path)
|
8
|
+
@output_path = output_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
return if !Perron.configuration.sitemap.enabled
|
13
|
+
|
14
|
+
puts "Generating sitemap.xml…"
|
15
|
+
|
16
|
+
xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
|
17
|
+
builder.urlset(xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9") do
|
18
|
+
Perron::Site.collections.each do |collection|
|
19
|
+
add_urls_for(collection, with: builder)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end.to_xml
|
23
|
+
|
24
|
+
File.write(@output_path.join("sitemap.xml"), xml)
|
25
|
+
|
26
|
+
puts "Sitemap generated at `#{@output_path.join("sitemap.xml")}`"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def add_urls_for(collection, with:)
|
32
|
+
return if collection.configuration.sitemap.exclude == true
|
33
|
+
|
34
|
+
collection.resources.each do |resource|
|
35
|
+
next if resource.metadata.sitemap == false
|
36
|
+
|
37
|
+
root = resource.slug == "/"
|
38
|
+
priority = resource.metadata.sitemap_priority || collection.configuration.sitemap.priority || Perron.configuration.sitemap.priority
|
39
|
+
change_frequency = resource.metadata.sitemap_change_frequency || collection.configuration.sitemap.change_frequency || Perron.configuration.sitemap.change_frequency
|
40
|
+
|
41
|
+
Rails.application.routes.url_helpers.with_options(Perron.configuration.default_url_options) do |url|
|
42
|
+
with.url do
|
43
|
+
with.loc root ? url.root_url : url.polymorphic_url(resource)
|
44
|
+
with.priority priority
|
45
|
+
with.changefreq change_frequency
|
46
|
+
begin
|
47
|
+
with.lastmod resource.metadata.updated_at.iso8601
|
48
|
+
rescue
|
49
|
+
Time.current.iso8601
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/perron/site/builder.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "perron/site/builder/assets"
|
4
|
+
require "perron/site/builder/sitemap"
|
4
5
|
require "perron/site/builder/public_files"
|
5
6
|
require "perron/site/builder/paths"
|
6
7
|
require "perron/site/builder/page"
|
@@ -15,6 +16,7 @@ module Perron
|
|
15
16
|
def build
|
16
17
|
if Perron.configuration.mode.standalone?
|
17
18
|
puts "🧹 Cleaning previous build…"
|
19
|
+
|
18
20
|
FileUtils.rm_rf(Dir.glob("#{@output_path}/*"))
|
19
21
|
|
20
22
|
Perron::Site::Builder::Assets.new.prepare
|
@@ -26,6 +28,8 @@ module Perron
|
|
26
28
|
|
27
29
|
paths.each { render_page(it) }
|
28
30
|
|
31
|
+
Perron::Site::Builder::Sitemap.new(@output_path).generate
|
32
|
+
|
29
33
|
puts "-" * 15
|
30
34
|
puts "✅ Build complete"
|
31
35
|
end
|
@@ -6,16 +6,21 @@ module Perron
|
|
6
6
|
|
7
7
|
def initialize(name)
|
8
8
|
@name = name
|
9
|
-
@collection_path = File.join(
|
9
|
+
@collection_path = File.join(Perron.configuration.input, name)
|
10
10
|
|
11
11
|
raise Errors::CollectionNotFoundError, "No such collection: #{name}" unless File.exist?(@collection_path) && File.directory?(@collection_path)
|
12
12
|
end
|
13
13
|
|
14
|
+
def configuration(resource_class = "Content::#{name.classify}".safe_constantize)
|
15
|
+
resource_class.configuration
|
16
|
+
end
|
17
|
+
|
14
18
|
def all(resource_class = "Content::#{name.classify}".safe_constantize)
|
15
19
|
@all ||= Dir.glob("#{@collection_path}/**/*.*").map do |file_path|
|
16
20
|
resource_class.new(file_path)
|
17
21
|
end.select(&:published?)
|
18
22
|
end
|
23
|
+
alias_method :resources, :all
|
19
24
|
|
20
25
|
def find(slug, resource_class = Resource)
|
21
26
|
resource = all(resource_class).find { it.slug == slug }
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perron
|
4
|
+
class Data
|
5
|
+
class Proxy
|
6
|
+
def method_missing(method_name, *arguments, &block)
|
7
|
+
raise ArgumentError, "Data `#{method_name}` does not accept arguments" if arguments.any?
|
8
|
+
|
9
|
+
Perron::Data.new(method_name.to_s)
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to_missing?(method_name, include_private = false)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Perron
|
4
|
+
class Resource
|
5
|
+
module Configuration
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def configuration
|
10
|
+
@configuration ||= Options.new.tap do |config|
|
11
|
+
config.feeds = Options.new
|
12
|
+
|
13
|
+
config.feeds.rss = ActiveSupport::OrderedOptions.new
|
14
|
+
config.feeds.atom = ActiveSupport::OrderedOptions.new
|
15
|
+
config.feeds.json = ActiveSupport::OrderedOptions.new
|
16
|
+
|
17
|
+
config.linked_data = ActiveSupport::OrderedOptions.new
|
18
|
+
|
19
|
+
config.related_posts = ActiveSupport::OrderedOptions.new
|
20
|
+
config.related_posts.enabled = false
|
21
|
+
config.related_posts.max = 5
|
22
|
+
|
23
|
+
config.sitemap = ActiveSupport::OrderedOptions.new
|
24
|
+
config.sitemap.exclude = false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def configure
|
29
|
+
yield(configuration)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Options < ActiveSupport::OrderedOptions
|
34
|
+
def method_missing(name, *arguments)
|
35
|
+
if name.to_s.end_with?("=")
|
36
|
+
key = name.to_s.chomp("=").to_sym
|
37
|
+
value = arguments.first
|
38
|
+
|
39
|
+
return self[key].merge!(value) if self[key].is_a?(ActiveSupport::OrderedOptions) && value.is_a?(Hash)
|
40
|
+
end
|
41
|
+
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_to_missing?(name, include_private = false) = super
|
46
|
+
end
|
47
|
+
private_constant :Options
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/perron/site/resource.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "perron/site/resource/configuration"
|
3
4
|
require "perron/site/resource/core"
|
4
5
|
require "perron/site/resource/class_methods"
|
5
6
|
require "perron/site/resource/publishable"
|
@@ -10,6 +11,7 @@ module Perron
|
|
10
11
|
class Resource
|
11
12
|
ID_LENGTH = 8
|
12
13
|
|
14
|
+
include Perron::Resource::Configuration
|
13
15
|
include Perron::Resource::Core
|
14
16
|
include Perron::Resource::ClassMethods
|
15
17
|
include Perron::Resource::Publishable
|
@@ -55,7 +57,7 @@ module Perron
|
|
55
57
|
|
56
58
|
def generate_id
|
57
59
|
Digest::SHA1.hexdigest(
|
58
|
-
@file_path.delete_prefix(Perron.configuration.input).parameterize
|
60
|
+
@file_path.delete_prefix(Perron.configuration.input.to_s).parameterize
|
59
61
|
).first(ID_LENGTH)
|
60
62
|
end
|
61
63
|
end
|
data/lib/perron/site.rb
CHANGED
@@ -4,6 +4,7 @@ require "perron/site/builder"
|
|
4
4
|
require "perron/site/collection"
|
5
5
|
require "perron/site/resource"
|
6
6
|
require "perron/site/data"
|
7
|
+
require "perron/site/data/proxy"
|
7
8
|
|
8
9
|
module Perron
|
9
10
|
module Site
|
@@ -24,13 +25,14 @@ module Perron
|
|
24
25
|
def collections
|
25
26
|
@collections ||= Dir.children(Perron.configuration.input)
|
26
27
|
.select { File.directory?(File.join(Perron.configuration.input, it)) }
|
28
|
+
.reject { it == "data" }
|
27
29
|
.map { Collection.new(it) }
|
28
30
|
end
|
29
31
|
|
30
32
|
def collection(name) = Collection.new(name)
|
31
33
|
|
32
|
-
def data(name)
|
33
|
-
Perron::Data.new(name)
|
34
|
+
def data(name = nil)
|
35
|
+
(name && Perron::Data.new(name)) || Perron::Data::Proxy.new
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
data/lib/perron/version.rb
CHANGED
data/perron.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
|
9
9
|
spec.summary = "Rails-based static site generator"
|
10
10
|
spec.description = "Perron is a Rails-based static site generator that follows Rails conventions. It allows you to create content collections with markdown or ERB, configure SEO metadata, and build production-ready static sites while leveraging your existing Rails knowledge with familiar patterns and minimal configuration."
|
11
|
-
spec.homepage = "https://
|
11
|
+
spec.homepage = "https://railsdesigner.com/perron/"
|
12
12
|
spec.license = "MIT"
|
13
13
|
|
14
14
|
spec.metadata["homepage_uri"] = spec.homepage
|
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.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rails Designer Developers
|
@@ -98,6 +98,8 @@ files:
|
|
98
98
|
- lib/perron/engine.rb
|
99
99
|
- lib/perron/errors.rb
|
100
100
|
- lib/perron/html_processor.rb
|
101
|
+
- lib/perron/html_processor/base.rb
|
102
|
+
- lib/perron/html_processor/lazy_load_images.rb
|
101
103
|
- lib/perron/html_processor/target_blank.rb
|
102
104
|
- lib/perron/markdown.rb
|
103
105
|
- lib/perron/metatags.rb
|
@@ -109,10 +111,13 @@ files:
|
|
109
111
|
- lib/perron/site/builder/page.rb
|
110
112
|
- lib/perron/site/builder/paths.rb
|
111
113
|
- lib/perron/site/builder/public_files.rb
|
114
|
+
- lib/perron/site/builder/sitemap.rb
|
112
115
|
- lib/perron/site/collection.rb
|
113
116
|
- lib/perron/site/data.rb
|
117
|
+
- lib/perron/site/data/proxy.rb
|
114
118
|
- lib/perron/site/resource.rb
|
115
119
|
- lib/perron/site/resource/class_methods.rb
|
120
|
+
- lib/perron/site/resource/configuration.rb
|
116
121
|
- lib/perron/site/resource/core.rb
|
117
122
|
- lib/perron/site/resource/publishable.rb
|
118
123
|
- lib/perron/site/resource/separator.rb
|
@@ -120,11 +125,11 @@ files:
|
|
120
125
|
- lib/perron/tasks/perron.rake
|
121
126
|
- lib/perron/version.rb
|
122
127
|
- perron.gemspec
|
123
|
-
homepage: https://
|
128
|
+
homepage: https://railsdesigner.com/perron/
|
124
129
|
licenses:
|
125
130
|
- MIT
|
126
131
|
metadata:
|
127
|
-
homepage_uri: https://
|
132
|
+
homepage_uri: https://railsdesigner.com/perron/
|
128
133
|
source_code_uri: https://github.com/Rails-Designer/perron/
|
129
134
|
rdoc_options: []
|
130
135
|
require_paths:
|
@@ -140,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
145
|
- !ruby/object:Gem::Version
|
141
146
|
version: '0'
|
142
147
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
148
|
+
rubygems_version: 3.6.9
|
144
149
|
specification_version: 4
|
145
150
|
summary: Rails-based static site generator
|
146
151
|
test_files: []
|