jekyll-notion 1.0.0 → 1.2.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/README.md +49 -9
- data/lib/jekyll-notion/abstract_generator.rb +15 -0
- data/lib/jekyll-notion/abstract_notion_resource.rb +41 -0
- data/lib/jekyll-notion/collection_generator.rb +10 -12
- data/lib/jekyll-notion/data_generator.rb +57 -0
- data/lib/jekyll-notion/generator.rb +31 -12
- data/lib/jekyll-notion/generator_factory.rb +14 -0
- data/lib/jekyll-notion/notion_database.rb +9 -26
- data/lib/jekyll-notion/notion_page.rb +27 -0
- data/lib/jekyll-notion/version.rb +1 -1
- data/lib/jekyll-notion.rb +5 -0
- 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: ac8561afc4f42d433ae33d4baafb38e9eaf7a34167513bf628eef849c3e773b7
|
4
|
+
data.tar.gz: 7c55ac94b8490943d981f3c25d36d0b3993680614ba25cdb16be78f07b5e028a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d402be5b38a3dc4cae78daf0e95140ecc0b593db1091ac325f262a68024236f50639c25f1bee42db6cee025122bfb82d2318f312909278509c66f2375062d4d1
|
7
|
+
data.tar.gz: c22e49f752ba7a848c6329e55c57707c6bc9d59e510f5407a112448335a9a36b877c9abe4e94cf30fd383db29defd5fafbba14558742417375c4df4990f91a90
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# jekyll-notion
|
2
2
|
|
3
|
-
Import notion pages to a jekyll collection.
|
3
|
+
Import notion pages to a jekyll collection or data.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -32,14 +32,17 @@ Export the notion secret token in an environment variable named `NOTION_TOKEN`.
|
|
32
32
|
$ export NOTION_TOKEN=<secret_...>
|
33
33
|
```
|
34
34
|
|
35
|
-
Once your notion database has been shared, specify the
|
35
|
+
Once your [notion database](https://www.notion.so/help/intro-to-databases) has been shared, specify the database `id` in your `_config.yml` as follows.
|
36
36
|
|
37
37
|
```yml
|
38
38
|
notion:
|
39
39
|
database:
|
40
|
-
id:
|
40
|
+
id: 5cfed4de3bdc4f43ae8ba653a7a2219b
|
41
41
|
```
|
42
42
|
|
43
|
+
After running `jekyll build` (or `serve`) command, the `posts` collection is loaded with pages of the notion database specified in the configuration.
|
44
|
+
|
45
|
+
|
43
46
|
### Mutiple dabatases
|
44
47
|
|
45
48
|
You can also define multiple databases as follows.
|
@@ -51,14 +54,51 @@ collections:
|
|
51
54
|
|
52
55
|
notion:
|
53
56
|
databases:
|
54
|
-
- id:
|
55
|
-
- id:
|
57
|
+
- id: b0e688e199af4295ae80b67eb52f2e2f
|
58
|
+
- id: 2190450d4cb34739a5c8340c4110fe21
|
56
59
|
collection: recipes
|
57
|
-
- id:
|
60
|
+
- id: e42383cd49754897b967ce453760499f
|
58
61
|
collection: films
|
59
62
|
```
|
60
63
|
|
61
|
-
|
64
|
+
### Data
|
65
|
+
|
66
|
+
Instead of storing notion pages in a collection, you can also map to the data object. Use the `data` property instead of `collection`.
|
67
|
+
|
68
|
+
```yml
|
69
|
+
notion:
|
70
|
+
database:
|
71
|
+
id: e42383cd49754897b967ce453760499f
|
72
|
+
data: films
|
73
|
+
```
|
74
|
+
|
75
|
+
Page properties and body are stored as a hash data.
|
76
|
+
|
77
|
+
As a particular characteristic, the page is stored in a key named `content`.
|
78
|
+
|
79
|
+
```html
|
80
|
+
<p>{{ site.data.films.content }}</p>
|
81
|
+
```
|
82
|
+
|
83
|
+
The rest of properties as mapped as expected.
|
84
|
+
|
85
|
+
### Pages
|
86
|
+
|
87
|
+
Individual Notion pages can also be mapped to data. Just define the `pages` or `page` property as follows.
|
88
|
+
|
89
|
+
```yaml
|
90
|
+
notion:
|
91
|
+
pages:
|
92
|
+
- id: e42383cd49754897b967ce453760499f
|
93
|
+
data: about
|
94
|
+
- id: b0e688e199af4295ae80b67eb52f2e2f
|
95
|
+
data: contact
|
96
|
+
- id: 2190450d4cb34739a5c8340c4110fe21
|
97
|
+
data: footer
|
98
|
+
|
99
|
+
```
|
100
|
+
|
101
|
+
_This feature is only available for data._
|
62
102
|
|
63
103
|
### Database options
|
64
104
|
|
@@ -72,7 +112,7 @@ Each dabatase support the following options.
|
|
72
112
|
```yml
|
73
113
|
notion:
|
74
114
|
database:
|
75
|
-
id:
|
115
|
+
id: e42383cd49754897b967ce453760499f
|
76
116
|
collection: posts
|
77
117
|
filter: { "property": "Published", "checkbox": { "equals": true } }
|
78
118
|
sort: { "property": "Last ordered", "direction": "ascending" }
|
@@ -88,7 +128,7 @@ Set `fetch_on_watch` to true to allow request on each rebuild.
|
|
88
128
|
notion:
|
89
129
|
fetch_on_watch: true
|
90
130
|
database:
|
91
|
-
id:
|
131
|
+
id: e42383cd49754897b967ce453760499f
|
92
132
|
```
|
93
133
|
|
94
134
|
And that's all. Each page in the notion database will be included in the selected collection.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllNotion
|
4
|
+
class AbstractGenerator
|
5
|
+
def initialize(notion_resource:, site:, plugin:)
|
6
|
+
@notion_resource = notion_resource
|
7
|
+
@site = site
|
8
|
+
@plugin = plugin
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
raise "Do not use the AbstractGenerator class. Implement the generate method in a subclass."
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllNotion
|
4
|
+
class AbstractNotionResource
|
5
|
+
def initialize(config:)
|
6
|
+
@notion = Notion::Client.new
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def config
|
11
|
+
@config || {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
config["id"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def fetch
|
19
|
+
raise "Do not use the AbstractNotionResource class. Implement the fetch method in a subclass."
|
20
|
+
end
|
21
|
+
|
22
|
+
def collection_name
|
23
|
+
raise "Do not use the AbstractGenerator class. Implement the collection_name method in a subclass."
|
24
|
+
end
|
25
|
+
|
26
|
+
def data_name
|
27
|
+
raise "Do not use the AbstractGenerator class. Implement the data_name method in a subclass."
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def id?
|
33
|
+
if id.nil? || id.empty?
|
34
|
+
Jekyll.logger.warn("Jekyll Notion:",
|
35
|
+
"Database or page id is not provided. Cannot read from Notion.")
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,22 +1,20 @@
|
|
1
|
-
|
2
|
-
class CollectionGenerator
|
3
|
-
def initialize(db:, site:)
|
4
|
-
@db = db
|
5
|
-
@site = site
|
6
|
-
end
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
3
|
+
module JekyllNotion
|
4
|
+
class CollectionGenerator < AbstractGenerator
|
8
5
|
def generate
|
9
|
-
@
|
6
|
+
@notion_resource.fetch.each do |page|
|
10
7
|
next if file_exists?(make_path(page))
|
11
8
|
|
12
9
|
collection.docs << make_doc(page)
|
13
10
|
log_new_page(page)
|
14
11
|
end
|
15
|
-
collection
|
12
|
+
# Caching current collection
|
13
|
+
@plugin.collections[@notion_resource.collection_name] = collection
|
16
14
|
end
|
17
15
|
|
18
16
|
def collection
|
19
|
-
@site.collections[@
|
17
|
+
@site.collections[@notion_resource.collection_name]
|
20
18
|
end
|
21
19
|
|
22
20
|
private
|
@@ -37,11 +35,11 @@ module JekyllNotion
|
|
37
35
|
end
|
38
36
|
|
39
37
|
def make_path(page)
|
40
|
-
"_#{@
|
38
|
+
"_#{@notion_resource.collection_name}/#{make_filename(page)}"
|
41
39
|
end
|
42
40
|
|
43
41
|
def make_filename(page)
|
44
|
-
if @
|
42
|
+
if @notion_resource.collection_name == "posts"
|
45
43
|
"#{page.created_time.to_date}-#{Jekyll::Utils.slugify(page.title,
|
46
44
|
:mode => "latin")}.md"
|
47
45
|
else
|
@@ -56,7 +54,7 @@ module JekyllNotion
|
|
56
54
|
def log_new_page(page)
|
57
55
|
Jekyll.logger.info("Jekyll Notion:", "Page => #{page.title}")
|
58
56
|
if @site.config.dig(
|
59
|
-
"collections", @
|
57
|
+
"collections", @notion_resource.collection_name, "output"
|
60
58
|
)
|
61
59
|
Jekyll.logger.info("",
|
62
60
|
"Path => #{collection.docs.last.path}")
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllNotion
|
4
|
+
class DataGenerator < AbstractGenerator
|
5
|
+
def generate
|
6
|
+
unless data.nil?
|
7
|
+
@site.data[@notion_resource.data_name] = data
|
8
|
+
# Caching current data in Generator instance (plugin)
|
9
|
+
@plugin.data[@notion_resource.data_name] = data
|
10
|
+
log_pages
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def data
|
17
|
+
@data ||= if @notion_resource.is_a?(NotionDatabase)
|
18
|
+
pages = @notion_resource.fetch
|
19
|
+
pages.map { |page| page.props.merge({ "content" => convert(page) }) }
|
20
|
+
else
|
21
|
+
page = @notion_resource.fetch
|
22
|
+
page&.props&.merge({ "content" => convert(page) })
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Convert the notion page body using the site.converters.
|
27
|
+
#
|
28
|
+
# Returns String the converted content.
|
29
|
+
def convert(page)
|
30
|
+
converters.reduce(page.body) do |output, converter|
|
31
|
+
converter.convert output
|
32
|
+
rescue StandardError => e
|
33
|
+
Jekyll.logger.error "Conversion error:",
|
34
|
+
"#{converter.class} encountered an error while "\
|
35
|
+
"converting notion page '#{page.title}':"
|
36
|
+
Jekyll.logger.error("", e.to_s)
|
37
|
+
raise e
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def converters
|
42
|
+
@converters ||= @site.converters.select { |c| c.matches(".md") }.tap(&:sort!)
|
43
|
+
end
|
44
|
+
|
45
|
+
def log_pages
|
46
|
+
if data.is_a?(Array)
|
47
|
+
data.each do |page|
|
48
|
+
Jekyll.logger.info("Jekyll Notion:", "Page => #{page["title"]}")
|
49
|
+
Jekyll.logger.debug("", "Props => #{page.keys.inspect}")
|
50
|
+
end
|
51
|
+
else
|
52
|
+
Jekyll.logger.info("Jekyll Notion:", "Page => #{data["title"]}")
|
53
|
+
Jekyll.logger.debug("", "Props => #{data.keys.inspect}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -9,30 +9,49 @@ module JekyllNotion
|
|
9
9
|
|
10
10
|
return unless notion_token? && config?
|
11
11
|
|
12
|
-
if fetch_on_watch? ||
|
13
|
-
|
12
|
+
if fetch_on_watch? || collections_and_data_empty?
|
13
|
+
read_notion_databases
|
14
|
+
read_notion_pages
|
14
15
|
else
|
15
16
|
collections.each_pair { |key, val| @site.collections[key] = val }
|
17
|
+
data.each_pair { |key, val| @site.data[key] = val }
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
def databases
|
22
|
+
config["databases"] || [config["database"]]
|
23
|
+
end
|
24
|
+
|
25
|
+
def pages
|
26
|
+
config["pages"] || [config["page"]]
|
27
|
+
end
|
28
|
+
|
29
|
+
def collections
|
30
|
+
@collections ||= {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def data
|
34
|
+
@data ||= {}
|
35
|
+
end
|
36
|
+
|
19
37
|
protected
|
20
38
|
|
21
|
-
def
|
39
|
+
def collections_and_data_empty?
|
40
|
+
collections.empty? && data.empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_notion_databases
|
22
44
|
databases.each do |db_config|
|
23
45
|
db = NotionDatabase.new(:config => db_config)
|
24
|
-
|
25
|
-
# Caching current collection
|
26
|
-
collections[db.collection] = new_collection
|
46
|
+
GeneratorFactory.for(:notion_resource => db, :site => @site, :plugin => self).generate
|
27
47
|
end
|
28
48
|
end
|
29
49
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@collections ||= {}
|
50
|
+
def read_notion_pages
|
51
|
+
pages.each do |page_config|
|
52
|
+
page = NotionPage.new(:config => page_config)
|
53
|
+
GeneratorFactory.for(:notion_resource => page, :site => @site, :plugin => self).generate
|
54
|
+
end
|
36
55
|
end
|
37
56
|
|
38
57
|
def config
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllNotion
|
4
|
+
class GeneratorFactory
|
5
|
+
def self.for(notion_resource:, site:, plugin:)
|
6
|
+
if notion_resource.is_a?(NotionDatabase) && notion_resource.data_name.nil?
|
7
|
+
CollectionGenerator.new(:notion_resource => notion_resource, :site => site,
|
8
|
+
:plugin => plugin)
|
9
|
+
else
|
10
|
+
DataGenerator.new(:notion_resource => notion_resource, :site => site, :plugin => plugin)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,24 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JekyllNotion
|
4
|
-
class NotionDatabase
|
5
|
-
|
6
|
-
|
7
|
-
@config = config
|
8
|
-
end
|
9
|
-
|
10
|
-
def pages
|
4
|
+
class NotionDatabase < AbstractNotionResource
|
5
|
+
# Returns an empty array or a NotionToMd:Page array
|
6
|
+
def fetch
|
11
7
|
return [] unless id?
|
12
8
|
|
13
|
-
@
|
14
|
-
NotionToMd::Page.new(:page => page)
|
9
|
+
@fetch ||= @notion.database_query(query)[:results].map do |page|
|
10
|
+
NotionToMd::Page.new(:page => page, :blocks => @notion.block_children(:id => page.id))
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
18
|
-
def config
|
19
|
-
@config || {}
|
20
|
-
end
|
21
|
-
|
22
14
|
def filter
|
23
15
|
config["filter"]
|
24
16
|
end
|
@@ -27,25 +19,16 @@ module JekyllNotion
|
|
27
19
|
config["sort"]
|
28
20
|
end
|
29
21
|
|
30
|
-
def
|
31
|
-
config["
|
22
|
+
def collection_name
|
23
|
+
config["collection"] || "posts"
|
32
24
|
end
|
33
25
|
|
34
|
-
def
|
35
|
-
config["
|
26
|
+
def data_name
|
27
|
+
config["data"]
|
36
28
|
end
|
37
29
|
|
38
30
|
private
|
39
31
|
|
40
|
-
def id?
|
41
|
-
if id.nil? || id.empty?
|
42
|
-
Jekyll.logger.warn("Jekyll Notion:",
|
43
|
-
"database id is not provided. Cannot read from Notion.")
|
44
|
-
return false
|
45
|
-
end
|
46
|
-
true
|
47
|
-
end
|
48
|
-
|
49
32
|
def query
|
50
33
|
{ :id => id, :filter => filter, :sort => sort }.compact
|
51
34
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllNotion
|
4
|
+
class NotionPage < AbstractNotionResource
|
5
|
+
# Returns the nil or a NotionToMd::Page instance
|
6
|
+
def fetch
|
7
|
+
return nil unless id?
|
8
|
+
|
9
|
+
@fetch ||= NotionToMd::Page.new(:page => @notion.page(query),
|
10
|
+
:blocks => @notion.block_children(query))
|
11
|
+
end
|
12
|
+
|
13
|
+
def data_name
|
14
|
+
config["data"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection_name
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def query
|
24
|
+
{ :id => id }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/jekyll-notion.rb
CHANGED
@@ -13,7 +13,12 @@ Notion.configure do |config|
|
|
13
13
|
end
|
14
14
|
|
15
15
|
module JekyllNotion
|
16
|
+
autoload :GeneratorFactory, "jekyll-notion/generator_factory"
|
17
|
+
autoload :AbstractGenerator, "jekyll-notion/abstract_generator"
|
18
|
+
autoload :AbstractNotionResource, "jekyll-notion/abstract_notion_resource"
|
16
19
|
autoload :CollectionGenerator, "jekyll-notion/collection_generator"
|
20
|
+
autoload :DataGenerator, "jekyll-notion/data_generator"
|
17
21
|
autoload :DocumentWithoutAFile, "jekyll-notion/document_without_a_file"
|
18
22
|
autoload :NotionDatabase, "jekyll-notion/notion_database"
|
23
|
+
autoload :NotionPage, "jekyll-notion/notion_page"
|
19
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-notion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Enrique Arias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
53
|
+
version: '1.0'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '0'
|
60
|
+
version: '1.0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: bundler
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,10 +110,15 @@ extra_rdoc_files:
|
|
110
110
|
files:
|
111
111
|
- README.md
|
112
112
|
- lib/jekyll-notion.rb
|
113
|
+
- lib/jekyll-notion/abstract_generator.rb
|
114
|
+
- lib/jekyll-notion/abstract_notion_resource.rb
|
113
115
|
- lib/jekyll-notion/collection_generator.rb
|
116
|
+
- lib/jekyll-notion/data_generator.rb
|
114
117
|
- lib/jekyll-notion/document_without_a_file.rb
|
115
118
|
- lib/jekyll-notion/generator.rb
|
119
|
+
- lib/jekyll-notion/generator_factory.rb
|
116
120
|
- lib/jekyll-notion/notion_database.rb
|
121
|
+
- lib/jekyll-notion/notion_page.rb
|
117
122
|
- lib/jekyll-notion/version.rb
|
118
123
|
homepage: https://github.com/emoriarty/jekyll-notion
|
119
124
|
licenses:
|