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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db8a62e0d2b12f5cedd1f405e289e95a974a22a80e8c4ffd9e0798a75806773a
4
- data.tar.gz: 4668f71e64ff3604223b664a251b22931ce23d889c535b06e39f735891252074
3
+ metadata.gz: f85b870a3e8c0aa6ea64575b8ef8541f61183fa25ced6f41570384057a3a36dd
4
+ data.tar.gz: c66f6d831e8352f029fc1f81608f751aac1ed2b5959b6c2ee19f861eafcdb6f0
5
5
  SHA512:
6
- metadata.gz: ae19056b6cd4692b327d37803bf2c4a7afda07f6736cf2af660c12908694249a34c5e813191843d6ee2aa230f211a4044fbdca1fb203a827f6629aa3707e9e5c
7
- data.tar.gz: a7dd6dea825e2124032ec6900638a913fcc4e05de009798e24b365aa19c41f80fd399316bc6b9f811ea4c8a96e659d9cab11371dff60650752a7bd3aff847df8
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: b91d5...
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
- `fetch_on_watch` when set to `true` it allows fetching notion pages on each rebuild. By default is off, pages are only retrieved in the first build.
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
- And that's all. Each page in the notion database will be included in the selected collection.
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
- ## Notion properties
81
+ ### Watch
63
82
 
64
- Below, page notion default properties are set in each page frontmatter.
83
+ By default, databases are only requested during the first build. Subsequent builds use the results from the cache.
65
84
 
66
- Default properties include `title`, created_time`, `last_edited_time`, `icon` and `cover.
85
+ Set `fetch_on_watch` to true to allow request on each rebuild.
67
86
 
68
- ```
69
- ---
70
- id: b2998...
71
- title: A title
72
- cover: https://img.bank.sh/an_image.jpg
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
- Any property provided in the frontmatter config that matches a default property will be overwritten by the default value.
94
+ And that's all. Each page in the notion database will be included in the selected collection.
79
95
 
80
- ### Custom properties
96
+ ## Notion properties
81
97
 
82
- In addition to default properties, custom properties are also supported.
98
+ Below, default properties per notion page are set for each document front matter.
83
99
 
84
- Custom properties are appended to page frontmatter by default. Every property name is snake-cased.
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: b2998...
90
- title: A 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: \U0001F4A5
94
- tags: tag1, tag2, tag3
95
- multiple_options: option1, option2
108
+ icon: 💥
109
+ archived: false
96
110
  ---
97
111
  ```
98
112
 
99
- The supported properties are:
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
- Check notion documentation about [property values](https://developers.notion.com/reference/property-value-object#all-property-values).
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? || docs.empty?
12
+ if fetch_on_watch? || collections.empty?
13
13
  read_notion_database
14
14
  else
15
- collection.docs = docs
15
+ collections.each_pair { |key, val| @site.collections[key] = val }
16
16
  end
17
17
  end
18
18
 
19
- def read_notion_database
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 make_frontmatter
48
- data = Jekyll::Utils.deep_merge_hashes(config_frontmatter, page_frontmatter)
49
- frontmatter = data.to_a.map { |k, v| "#{k}: #{v}" }.join("\n")
50
- <<~CONTENT
51
- ---
52
- #{frontmatter}
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 collection_name
75
- config.dig("database", "collection") || "posts"
30
+ def databases
31
+ config["databases"] || [config["database"]]
76
32
  end
77
33
 
78
- def collection
79
- @site.collections[collection_name]
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"].present?
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
- NotionPage.new(:page => page, :layout => config["layout"])
14
+ NotionToMd::Page.new(:page => page)
15
15
  end
16
16
  end
17
17
 
18
- private
19
-
20
18
  def config
21
- @config["database"]
19
+ @config || {}
22
20
  end
23
21
 
24
22
  def filter
25
- @config.dig("database", "filter")
23
+ config["filter"]
26
24
  end
27
25
 
28
26
  def sort
29
- @config.dig("database", "sort")
27
+ config["sort"]
30
28
  end
31
29
 
32
30
  def id
33
- @config.dig("database", "id")
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:",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllNotion
4
- VERSION = "0.1.6"
4
+ VERSION = "1.0.0"
5
5
  end
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.1.6
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-05 00:00:00.000000000 Z
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