jekyll-notion 0.1.6 → 1.0.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 +51 -50
- data/lib/jekyll-notion/collection_generator.rb +67 -0
- data/lib/jekyll-notion/generator.rb +15 -59
- data/lib/jekyll-notion/notion_database.rb +11 -7
- data/lib/jekyll-notion/version.rb +1 -1
- data/lib/jekyll-notion.rb +1 -3
- metadata +3 -17
- data/lib/jekyll-notion/notion_page.rb +0 -123
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f85b870a3e8c0aa6ea64575b8ef8541f61183fa25ced6f41570384057a3a36dd
|
4
|
+
data.tar.gz: c66f6d831e8352f029fc1f81608f751aac1ed2b5959b6c2ee19f861eafcdb6f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26fda79bcfce19d75fda17e6f3e1a90080089c05132359b50f00ec3a4d54d844e6ef583bb558c961209d5818465c6ada865413a33f22fea15fdf943ecd213d8d
|
7
|
+
data.tar.gz: 430aa7ef405283f1568eacf4062a90a60fc0e086ae6c7d68cd96cd1eac5f8208d57d8cdebc02b0e98c653d0bff62b119c4ec6ceb4af31777c2a4a28121e0eb55
|
data/README.md
CHANGED
@@ -32,86 +32,87 @@ 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 `id` in your `_config.yml` as follows.
|
35
|
+
Once your notion database has been shared, specify the database `id` in your `_config.yml` as follows.
|
36
36
|
|
37
37
|
```yml
|
38
38
|
notion:
|
39
|
-
fetch_on_watch: false
|
40
39
|
database:
|
41
|
-
id:
|
42
|
-
collection: posts
|
43
|
-
filter: { "property": "Published", "checkbox": { "equals": true } }
|
44
|
-
sort: { "property": "Last ordered", "direction": "ascending" }
|
45
|
-
frontmatter:
|
46
|
-
layout: post
|
40
|
+
id: e42383cd-4975-4897-b967-ce453760499f
|
47
41
|
```
|
48
42
|
|
49
|
-
|
43
|
+
### Mutiple dabatases
|
44
|
+
|
45
|
+
You can also define multiple databases as follows.
|
46
|
+
|
47
|
+
```yml
|
48
|
+
collections:
|
49
|
+
- recipes
|
50
|
+
- films
|
51
|
+
|
52
|
+
notion:
|
53
|
+
databases:
|
54
|
+
- id: b0e688e1-99af-4295-ae80-b67eb52f2e2f
|
55
|
+
- id: 2190450d-4cb3-4739-a5c8-340c4110fe21
|
56
|
+
collection: recipes
|
57
|
+
- id: e42383cd-4975-4897-b967-ce453760499f
|
58
|
+
collection: films
|
59
|
+
```
|
60
|
+
|
61
|
+
When no collection is defined, the `posts` collection is used by default.
|
62
|
+
|
63
|
+
### Database options
|
64
|
+
|
65
|
+
Each dabatase support the following options.
|
50
66
|
|
51
|
-
`database` properties are:
|
52
67
|
* `id`: the notion database unique identifier,
|
53
68
|
* `collection`: the collection each page belongs to (posts by default),
|
54
69
|
* `filter`: the database query filter,
|
55
70
|
* `sort`: the database query sort,
|
56
|
-
* `frontmatter`: additional frontmatter to append to each page in the collection.
|
57
|
-
|
58
|
-
Note: Only one notion database is available.
|
59
71
|
|
60
|
-
|
72
|
+
```yml
|
73
|
+
notion:
|
74
|
+
database:
|
75
|
+
id: e42383cd-4975-4897-b967-ce453760499f
|
76
|
+
collection: posts
|
77
|
+
filter: { "property": "Published", "checkbox": { "equals": true } }
|
78
|
+
sort: { "property": "Last ordered", "direction": "ascending" }
|
79
|
+
```
|
61
80
|
|
62
|
-
|
81
|
+
### Watch
|
63
82
|
|
64
|
-
|
83
|
+
By default, databases are only requested during the first build. Subsequent builds use the results from the cache.
|
65
84
|
|
66
|
-
|
85
|
+
Set `fetch_on_watch` to true to allow request on each rebuild.
|
67
86
|
|
68
|
-
```
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
date: 2022-01-23T12:31:00.000Z
|
74
|
-
icon: \U0001F4A5
|
75
|
-
---
|
87
|
+
```yml
|
88
|
+
notion:
|
89
|
+
fetch_on_watch: true
|
90
|
+
database:
|
91
|
+
id: e42383cd-4975-4897-b967-ce453760499f
|
76
92
|
```
|
77
93
|
|
78
|
-
|
94
|
+
And that's all. Each page in the notion database will be included in the selected collection.
|
79
95
|
|
80
|
-
|
96
|
+
## Notion properties
|
81
97
|
|
82
|
-
|
98
|
+
Below, default properties per notion page are set for each document front matter.
|
83
99
|
|
84
|
-
|
85
|
-
For example, two properties named `Multiple Options` and `Tags` will be transformed to `multiple_options` and `tags`, respectively.
|
100
|
+
Notion page properties are `id`, `title`, `created_time`, `last_edited_time`, `icon`, `cover` and `archived`.
|
86
101
|
|
87
102
|
```
|
88
103
|
---
|
89
|
-
id:
|
90
|
-
title:
|
104
|
+
id: e42383cd-4975-4897-b967-ce453760499f
|
105
|
+
title: An amazing post
|
91
106
|
cover: https://img.bank.sh/an_image.jpg
|
92
107
|
date: 2022-01-23T12:31:00.000Z
|
93
|
-
icon:
|
94
|
-
|
95
|
-
multiple_options: option1, option2
|
108
|
+
icon: 💥
|
109
|
+
archived: false
|
96
110
|
---
|
97
111
|
```
|
98
112
|
|
99
|
-
|
100
|
-
|
101
|
-
* `number`
|
102
|
-
* `select`
|
103
|
-
* `multi_select`
|
104
|
-
* `date`
|
105
|
-
* `people`
|
106
|
-
* `files`
|
107
|
-
* `checkbox`
|
108
|
-
* `url`
|
109
|
-
* `email`
|
110
|
-
* `phone_number`
|
111
|
-
|
112
|
-
`created_by`, `last_edited_by`, `rich_text` as advanced types like `formula`, `relation` and `rollup` are not supported.
|
113
|
+
In addition to default properties, custom properties are also appended to front matter.
|
113
114
|
|
114
|
-
|
115
|
+
Please, refer to the [notion_to_md](https://github.com/emoriarty/notion_to_md/) gem to learn more.
|
115
116
|
|
116
117
|
## Page filename
|
117
118
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module JekyllNotion
|
2
|
+
class CollectionGenerator
|
3
|
+
def initialize(db:, site:)
|
4
|
+
@db = db
|
5
|
+
@site = site
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate
|
9
|
+
@db.pages.each do |page|
|
10
|
+
next if file_exists?(make_path(page))
|
11
|
+
|
12
|
+
collection.docs << make_doc(page)
|
13
|
+
log_new_page(page)
|
14
|
+
end
|
15
|
+
collection
|
16
|
+
end
|
17
|
+
|
18
|
+
def collection
|
19
|
+
@site.collections[@db.collection]
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Checks if a file already exists in the site source
|
25
|
+
def file_exists?(file_path)
|
26
|
+
File.exist? @site.in_source_dir(file_path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def make_doc(page)
|
30
|
+
new_post = DocumentWithoutAFile.new(
|
31
|
+
make_path(page),
|
32
|
+
{ :site => @site, :collection => collection }
|
33
|
+
)
|
34
|
+
new_post.content = make_md(page)
|
35
|
+
new_post.read
|
36
|
+
new_post
|
37
|
+
end
|
38
|
+
|
39
|
+
def make_path(page)
|
40
|
+
"_#{@db.collection}/#{make_filename(page)}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_filename(page)
|
44
|
+
if @db.collection == "posts"
|
45
|
+
"#{page.created_time.to_date}-#{Jekyll::Utils.slugify(page.title,
|
46
|
+
:mode => "latin")}.md"
|
47
|
+
else
|
48
|
+
"#{page.title.downcase.parameterize}.md"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def make_md(page)
|
53
|
+
NotionToMd::Converter.new(:page_id => page.id).convert(:frontmatter => true)
|
54
|
+
end
|
55
|
+
|
56
|
+
def log_new_page(page)
|
57
|
+
Jekyll.logger.info("Jekyll Notion:", "Page => #{page.title}")
|
58
|
+
if @site.config.dig(
|
59
|
+
"collections", @db.collection, "output"
|
60
|
+
)
|
61
|
+
Jekyll.logger.info("",
|
62
|
+
"Path => #{collection.docs.last.path}")
|
63
|
+
end
|
64
|
+
Jekyll.logger.debug("", "Props => #{collection.docs.last.data.keys.inspect}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -2,81 +2,37 @@
|
|
2
2
|
|
3
3
|
module JekyllNotion
|
4
4
|
class Generator < Jekyll::Generator
|
5
|
-
attr_reader :current_page
|
5
|
+
attr_reader :current_page, :current_db
|
6
6
|
|
7
7
|
def generate(site)
|
8
8
|
@site = site
|
9
9
|
|
10
10
|
return unless notion_token? && config?
|
11
11
|
|
12
|
-
if fetch_on_watch? ||
|
12
|
+
if fetch_on_watch? || collections.empty?
|
13
13
|
read_notion_database
|
14
14
|
else
|
15
|
-
|
15
|
+
collections.each_pair { |key, val| @site.collections[key] = val }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
@db = NotionDatabase.new(:config => config)
|
21
|
-
@db.pages.each do |page|
|
22
|
-
@current_page = page
|
23
|
-
collection.docs << make_page
|
24
|
-
Jekyll.logger.info("Jekyll Notion:", "New notion page at #{collection.docs.last.path}")
|
25
|
-
end
|
26
|
-
@docs = collection.docs
|
27
|
-
end
|
28
|
-
|
29
|
-
def docs
|
30
|
-
@docs ||= []
|
31
|
-
end
|
32
|
-
|
33
|
-
def make_page
|
34
|
-
new_post = DocumentWithoutAFile.new(
|
35
|
-
"#{Dir.pwd}/_#{collection_name}/#{make_filename}",
|
36
|
-
{ :site => @site, :collection => collection }
|
37
|
-
)
|
38
|
-
new_post.content = "#{make_frontmatter}\n\n#{make_md}"
|
39
|
-
new_post.read
|
40
|
-
new_post
|
41
|
-
end
|
42
|
-
|
43
|
-
def make_md
|
44
|
-
NotionToMd::Converter.new(:page_id => current_page.id).convert
|
45
|
-
end
|
19
|
+
protected
|
46
20
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
---
|
54
|
-
CONTENT
|
55
|
-
end
|
56
|
-
|
57
|
-
def page_frontmatter
|
58
|
-
Jekyll::Utils.deep_merge_hashes(current_page.custom_props, current_page.default_props)
|
59
|
-
end
|
60
|
-
|
61
|
-
def config_frontmatter
|
62
|
-
config.dig("database", "frontmatter") || {}
|
63
|
-
end
|
64
|
-
|
65
|
-
def make_filename
|
66
|
-
if collection_name == "posts"
|
67
|
-
"#{current_page.created_date}-#{Jekyll::Utils.slugify(current_page.title,
|
68
|
-
:mode => "latin")}.md"
|
69
|
-
else
|
70
|
-
"#{current_page.title.downcase.parameterize}.md"
|
21
|
+
def read_notion_database
|
22
|
+
databases.each do |db_config|
|
23
|
+
db = NotionDatabase.new(:config => db_config)
|
24
|
+
new_collection = CollectionGenerator.new(:db => db, :site => @site).generate
|
25
|
+
# Caching current collection
|
26
|
+
collections[db.collection] = new_collection
|
71
27
|
end
|
72
28
|
end
|
73
29
|
|
74
|
-
def
|
75
|
-
config
|
30
|
+
def databases
|
31
|
+
config["databases"] || [config["database"]]
|
76
32
|
end
|
77
33
|
|
78
|
-
def
|
79
|
-
@
|
34
|
+
def collections
|
35
|
+
@collections ||= {}
|
80
36
|
end
|
81
37
|
|
82
38
|
def config
|
@@ -84,7 +40,7 @@ module JekyllNotion
|
|
84
40
|
end
|
85
41
|
|
86
42
|
def fetch_on_watch?
|
87
|
-
config["fetch_on_watch"]
|
43
|
+
config["fetch_on_watch"] == true
|
88
44
|
end
|
89
45
|
|
90
46
|
def notion_token?
|
@@ -11,28 +11,32 @@ module JekyllNotion
|
|
11
11
|
return [] unless id?
|
12
12
|
|
13
13
|
@pages ||= @notion.database_query(query)[:results].map do |page|
|
14
|
-
|
14
|
+
NotionToMd::Page.new(:page => page)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
private
|
19
|
-
|
20
18
|
def config
|
21
|
-
@config
|
19
|
+
@config || {}
|
22
20
|
end
|
23
21
|
|
24
22
|
def filter
|
25
|
-
|
23
|
+
config["filter"]
|
26
24
|
end
|
27
25
|
|
28
26
|
def sort
|
29
|
-
|
27
|
+
config["sort"]
|
30
28
|
end
|
31
29
|
|
32
30
|
def id
|
33
|
-
|
31
|
+
config["id"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def collection
|
35
|
+
config["collection"] || "posts"
|
34
36
|
end
|
35
37
|
|
38
|
+
private
|
39
|
+
|
36
40
|
def id?
|
37
41
|
if id.nil? || id.empty?
|
38
42
|
Jekyll.logger.warn("Jekyll Notion:",
|
data/lib/jekyll-notion.rb
CHANGED
@@ -4,8 +4,6 @@ require "jekyll"
|
|
4
4
|
require "notion"
|
5
5
|
require "notion_to_md"
|
6
6
|
require "logger"
|
7
|
-
require "active_support/inflector"
|
8
|
-
require "active_support/core_ext/object/blank"
|
9
7
|
require "jekyll-notion/generator"
|
10
8
|
|
11
9
|
NotionToMd::Logger.level = Logger::ERROR
|
@@ -15,7 +13,7 @@ Notion.configure do |config|
|
|
15
13
|
end
|
16
14
|
|
17
15
|
module JekyllNotion
|
16
|
+
autoload :CollectionGenerator, "jekyll-notion/collection_generator"
|
18
17
|
autoload :DocumentWithoutAFile, "jekyll-notion/document_without_a_file"
|
19
18
|
autoload :NotionDatabase, "jekyll-notion/notion_database"
|
20
|
-
autoload :NotionPage, "jekyll-notion/notion_page"
|
21
19
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-notion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.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-02-
|
11
|
+
date: 2022-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '6'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '6'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: jekyll
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,10 +110,10 @@ extra_rdoc_files:
|
|
124
110
|
files:
|
125
111
|
- README.md
|
126
112
|
- lib/jekyll-notion.rb
|
113
|
+
- lib/jekyll-notion/collection_generator.rb
|
127
114
|
- lib/jekyll-notion/document_without_a_file.rb
|
128
115
|
- lib/jekyll-notion/generator.rb
|
129
116
|
- lib/jekyll-notion/notion_database.rb
|
130
|
-
- lib/jekyll-notion/notion_page.rb
|
131
117
|
- lib/jekyll-notion/version.rb
|
132
118
|
homepage: https://github.com/emoriarty/jekyll-notion
|
133
119
|
licenses:
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JekyllNotion
|
4
|
-
class NotionPage
|
5
|
-
attr_reader :page, :layout
|
6
|
-
|
7
|
-
def initialize(page:, layout:)
|
8
|
-
@page = page
|
9
|
-
@layout = layout
|
10
|
-
end
|
11
|
-
|
12
|
-
def title
|
13
|
-
page.dig(:properties, :Name, :title).inject("") do |acc, slug|
|
14
|
-
acc + slug[:plain_text]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def cover
|
19
|
-
page.dig(:cover, :external, :url)
|
20
|
-
end
|
21
|
-
|
22
|
-
def icon
|
23
|
-
page.dig(:icon, :emoji)
|
24
|
-
end
|
25
|
-
|
26
|
-
def id
|
27
|
-
page[:id]
|
28
|
-
end
|
29
|
-
|
30
|
-
def created_date
|
31
|
-
created_datetime.to_date
|
32
|
-
end
|
33
|
-
|
34
|
-
def created_datetime
|
35
|
-
DateTime.parse(page["created_time"])
|
36
|
-
end
|
37
|
-
|
38
|
-
def updated_date
|
39
|
-
updated_datetime.to_date
|
40
|
-
end
|
41
|
-
|
42
|
-
def updated_datetime
|
43
|
-
DateTime.parse(page["last_edited_time"])
|
44
|
-
end
|
45
|
-
|
46
|
-
def url
|
47
|
-
page[:url]
|
48
|
-
end
|
49
|
-
|
50
|
-
def custom_props
|
51
|
-
@custom_props ||= page.properties.each_with_object({}) do |prop, memo|
|
52
|
-
name = prop.first
|
53
|
-
value = prop.last # Notion::Messages::Message
|
54
|
-
type = value.type
|
55
|
-
|
56
|
-
next memo unless CustomProperty.respond_to?(type.to_sym)
|
57
|
-
|
58
|
-
memo[name.parameterize.underscore] = CustomProperty.send(type, value)
|
59
|
-
end.reject { |_k, v| v.presence.nil? }
|
60
|
-
end
|
61
|
-
|
62
|
-
def default_props
|
63
|
-
@default_props ||= {
|
64
|
-
:id => id,
|
65
|
-
:title => title,
|
66
|
-
:date => created_datetime,
|
67
|
-
:cover => cover,
|
68
|
-
:icon => icon,
|
69
|
-
:updated_date => updated_datetime,
|
70
|
-
}
|
71
|
-
end
|
72
|
-
|
73
|
-
class CustomProperty
|
74
|
-
class << self
|
75
|
-
def multi_select(prop)
|
76
|
-
multi_select = prop.multi_select.map(&:name).join(", ")
|
77
|
-
"[#{multi_select}]"
|
78
|
-
end
|
79
|
-
|
80
|
-
def select(prop)
|
81
|
-
prop["select"].name
|
82
|
-
end
|
83
|
-
|
84
|
-
def people(prop)
|
85
|
-
people = prop.people.map(&:name).join(", ")
|
86
|
-
"[#{people}]"
|
87
|
-
end
|
88
|
-
|
89
|
-
def files(prop)
|
90
|
-
files = prop.files.map { |f| f.file.url }.join(", ")
|
91
|
-
"[#{files}]"
|
92
|
-
end
|
93
|
-
|
94
|
-
def phone_number(prop)
|
95
|
-
prop.phone_number
|
96
|
-
end
|
97
|
-
|
98
|
-
def number(prop)
|
99
|
-
prop.number
|
100
|
-
end
|
101
|
-
|
102
|
-
def email(prop)
|
103
|
-
prop.email
|
104
|
-
end
|
105
|
-
|
106
|
-
def checkbox(prop)
|
107
|
-
prop.checkbox.to_s
|
108
|
-
end
|
109
|
-
|
110
|
-
# date type properties not supported:
|
111
|
-
# - end
|
112
|
-
# - time_zone
|
113
|
-
def date(prop)
|
114
|
-
prop.date.start
|
115
|
-
end
|
116
|
-
|
117
|
-
def url(prop)
|
118
|
-
prop.url
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|