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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b7d197a1f26d5fae6c488fe7be6aef6c3818e408d97b5d789f46111db3207be
|
|
4
|
+
data.tar.gz: 0cb809db9260c8e5ded0626f9d790dfb003b937892c1bbce022bcbdac3e5053d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cc876ae9e8fb6daf1c6496c381efc05eba46fe5bbff9174502480488c34a4dbf5c94d9a360752942a53c395d7df6cb3b9e8342936e8e795b3ab3ccc20f6b3cdd
|
|
7
|
+
data.tar.gz: 99681d91d5d5ea2ffb8488ba4c93c27b2115aebde8132d6f0c8376a6b3e7819c62aef196b424e244af04d8ada7a12080c181cd0f44cf9d52c79125263c3f849b
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
perron (0.
|
|
4
|
+
perron (0.18.0)
|
|
5
5
|
csv
|
|
6
6
|
json
|
|
7
|
+
mata (~> 0.8.0)
|
|
7
8
|
psych
|
|
8
9
|
rails (>= 7.2.0)
|
|
9
10
|
|
|
@@ -81,6 +82,10 @@ GEM
|
|
|
81
82
|
minitest (>= 5.1)
|
|
82
83
|
securerandom (>= 0.3)
|
|
83
84
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
85
|
+
appraisal (2.5.0)
|
|
86
|
+
bundler
|
|
87
|
+
rake
|
|
88
|
+
thor (>= 0.14.0)
|
|
84
89
|
ast (2.4.3)
|
|
85
90
|
base64 (0.3.0)
|
|
86
91
|
benchmark (0.4.1)
|
|
@@ -97,6 +102,14 @@ GEM
|
|
|
97
102
|
drb (2.2.3)
|
|
98
103
|
erb (5.0.1)
|
|
99
104
|
erubi (1.13.1)
|
|
105
|
+
ffi (1.17.3-aarch64-linux-gnu)
|
|
106
|
+
ffi (1.17.3-aarch64-linux-musl)
|
|
107
|
+
ffi (1.17.3-arm-linux-gnu)
|
|
108
|
+
ffi (1.17.3-arm-linux-musl)
|
|
109
|
+
ffi (1.17.3-arm64-darwin)
|
|
110
|
+
ffi (1.17.3-x86_64-darwin)
|
|
111
|
+
ffi (1.17.3-x86_64-linux-gnu)
|
|
112
|
+
ffi (1.17.3-x86_64-linux-musl)
|
|
100
113
|
globalid (1.2.1)
|
|
101
114
|
activesupport (>= 6.1)
|
|
102
115
|
i18n (1.14.7)
|
|
@@ -109,6 +122,10 @@ GEM
|
|
|
109
122
|
json (2.12.2)
|
|
110
123
|
language_server-protocol (3.17.0.5)
|
|
111
124
|
lint_roller (1.1.0)
|
|
125
|
+
listen (3.10.0)
|
|
126
|
+
logger
|
|
127
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
128
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
|
112
129
|
logger (1.7.0)
|
|
113
130
|
loofah (2.24.1)
|
|
114
131
|
crass (~> 1.0.2)
|
|
@@ -119,6 +136,9 @@ GEM
|
|
|
119
136
|
net-pop
|
|
120
137
|
net-smtp
|
|
121
138
|
marcel (1.0.4)
|
|
139
|
+
mata (0.8.0)
|
|
140
|
+
listen (~> 3.0)
|
|
141
|
+
rack (>= 3.0)
|
|
122
142
|
mini_mime (1.1.5)
|
|
123
143
|
mini_portile2 (2.8.9)
|
|
124
144
|
minitest (5.27.0)
|
|
@@ -202,6 +222,9 @@ GEM
|
|
|
202
222
|
zeitwerk (~> 2.6)
|
|
203
223
|
rainbow (3.1.1)
|
|
204
224
|
rake (13.3.0)
|
|
225
|
+
rb-fsevent (0.11.2)
|
|
226
|
+
rb-inotify (0.11.1)
|
|
227
|
+
ffi (~> 1.0)
|
|
205
228
|
rdoc (6.14.2)
|
|
206
229
|
erb
|
|
207
230
|
psych (>= 4.0.0)
|
|
@@ -267,10 +290,10 @@ PLATFORMS
|
|
|
267
290
|
x86_64-linux-musl
|
|
268
291
|
|
|
269
292
|
DEPENDENCIES
|
|
293
|
+
appraisal
|
|
270
294
|
debug (~> 1.11.0)
|
|
271
295
|
minitest (~> 5.25, >= 5.25.5)
|
|
272
296
|
perron!
|
|
273
|
-
rails (~> 7.2.0)
|
|
274
297
|
rake (~> 13.3.0)
|
|
275
298
|
rouge (~> 4.6.0)
|
|
276
299
|
standard (~> 1.50.0)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Perron
|
|
4
|
+
class SearchesController < ApplicationController
|
|
5
|
+
before_action :force_json, only: %w[show]
|
|
6
|
+
|
|
7
|
+
def show
|
|
8
|
+
resources = search_scope.flat_map(&:all)
|
|
9
|
+
index = resources.map do |resource|
|
|
10
|
+
base_fields(resource).merge(additional_search_fields(resource))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
render json: index
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def force_json
|
|
19
|
+
request.format = :json
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def search_scope
|
|
23
|
+
Perron
|
|
24
|
+
.configuration
|
|
25
|
+
.search_scope
|
|
26
|
+
.map { "Content::#{it.classify}".safe_constantize }
|
|
27
|
+
.compact_blank
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def base_fields(resource)
|
|
31
|
+
{
|
|
32
|
+
slug: polymorphic_path(resource),
|
|
33
|
+
href: polymorphic_path(resource),
|
|
34
|
+
title: resource.try(:title) || resource.metadata.title,
|
|
35
|
+
headings: resource.extracted_headings.flatten.join(" "),
|
|
36
|
+
body: resource.sweeped_content
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def additional_search_fields(resource)
|
|
41
|
+
return {} unless resource.class.search_fields_list.any?
|
|
42
|
+
|
|
43
|
+
resource.class.search_fields_list.to_h do |field|
|
|
44
|
+
[field, resource.public_send(field)]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -4,10 +4,10 @@ require "perron/markdown"
|
|
|
4
4
|
|
|
5
5
|
module Perron
|
|
6
6
|
module MarkdownHelper
|
|
7
|
-
def markdownify(content = nil,
|
|
8
|
-
|
|
7
|
+
def markdownify(content = nil, process: [], &block)
|
|
8
|
+
text = block_given? ? capture(&block).strip_heredoc : content
|
|
9
9
|
|
|
10
|
-
Perron::Markdown.render(
|
|
10
|
+
Perron::Markdown.render(text, processors: process)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Perron
|
|
4
|
+
module MetaTagsHelper
|
|
5
|
+
def meta_tags(options = {}) = Perron::Metatags.new(resource.metadata).render(options)
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
Resource = Data.define(:path, :collection, :metadata, :published_at)
|
|
10
|
+
|
|
11
|
+
def resource
|
|
12
|
+
return Resource.new(request.path, nil, @metadata, nil) if @metadata.present?
|
|
13
|
+
|
|
14
|
+
@resource || Resource.new(request.path, nil, {}, nil)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/bin/release
CHANGED
|
@@ -3,17 +3,32 @@
|
|
|
3
3
|
VERSION=$1
|
|
4
4
|
|
|
5
5
|
if [ -z "$VERSION" ]; then
|
|
6
|
-
echo "Error:
|
|
7
|
-
echo "Usage: $0 <version-number>"
|
|
6
|
+
echo "Error: Version number or bump type is required"
|
|
7
|
+
echo " Usage: $0 <major|minor|patch|version-number>"
|
|
8
|
+
|
|
8
9
|
exit 1
|
|
9
10
|
fi
|
|
10
11
|
|
|
12
|
+
if [[ "$VERSION" =~ ^(major|minor|patch)$ ]]; then
|
|
13
|
+
CURRENT=$(grep -o '"[^"]*"' ./lib/perron/version.rb | tr -d '"')
|
|
14
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
|
|
15
|
+
|
|
16
|
+
case $VERSION in
|
|
17
|
+
major) VERSION="$((MAJOR + 1)).0.0" ;;
|
|
18
|
+
minor) VERSION="$MAJOR.$((MINOR + 1)).0" ;;
|
|
19
|
+
patch) VERSION="$MAJOR.$MINOR.$((PATCH + 1))" ;;
|
|
20
|
+
esac
|
|
21
|
+
fi
|
|
22
|
+
|
|
11
23
|
printf "module Perron\n VERSION = \"$VERSION\"\nend\n" > ./lib/perron/version.rb
|
|
24
|
+
|
|
12
25
|
bundle
|
|
26
|
+
|
|
13
27
|
git add Gemfile.lock lib/perron/version.rb
|
|
14
28
|
git commit -m "Bump version for $VERSION"
|
|
15
29
|
git push
|
|
16
30
|
git tag v$VERSION
|
|
17
31
|
git push --tags
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
|
|
33
|
+
bundle exec rake build
|
|
34
|
+
gem push "pkg/perron-$VERSION.gem"
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
# Data
|
|
2
2
|
|
|
3
|
-
Perron can consume structured data from YML, JSON
|
|
3
|
+
Perron can consume structured data from YML, JSON or CSV files, making them available within views. This is useful for populating features, team members or any other repeated data structure.
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
## Usage
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Access data sources using the `Content::Data` namespace with the class name matching the file's basename:
|
|
9
9
|
```erb
|
|
10
|
-
<%%
|
|
10
|
+
<%% Content::Data::Features.all.each do |feature| %>
|
|
11
11
|
<h4><%%= feature.name %></h4>
|
|
12
12
|
<p><%%= feature.description %></p>
|
|
13
13
|
<%% end %>
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
Look up a single entry with `Content::Data::Features.find("advanced-search")`, where `"advanced-search"` matches the value of the entry's `id` field.
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
## File location and formats
|
|
18
20
|
|
|
19
|
-
By default, Perron looks up `app/content/data/` for files with a `.yml`, `.json
|
|
21
|
+
By default, Perron looks up `app/content/data/` for files with a `.yml`, `.json` or `.csv` extension. For a `features` call, it would find `features.yml`, `features.json` or `features.csv`. Provide a path to any data resource in `/app/content/data/`, via `Content::Data.new("path/to/data-resource")`.
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
## Accessing data
|
|
@@ -30,12 +32,12 @@ feature[:name]
|
|
|
30
32
|
|
|
31
33
|
## Rendering
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
Render data collections directly using Rails-like partial rendering:
|
|
34
36
|
```erb
|
|
35
|
-
<%%= render
|
|
37
|
+
<%%= render Content::Data::Features.all %>
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
This expects a partial at `app/views/content/features/_feature.html.erb` that will be rendered once for each
|
|
40
|
+
This expects a partial at `app/views/content/features/_feature.html.erb` that will be rendered once for each item in `Content::Data::Features.all`. The individual record is made available as a local variable matching the singular form of the collection name.
|
|
39
41
|
```erb
|
|
40
42
|
<!-- app/views/content/features/_feature.html.erb -->
|
|
41
43
|
<div class="feature">
|
|
@@ -43,3 +45,25 @@ This expects a partial at `app/views/content/features/_feature.html.erb` that wi
|
|
|
43
45
|
<p><%%= feature.description %></p>
|
|
44
46
|
</div>
|
|
45
47
|
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Data structure
|
|
51
|
+
|
|
52
|
+
Data resources must contain an array of objects. Each record should include an `id` field if used with [associations](/docs/resources/#associations) or with the `find` method:
|
|
53
|
+
```yaml
|
|
54
|
+
# app/content/data/authors.yml
|
|
55
|
+
- id: rails-designer
|
|
56
|
+
name: Rails Designer
|
|
57
|
+
bio: Creator of Perron
|
|
58
|
+
|
|
59
|
+
- id: cam
|
|
60
|
+
name: Cam
|
|
61
|
+
bio: Contributing author
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## Enumerable methods
|
|
66
|
+
|
|
67
|
+
[!label v0.17.0+]
|
|
68
|
+
|
|
69
|
+
All data objects support enumerable methods like `select`, `sort_by`, `first` and `count`. See [Enumerable methods](/docs/rendering/#enumerable-methods) for the full list of available methods.
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
Perron.configure do |config|
|
|
2
|
-
#
|
|
2
|
+
# For all options check out:
|
|
3
|
+
# https://perron.railsdesigner.com/docs/configuration/
|
|
3
4
|
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
# The build mode for Perron. Can be :standalone (SSG) or :integrated (alongside your Rails app)
|
|
5
|
+
# The build mode for Perron. Can be :standalone (SSG, default) or :integrated (alongside your Rails app)
|
|
7
6
|
# config.mode = :standalone
|
|
8
7
|
|
|
8
|
+
# Enable Live Reload with DOM Morphing in development
|
|
9
|
+
# config.live_reload = true
|
|
10
|
+
|
|
9
11
|
# config.default_url_options = {host: "chirpform.com", protocol: "https", trailing_slash: true}
|
|
10
12
|
|
|
11
13
|
# The options hash is passed directly to the chosen library
|
|
12
14
|
# config.markdown_options = {}
|
|
13
15
|
|
|
16
|
+
# config.site_name = "Chirp Form"
|
|
17
|
+
|
|
14
18
|
# Set meta title suffix
|
|
15
19
|
# config.metadata.title_suffix = nil
|
|
16
20
|
# config.metadata.title_separator = " — "
|
|
@@ -2,63 +2,65 @@ Description:
|
|
|
2
2
|
Generates content model scaffold (controller, views, routes) or creates
|
|
3
3
|
new content files from templates.
|
|
4
4
|
|
|
5
|
+
Arguments:
|
|
6
|
+
NAME Name of the content model (singular or plural)
|
|
7
|
+
actions Actions to generate (default: index show)
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
--new [TITLE] Create new content file instead of scaffold
|
|
11
|
+
--data [SOURCE...] Create data source files (default extension: .yml)
|
|
12
|
+
--force-plural Use plural form for model name and class
|
|
13
|
+
--[no-]include-root Include root action and route
|
|
14
|
+
(default: true for pages, false otherwise)
|
|
15
|
+
|
|
5
16
|
Examples:
|
|
6
|
-
Generate content scaffold:
|
|
17
|
+
Generate basic content scaffold:
|
|
7
18
|
rails generate content Post
|
|
8
19
|
rails generate content Post index
|
|
9
20
|
rails generate content Post index show
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
Creates:
|
|
12
23
|
app/content/posts/
|
|
13
24
|
app/models/content/post.rb
|
|
14
25
|
app/controllers/content/posts_controller.rb
|
|
15
26
|
app/views/content/posts/index.html.erb
|
|
16
27
|
app/views/content/posts/show.html.erb
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
Adds route:
|
|
30
|
+
resources :posts, module: :content, only: %w[index show]
|
|
19
31
|
|
|
20
32
|
Generate pages scaffold with root:
|
|
21
33
|
rails generate content Page
|
|
22
34
|
|
|
23
|
-
|
|
35
|
+
Additionally creates:
|
|
24
36
|
app/content/pages/root.erb
|
|
25
|
-
|
|
26
|
-
root route in config/routes.rb
|
|
37
|
+
root action in app/controllers/content/pages_controller.rb
|
|
38
|
+
root route in config/routes.rb
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
Control root generation:
|
|
29
41
|
rails generate content Page --no-include-root
|
|
30
|
-
|
|
31
|
-
Include root for non-pages content:
|
|
32
42
|
rails generate content Article --include-root
|
|
33
43
|
|
|
34
|
-
Generate
|
|
44
|
+
Generate scaffold with data sources:
|
|
35
45
|
rails generate content Product --data countries products
|
|
36
46
|
rails generate content Product --data countries.json products.yml
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
and
|
|
48
|
+
Creates data source files in app/content/data/ and adds
|
|
49
|
+
.sources and .template_source class methods to the model.
|
|
50
|
+
|
|
51
|
+
Adds .sources and .template_source class methods to model.
|
|
40
52
|
|
|
41
53
|
Create new content file from template:
|
|
42
54
|
rails generate content Post --new
|
|
43
55
|
rails generate content Post --new "My First Post"
|
|
44
56
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
57
|
+
Creates a new content file in app/content/posts/ using:
|
|
58
|
+
1. YYYY-MM-DD-template.*.tt (if exists, with date prefix)
|
|
59
|
+
2. template.*.tt (if exists, without date prefix)
|
|
60
|
+
3. Empty file with frontmatter dashes (if no template)
|
|
49
61
|
|
|
50
62
|
Template files support ERB:
|
|
51
63
|
---
|
|
52
64
|
title: <%= @title %>
|
|
53
65
|
published_at: <%= Time.current %>
|
|
54
66
|
---
|
|
55
|
-
|
|
56
|
-
Arguments:
|
|
57
|
-
NAME: Name of the content model (singular or plural)
|
|
58
|
-
actions: Actions to generate (default: index show)
|
|
59
|
-
|
|
60
|
-
Options:
|
|
61
|
-
--new [TITLE]: Create new content file instead of scaffold
|
|
62
|
-
--data [source1(.ext) source2(.ext)]: Create data source files (default extension: .yml)
|
|
63
|
-
--force-plural: Use plural form for model name and class
|
|
64
|
-
--[no-]include-root: Include root action and route (default: true for pages, false otherwise)
|
|
@@ -76,7 +76,7 @@ module Rails
|
|
|
76
76
|
options[:data].each do |source|
|
|
77
77
|
name, extension = source.split(".", 2)
|
|
78
78
|
|
|
79
|
-
create_file File.join(
|
|
79
|
+
create_file File.join("app", "content", "data", "#{name}.#{extension || "yml"}"), ""
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
82
|
|
|
@@ -85,13 +85,12 @@ module Rails
|
|
|
85
85
|
return unless should_include_root?
|
|
86
86
|
|
|
87
87
|
inject_into_class "app/controllers/content/#{plural_file_name}_controller.rb", "Content::#{plural_class_name}Controller" do
|
|
88
|
-
|
|
88
|
+
<<~RUBY
|
|
89
|
+
def root
|
|
90
|
+
@resource = Content::#{class_name}.root
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
render :show
|
|
94
|
-
end
|
|
92
|
+
render :show
|
|
93
|
+
end
|
|
95
94
|
RUBY
|
|
96
95
|
end
|
|
97
96
|
end
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
class Content::<%= plural_class_name %>Controller < ApplicationController
|
|
2
|
-
<%- if pages_controller? -%>
|
|
3
|
-
include Perron::Root
|
|
4
|
-
<%- end -%>
|
|
5
|
-
|
|
6
2
|
<%- if actions.include?("index") -%>
|
|
7
3
|
def index
|
|
8
4
|
@resources = Content::<%= class_name %>.all
|
|
@@ -11,7 +7,7 @@ class Content::<%= plural_class_name %>Controller < ApplicationController
|
|
|
11
7
|
<%- end -%>
|
|
12
8
|
<%- if actions.include?("show") -%>
|
|
13
9
|
def show
|
|
14
|
-
@resource = Content::<%= class_name %>.find(params[:id])
|
|
10
|
+
@resource = Content::<%= class_name %>.find!(params[:id])
|
|
15
11
|
end
|
|
16
12
|
<%- end -%>
|
|
17
13
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
class Content::<%= class_name %> < Perron::Resource
|
|
2
2
|
<% if data_sources? -%>
|
|
3
|
-
|
|
4
3
|
sources <%= data_sources.map { ":#{it}" }.join(", ") %>
|
|
5
4
|
|
|
6
5
|
def self.source_template(sources)
|
|
7
|
-
<<~
|
|
6
|
+
<<~MARKDOWN
|
|
8
7
|
---
|
|
9
8
|
---
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
MARKDOWN
|
|
11
11
|
end
|
|
12
12
|
<% end -%>
|
|
13
13
|
end
|
data/lib/perron/collection.rb
CHANGED
|
@@ -16,11 +16,20 @@ module Perron
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def all(resource_class = "Content::#{name.classify}".safe_constantize)
|
|
19
|
-
load_resources(resource_class).select(&:published?)
|
|
19
|
+
Perron::Relation.new(load_resources(resource_class).select(&:published?))
|
|
20
20
|
end
|
|
21
21
|
alias_method :resources, :all
|
|
22
22
|
|
|
23
23
|
def find(slug, resource_class = Resource)
|
|
24
|
+
Perron.deprecator.deprecation_warning(
|
|
25
|
+
:find,
|
|
26
|
+
"Collection#find will return nil instead of raising in the next major version. Use #find! to raise an error."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
find!(slug, resource_class)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def find!(slug, resource_class = Resource)
|
|
24
33
|
resource = load_resources(resource_class).find { it.slug == slug }
|
|
25
34
|
|
|
26
35
|
return resource if resource
|
data/lib/perron/configuration.rb
CHANGED
|
@@ -13,17 +13,17 @@ module Perron
|
|
|
13
13
|
def initialize
|
|
14
14
|
@config = ActiveSupport::OrderedOptions.new
|
|
15
15
|
|
|
16
|
-
@config.site_name = nil
|
|
17
|
-
@config.site_description = nil
|
|
18
|
-
|
|
19
16
|
@config.output = "output"
|
|
20
17
|
|
|
21
18
|
@config.mode = :standalone
|
|
22
19
|
|
|
23
|
-
@config.
|
|
20
|
+
@config.live_reload = false
|
|
21
|
+
@config.live_reload_watch_paths = %w[app/content app/views app/assets]
|
|
22
|
+
@config.live_reload_skip_paths = %w[app/assets/builds]
|
|
24
23
|
|
|
25
24
|
@config.exclude_from_public = %w[assets storage]
|
|
26
25
|
@config.excluded_assets = %w[action_cable actioncable actiontext activestorage rails-ujs trix turbo]
|
|
26
|
+
@config.allowed_extensions = %w[erb md]
|
|
27
27
|
|
|
28
28
|
@config.view_unpublished = Rails.env.development?
|
|
29
29
|
|
|
@@ -35,11 +35,16 @@ module Perron
|
|
|
35
35
|
|
|
36
36
|
@config.markdown_options = {}
|
|
37
37
|
|
|
38
|
+
@config.search_scope = []
|
|
39
|
+
|
|
38
40
|
@config.sitemap = ActiveSupport::OrderedOptions.new
|
|
39
41
|
@config.sitemap.enabled = false
|
|
40
42
|
@config.sitemap.priority = 0.5
|
|
41
43
|
@config.sitemap.change_frequency = :monthly
|
|
42
44
|
|
|
45
|
+
@config.site_name = nil
|
|
46
|
+
@config.site_description = nil
|
|
47
|
+
|
|
43
48
|
@config.metadata = ActiveSupport::OrderedOptions.new
|
|
44
49
|
@config.metadata.title_separator = " — "
|
|
45
50
|
end
|
data/lib/perron/content/data.rb
CHANGED
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module Content
|
|
4
4
|
module Data
|
|
5
|
+
def self.new(identifier)
|
|
6
|
+
Perron::DataSource.new(identifier)
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
def self.const_missing(name)
|
|
6
|
-
klass = Class.new(Perron::
|
|
7
|
-
def self.const_missing(nested_name) = const_set(nested_name, Class.new(Perron::
|
|
10
|
+
klass = Class.new(Perron::DataSource) do
|
|
11
|
+
def self.const_missing(nested_name) = const_set(nested_name, Class.new(Perron::DataSource))
|
|
8
12
|
end
|
|
9
13
|
|
|
10
14
|
const_set(name, klass)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Perron
|
|
4
|
+
class DataSource < SimpleDelegator
|
|
5
|
+
module ClassMethods
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
class_methods do
|
|
9
|
+
def all
|
|
10
|
+
parts = name.to_s.split("::").drop(2)
|
|
11
|
+
identifier = parts.empty? ? name.demodulize.underscore : parts.map(&:underscore).join("/")
|
|
12
|
+
|
|
13
|
+
new(identifier)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def find(id)
|
|
17
|
+
all.find { it[:id] == id || it["id"] == id }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def count = all.size
|
|
21
|
+
|
|
22
|
+
def first = all.first
|
|
23
|
+
|
|
24
|
+
def second = all[1]
|
|
25
|
+
|
|
26
|
+
def third = all[2]
|
|
27
|
+
|
|
28
|
+
def fourth = all[3]
|
|
29
|
+
|
|
30
|
+
def fifth = all[4]
|
|
31
|
+
|
|
32
|
+
def forty_two = all[41]
|
|
33
|
+
|
|
34
|
+
def last = all.last
|
|
35
|
+
|
|
36
|
+
def take(n) = all.first(n)
|
|
37
|
+
|
|
38
|
+
def path_for(identifier)
|
|
39
|
+
path = Pathname.new(identifier)
|
|
40
|
+
|
|
41
|
+
return path.to_s if path.file? && path.absolute?
|
|
42
|
+
|
|
43
|
+
base_path = Rails.root.join("app", "content", "data")
|
|
44
|
+
|
|
45
|
+
SUPPORTED_EXTENSIONS.lazy.map { base_path.join("#{identifier}#{it}") }.find(&:exist?)&.to_s
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def path_for!(identifier)
|
|
49
|
+
path_for(identifier).tap do |path|
|
|
50
|
+
raise Errors::FileNotFoundError, "No data file found for `#{identifier}`" unless path
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def directory?(identifier) = Dir.exist?(Rails.root.join("app", "content", "data", identifier))
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Perron
|
|
4
|
+
class DataSource < SimpleDelegator
|
|
5
|
+
class HelperContext
|
|
6
|
+
include Singleton
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
self.class.include ActionView::Helpers::AssetUrlHelper
|
|
10
|
+
self.class.include ActionView::Helpers::DateHelper
|
|
11
|
+
self.class.include Rails.application.routes.url_helpers
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get_binding = binding
|
|
15
|
+
|
|
16
|
+
def default_url_options = Perron.configuration.default_url_options || {}
|
|
17
|
+
end
|
|
18
|
+
private_constant :HelperContext
|
|
19
|
+
end
|
|
20
|
+
end
|