jekyll-og-image 1.3.0 → 1.5.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: 3d4faf0a2f12cf99798b8fb4fc56586ea659c37feceb3b34a7aac677fac0d43e
4
- data.tar.gz: 6e7acd8ca461e1dc366255b3f01144fc3dca605eac70256ad1cc7fab135b3011
3
+ metadata.gz: 260918d98e574361037584e4d0d4097dd41fdcd3526386d3abfde00e2dc4b0f6
4
+ data.tar.gz: e0c75eec8ddb3f3911aac2ef2b45687ecc1bb036057ed183802570a82f1a4922
5
5
  SHA512:
6
- metadata.gz: aeea9d6fba76f7502a090f7d35dc2f062be6b1f7c5656f8d76719eeca715776fd818bd2f88faecd07b2d709bfbb3e0efbefeaac5c5c8f81f2b50af41bbc064a9
7
- data.tar.gz: c602ea3d92aca6b20ef950c1300c4b28aecdc180a1076e12b1bcc9d7a5f7eb848511085c868b3af18385b432e6f1c7f44c1921ea85823400eb734ab1356d7d79
6
+ metadata.gz: 16f6da984ff3821513fdfd51eb9beb06e45bfb76c4530464ebc2f7d9164985a4583ec894258580ea125aed96b9ea489acc55332adc920cfda64e7f9f4c7ec3ee
7
+ data.tar.gz: eb147ebfeb11d50a80370ced4b82b33c1b33730c6b087c3eddc2871b6aed570dac8014cd01f687711b4f316cdf51bb9cf37cbb8eb82b58e048bafa8f3a21bcac
data/README.md CHANGED
@@ -11,7 +11,7 @@ A Jekyll plugin to automatically generate open graph images for posts.
11
11
  Add this line to your site's Gemfile:
12
12
 
13
13
  ```ruby
14
- gem 'jekyll-feed'
14
+ gem 'jekyll-og-image'
15
15
  ```
16
16
 
17
17
  And then add this line to your site's `_config.yml`:
@@ -26,12 +26,53 @@ plugins:
26
26
 
