Created
May 6, 2013 02:07
-
-
Save schpet/5523001 to your computer and use it in GitHub Desktop.
ghetto gallery generator for jekyll - put images in directories inside _galleries
- add gallery.html to layouts
This file contains hidden or 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
| --- | |
| layout: base | |
| --- | |
| <!-- i will die alone and sad without this file in _layouts --> | |
| {% for image in images %} | |
| <a href="{{ image }}"> | |
| <img src="200/{{ image }}"> | |
| </a> | |
| {% endfor %} | |
This file contains hidden or 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
| # todo | |
| # these images need width and heights | |
| require 'pry' | |
| require 'RMagick' | |
| include Magick | |
| module Jekyll | |
| class Gallery | |
| include Convertible | |
| attr_writer :dir | |
| attr_accessor :site, :pager | |
| attr_accessor :name, :ext, :slug, :id | |
| attr_accessor :data, :content, :output | |
| # allows an optional id for sorting | |
| MATCHER = /^(?:(\d+)-)?(.*)$/ | |
| def self.valid?(name) | |
| name =~ MATCHER | |
| end | |
| def initialize(site, source, name, images) | |
| @site = site | |
| @base = self.containing_dir(source) | |
| @name = name | |
| @images = images | |
| @config = { | |
| symlink: true, # todo make it a site setting | |
| resolutions: [ 125, 200, 1000 ] | |
| } | |
| @cache = self.cache_dir(source) | |
| self.data = { | |
| "layout" => 'gallery' | |
| } | |
| self.process(name) | |
| end | |
| def process(name) | |
| m, id, slug = *name.match(MATCHER) | |
| self.slug = slug | |
| self.id = id | |
| end | |
| # Get the full path to the directory containing the post files | |
| def containing_dir(source) | |
| return File.join(source, '_galleries') | |
| end | |
| def cache_dir(source) | |
| return File.join(source, '_tmp', 'image_cache') | |
| end | |
| def template | |
| "/:slug/" | |
| end | |
| # The generated relative url of this page. e.g. /about.html. | |
| # | |
| # Returns the String url. | |
| def url | |
| return @url if @url | |
| url = { | |
| "slug" => self.slug, | |
| }.inject(template) { |result, token| | |
| result.gsub(/:#{token.first}/, token.last) | |
| }.gsub(/\/\//, "/") | |
| # sanitize url | |
| @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/') | |
| @url += "/" if url =~ /\/$/ | |
| @url | |
| end | |
| # Add any necessary layouts to this post | |
| # | |
| # layouts - The Hash of {"name" => "layout"}. | |
| # site_payload - The site payload Hash. | |
| # | |
| # Returns nothing. | |
| def render(layouts, site_payload) | |
| payload = { | |
| "page" => self.to_liquid, | |
| 'paginator' => pager.to_liquid, | |
| 'images' => @images | |
| }.deep_merge(site_payload) | |
| do_layout(payload, layouts) | |
| end | |
| # Convert this Page's data to a Hash suitable for use by Liquid. | |
| # | |
| # Returns the Hash representation of this Page. | |
| def to_liquid | |
| self.data.deep_merge({ | |
| "layout" => 'gallery', | |
| "id" => self.id, | |
| "url" => self.url, | |
| "slug" => self.slug, | |
| "title" => self.slug.gsub('-', ' '), | |
| "content" => self.content, | |
| "images" => @images}) | |
| end | |
| # Obtain destination path. | |
| # | |
| # dest - The String path to the destination dir. | |
| # | |
| # Returns the destination file path String. | |
| def destination(dest) | |
| # The url needs to be unescaped in order to preserve the correct | |
| # filename. | |
| path = File.join(dest, CGI.unescape(self.url)) | |
| path = File.join(path, "index.html") if self.url =~ /\/$/ | |
| path | |
| end | |
| def html? | |
| true | |
| end | |
| # Returns the Boolean of whether this Page is an index file or not. | |
| def index? | |
| true | |
| end | |
| # Write the generated page file to the destination directory. | |
| # | |
| # dest - The String path to the destination dir. | |
| # | |
| # Returns nothing. | |
| def write(dest) | |
| path = destination(dest) | |
| cached_path = destination(@cache) | |
| copy_method = @config[:symlink] ? 'ln_s' : 'cp' | |
| FileUtils.mkdir_p(File.dirname(path)) | |
| File.open(path, 'w') do |f| | |
| f.write(self.output) | |
| end | |
| @images.each do |i| | |
| original = File.join(@base, @name, i) | |
| w, slug, ext = *i.match(/^(.*)\.(.*)$/) | |
| FileUtils.mkdir_p(@cache) | |
| img = nil | |
| @config[:resolutions].each do |rez| | |
| # check if image is in the cache | |
| FileUtils.mkdir_p(File.join(File.dirname(cached_path), rez.to_s)) | |
| cached_image = File.join(File.dirname(cached_path), rez.to_s, i) | |
| if File.exist?(cached_image) | |
| # fails if the image has changed, oh well | |
| else | |
| unless img | |
| img = Image.read(original).first | |
| end | |
| img.resize_to_fit(rez).write cached_image | |
| end | |
| end | |
| FileUtils.send(copy_method, original, File.dirname(path)) | |
| end | |
| @config[:resolutions].each do |rez| | |
| cached_resized = File.join(File.dirname(cached_path), rez.to_s) | |
| dest_resized = File.join(File.dirname(path), rez.to_s) | |
| FileUtils.send(copy_method, cached_resized, dest_resized) | |
| end | |
| end | |
| end | |
| #class Image | |
| #MATCHER = /^(\d+)-(.*)(\.[^.]+)$/ | |
| ## Image name validator. Image filenames must be like: | |
| ## 001-my-cool-pic.jpg | |
| ## | |
| ## Returns true if valid, false if not. | |
| #def self.valid_image?(name) | |
| #name =~ IMAGE_MATCHER | |
| #end | |
| #def initialize() | |
| #end | |
| #end | |
| class GalleryGenerator < Generator | |
| def generate(site) | |
| galleries = get_galleries(site, '_galleries') | |
| # hacky: shove it into config so it's accessible from the "site" in liquid | |
| site.config['galleries'] = [] | |
| galleries.each do |k, v| | |
| if Gallery.valid?(k) | |
| gallery = Gallery.new(site, site.source, k, v) | |
| site.pages << gallery | |
| site.config['galleries'] << gallery.to_liquid | |
| end | |
| end | |
| end | |
| def get_galleries(site, subfolder) | |
| base = File.join(site.source, subfolder) | |
| return [] unless File.exists?(base) | |
| entries = Dir.chdir(base) { site.filter_entries(Dir['**/*']) } | |
| galleries = {} | |
| entries.each do |e| | |
| unless File.directory?(File.join(base, e)) | |
| gallery = File.basename(File.expand_path('..', e)) | |
| galleries[gallery] = [] unless galleries[gallery] | |
| galleries[gallery] << File.basename(e) | |
| end | |
| end | |
| galleries | |
| end | |
| def get_images(site, subfolder, gallery) | |
| base = File.join(site.source, subfolder) | |
| return [] unless File.exists?(base) | |
| entries = Dir.chdir(base) { site.filter_entries(Dir['**/*']) } | |
| entries.select { |e| File.directory?(File.join(base, e)) } | |
| end | |
| end | |
| end |
This file contains hidden or 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
| <!-- access galleries globally --> | |
| <ul> | |
| {% for gallery in site.galleries %} | |
| <li> | |
| <a href="{{ gallery.url }}"> | |
| {{ gallery.title }} | |
| </a> | |
| {% for image in gallery.images %} | |
| <img src="{{ gallery.slug }}/200/{{ image }}" data-fullsize="{{ gallery.slug }}/1000/{{ image }}"> | |
| {% endfor %} | |
| </li> | |
| {% endfor %} | |
| </ul> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment