jekyll-image-gallery 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 849fa5460b1ac2e8044abf0d13eae3b2982038c0c753f511e0ec17179fcdcbf0
4
+ data.tar.gz: 99b257f6d9aa547a0a117f20bb188fcdc29a0c2ee2635e170844e679d2add3b2
5
+ SHA512:
6
+ metadata.gz: 132565ef429e45232019f138c4a45d383c9b27be8049e5f76f6dd48082550528627e2a98836799ba1888147d3ba1c3e22e8fae8817b1b037ce9324363d0da88c
7
+ data.tar.gz: f1ec6ddc49b2ed9336e12470e85a9856a07be917482fa6bc55681586b93301ac8b46638c27475f4f5f58d8c8a27bc0f93fa7b1c215333d3390070a8b82473d3d
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ Layout/LineLength:
2
+ Max: 120
3
+
4
+ Style/TrailingCommaInArrayLiteral:
5
+ Description: Prefer always trailing comma on multiline literals. This makes diffs, and re-ordering nicer.
6
+ EnforcedStyleForMultiline: consistent_comma
7
+
8
+ Style/TrailingCommaInHashLiteral:
9
+ Description: Prefer always trailing comma on multiline literals. This makes diffs, and re-ordering nicer.
10
+ EnforcedStyleForMultiline: consistent_comma
11
+
12
+
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 1.0.1
2
+
3
+ Initial Release
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in jekyll-image-gallery.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 13.0'
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Jekyll Image Gallery
2
+ A image gallery generator for Jekyll. The differentiating feature from other gallery plugins is that it generates galleries
3
+ automatically grouped into years.
4
+
5
+ The feature list is pretty standard:
6
+ - Thumbnail generation
7
+ - Optional image compression
8
+ - Exif data stripping
9
+ - Automatic conversion of raw formats (e.g. [HEIC](https://en.wikipedia.org/wiki/High_Efficiency_Image_File_Format)) into browser supported formats
10
+
11
+ Example can be found at [photos.jacobessex.com](https://photos.jacobessex.com) \[[source](https://github.com/Yacoby/photos.jacobessex.com)\]
12
+
13
+ ### Alternatives
14
+
15
+ Also consider:
16
+ - [cheesy-gallery](https://github.com/DavidS/cheesy-gallery) - Allows more flexibility in structure
17
+ - [jekyll-gallery-generator](https://github.com/ggreer/jekyll-gallery-generator) - Similar to this plugin but without the year based grouping
18
+
19
+ ## Installation
20
+ See the [Jekyll guide on installing plugins](https://jekyllrb.com/docs/plugins/installation/) and install "jekyll-image-gallery"
21
+
22
+ Ensure you install the transitive dependency ImageMagick, as this is required by the [mini_magick](https://github.com/minimagick/minimagick) gem. On Mac this is as simple as
23
+ ```
24
+ $ brew install imagemagick
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ After installation, create a `_galleries` directory and within the `_galleries` directory, create sub-directories for each gallery. For example your directory structure could look like this:
30
+
31
+ ```
32
+ - _galleries/
33
+ --- 2022/
34
+ ----- 2022-05-23-first-gallery/
35
+ ------- first_image.jpg
36
+ ------- second_image.png
37
+ ----- 2022-09-01-second/
38
+ ------- awesome.jpg
39
+ ```
40
+
41
+ This will result in the generated galleries:
42
+ ```
43
+ - _site/
44
+ --- index.html (optional root index.html)
45
+ --- 2022/
46
+ ----- index.html
47
+ ----- 05/
48
+ ------- first-gallery.html
49
+ ------- first_image.jpg
50
+ ------- second_image.png
51
+ ------- [.. and thumbnails ..]
52
+ ----- 09/
53
+ ------- second.html
54
+ ------- awesome.jpg
55
+ ------- [.. and thumbnails ..]
56
+ ```
57
+
58
+ As you can see from the example, the directory structure you use doesn't matter, each sub directory containing images will be considered its own gallery (even subdirectories nested in an existing gallery) and the structure will be based on the year and the month of each gallery.
59
+
60
+ The year and month of the gallery is inferred from the first of
61
+ - The \_metadata file (see the "Per gallery configuration" section), if it exists and the key is set
62
+ - The earliest date contained in image Exif data if the images have Exif data
63
+ - The gallery directory name (if suffixed with an date)
64
+
65
+ ### Layouts
66
+
67
+ This plugin generates pages which use two layouts
68
+ - `gallery_index` - an index of galleries
69
+ - `gallery_page` - the gallery itself
70
+
71
+ These layouts are not included in the plugin and so you will need to implement them yourself. An example can be found [here](https://github.com/Yacoby/photos.jacobessex.com/tree/master/_layouts)
72
+
73
+ ### Highlighted image
74
+
75
+ The gallery index page displays a thumbnail for the image gallery. By default this is the first image but a specific image
76
+ can be chosen by prefixing the image name with `hl_` or suffixing it with `_hl`. e.g. `myimage_hl.png`.
77
+
78
+ ### Plugin Configuration
79
+
80
+ Global gallery configuration uses the standard Jekyll configuration (default of `_config.yaml`)
81
+
82
+ ```yaml
83
+ gallery:
84
+ generate_root_index: true # Generate a index gallery at the root of the gallery (default false)
85
+ path: 'some/path' # Slash seperated output path of the gallery, set to an empty string to generate a gallery in the root of the site
86
+ # (default is 'gallery')
87
+ title_prefix: 'Photos' # The prefix of the title variable (default is 'Photos')
88
+ title_seperator: '|' # The seperator between the title components (prefix, year and gallery title). (default is '|')
89
+
90
+ thumbnail_size: # Size of generated thumbnails
91
+ x: 512
92
+ y: 512
93
+
94
+ image_size: # The maximum size of images, remove the configuration to not compress images (default is no compression)
95
+ x: 2048
96
+ y: 2048
97
+ ```
98
+
99
+ ### Per gallery configuration
100
+
101
+ Gallery configuration can be overridden by adding a `_metadata.toml` or `_metadata.json` file to the gallery directory.
102
+
103
+ ```toml
104
+ name = "Gallery Name"
105
+ datetime = "2001-02-03T04:05:06+07:00"
106
+ ```
107
+
108
+ The datetime field is parsed using the [Datetime::parse method](https://ruby-doc.org/stdlib-2.6.1/libdoc/date/rdoc/DateTime.html)
109
+
110
+
111
+ ## Development
112
+
113
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
114
+
115
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
116
+
117
+ ## License
118
+
119
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ task default: %i[]
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/gallery/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'jekyll-image-gallery'
7
+ spec.version = ImageGallery::VERSION
8
+ spec.authors = ['Jacob Essex']
9
+ spec.email = ['ruby_gems@JacobEssex.com']
10
+
11
+ spec.summary = 'Gallery generator for Jekyll'
12
+ spec.homepage = 'https://github.com/Yacoby/jekyll-image-gallery'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = '>= 2.6.0'
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = spec.homepage
18
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
+ end
26
+ end
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_dependency 'jekyll', '~> 4.0'
32
+ spec.add_dependency 'mini_magick', '~> 4.1'
33
+ spec.add_dependency 'toml', '~> 0.3.0'
34
+
35
+ spec.add_development_dependency 'rubocop'
36
+ end
@@ -0,0 +1,386 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require 'mini_magick'
5
+ require 'pathname'
6
+ require 'toml'
7
+
8
+ module ImageGallery
9
+ class GalleryGenerator < Jekyll::Generator
10
+ safe true
11
+
12
+ IGNORED_FILES = ['.ds_store', 'thumbs.db'].freeze
13
+
14
+ GalleryImageModel = Struct.new(:path, :thumbnail_path, :creation_datetime, :original_path) do
15
+ def to_liquid
16
+ to_h.transform_keys(&:to_s)
17
+ end
18
+ end
19
+
20
+ GalleryModel = Struct.new(:id, :name, :images, :highlight_image, :datetime) do
21
+ def to_liquid
22
+ to_h.map do |k, v|
23
+ if k == :datetime
24
+ [k.to_s, { 'year' => v.year, 'month' => v.month, 'day' => v.day }]
25
+ elsif v.class.method_defined?(:to_liquid)
26
+ [k.to_s, v.to_liquid]
27
+ else
28
+ [k.to_s, v]
29
+ end
30
+ end.to_h
31
+ end
32
+ end
33
+
34
+ def generate(site)
35
+ galleries_dir = File.join(site.source, '_galleries')
36
+ unless File.directory?(galleries_dir)
37
+ ImageGallery._log(:warn, "No directory found at #{galleries_dir}, skipping gallery generation")
38
+ return
39
+ end
40
+
41
+ all_galleries = Dir.chdir(galleries_dir) do
42
+ Dir.glob('**/*/')
43
+ end
44
+
45
+ galleries = []
46
+ all_galleries.each do |gallery_path|
47
+ gallery_path_abs = File.join(site.source, '_galleries', gallery_path)
48
+
49
+ source_images = Dir.children(gallery_path_abs)
50
+ .select { |file_name| File.file?(File.join(gallery_path_abs, file_name)) }
51
+ .reject { |file_name| File.basename(file_name, '.*') == '_metadata' }
52
+ .reject { |file_name| IGNORED_FILES.include?(file_name.downcase) }
53
+
54
+ next if source_images.empty?
55
+
56
+ gallery_path_rel = File.join('_galleries', gallery_path)
57
+
58
+ gallery_images_and_times = source_images.map do |src_image_file_name|
59
+ src_image_file_path = File.join(gallery_path_rel, src_image_file_name)
60
+
61
+ # TODO: this assumes the image at a path doesn't change
62
+ exif = exif_cache.getset(src_image_file_path) do
63
+ ImageGallery._log_once(:info, 'Loading EXIF data. This may take some time on the first run')
64
+ MiniMagick::Image.open(src_image_file_path).exif
65
+ end
66
+ image_time = DateTime.strptime(exif['DateTimeOriginal'], '%Y:%m:%d %H:%M:%S') if exif['DateTimeOriginal']
67
+
68
+ {
69
+ path: src_image_file_path,
70
+ creation_datetime: image_time,
71
+ }
72
+ end
73
+
74
+ gallery = construct_gallery(gallery_path_abs, gallery_images_and_times)
75
+ gallery.images = copy_images(site, gallery, gallery_path_rel, gallery_images_and_times).sort_by do |gi|
76
+ if gi.creation_datetime.nil?
77
+ 1.0 / 0.0
78
+ else
79
+ gi.creation_datetime
80
+ end
81
+ end.reverse
82
+
83
+ gallery.highlight_image = gallery.images.detect do |gi|
84
+ basename = File.basename(gi.original_path, '.*')
85
+ basename.start_with?('hl_') || basename.end_with?('_hl')
86
+ end || gallery.images[0]
87
+
88
+ galleries << gallery
89
+ site.pages << GalleryPage.new(site, gallery)
90
+ end
91
+
92
+ galleries = galleries.sort_by(&:datetime)
93
+ galleries.reverse!
94
+
95
+ galleries.group_by { |gallery| gallery.datetime.year }.each do |year, _galleries|
96
+ site.pages << GalleryIndexPage.new(site, year)
97
+ end
98
+
99
+ site.data['galleries'] = galleries
100
+ site.data['gallery_years'] = galleries.group_by { |gallery| gallery.datetime.year }.keys.sort
101
+ site.data['max_gallery_year'] = site.data['gallery_years'].max
102
+
103
+ if ImageGallery._config_with_defaults(site)['generate_root_index']
104
+ site.pages << GalleryIndexPage.new(
105
+ site,
106
+ site.data['max_gallery_year'],
107
+ override_dir: File.join(*ImageGallery.gallery_path_array(site))
108
+ )
109
+ end
110
+ end
111
+
112
+ def construct_gallery(gallery_path_abs, gallery_images)
113
+ gallery = {}
114
+
115
+ _ancestors, gallery_id = Pathname.new(gallery_path_abs).split
116
+ gallery_id = gallery_id.to_s
117
+
118
+ gallery_regex = /^(\d{4})[-_]?(\d{2})[-_]?(\d{2})[-_]?(.*)$/
119
+ gallery_dir_match = gallery_id.match(gallery_regex)
120
+ if gallery_dir_match
121
+ gallery['id'] = gallery_dir_match[4]
122
+ gallery['name'] = gallery_dir_match[4].split(/[_-]+/).map(&:capitalize).join(' ')
123
+ gallery['datetime'] = DateTime.new(gallery_dir_match[1].to_i, gallery_dir_match[2].to_i, gallery_dir_match[3].to_i)
124
+ else
125
+ ImageGallery._log(:debug, "Gallery name #{gallery_id} doesn't match the expected regex #{gallery_regex}")
126
+ gallery['id'] = gallery_id
127
+ gallery['name'] = gallery_id.split(/[_-]+/).map(&:capitalize).join(' ')
128
+ end
129
+
130
+ earliest_image = gallery_images.reject { |gi| gi[:creation_datetime].nil? }.min { |gi| gi[:creation_datetime] }
131
+ gallery['datetime'] = earliest_image[:creation_datetime] if earliest_image
132
+
133
+ file_metadata = load_metadata_from_dir(gallery_path_abs)
134
+ gallery = gallery.merge(transform_metadata(file_metadata)) if file_metadata
135
+
136
+ if gallery['datetime'].nil?
137
+ raise "Gallery at #{gallery_path_abs} has no datetime specified - it needs to be in EXIF data, the gallery prefix or the _metadata.json file"
138
+ end
139
+
140
+ GalleryModel.new(*gallery.transform_keys(&:to_sym).values_at(*GalleryModel.members))
141
+ end
142
+
143
+ def load_metadata_from_dir(path)
144
+ ext_to_parsers = [
145
+ ['toml', ->(f) { TOML.load_file(f) }],
146
+ ['json', ->(f) { JSON.parse(File.new(f)) }],
147
+ ]
148
+
149
+ path_to_parsers = ext_to_parsers.map do |(ext, fn)|
150
+ full_path = File.join(path, "_metadata.#{ext}")
151
+ [full_path, fn]
152
+ end
153
+ first_existing_file = path_to_parsers.find do |(full_path, _fn)|
154
+ File.file?(full_path)
155
+ end
156
+
157
+ if first_existing_file
158
+ full_path, fn = first_existing_file
159
+ fn.call(full_path)
160
+ end
161
+ end
162
+
163
+ def transform_metadata(raw_data)
164
+ raw_data.map do |k, v|
165
+ if k == 'datetime'
166
+ [k, DateTime.parse(v)]
167
+ else
168
+ [k, v]
169
+ end
170
+ end.to_h
171
+ end
172
+
173
+ def copy_images(site, gallery, gallery_path_rel, gallery_images_and_times)
174
+ image_directory = File.join(*ImageGallery.gallery_path_array(site, gallery.datetime.year, gallery.datetime.month))
175
+
176
+ gallery_images_and_times.map do |img_and_time|
177
+ src_image_file_path = img_and_time[:path]
178
+ src_image_file_name = File.basename(src_image_file_path)
179
+ sha = Digest::SHA256.hexdigest(src_image_file_path)
180
+ image_file_name = "#{sha}#{File.extname(src_image_file_path)}"
181
+ thumb_file_name = "#{sha}_t#{File.extname(src_image_file_path)}"
182
+
183
+ config = ImageGallery._config_with_defaults(site)
184
+
185
+ image_file = CompressedStaticGalleryFile.new(site, site.source, gallery_path_rel, src_image_file_name, image_directory, image_file_name) do |i|
186
+ if config['image_size']
187
+ i.resize("#{config['image_size']['x']}x#{config['image_size']['y']}>")
188
+ ImageGallery._log(:info, "Processing image #{src_image_file_path} to extents #{config['image_size']}")
189
+ else
190
+ ImageGallery._log(:info, "Processing image #{src_image_file_path}")
191
+ end
192
+ end
193
+ thumb_file = CompressedStaticGalleryFile.new(site, site.source, gallery_path_rel, src_image_file_name, image_directory, thumb_file_name) do |i|
194
+ i.gravity('Center')
195
+ i.resize("#{config['thumbnail_size']['x']}x#{config['thumbnail_size']['y']}^")
196
+ i.extent("#{config['thumbnail_size']['x']}x#{config['thumbnail_size']['y']}")
197
+ ImageGallery._log(:info, "Processing image #{src_image_file_path} to #{config['thumbnail_size']}")
198
+ end
199
+
200
+ site.static_files.push(image_file).push(thumb_file)
201
+
202
+ GalleryImageModel.new(
203
+ File.join('/', image_file.relative_destination),
204
+ File.join('/', thumb_file.relative_destination),
205
+ img_and_time[:creation_datetime],
206
+ src_image_file_path
207
+ )
208
+ end
209
+ end
210
+
211
+ def exif_cache
212
+ @@exif_cache ||= Jekyll::Cache.new('jekyll-image-gallery::exif')
213
+ end
214
+ end
215
+
216
+ class GalleryPage < Jekyll::Page
217
+ def initialize(site, gallery)
218
+ @site = site
219
+ @base = site.source
220
+
221
+ year = gallery.datetime.year
222
+ month = gallery.datetime.month
223
+ @dir = File.join(*ImageGallery.gallery_path_array(site, year, month))
224
+
225
+ @basename = gallery.id
226
+ @ext = '.html'
227
+ @name = "#{@basename}#{@ext}"
228
+
229
+ config = ImageGallery._config_with_defaults(site)
230
+ @data = {
231
+ 'layout' => 'gallery_page',
232
+ 'gallery' => gallery,
233
+ 'year' => year,
234
+ 'title' => [config['title_prefix'], year, gallery.name].join(" #{config['title_seperator']} "),
235
+ }
236
+
237
+ data.default_proc = proc do |_, key|
238
+ site.frontmatter_defaults.find(relative_path, :galleries, key)
239
+ end
240
+ end
241
+ end
242
+
243
+ class GalleryIndexPage < Jekyll::Page
244
+ def initialize(site, year, override_dir: nil)
245
+ @site = site
246
+ @base = site.source
247
+ @dir = override_dir || File.join(*ImageGallery.gallery_path_array(site, year))
248
+
249
+ @basename = 'index'
250
+ @ext = '.html'
251
+ @name = "#{@basename}#{@ext}"
252
+
253
+ config = ImageGallery._config_with_defaults(site)
254
+ @data = {
255
+ 'layout' => 'gallery_index',
256
+ 'year' => year,
257
+ 'title' => [config['title_prefix'], year].join(" #{config['title_seperator']} "),
258
+ }
259
+
260
+ data.default_proc = proc do |_, key|
261
+ site.frontmatter_defaults.find(relative_path, :gallery_indexes, key)
262
+ end
263
+ end
264
+ end
265
+
266
+ class CompressedStaticGalleryFile < Jekyll::StaticFile
267
+ BROWSER_SUPPORTED_EXTENSIONS = ['.png', '.jpeg', '.jpg'].freeze
268
+ FALLBACK_FORMAT = 'png'.freeze
269
+
270
+ def initialize(site, base, source_path, source_name, dest_path, dest_name, &resize_fn)
271
+ super(site, base, source_path, source_name)
272
+ @dest_path = dest_path
273
+ @dest_name = dest_name
274
+ @resize_fn = resize_fn
275
+
276
+ # Apples HEIC format isn't supported by browsers. Using filename isn't an ideal heuristic, but it is probably good
277
+ # enough
278
+ @convert_format = false
279
+ unless BROWSER_SUPPORTED_EXTENSIONS.include?(File.extname(@dest_name).downcase)
280
+ @convert_format = true
281
+ @dest_name = "#{File.basename(@dest_name, '.*')}.#{FALLBACK_FORMAT}"
282
+ end
283
+ end
284
+
285
+ def destination(dest)
286
+ File.join(dest, @dest_path, @dest_name)
287
+ end
288
+
289
+ def relative_destination
290
+ File.join(@dest_path, @dest_name)
291
+ end
292
+
293
+ def write(dest)
294
+ dest_path = destination(dest)
295
+
296
+ return false if File.exist?(dest_path) && (File.stat(path).mtime.to_i == File.stat(dest_path).mtime.to_i)
297
+
298
+ FileUtils.mkdir_p(File.dirname(dest_path))
299
+ FileUtils.rm(dest_path) if File.exist?(dest_path)
300
+
301
+ image = MiniMagick::Image.open(path)
302
+ image.combine_options do |i|
303
+ i.auto_orient
304
+ i.strip
305
+ @resize_fn.call(i)
306
+ end
307
+ image.format FALLBACK_FORMAT if @convert_format
308
+ image.write(dest_path)
309
+
310
+ File.utime(File.atime(dest_path), mtime, dest_path)
311
+
312
+ true
313
+ end
314
+ end
315
+
316
+ def self._config_with_defaults(site)
317
+ defaults = {
318
+ 'path' => 'gallery',
319
+ 'generate_root_index' => false,
320
+ 'thumbnail_size' => {
321
+ 'x' => 512,
322
+ 'y' => 512,
323
+ },
324
+ "title_prefix" => 'Photos',
325
+ "title_seperator" => '|',
326
+ }
327
+
328
+ config = site.config
329
+ unless config
330
+ ImageGallery._log_once(:warn, 'No configuration (site.config) found for jekyll-image-gallery, defaults will be used')
331
+ return defaults
332
+ end
333
+
334
+ gallery_config = config['gallery']
335
+ unless gallery_config
336
+ ImageGallery._log_once(:warn, 'No configuration found for jekyll-image-gallery, defaults will be used')
337
+ return defaults
338
+ end
339
+
340
+ defaults.merge(gallery_config)
341
+ end
342
+
343
+ def self._log(level, message)
344
+ Jekyll.logger.public_send(level, "\tjekyll-image-gallery: #{message}")
345
+ end
346
+
347
+ def self._log_once(level, message)
348
+ @@seen_log_messages ||= {}
349
+ return if @@seen_log_messages.include?(message)
350
+
351
+ @@seen_log_messages[message] = true
352
+ ImageGallery._log(level, message)
353
+ end
354
+
355
+ def self.gallery_path_array(site, year = nil, month = nil)
356
+ config = ImageGallery._config_with_defaults(site)
357
+
358
+ gallery_path = []
359
+ gallery_path = config['path'].split('/') if config['path']
360
+
361
+ gallery_path.push(year.to_s) if year
362
+
363
+ if month
364
+ padded_month = format('%02d', month)
365
+ gallery_path.push(padded_month)
366
+ end
367
+
368
+ gallery_path
369
+ end
370
+
371
+ module Filters
372
+ def gallery_url(gallery)
373
+ site = @context.registers[:site]
374
+ creation_time = gallery['datetime']
375
+ gallery_path = ImageGallery.gallery_path_array(site, creation_time['year'], creation_time['month']).join('/')
376
+ "/#{gallery_path}/#{gallery['id']}.html"
377
+ end
378
+
379
+ def gallery_index_url(year)
380
+ site = @context.registers[:site]
381
+ "/#{ImageGallery.gallery_path_array(site, year).join('/')}/"
382
+ end
383
+ end
384
+ end
385
+
386
+ Liquid::Template.register_filter(ImageGallery::Filters)
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImageGallery
4
+ VERSION = '1.0.1'
5
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ImageGallery
4
+ end
5
+
6
+ require_relative 'gallery/gallery'
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-image-gallery
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jacob Essex
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-09-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mini_magick
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: toml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - ruby_gems@JacobEssex.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".rubocop.yml"
77
+ - CHANGELOG.md
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - jekyll-image-gallery.gemspec
83
+ - lib/gallery/gallery.rb
84
+ - lib/gallery/version.rb
85
+ - lib/jekyll-image-gallery.rb
86
+ homepage: https://github.com/Yacoby/jekyll-image-gallery
87
+ licenses:
88
+ - MIT
89
+ metadata:
90
+ homepage_uri: https://github.com/Yacoby/jekyll-image-gallery
91
+ source_code_uri: https://github.com/Yacoby/jekyll-image-gallery
92
+ changelog_uri: https://github.com/Yacoby/jekyll-image-gallery/blob/master/CHANGELOG.md
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: 2.6.0
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.3.7
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Gallery generator for Jekyll
112
+ test_files: []