27
27
  Jekyll OG Image works together with [jekyll-seo-tag](https://github.com/jekyll/jekyll-seo-tag) plugin. It automatically generates open graph images for posts and inserts them into the posts metadata.
28
28
 
29
+ ## Configuration
30
+
31
+ The plugin can be configured in the `_config.yml` file or in the post's front matter.
32
+
33
+ The following configuration options are available:
34
+
35
+ * `collections` - An array specifying which types of collections to generate images for. Supports `"posts"`, `"pages"`, and the names of any custom collections. Default: `["posts"]`
36
+
37
+ * `output_dir` – The directory where the generated images will be saved. Images will be placed in subdirectories named after their collection type (e.g., `assets/images/og/posts`, `assets/images/og/pages`). Default: `assets/images/og`
38
+
39
+ * `force` – If set to `true`, the plugin will generate an image for every document, even if the document already has an image. Default: `false`
40
+ * `verbose` – If set to `true`, the plugin will output additional information about the image generation process. Default: `false`
41
+
42
+ * `skip_drafts` – If set to `true`, the plugin will skip post drafts when generating images. Default: `true`
43
+
44
+ * `canvas` – The canvas configuration options:
45
+ * `background_color` – The background color of the canvas. Default: `#FFFFFF`
46
+ * `background_image` – The background image of the canvas. Default: `nil`
47
+
48
+ * `header` – The header configuration options:
49
+ * `font_family` – The font family of the header text. Default: `Helvetica, Bold`
50
+ * `color` – The color of the header text. Default: `#2f313d`
51
+
52
+ * `content` – The content configuration options:
53
+ * `font_family` – The font family of the content text. Default: `Helvetica, Regular`
54
+ * `color` – The color of the content text. Default: `#535358`
55
+
56
+ * `border_bottom` – The border bottom configuration options:
57
+ * `width` – The width of the border bottom. Default: `20`
58
+ * `fill` – The array of colors to fill the border bottom. Default: `["#000000"]`
59
+
60
+ * `domain` – The domain name to use in the image. Default: `nil`
61
+
62
+ * `image` – Path to the image to use as the logo. Default: `nil`
63
+
29
64
  ## Examples
30
65
 
66
+ Configuration can be defined on the site level or on the post level.
67
+
68
+ For a side wide level configuration, edit your `_config.yml`, for a post level configuration, edit the post's front matter.
69
+
31
70
  ### Single Color
32
71
 
33
72
  ```yaml
73
+ # _config.yml
34
74
  og_image:
75
+ collections: ["posts", "pages"]
35
76
  output_dir: "assets/images/og"
36
77
  domain: "igor.works"
37
78
  border_bottom:
@@ -45,6 +86,7 @@ og_image:
45
86
  ### Multiple Colors
46
87
 
47
88
  ```yaml
89
+ # _config.yml
48
90
  og_image:
49
91
  output_dir: "assets/images/og"
50
92
  image: "/assets/images/igor.jpeg"
@@ -64,6 +106,7 @@ og_image:
64
106
  ### Background Color and Text Color
65
107
 
66
108
  ```yaml
109
+ # _config.yml
67
110
  og_image:
68
111
  output_dir: "/assets/og"
69
112
  image: "/assets/images/igor.jpeg"
@@ -90,11 +133,10 @@ og_image:
90
133
  ### Background Image
91
134
 
92
135
  ```yaml
136
+ # _config.yml
93
137
  og_image:
94
138
  output_dir: "/assets/og"
95
139
  image: "/assets/images/igor.jpeg"
96
- canvas:
97
- background_image: "/assets/images/bc_3.jpg"
98
140
  header:
99
141
  font_family: "Roboto, Bold"
100
142
  color: "#333333"
@@ -103,6 +145,18 @@ og_image:
103
145
  color: "#333333"
104
146
  force: false
105
147
  domain: "igor.works"
148
+
149
+ # _posts/2024-02-15-traefik-tunning-for-rails-applications-part-1.md
150
+ ---
151
+ title: Traefik Tuning for Rails Applications (part 1)
152
+ layout: post
153
+ tags:
154
+ - Rails
155
+ - Traefik
156
+ - Kamal
157
+ og_image:
158
+ canvas:
159
+ background_image: "/assets/images/bc_3.jpg"
106
160
  ```
107
161
 
108
162
  ![Example 4](examples/4.png)
@@ -118,4 +172,4 @@ og_image:
118
172
 
119
173
  ## License
120
174
 
121
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
175
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -49,16 +49,24 @@ class JekyllOgImage::Configuration
49
49
  to_h == other.to_h
50
50
  end
51
51
 
52
+ def collections
53
+ @raw_config["collections"] || [ "posts" ]
54
+ end
55
+
52
56
  def output_dir
53
57
  @raw_config["output_dir"] || "assets/images/og"
54
58
  end
55
59
 
56
60
  def force?
57
- @raw_config["force"] || false
61
+ @raw_config["force"].nil? ? false : @raw_config["force"]
58
62
  end
59
63
 
60
64
  def verbose?
61
- @raw_config["verbose"] || false
65
+ @raw_config["verbose"].nil? ? false : @raw_config["verbose"]
66
+ end
67
+
68
+ def skip_drafts?
69
+ @raw_config["skip_drafts"].nil? ? true : @raw_config["skip_drafts"]
62
70
  end
63
71
 
64
72
  def canvas
@@ -4,48 +4,93 @@ class JekyllOgImage::Generator < Jekyll::Generator
4
4
  safe true
5
5
 
6
6
  def generate(site)
7
- base_path = File.join(JekyllOgImage.config.output_dir, "posts")
7
+ config = JekyllOgImage.config
8
8
 
9
- FileUtils.mkdir_p File.join(site.config["source"], base_path)
9
+ config.collections.each do |type|
10
+ process_collection(site, type, config)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def process_collection(site, type, config)
17
+ Jekyll.logger.info "Jekyll Og Image:", "Processing type: #{type}" if config.verbose?
10
18
 
11
- site.posts.docs.each do |post|
12
- path = File.join(site.config["source"], base_path, "#{post.data['slug']}.png")
19
+ items = get_items_for_collection(site, type)
20
+ return if items.empty?
13
21
 
14
- if !File.exist?(path) || JekyllOgImage.config.force?
15
- Jekyll.logger.info "Jekyll Og Image:", "Generating image #{path}" if JekyllOgImage.config.verbose?
16
- generate_image_for_post(site, post, path)
22
+ base_output_dir = File.join(config.output_dir, type)
23
+ absolute_output_dir = File.join(site.config["source"], base_output_dir)
24
+ FileUtils.mkdir_p absolute_output_dir
25
+
26
+ items.each do |item|
27
+ if item.respond_to?(:draft?) && item.draft? && config.skip_drafts?
28
+ Jekyll.logger.info "Jekyll Og Image:", "Skipping draft: #{item.data['title']}" if config.verbose?
29
+ next
30
+ end
31
+
32
+ fallback_basename = if item.respond_to?(:basename_without_ext)
33
+ item.basename_without_ext
34
+ # rubocop:disable Layout/ElseAlignment # Disabled due to RuboCop error in v3.3.0
35
+ else
36
+ # rubocop:enable Layout/ElseAlignment
37
+ File.basename(item.name, File.extname(item.name))
38
+ end
39
+ slug = item.data["slug"] || Jekyll::Utils.slugify(item.data["title"] || fallback_basename)
40
+ image_filename = "#{slug}.png"
41
+ absolute_image_path = File.join(absolute_output_dir, image_filename)
42
+ relative_image_path = File.join("/", base_output_dir, image_filename) # Use leading slash for URL
43
+
44
+ if !File.exist?(absolute_image_path) || config.force?
45
+ Jekyll.logger.info "Jekyll Og Image:", "Generating image #{absolute_image_path}" if config.verbose?
46
+ generate_image_for_document(site, item, absolute_image_path, config)
17
47
  else
18
- Jekyll.logger.info "Jekyll Og Image:", "Skipping image generation #{path} as it already exists." if JekyllOgImage.config.verbose?
48
+ Jekyll.logger.info "Jekyll Og Image:", "Skipping image generation for #{relative_image_path} as it already exists." if config.verbose?
19
49
  end
20
50
 
21
- post.data["image"] ||= {
22
- "path" => File.join(base_path, "#{post.data['slug']}.png"),
51
+ item.data["image"] ||= {
52
+ "path" => relative_image_path,
23
53
  "width" => 1200,
24
54
  "height" => 600,
25
- "alt" => post.data["title"]
55
+ "alt" => item.data["title"]
26
56
  }
27
57
  end
28
58
  end
29
59
 
30
- private
60
+ def get_items_for_collection(site, type)
61
+ case type
62
+ when "posts"
63
+ site.posts.docs
64
+ when "pages"
65
+ site.pages.reject { |page| !page.html? }
66
+ else
67
+ if site.collections.key?(type)
68
+ site.collections[type].docs
69
+ else
70
+ Jekyll.logger.warn "Jekyll Og Image:", "Unknown collection type \"#{type}\" configured. Skipping."
71
+ []
72
+ end
73
+ end
74
+ end
31
75
 
32
- def generate_image_for_post(site, post, path)
33
- config = JekyllOgImage.config.merge!(post.data["og_image"])
76
+ def generate_image_for_document(site, item, path, base_config)
77
+ config = base_config.merge!(item.data["og_image"] || {})
34
78
 
35
79
  canvas = generate_canvas(site, config)
36
80
  canvas = add_border_bottom(canvas, config) if config.border_bottom
37
81
  canvas = add_image(canvas, File.read(File.join(site.config["source"], config.image))) if config.image
38
- canvas = add_header(canvas, post, config)
39
- canvas = add_publish_date(canvas, post, config)
40
- canvas = add_tags(canvas, post, config) if post.data["tags"].any?
41
- canvas = add_domain(canvas, post, config) if config.domain
82
+ canvas = add_header(canvas, item, config)
83
+ canvas = add_publish_date(canvas, item, config)
84
+ canvas = add_tags(canvas, item, config) if item.data["tags"]&.any?
85
+ canvas = add_domain(canvas, item, config) if config.domain
42
86
 
43
87
  canvas.save(path)
44
88
  end
45
89
 
46
90
  def generate_canvas(site, config)
47
91
  background_image = if config.canvas.background_image
48
- File.read(File.join(site.config["source"], config.canvas.background_image))
92
+ bg_path = File.join(site.config["source"], config.canvas.background_image.gsub(/^\//, ""))
93
+ File.exist?(bg_path) ? File.read(bg_path) : nil
49
94
  end
50
95
 
51
96
  JekyllOgImage::Element::Canvas.new(1200, 600,
@@ -70,8 +115,9 @@ class JekyllOgImage::Generator < Jekyll::Generator
70
115
  ) { |_canvas, _text| { x: 80, y: 100 } }
71
116
  end
72
117
 
73
- def add_header(canvas, post, config)
74
- canvas.text(post.data["title"],
118
+ def add_header(canvas, item, config)
119
+ title = item.data["title"] || "Untitled"
120
+ canvas.text(title,
75
121
  width: config.image ? 870 : 1040,
76
122
  color: config.header.color,
77
123
  dpi: 400,
@@ -79,19 +125,25 @@ class JekyllOgImage::Generator < Jekyll::Generator
79
125
  ) { |_canvas, _text| { x: 80, y: 100 } }
80
126
  end
81
127
 
82
- def add_publish_date(canvas, post, config)
83
- date = post.date.strftime("%B %d, %Y")
128
+ def add_publish_date(canvas, item, config)
129
+ return canvas unless item.respond_to?(:date) && item.date
130
+
131
+ date = item.date.strftime("%B %d, %Y")
132
+ y_pos = (item.data["tags"]&.any? ? config.margin_bottom + 50 : config.margin_bottom)
84
133
 
85
134
  canvas.text(date,
86
135
  gravity: :sw,
87
136
  color: config.content.color,
88
137
  dpi: 150,
89
138
  font: config.content.font_family
90
- ) { |_canvas, _text| { x: 80, y: post.data["tags"].any? ? config.margin_bottom + 50 : config.margin_bottom } }
139
+ ) { |_canvas, _text| { x: 80, y: y_pos } }
91
140
  end
92
141
 
93
- def add_tags(canvas, post, config)
94
- tags = post.data["tags"].map { |tag| "##{tag}" }.join(" ")
142
+ def add_tags(canvas, item, config)
143
+ tags_list = item.data["tags"]
144
+ return canvas unless tags_list.is_a?(Array) && tags_list.any?
145
+
146
+ tags = tags_list.map { |tag| "##{tag}" }.join(" ")
95
147
 
96
148
  canvas.text(tags,
97
149
  gravity: :sw,
@@ -101,17 +153,20 @@ class JekyllOgImage::Generator < Jekyll::Generator
101
153
  ) { |_canvas, _text| { x: 80, y: config.margin_bottom } }
102
154
  end
103
155
 
104
- def add_domain(canvas, post, config)
156
+ def add_domain(canvas, item, config)
157
+ y_pos = if item.data["tags"]&.any?
158
+ config.margin_bottom + 50
159
+ # rubocop:disable Layout/ElseAlignment # Disabled due to RuboCop error in v3.3.0
160
+ else
161
+ # rubocop:enable Layout/ElseAlignment
162
+ config.margin_bottom
163
+ end
164
+
105
165
  canvas.text(config.domain,
106
166
  gravity: :se,
107
167
  color: config.content.color,
108
168
  dpi: 150,
109
169
  font: config.content.font_family
110
- ) do |_canvas, _text|
111
- {
112
- x: 80,
113
- y: post.data["tags"].any? ? config.margin_bottom + 50 : config.margin_bottom
114
- }
115
- end
170
+ ) { |_canvas, _text| { x: 80, y: y_pos } }
116
171
  end
117
172
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllOgImage
4
- VERSION = "1.3.0"
4
+ VERSION = "1.5.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-og-image
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Alexandrov
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-02-18 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: jekyll-seo-tag
@@ -72,7 +71,20 @@ dependencies:
72
71
  - - "<"
73
72
  - !ruby/object:Gem::Version
74
73
  version: '5.0'
75
- description:
74
+ - !ruby/object:Gem::Dependency
75
+ name: csv
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ type: :development
82
+ prerelease: false
83
+ version_requirements: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
76
88
  email:
77
89
  - igor.alexandrov@gmail.com
78
90
  executables: []
@@ -80,7 +92,6 @@ extensions: []
80
92
  extra_rdoc_files: []
81
93
  files:
82
94
  - ".rspec"
83
- - ".rspec_status"
84
95
  - ".rubocop.yml"
85
96
  - CODE_OF_CONDUCT.md
86
97
  - LICENSE.txt
@@ -105,7 +116,6 @@ licenses:
105
116
  - MIT
106
117
  metadata:
107
118
  homepage_uri: https://github.com/igor-alexandrov/jekyll-og-image
108
- post_install_message:
109
119
  rdoc_options: []
110
120
  require_paths:
111
121
  - lib
@@ -120,8 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
130
  - !ruby/object:Gem::Version
121
131
  version: '0'
122
132
  requirements: []
123
- rubygems_version: 3.5.3
124
- signing_key:
133
+ rubygems_version: 3.6.7
125
134
  specification_version: 4
126
135
  summary: Jekyll plugin to generate GitHub-style open graph images
127
136
  test_files: []
data/.rspec_status DELETED
@@ -1,27 +0,0 @@
1
- example_id | status | run_time |
2
- ------------------------------------------------------- | ------ | --------------- |
3
- ./spec/jekyll_og_image/configuration_spec.rb[1:1:1] | passed | 0.00097 seconds |
4
- ./spec/jekyll_og_image/configuration_spec.rb[1:1:2:1] | passed | 0.00005 seconds |
5
- ./spec/jekyll_og_image/configuration_spec.rb[1:2:1:1] | passed | 0.00005 seconds |
6
- ./spec/jekyll_og_image/configuration_spec.rb[1:2:2:1] | passed | 0.00003 seconds |
7
- ./spec/jekyll_og_image/configuration_spec.rb[1:3:1:1] | passed | 0.00026 seconds |
8
- ./spec/jekyll_og_image/configuration_spec.rb[1:3:2:1] | passed | 0.00003 seconds |
9
- ./spec/jekyll_og_image/configuration_spec.rb[1:4:1:1] | passed | 0.00003 seconds |
10
- ./spec/jekyll_og_image/configuration_spec.rb[1:4:2:1] | passed | 0.00003 seconds |
11
- ./spec/jekyll_og_image/configuration_spec.rb[1:5:1:1] | passed | 0.00039 seconds |
12
- ./spec/jekyll_og_image/configuration_spec.rb[1:5:2:1] | passed | 0.00004 seconds |
13
- ./spec/jekyll_og_image/configuration_spec.rb[1:6:1:1] | passed | 0.00004 seconds |
14
- ./spec/jekyll_og_image/configuration_spec.rb[1:6:2:1] | passed | 0.00003 seconds |
15
- ./spec/jekyll_og_image/configuration_spec.rb[1:7:1:1] | passed | 0.00004 seconds |
16
- ./spec/jekyll_og_image/configuration_spec.rb[1:7:1:2:1] | passed | 0.00005 seconds |
17
- ./spec/jekyll_og_image/configuration_spec.rb[1:8:1:1] | passed | 0.00004 seconds |
18
- ./spec/jekyll_og_image/configuration_spec.rb[1:8:2:1] | passed | 0.00006 seconds |
19
- ./spec/jekyll_og_image/configuration_spec.rb[1:9:1:1] | passed | 0.00004 seconds |
20
- ./spec/jekyll_og_image/configuration_spec.rb[1:9:2:1] | passed | 0.00003 seconds |
21
- ./spec/jekyll_og_image/configuration_spec.rb[1:10:1:1] | passed | 0.00003 seconds |
22
- ./spec/jekyll_og_image/configuration_spec.rb[1:10:2:1] | passed | 0.00003 seconds |
23
- ./spec/jekyll_og_image/configuration_spec.rb[1:11:1:1] | passed | 0.00003 seconds |
24
- ./spec/jekyll_og_image/configuration_spec.rb[1:11:2:1] | passed | 0.00003 seconds |
25
- ./spec/jekyll_og_image/version_spec.rb[1:1] | passed | 0.00003 seconds |
26
- ./spec/jekyll_og_image_spec.rb[1:1] | passed | 0.24499 seconds |
27
- ./spec/jekyll_og_image_spec.rb[1:2] | passed | 0.04171 seconds |