Skip to content

Instantly share code, notes, and snippets.

@brrygrdn
Last active December 18, 2015 00:08
Show Gist options
  • Save brrygrdn/5694043 to your computer and use it in GitHub Desktop.
Save brrygrdn/5694043 to your computer and use it in GitHub Desktop.
Collection of Jekyll plugins.

Jekyll Plugins

This is a small collection of plugins I'm using in a couple of Jekyll sites. The intent is to collapse these into a gem eventually.

Dependancies

Add the following to the project's Gemfile:

gem "jekyll-asset-pipeline"
gem "yui-compressor", "~> 0.9.6"
gem "uglifier", "~> 2.1.0"
# A simple way to inspect liquid template variables.
# Usage:
# Can be used anywhere liquid syntax is parsed (templates, includes, posts/pages)
# {{ site | debug }}
# {{ site.posts | debug }}
#
require 'pp'
module Jekyll
# Need to overwrite the inspect method here because the original
# uses < > to encapsulate the psuedo post/page objects in which case
# the output is taken for HTML tags and hidden from view.
#
class Post
def inspect
"#Jekyll:Post @id=#{self.id.inspect}"
end
end
class Page
def inspect
"#Jekyll:Page @name=#{self.name.inspect}"
end
end
end # Jekyll
module Jekyll
module DebugFilter
def debug(obj, stdout=false)
puts obj.pretty_inspect if stdout
"<pre>#{obj.class}\n#{obj.pretty_inspect}</pre>"
end
end # DebugFilter
end # Jekyll
Liquid::Template.register_filter(Jekyll::DebugFilter)
module Jekyll
module HtmlCompressor
def compress_html(content)
content
.gsub(/^\s*/, '')
.gsub(/(\n|\t|\r)/, ' ')
.gsub(/>\s*</, '><')
.gsub(/<!--[^>]*-->/, ' ')
.squeeze(' ')
end
def output_file(dest, content)
FileUtils.mkdir_p(File.dirname(dest))
File.open(dest, 'w') do |f|
f.write(content)
end
end
def output_html(dest, content)
path = self.destination(dest)
self.output_file(path, compress_html(content))
end
end
class Post
include HtmlCompressor
def write(dest)
self.output_html(dest, self.output)
end
end
class Page
include HtmlCompressor
alias_method :write_other, :write
def write_html(dest)
self.output_html(dest, self.output)
end
def write(dest)
if self.html?
self.write_html(dest)
else
self.write_other(dest)
end
end
end
end
require 'jekyll_asset_pipeline'
module JekyllAssetPipeline
class CssCompressor < JekyllAssetPipeline::Compressor
require 'yui/compressor'
def self.filetype
'.css'
end
def compress
return YUI::CssCompressor.new.compress(@content)
end
end
class JavaScriptCompressor < JekyllAssetPipeline::Compressor
require 'uglifier'
def self.filetype
'.js'
end
def compress
return Uglifier.new(output: { comments: :none }).compile(@content)
end
end
end
module Jekyll
class SortedCategoriesBuilder < Generator
safe true
def generate(site)
site.config['sorted_categories'] = site.categories.sort_by { |category, posts| category }
end
end
end
# Copyright (C) 2011 Anurag Priyam - MIT License
# Source: https://gist.github.com/yeban/2290195
module Jekyll
# Jekyll plugin to generate tag clouds.
#
# The plugin defines a `tag_cloud` tag that is rendered by Liquid into a tag
# cloud:
#
# <div class='cloud'>
# {% tag_cloud %}
# </div>
#
# The tag cloud itself is a collection of anchor tags, styled dynamically
# with the `font-size` CSS property. The range of values, and unit to use for
# `font-size` can be specified with a very simple syntax:
#
# {% tag_cloud font-size: 16 - 28px %}
#
# The output is automatically formatted to use the same number of decimal
# places as used in the argument:
#
# {% tag_cloud font-size: 0.8 - 1.8em %} # => 1
# {% tag_cloud font-size: 0.80 - 1.80em %} # => 2
#
# Tags that have been used less than a certain number of times can be
# filtered out from the tag cloud with the optional `threshold` parameter:
#
# {% tag_cloud threshold: 2%}
#
# Both the parameters can be easily clubbed together:
#
# {% tag_cloud font-size: 50 - 150%, threshold: 2%}
#
# The plugin randomizes the order of tags every time the cloud is generated.
class TagCloud < Liquid::Tag
safe = true
# tag cloud variables - these are setup in `initialize`
attr_reader :size_min, :size_max, :precision, :unit, :threshold
def initialize(name, params, tokens)
# initialize default values
@size_min, @size_max, @precision, @unit = 70, 170, 0, '%'
@threshold = 1
# process parameters
@params = Hash[*params.split(/(?:: *)|(?:, *)/)]
process_font_size(@params['font-size'])
process_threshold(@params['threshold'])
super
end
def render(context)
# get an Array of [tag name, tag count] pairs
count = context.registers[:site].tags.map do |name, posts|
[name, posts.count] if posts.count >= threshold
end
# clear nils if any
count.compact!
# get the minimum, and maximum tag count
min, max = count.map(&:last).minmax
# map: [[tag name, tag count]] -> [[tag name, tag weight]]
weight = count.map do |name, count|
# logarithmic distribution
weight = (Math.log(count) - Math.log(min))/(Math.log(max) - Math.log(min))
[name, weight]
end
# shuffle the [tag name, tag weight] pairs
weight.sort_by! { |tag| tag[0] }
# reduce the Array of [tag name, tag weight] pairs to HTML
weight.reduce("") do |html, tag|
name, weight = tag
size = size_min + ((size_max - size_min) * weight).to_f
size = sprintf("%.#{@precision}f", size)
html << "<a style='font-size: #{size}#{unit}' href='/tag/#{name}'>#{name}</a>\n"
end
end
private
def process_font_size(param)
/(\d*\.{0,1}(\d*)) *- *(\d*\.{0,1}(\d*)) *(%|em|px)/.match(param) do |m|
@size_min = m[1].to_f
@size_max = m[3].to_f
@precision = [m[2].size, m[4].size].max
@unit = m[5]
end
end
def process_threshold(param)
/\d*/.match(param) do |m|
@threshold = m[0].to_i
end
end
end
end
Liquid::Template.register_tag('tag_cloud', Jekyll::TagCloud)
# Source: https://github.com/realjenius/realjenius.com/blob/master/_plugins/cat_and_tag_generator.rb
module Jekyll
class Taxons < Generator
safe true
def generate(site)
site.categories.each do |category|
build_subpages(site, "category", category)
end
site.tags.each do |tag|
build_subpages(site, "tag", tag)
end
end
def build_subpages(site, type, posts)
posts[1] = posts[1].sort_by { |p| -p.date.to_f }
paginate(site, type, posts)
end
def paginate(site, type, posts)
pages = Pager.calculate_pages(posts[1], site.config['paginate'].to_i)
(1..pages).each do |num_page|
pager = Pager.new(site.config, num_page, posts[1], pages)
if type == 'category'
path = "/#{posts[0]}"
else
path = "/#{type}/#{posts[0]}"
end
if num_page > 1
path = path + "/page#{num_page}"
end
newpage = TaxonPage.new(site, site.source, path, type, posts[0])
newpage.pager = pager
site.pages << newpage
end
end
end
class TaxonPage < Page
def initialize(site, base, dir, type, val)
@site = site
@base = base
@dir = dir
@name = 'index.html'
self.process(@name)
self.read_yaml(File.join(base, '_layouts'), "taxon.html")
self.data["grouptype"] = type
self.data[type] = val
self.data['title'] = type == 'category' ? val.capitalize : "Posts tagged with '#{val}'"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment