jekyll-notion 2.4.4 → 3.0.0.beta1
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/README.md +178 -88
- data/lib/jekyll-notion/cacheable.rb +51 -20
- data/lib/jekyll-notion/cassette_manager.rb +107 -0
- data/lib/jekyll-notion/generator.rb +71 -61
- data/lib/jekyll-notion/generators/collection.rb +70 -0
- data/lib/jekyll-notion/generators/collectionable.rb +26 -0
- data/lib/jekyll-notion/generators/data.rb +57 -0
- data/lib/jekyll-notion/generators/generator.rb +50 -0
- data/lib/jekyll-notion/generators/page.rb +35 -0
- data/lib/jekyll-notion/version.rb +1 -1
- data/lib/jekyll-notion.rb +12 -9
- metadata +18 -63
- data/lib/jekyll-notion/abstract_notion_resource.rb +0 -47
- data/lib/jekyll-notion/factories/database_factory.rb +0 -14
- data/lib/jekyll-notion/factories/page_factory.rb +0 -14
- data/lib/jekyll-notion/generators/abstract_generator.rb +0 -19
- data/lib/jekyll-notion/generators/collection_generator.rb +0 -74
- data/lib/jekyll-notion/generators/data_generator.rb +0 -59
- data/lib/jekyll-notion/generators/page_generator.rb +0 -30
- data/lib/jekyll-notion/notion_database.rb +0 -39
- data/lib/jekyll-notion/notion_page.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed820907d9684cde0edb6ec147eec63f01c5d0c84ece59e2eae336ffeae89576
|
4
|
+
data.tar.gz: d1007a311273a529246618a538a658ac88e0ac688160294cd730053f721ddb46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7492e73cf69027072ce70e458446c27834344e33bccaab9d4e77b5f8f4d6703993b39bde77c96c29658ddfed93e69f49c23882bb4fe803148faa35ca78bca4a4
|
7
|
+
data.tar.gz: 3a0c7bf81c0c2ac03a1b46912dfbb1c499caf5db9621716bfb1a292c697a31dde4b50706b6b6558a9920da69c30ee95a5edf070d7803cd7befac8a20fd376508
|
data/README.md
CHANGED
@@ -1,61 +1,94 @@
|
|
1
|
+
<img src="https://ik.imagekit.io/gxidvqvc9/jekyll_notion_logo_Thmlxy7GZ.png?updatedAt=1756230501479" width="200">
|
2
|
+
|
1
3
|
# jekyll-notion
|
2
4
|
|
3
|
-
|
5
|
+
> [!WARNING]
|
6
|
+
> The **main branch** is under active development for version 3.
|
7
|
+
> For the current **stable release**, please check out the [v2.x.x branch](https://github.com/emoriarty/jekyll-notion/tree/v2.x.x).
|
4
8
|
|
5
|
-
|
9
|
+
Import [Notion](https://www.notion.so) pages into
|
10
|
+
[Jekyll](https://jekyllrb.com/).
|
6
11
|
|
7
|
-
|
8
|
-
|
9
|
-
|
12
|
+
📚 Learn more with these guides:
|
13
|
+
- [Load Notion pages in
|
14
|
+
Jekyll](https://enrq.me/dev/2022/03/20/load-notion-pages-in-jekyll/)
|
15
|
+
- [Managing Jekyll posts in
|
16
|
+
Notion](https://enrq.me/dev/2022/03/24/managing-jekyll-posts-in-notion/)
|
17
|
+
- [Embedding videos with
|
18
|
+
jekyll-notion](https://enrq.me/dev/2023/03/31/embedding-videos-with-jekyll-notion/)
|
10
19
|
|
11
20
|
## Installation
|
12
21
|
|
13
|
-
|
14
|
-
|
15
|
-
|
22
|
+
Install via RubyGems:
|
23
|
+
|
24
|
+
``` bash
|
25
|
+
gem install jekyll-notion
|
16
26
|
```
|
17
27
|
|
18
|
-
Or add it to
|
19
|
-
|
28
|
+
Or add it to your `Gemfile`:
|
29
|
+
|
30
|
+
``` ruby
|
20
31
|
# Gemfile
|
21
32
|
gem 'jekyll-notion'
|
22
33
|
```
|
23
34
|
|
24
|
-
> [!IMPORTANT]
|
25
|
-
>
|
35
|
+
> \[!IMPORTANT\]\
|
36
|
+
> If you are using **jekyll-archives**, list `jekyll-notion` *before*
|
37
|
+
> `jekyll-archives` in the Gemfile. Otherwise, imported pages will not
|
38
|
+
> be picked up.\
|
39
|
+
> See the discussion
|
40
|
+
> [here](https://github.com/emoriarty/jekyll-notion/issues/95#issuecomment-2732112458).
|
26
41
|
|
27
|
-
|
42
|
+
Then enable the plugin in `_config.yml`:
|
28
43
|
|
29
|
-
```
|
44
|
+
``` yaml
|
30
45
|
plugins:
|
31
46
|
- jekyll-notion
|
32
47
|
```
|
33
|
-
|
34
48
|
## Usage
|
35
49
|
|
36
|
-
Before using the gem, create
|
50
|
+
Before using the gem, [create a Notion
|
51
|
+
integration](https://developers.notion.com/docs/getting-started) and
|
52
|
+
generate a secret token.
|
37
53
|
|
38
|
-
|
54
|
+
Export the token as an environment variable:
|
39
55
|
|
40
|
-
```bash
|
41
|
-
|
56
|
+
``` bash
|
57
|
+
export NOTION_TOKEN=<secret_...>
|
58
|
+
```
|
59
|
+
|
60
|
+
### Environment Variables
|
61
|
+
|
62
|
+
The plugin supports the following environment variables for configuration:
|
63
|
+
|
64
|
+
- **`NOTION_TOKEN`** (required): Your Notion integration secret token
|
65
|
+
- **`JEKYLL_NOTION_CACHE`**: Fallback cache setting when not specified in `_config.yml` (`1`, `true`, `yes` to enable; `0`, `false`, `no` to disable)
|
66
|
+
- **`JEKYLL_NOTION_CACHE_DIR`**: Fallback cache directory when not specified in `_config.yml` (defaults to `.cache/jekyll-notion/vcr_cassettes`)
|
67
|
+
|
68
|
+
Example usage:
|
69
|
+
``` bash
|
70
|
+
export NOTION_TOKEN=secret_abc123...
|
71
|
+
export JEKYLL_NOTION_CACHE=false
|
72
|
+
export JEKYLL_NOTION_CACHE_DIR=/tmp/my-custom-cache
|
42
73
|
```
|
43
74
|
|
44
75
|
### Databases
|
45
76
|
|
46
|
-
|
77
|
+
Share a [Notion
|
78
|
+
database](https://developers.notion.com/docs/working-with-databases),
|
79
|
+
then specify its `id` in `_config.yml`:
|
47
80
|
|
48
|
-
```
|
81
|
+
``` yaml
|
49
82
|
notion:
|
50
83
|
databases:
|
51
84
|
- id: 5cfed4de3bdc4f43ae8ba653a7a2219b
|
52
85
|
```
|
53
86
|
|
54
|
-
By default,
|
87
|
+
By default, entries will be added to the `posts` collection.
|
55
88
|
|
56
|
-
|
89
|
+
You can also define **multiple databases**:
|
57
90
|
|
58
|
-
```
|
91
|
+
``` yaml
|
59
92
|
collections:
|
60
93
|
- recipes
|
61
94
|
- films
|
@@ -65,22 +98,26 @@ notion:
|
|
65
98
|
- id: b0e688e199af4295ae80b67eb52f2e2f
|
66
99
|
- id: 2190450d4cb34739a5c8340c4110fe21
|
67
100
|
collection: recipes
|
68
|
-
- id: e42383cd49754897b967ce453760499f
|
101
|
+
- id: e42383cd49754897b967ce453760499f
|
69
102
|
collection: films
|
70
103
|
```
|
71
104
|
|
72
|
-
After running `jekyll build`
|
105
|
+
After running `jekyll build` or `jekyll serve`, the `posts`, `recipes`,
|
106
|
+
and `films` collections will contain pages from the specified databases.
|
73
107
|
|
74
108
|
#### Database options
|
75
109
|
|
76
|
-
Each
|
110
|
+
Each database supports the following options:
|
77
111
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
112
|
+
- `id`: the unique Notion database ID
|
113
|
+
- `collection`: which collection to assign pages to (`posts` by
|
114
|
+
default)
|
115
|
+
- `filter`: a database
|
116
|
+
[filter](https://developers.notion.com/reference/post-database-query-filter)
|
117
|
+
- `sorts`: database [sorting
|
118
|
+
criteria](https://developers.notion.com/reference/post-database-query-sort)
|
82
119
|
|
83
|
-
```
|
120
|
+
``` yaml
|
84
121
|
notion:
|
85
122
|
databases:
|
86
123
|
- id: e42383cd49754897b967ce453760499f
|
@@ -89,25 +126,29 @@ notion:
|
|
89
126
|
sorts: [{ "timestamp": "created_time", "direction": "ascending" }]
|
90
127
|
```
|
91
128
|
|
92
|
-
####
|
129
|
+
#### Post dates
|
93
130
|
|
94
|
-
|
131
|
+
By default, the Notion page `created_time` property sets the post
|
132
|
+
filename date. This value is used for Jekyll's [`date`
|
133
|
+
variable\`](https://jekyllrb.com/docs/front-matter/#predefined-variables-for-posts).
|
95
134
|
|
96
|
-
|
135
|
+
Since `created_time` cannot be modified, you can override it by adding a
|
136
|
+
custom Notion property named `date` (or `Date`). That property will be
|
137
|
+
used instead.
|
97
138
|
|
98
139
|
### Pages
|
99
140
|
|
100
|
-
|
141
|
+
You can also load individual Notion pages:
|
101
142
|
|
102
|
-
```
|
143
|
+
``` yaml
|
103
144
|
notion:
|
104
145
|
pages:
|
105
146
|
- id: 5cfed4de3bdc4f43ae8ba653a7a2219b
|
106
147
|
```
|
107
148
|
|
108
|
-
|
149
|
+
Multiple pages are supported:
|
109
150
|
|
110
|
-
```yaml
|
151
|
+
``` yaml
|
111
152
|
notion:
|
112
153
|
pages:
|
113
154
|
- id: e42383cd49754897b967ce453760499f
|
@@ -115,15 +156,19 @@ notion:
|
|
115
156
|
- id: 2190450d4cb34739a5c8340c4110fe21
|
116
157
|
```
|
117
158
|
|
118
|
-
The filename
|
159
|
+
The generated filename is based on the Notion page title (see [Page
|
160
|
+
filename](#page-filename)).
|
119
161
|
|
120
|
-
All
|
162
|
+
All page properties are exposed as Jekyll front matter. For example, if
|
163
|
+
a page has a `permalink` property set to `/about/`, Jekyll will generate
|
164
|
+
`/about/index.html`.
|
121
165
|
|
122
166
|
### Data
|
123
167
|
|
124
|
-
Instead of
|
168
|
+
Instead of adding Notion pages to collections or `pages`, you can store
|
169
|
+
them under the Jekyll **data object** using the `data` option:
|
125
170
|
|
126
|
-
```
|
171
|
+
``` yaml
|
127
172
|
notion:
|
128
173
|
databases:
|
129
174
|
- id: b0e688e199af4295ae80b67eb52f2e2f
|
@@ -135,93 +180,138 @@ notion:
|
|
135
180
|
data: about
|
136
181
|
```
|
137
182
|
|
138
|
-
|
183
|
+
Each page is stored as a hash. The page body is available under the
|
184
|
+
`content` key.
|
139
185
|
|
140
|
-
|
186
|
+
Example:
|
141
187
|
|
142
|
-
```html
|
188
|
+
``` html
|
143
189
|
<ul>
|
144
|
-
{% for film in site.data.films %}
|
145
|
-
|
146
|
-
{% endfor %}
|
190
|
+
{% for film in site.data.films %}
|
191
|
+
<li>{{ film.title }}</li>
|
192
|
+
{% endfor %}
|
147
193
|
</ul>
|
148
|
-
```
|
149
|
-
|
150
|
-
Notice, the page body is stored in the key `content`.
|
151
194
|
|
152
|
-
```html
|
153
195
|
{{ site.data.about.content }}
|
154
196
|
```
|
155
197
|
|
156
|
-
|
198
|
+
Other properties are mapped normally (see [Notion
|
199
|
+
properties](#notion-properties)).
|
157
200
|
|
158
|
-
###
|
201
|
+
### Cache
|
159
202
|
|
160
|
-
|
203
|
+
All Notion requests are cached locally with the [VCR](https://github.com/vcr/vcr) gem to speed up rebuilds.
|
204
|
+
The first build fetches from the Notion API; subsequent builds reuse the cache.
|
161
205
|
|
162
|
-
|
206
|
+
The cache mechanism provides:
|
163
207
|
|
164
|
-
|
208
|
+
- Per-page cache files that include the Notion page title + ID, making them easy to identify.
|
209
|
+
- Page-level deletion: remove a single cached page without affecting others.
|
210
|
+
- Databases fetched on every rebuild: new content in Notion is always discovered, while cached pages prevent unnecessary re-fetches.
|
165
211
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
databases:
|
170
|
-
- id: e42383cd49754897b967ce453760499f
|
212
|
+
**Example cached file (title + ID):**
|
213
|
+
```bash
|
214
|
+
.cache/jekyll-notion/vcr_cassettes/my-page-title-e42383cd49754897b967ce453760499f.yml
|
171
215
|
```
|
172
216
|
|
173
|
-
|
217
|
+
#### Cache folder
|
174
218
|
|
175
|
-
|
219
|
+
Default: `.cache/jekyll-notion/vcr_cassettes`
|
176
220
|
|
177
|
-
|
221
|
+
You can override the cache directory in two ways:
|
178
222
|
|
179
|
-
|
223
|
+
**Option 1: Configuration file** (in `_config.yml`):
|
224
|
+
``` yaml
|
225
|
+
notion:
|
226
|
+
cache_dir: another/folder
|
227
|
+
```
|
180
228
|
|
181
|
-
|
182
|
-
|
229
|
+
**Option 2: Environment variable**:
|
230
|
+
``` bash
|
231
|
+
export JEKYLL_NOTION_CACHE_DIR=/path/to/custom/cache
|
183
232
|
```
|
184
233
|
|
185
|
-
|
234
|
+
The `_config.yml` setting takes precedence over the environment variable.
|
235
|
+
Both relative and absolute paths are supported - relative paths are resolved
|
236
|
+
from the project root.
|
186
237
|
|
187
|
-
####
|
238
|
+
#### Cleaning the cache
|
239
|
+
|
240
|
+
- Delete the entire cache folder to reset everything.
|
241
|
+
- Or delete a single cached page file to refresh only that page.
|
242
|
+
|
243
|
+
#### Disabling the cache
|
188
244
|
|
189
|
-
|
245
|
+
To disable caching entirely:
|
190
246
|
|
191
|
-
```yaml
|
247
|
+
``` yaml
|
192
248
|
notion:
|
193
|
-
|
249
|
+
cache: false
|
194
250
|
```
|
195
251
|
|
196
|
-
|
252
|
+
Or use the `JEKYLL_NOTION_CACHE` environment variable:
|
197
253
|
|
198
|
-
|
254
|
+
```bash
|
255
|
+
export JEKYLL_NOTION_CACHE=false # or 0, no
|
256
|
+
```
|
199
257
|
|
200
|
-
|
258
|
+
## Sensitive data
|
201
259
|
|
202
|
-
|
260
|
+
The cache stores full request and response payloads from the Notion API.
|
261
|
+
This may include sensitive information such as authentication tokens, URLs, or private content.
|
203
262
|
|
204
|
-
If you
|
263
|
+
If you intend to store cached files in version control or share them with others, be mindful of what they contain.
|
264
|
+
By default, jekyll-notion automatically redacts the `NOTION_TOKEN` from all cache files.
|
265
|
+
If you need to mask additional values, you can configure [VCR filters](https://benoittgt.github.io/vcr/#/configuration/filter_sensitive_data?id=filter-sensitive-data).
|
205
266
|
|
206
|
-
|
207
|
-
|
208
|
-
|
267
|
+
For example, add a file `_plugins/vcr_config.rb`:
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
VCR.configure do |config|
|
271
|
+
# Already handled by jekyll-notion: NOTION_TOKEN
|
272
|
+
# Example of masking a custom header or property:
|
273
|
+
config.filter_sensitive_data("[MASKED]") do |interaction|
|
274
|
+
interaction.request.headers["User-Agent"]&.first
|
275
|
+
end
|
276
|
+
end
|
209
277
|
```
|
210
278
|
|
279
|
+
This file will be automatically picked up by Jekyll and merged into the VCR configuration provided by jekyll-notion.
|
280
|
+
|
281
|
+
You can add filters for headers, query parameters, or any other values you don’t want exposed in the cache.
|
282
|
+
|
211
283
|
## Notion properties
|
212
284
|
|
213
|
-
Notion page properties are
|
285
|
+
Notion page properties are mapped into each Jekyll document's front
|
286
|
+
matter.
|
214
287
|
|
215
|
-
|
288
|
+
See the companion gem
|
289
|
+
[notion_to_md](https://github.com/emoriarty/notion_to_md/) for details.
|
216
290
|
|
217
291
|
## Page filename
|
218
292
|
|
219
|
-
|
293
|
+
Jekyll distinguishes between **posts** and **other documents**:
|
294
|
+
|
295
|
+
- **Posts**: filenames follow the format
|
296
|
+
`YEAR-MONTH-DAY-title.MARKUP`, where the date comes from the Notion
|
297
|
+
`created_time` (or the `date` property if present).\
|
298
|
+
- **Other documents**: filenames are derived from the Notion page
|
299
|
+
title.
|
300
|
+
|
301
|
+
## Testing
|
220
302
|
|
221
|
-
|
303
|
+
Run the test suite:
|
222
304
|
|
305
|
+
```bash
|
306
|
+
bundle exec rspec # Run all tests
|
307
|
+
bundle exec rspec spec/path/to/test # Run specific test file
|
223
308
|
```
|
224
|
-
|
309
|
+
|
310
|
+
### Golden Files
|
311
|
+
|
312
|
+
Tests use golden files to validate generated output against known-good snapshots. Update snapshots when expected output changes:
|
313
|
+
|
314
|
+
```bash
|
315
|
+
UPDATE_GOLDEN=1 bundle exec rspec
|
225
316
|
```
|
226
317
|
|
227
|
-
The filename for any other document is the page title.
|
@@ -1,33 +1,64 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative "cassette_manager"
|
4
4
|
|
5
5
|
module JekyllNotion
|
6
6
|
module Cacheable
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
class << self
|
8
|
+
def configure(cache_dir:, cache_enabled:)
|
9
|
+
@cache_dir = cache_dir
|
10
|
+
@cache_enabled = cache_enabled
|
11
|
+
|
12
|
+
configure_vcr
|
13
|
+
end
|
14
|
+
|
15
|
+
def cache_dir
|
16
|
+
# Always return VCR's configured directory to ensure consistency
|
17
|
+
# between CassetteManager operations and VCR cassette storage
|
18
|
+
VCR.configuration.cassette_library_dir
|
19
|
+
end
|
20
|
+
|
21
|
+
def enabled?
|
22
|
+
@cache_enabled
|
18
23
|
end
|
19
|
-
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
File.join(Dir.
|
25
|
+
private
|
26
|
+
|
27
|
+
def configure_vcr
|
28
|
+
# Determine the directory to use based on configuration and environment
|
29
|
+
target_dir = @cache_dir || ENV["JEKYLL_NOTION_CACHE_DIR"] || File.join(Dir.pwd, ".cache",
|
30
|
+
"jekyll-notion", "vcr_cassettes")
|
31
|
+
|
32
|
+
VCR.configure do |config|
|
33
|
+
config.cassette_library_dir = target_dir
|
34
|
+
config.hook_into :faraday # Faraday is used by notion-ruby-client gem
|
35
|
+
config.filter_sensitive_data("<REDACTED>") { ENV.fetch("NOTION_TOKEN", nil) }
|
36
|
+
config.allow_http_connections_when_no_cassette = true
|
37
|
+
config.default_cassette_options = {
|
38
|
+
:allow_playback_repeats => true,
|
39
|
+
:record => :new_episodes,
|
40
|
+
}
|
41
|
+
end
|
26
42
|
end
|
27
43
|
end
|
28
44
|
|
29
|
-
def
|
30
|
-
|
45
|
+
def call
|
46
|
+
return super unless JekyllNotion::Cacheable.enabled?
|
47
|
+
|
48
|
+
cassette_manager = CassetteManager.new(JekyllNotion::Cacheable.cache_dir)
|
49
|
+
cassette_name = cassette_manager.cassette_name_for(id)
|
50
|
+
result = nil
|
51
|
+
|
52
|
+
VCR.use_cassette(
|
53
|
+
cassette_name,
|
54
|
+
:record => :new_episodes,
|
55
|
+
:allow_playback_repeats => true
|
56
|
+
) do
|
57
|
+
result = super
|
58
|
+
end
|
59
|
+
|
60
|
+
cassette_manager.update_after_call(id, result)
|
61
|
+
result
|
31
62
|
end
|
32
63
|
end
|
33
64
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
module JekyllNotion
|
7
|
+
class CassetteManager
|
8
|
+
INDEX_BASENAME = ".pages_index.yml"
|
9
|
+
PAGES_DIR = "pages"
|
10
|
+
|
11
|
+
def initialize(cache_dir)
|
12
|
+
@cache_dir = cache_dir
|
13
|
+
end
|
14
|
+
|
15
|
+
def cassette_name_for(id)
|
16
|
+
sanitized_id = sanitize_id(id)
|
17
|
+
|
18
|
+
# a) index mapping wins
|
19
|
+
if (pretty = load_index_yaml[sanitized_id]) && File.exist?(cassette_path(pretty))
|
20
|
+
return pretty
|
21
|
+
end
|
22
|
+
|
23
|
+
# b) any existing "*-id.yml" (handles prior runs / title changes)
|
24
|
+
if (found = find_existing_by_id(sanitized_id))
|
25
|
+
return found
|
26
|
+
end
|
27
|
+
|
28
|
+
# c) fallback to plain id (first run)
|
29
|
+
"#{PAGES_DIR}/#{sanitized_id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_after_call(id, result)
|
33
|
+
return unless (title = extract_title(result)).to_s != ""
|
34
|
+
|
35
|
+
sanitized_id = sanitize_id(id)
|
36
|
+
current_cassette = cassette_name_for(sanitized_id)
|
37
|
+
pretty_name = "#{PAGES_DIR}/#{sanitize_title(title)}-#{sanitized_id}"
|
38
|
+
|
39
|
+
rename_cassette_if_needed(:from => current_cassette, :to => pretty_name)
|
40
|
+
update_index_yaml(:id => sanitized_id, :pretty => pretty_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
attr_reader :cache_dir
|
46
|
+
|
47
|
+
def cassette_path(name)
|
48
|
+
File.join(cache_dir, "#{name}.yml")
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_existing_by_id(id)
|
52
|
+
matches = Dir[File.join(cache_dir, "pages", "*-#{id}.yml")]
|
53
|
+
return nil if matches.empty?
|
54
|
+
|
55
|
+
File.join(PAGES_DIR, File.basename(matches.first, ".yml"))
|
56
|
+
end
|
57
|
+
|
58
|
+
def rename_cassette_if_needed(from:, to:)
|
59
|
+
return if from == to
|
60
|
+
|
61
|
+
src = cassette_path(from)
|
62
|
+
dst = cassette_path(to)
|
63
|
+
return unless File.exist?(src)
|
64
|
+
return if File.exist?(dst)
|
65
|
+
|
66
|
+
FileUtils.mkdir_p(File.dirname(dst))
|
67
|
+
FileUtils.mv(src, dst)
|
68
|
+
rescue SystemCallError
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def index_path
|
73
|
+
File.join(cache_dir, INDEX_BASENAME)
|
74
|
+
end
|
75
|
+
|
76
|
+
def load_index_yaml
|
77
|
+
return {} unless File.exist?(index_path)
|
78
|
+
|
79
|
+
YAML.safe_load(File.read(index_path), :permitted_classes => [], :aliases => false) || {}
|
80
|
+
rescue Psych::SyntaxError
|
81
|
+
{}
|
82
|
+
end
|
83
|
+
|
84
|
+
def update_index_yaml(id:, pretty:)
|
85
|
+
idx = load_index_yaml
|
86
|
+
return if idx[id] == pretty
|
87
|
+
|
88
|
+
FileUtils.mkdir_p(File.dirname(index_path))
|
89
|
+
tmp = "#{index_path}.tmp"
|
90
|
+
idx[id] = pretty
|
91
|
+
File.write(tmp, idx.to_yaml)
|
92
|
+
FileUtils.mv(tmp, index_path)
|
93
|
+
end
|
94
|
+
|
95
|
+
def sanitize_title(str)
|
96
|
+
Jekyll::Utils.slugify(str)
|
97
|
+
end
|
98
|
+
|
99
|
+
def sanitize_id(id)
|
100
|
+
id.delete("-")
|
101
|
+
end
|
102
|
+
|
103
|
+
def extract_title(metadata)
|
104
|
+
metadata.title
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|