Skip to content

Instantly share code, notes, and snippets.

Last active April 7, 2021 04:48
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tobru/9171700 to your computer and use it in GitHub Desktop.
Save tobru/9171700 to your computer and use it in GitHub Desktop.
A Liquid tag for Jekyll sites that allows embedding Lychee albums. See
# Connects Jekyll with Lychee (
# # Features
# * Generate album overview and link to image
# * Caching of JSON data
# # Usage
# {% lychee_album <album_id> %}
# {% lychee_album_no_cache <album_id> %}
# # Example
# {% lychee_album 1 %}
# {% lychee_album_no_cache 1 %}
# # Default configuration (override in _config.yml)
# lychee:
# url:
# album_title_tag: h1
# link_big_to: lychee
# cache_folder: _lychee_cache
# Change at least "url" to your own Lychee installation
# album_title_tag: let's you chose which HTML tag to use around the album title
# link_big_to: choose "lychee" or "img".
# lychee: links the image to the Lychee image view
# img: links the image to it's original image
# # Author and license
# Tobias Brunner <> -
# License: MIT
require 'json'
require 'net/http'
require 'net/https'
require 'uri'
module Jekyll
class LycheeAlbumTag < Liquid::Tag
def initialize(tag_name, config, token)
# params coming from the liquid tag
@params = config.strip
# get config from _config.yml
@config = Jekyll.configuration({})['lychee'] || {}
# set default values
@config['album_title_tag'] ||= 'h1'
@config['link_big_to'] ||= 'lychee'
@config['url'] ||= ''
@config['cache_folder'] ||= '_lychee_cache'
# construct class wide usable variables
@thumb_url = @config['url'] + "/"
@big_url = @config['url'] + "/"
@album_id = @params
# initialize caching
@cache_disabled = false
@cache_folder = File.expand_path "../#{@config['cache_folder']}", File.dirname(__FILE__)
FileUtils.mkdir_p @cache_folder
def render(context)
# initialize session with Lychee
api_url = @config['url'] + "/php/api.php"
uri = URI.parse(api_url)
@http =, uri.port)
@http.use_ssl = true
@request =
@request['Cookie'] = init_lychee_session
album = cached_response(@album_id, 'album') || get_album(@album_id)
puts "[Lychee Tag] Processing Lychee album id #{@album_id}: '#{album['title']}'"
html = "<#{@config['album_title_tag']}>#{album['title']}</#{@config['album_title_tag']}>\n"
album_content = album['content']
album_content.each do |photo_id, photo_data|
big_href = case @config['link_big_to']
when "img"
photo_data = cached_response(photo_id, 'photo') || get_photo(@album_id, photo_id)
@big_url + photo_data['url']
when "lychee" then @config['url'] + "#" + @album_id + "/" + photo_id
else "#"
html << "<a href=\"#{big_href}\" title=\"#{photo_data['title']}\"><img src=\"#{@thumb_url}#{photo_data['thumbUrl']}\"/></a>\n"
return html
# Caching
def cache(id, type, data)
puts "[Lychee Tag] Caching Lychee #{type} id #{id}"
cache_file = cache_file_for(id, type), "w") do |f|
def cache_file_for(id, type)
filename = "#{type}_#{id}"
File.join(@cache_folder, filename)
def cached_response(id, type)
return nil if @cache_disabled
cache_file = cache_file_for(id, type)
JSON.parse( if File.exist?(cache_file)
# Lychee API mapping
def init_lychee_session
# construct request
@request.set_form_data({'function' => 'Session::init'})
# send request now and save cookies
response = @http.request(@request)
return response.response['set-cookie']
def get_albums
@request.set_form_data({'function' => 'Album::getAll'})
return JSON.parse(@http.request(@request).body)
def get_album(id)
@request.set_form_data({'function' => 'Album::get', 'albumID' => id, 'password' => ''})
response = @http.request(@request).body
cache(id, 'album', response) unless @cache_disabled
return JSON.parse(response)
def get_photo(album_id, photo_id)
@request.set_form_data({'function' => 'Photo::get', 'albumID' => album_id, 'photoID' => photo_id, 'password' => ''})
response = @http.request(@request).body
cache(photo_id, 'photo', response) unless @cache_disabled
return JSON.parse(response)
class LycheeAlbumTagNoCache < LycheeAlbumTag
def initialize(tag_name, config, token)
@cache_disabled = true
Liquid::Template.register_tag('lychee_album', Jekyll::LycheeAlbumTag)
Liquid::Template.register_tag('lychee_album_no_cache', Jekyll::LycheeAlbumTagNoCache)
Copy link

When retrieving the image (on line 91), the output URL contains uploads/thumb (or uploads/big) twice, which is problematic. You should use the following:

# for the big image
@config + photo_data['url']
# for the small image
@config + photo_data['thumbUrl']

instead of

# for the big image
@big_url + photo_data['url']
# for the small image
@thumb_url + photo_data['thumbUrl']

Copy link

There is a problem with the plugin/API: when retrieving an image from an album, the response does not provide the photo properties (such as the description). How can it be done?

Copy link

I got it: there is a function at the bottom of the Gist, called get_photo(), which allows me to retrieve photo information about the photo specifically.

So, at line 83, instead of getting the images from the get_album() function (which only returns basic information, not each photo description), we should use the get_photo() function, as:

album_content.each do |photo_id, photo_data|
photo_id = photo_data['id']
photo = get_photo(@album_id, photo_id)

Copy link

n00tz commented Dec 8, 2016

Update line 72, for the current implementation of the api url.

api_url = @config['url'] + "/php/index.php"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment