Created
September 3, 2015 23:01
-
-
Save macmichael01/56a7276c34a778f80a7b to your computer and use it in GitHub Desktop.
This is a modified version of this: https://github.com/ggreer/jekyll-gallery-generator. Read the comments below for additional details.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a modified version of this: https://github.com/ggreer/jekyll-gallery-generator | |
# | |
# Maybe I should actually fork this at some point but I didn't actually think that | |
# this was something that would stand the chance of getting merged back into | |
# the actual plug-in itself. | |
# | |
# Basically my mods allow for you to have a structure which looks changes from this: | |
# http://example.com/gallery/awesome-trip-2015/awesome-photo-from-my-trip-001.jpg | |
# and is converted to this: | |
# http://example.com/gallery/awesome-trip-2015/awesome-photo-from-my-trip-001/ (notice the third level). | |
# You can checkout a live version of what I have done here: | |
# http://chrismcmichael.com/gallery/ | |
# | |
# The Details: | |
# When this plug-in goes to render a gallery, it creates a folder for every image inside of | |
# your gallery based on the name of that image, then adds a single index.html file | |
# inside of that folder which is the file that actually references the actual image to be displayed. | |
# | |
# Another thing I changed was to default first image in the folder to be "best_image" | |
# or the image which represents the entire gallery. This may not work with the "best_image" | |
# which can be defined in your _cofig.yml. (haven't tested but likely broken) | |
# | |
# Lastly I added an next and previous template variable which will render a next and/or previous | |
# link so that move on to the next or previous image in the gallery. (basically navigation) | |
# | |
# Why I did this: | |
# I was in the process of converting my current blog to Jekyll but wanted to preserve its functionality. | |
# This is what I came up with. The code could be complete garbage for all I know but it works. | |
# Hope this is useful to whoever might be viewing this. | |
# | |
# Dont for get to install the proper modules required to run this. | |
# You will need gallery_index.html, gallery_page.html, and gallery_photo_index.html in your layouts/ | |
# folder as well. | |
require 'exifr' | |
require 'RMagick' | |
include Magick | |
include FileUtils | |
$image_extensions = [".png", ".jpg", ".jpeg", ".gif"] | |
module Jekyll | |
class GalleryFile < StaticFile | |
def write(dest) | |
return false | |
end | |
end | |
class ReadYamlPage < Page | |
def read_yaml(base, name, opts = {}) | |
begin | |
self.content = File.read(File.join(base, name), merged_file_read_opts(opts)) | |
if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m | |
self.content = $POSTMATCH | |
self.data = SafeYAML.load($1) | |
end | |
rescue SyntaxError => e | |
Jekyll.logger.warn "YAML Exception reading #{File.join(base, name)}: #{e.message}" | |
rescue Exception => e | |
Jekyll.logger.warn "Error reading file #{File.join(base, name)}: #{e.message}" | |
end | |
self.data ||= {} | |
end | |
end | |
class PhotoIndex < ReadYamlPage | |
def initialize(site, base, dir, photo_info) | |
@site = site | |
@base = base | |
@dir = dir.gsub("source/", "") | |
@name = photo_info['path'] + "/index.html" | |
config = site.config["gallery"] || {} | |
self.process(@name) | |
gallery_index = File.join(base, "_layouts", "gallery_photo_index.html") | |
unless File.exists?(gallery_index) | |
gallery_index = File.join(File.dirname(__FILE__), "gallery_photo_index.html") | |
end | |
self.read_yaml(File.dirname(gallery_index), File.basename(gallery_index)) | |
self.data["image"] = photo_info['filename'] | |
self.data = self.data.merge(photo_info) | |
end | |
end | |
class GalleryIndex < ReadYamlPage | |
def initialize(site, base, dir, galleries) | |
@site = site | |
@base = base | |
@dir = dir.gsub("source/", "") | |
@name = "index.html" | |
config = site.config["gallery"] || {} | |
self.process(@name) | |
gallery_index = File.join(base, "_layouts", "gallery_index.html") | |
unless File.exists?(gallery_index) | |
gallery_index = File.join(File.dirname(__FILE__), "gallery_index.html") | |
end | |
self.read_yaml(File.dirname(gallery_index), File.basename(gallery_index)) | |
self.data["title"] = config["title"] || "Photos" | |
self.data["galleries"] = [] | |
begin | |
sort_field = config["sort_field"] || "date_time" | |
galleries.sort! {|a,b| b.data[sort_field] <=> a.data[sort_field]} | |
rescue Exception => e | |
puts "Error sorting galleries: #{e}" | |
puts e.backtrace | |
end | |
if config["sort_reverse"] | |
galleries.reverse! | |
end | |
galleries.each {|gallery| | |
unless gallery.hidden | |
self.data["galleries"].push(gallery.data) | |
end | |
} | |
end | |
end | |
class GalleryPage < ReadYamlPage | |
attr_reader :hidden, :photo_info, :data | |
def initialize(site, base, dir, gallery_name) | |
@site = site | |
@base = base | |
@dest_dir = dir.gsub("source/", "") | |
@dir = @dest_dir | |
@name = "index.html" | |
@images = [] | |
@hidden = false | |
@photo_info = [] | |
config = site.config["gallery"] || {} | |
gallery_config = {} | |
best_image = nil | |
max_size_x = 400 | |
max_size_y = 400 | |
symlink = config["symlink"] || false | |
scale_method = config["scale_method"] || "fit" | |
begin | |
max_size_x = config["thumbnail_size"]["x"] | |
rescue | |
end | |
begin | |
max_size_y = config["thumbnail_size"]["y"] | |
rescue | |
end | |
begin | |
gallery_config = config["galleries"][gallery_name] || {} | |
rescue | |
end | |
self.process(@name) | |
gallery_page = File.join(base, "_layouts", "gallery_page.html") | |
unless File.exists?(gallery_page) | |
gallery_page = File.join(File.dirname(__FILE__), "gallery_page.html") | |
end | |
self.read_yaml(File.dirname(gallery_page), File.basename(gallery_page)) | |
self.data["gallery"] = gallery_name | |
gallery_title_prefix = config["title_prefix"] || "Photos: " | |
gallery_name = gallery_name.gsub("-", " ").gsub("_", " ").gsub(/\w+/) {|word| word.capitalize} | |
begin | |
gallery_name = gallery_config["name"] || gallery_name | |
rescue | |
end | |
self.data["name"] = gallery_name | |
self.data["title"] = "#{gallery_title_prefix}#{gallery_name}" | |
thumbs_dir = File.join(site.dest, @dest_dir, "thumbs") | |
begin | |
@hidden = gallery_config["hidden"] || false | |
rescue | |
end | |
if @hidden | |
self.data["sitemap"] = false | |
end | |
FileUtils.mkdir_p(thumbs_dir, :mode => 0755) | |
date_times = {} | |
i = 0 | |
image_list = Dir.foreach(dir).to_a | |
# Only checks for common mac hidden files. | |
# Does not check for sub folders. | |
image_list -= ['.', '..', '.DS_Store'] | |
image_list.each do |image| | |
next if image.chars.first == "." | |
next unless image.downcase().end_with?(*$image_extensions) | |
@images.push(image) | |
best_image = image | |
@site.static_files << GalleryFile.new(site, base, File.join(@dest_dir, "thumbs"), image) | |
image_path = File.join(dir, image) | |
begin | |
date_times[image] = EXIFR::JPEG.new(image_path).date_time.to_i | |
rescue Exception => e | |
date_times[image] = 0 | |
puts "Error getting date_time for #{image}: #{e}" | |
end | |
photo_dirname = File.basename(image, File.extname(image)) | |
photo_inf = {} | |
photo_inf['filename'] = image | |
photo_inf['date_time'] = date_times[image] | |
photo_inf['path'] = File.join(self.data["gallery"], photo_dirname) | |
photo_inf['gallery_path'] = dir | |
photo_inf['photo_path'] = photo_inf['path'] | |
if i + 1 < image_list.length | |
img_item = image_list[i + 1] | |
img_name = File.basename(img_item, File.extname(img_item)) | |
img_path = File.join(@dest_dir, img_name) | |
photo_inf['next'] = img_path | |
end | |
if i > 0 | |
img_item = image_list[i - 1] | |
img_name = File.basename(img_item, File.extname(img_item)) | |
img_path = File.join(@dest_dir, img_name) | |
photo_inf['previous'] = img_path | |
end | |
@photo_info.push(photo_inf) | |
i += 1 | |
if symlink | |
link_src = site.in_source_dir(image_path) | |
link_dest = site.in_dest_dir(image_path) | |
@site.static_files.delete_if { |sf| | |
sf.relative_path == "/" + image_path | |
} | |
@site.static_files << GalleryFile.new(site, base, dir, image) | |
if File.exists?(link_dest) or File.symlink?(link_dest) | |
if not File.symlink?(link_dest) | |
puts "#{link_dest} exists but is not a symlink. Deleting." | |
File.delete(link_dest) | |
elsif File.readlink(link_dest) != link_src | |
puts "#{link_dest} points to the wrong file. Deleting." | |
File.delete(link_dest) | |
end | |
end | |
if not File.exists?(link_dest) and not File.symlink?(link_dest) | |
puts "Symlinking #{link_src} -> #{link_dest}" | |
File.symlink(link_src, link_dest) | |
end | |
end | |
thumb_path = File.join(thumbs_dir, image) | |
if File.file?(thumb_path) == false or File.mtime(image_path) > File.mtime(thumb_path) | |
begin | |
m_image = ImageList.new(image_path) | |
m_image.send("resize_to_#{scale_method}!", max_size_x, max_size_y) | |
puts "Writing thumbnail to #{thumb_path}" | |
m_image.write(thumb_path) | |
rescue e | |
puts "Error generating thumbnail for #{image_path}: #{e}" | |
puts e.backtrace | |
end | |
GC.start | |
end | |
end | |
begin | |
@images.sort! {|a,b| | |
if date_times[a] == date_times[b] | |
a <=> b | |
else | |
date_times[a] <=> date_times[b] | |
end | |
} | |
if gallery_config["sort_reverse"] | |
@images.reverse! | |
end | |
rescue Exception => e | |
puts "Error sorting images in gallery #{gallery_name}: #{e}" | |
puts e.backtrace | |
end | |
site.static_files = @site.static_files | |
self.data["images"] = @images | |
self.data["best_image"] = gallery_config["best_image"] || best_image | |
best_image_path = File.join(dir, best_image) | |
begin | |
self.data["date_time"] = EXIFR::JPEG.new(best_image_path).date_time.to_i | |
rescue Exception => e | |
self.data["date_time"] = 0 | |
puts "Error getting date_time for #{best_image_path}: #{e}" | |
end | |
end | |
end | |
class GalleryGenerator < Generator | |
safe true | |
def generate(site) | |
config = site.config["gallery"] || {} | |
dir = config["dir"] || "photos" | |
galleries = [] | |
original_dir = Dir.getwd | |
Dir.chdir(site.source) | |
begin | |
Dir.foreach(dir) do |gallery_dir| | |
gallery_path = File.join(dir, gallery_dir) | |
if File.directory?(gallery_path) and gallery_dir.chars.first != "." | |
gallery = GalleryPage.new(site, site.source, gallery_path, gallery_dir) | |
gallery.photo_info.each {|info| | |
hash = info.merge(gallery.data) | |
photo_index = PhotoIndex.new(site, site.source, dir, hash) | |
photo_index.render(site.layouts, site.site_payload) | |
photo_index.write(site.dest) | |
site.pages << photo_index | |
} | |
gallery.render(site.layouts, site.site_payload) | |
gallery.write(site.dest) | |
site.pages << gallery | |
galleries << gallery | |
end | |
end | |
rescue Exception => e | |
puts "Error generating galleries: #{e}" | |
puts e.backtrace | |
end | |
Dir.chdir(original_dir) | |
gallery_index = GalleryIndex.new(site, site.source, dir, galleries) | |
gallery_index.render(site.layouts, site.site_payload) | |
gallery_index.write(site.dest) | |
site.pages << gallery_index | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment