jekyll-notion 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|