Skip to content

Instantly share code, notes, and snippets.

@w0rd-driven
Last active March 20, 2016 23:32
Show Gist options
  • Save w0rd-driven/7035022 to your computer and use it in GitHub Desktop.
Save w0rd-driven/7035022 to your computer and use it in GitHub Desktop.
Implementing Wordpress-style tags in Octopress
tag_dir: tags
{% capture tag %}{{ post.tags | size }}{% endcapture %}
<div class="row-fluid">
<div class="span1">
<h1 class="date-time"><time datetime="{{ post.date | datetime | date_to_xmlschema }}" pubdate>{{ post.date | date: "<span class='month'>%b</span> <span class='day'>%d</span><span class='year'><!--%Y--></span>"}}</time></h1>
</div>
<div class="span10">
<h1><a href="{{ root_url }}{{ post.url }}">{{post.title}}</a></h1>
</div>
</div>
{% if tag != '0' %}
<div class="row-fluid">
<div class="span1">
</div>
<div class="span10">
<footer class="archive">
<span class="tags">posted in {{ post.tags | tag_links }}</span>
</footer>
</div>
</div>
{% endif %}
---
layout: nil
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="text" xml:lang="en"><![CDATA[{{ site.title }}]]></title>
<link type="application/atom+xml" href="{{ site.url }}/{{ page.feed_url }}" rel="self"/>
<link type="text" href="{{ site.url }}/"/>
<updated>{{ site.time | date_to_xmlschema }}</updated>
<id>{{ site.url }}/</id>
<author>
<name><![CDATA[{{ site.author | strip_html }}]]></name>
{% if site.email %}<email><![CDATA[{{ site.email }}]]></email>{% endif %}
</author>
<rights>Copyright (c) 2010-{{ site.time | date_to_string | date: "%Y" }} <![CDATA[{{ site.author | strip_html }}]]></rights>
<generator uri="http://octopress.org/">Octopress</generator>
{% for post in site.tags[page.tag] limit: 5 %}
<entry>
<title type="html"><![CDATA[{{ post.title | cdata_escape }}]]></title>
<link href="{{ site.url }}{{ post.url }}"/>
<updated>{{ post.date | date_to_xmlschema }}</updated>
<id>{{ site.url }}{{ post.id }}</id>
{% if post.has_excerpt %}<summary type="html">{{ post.excerpt | xml_escape }}</summary>{% endif %}
<content type="html"><![CDATA[{{ post.content | expand_urls: site.url | markdownify | cdata_escape }}]]></content>
</entry>
{% endfor %}
</feed>
# encoding: utf-8
#
# Jekyll tag page generator.
# Completely stolen from the category generator, where I copied the file and replaced text here:
# http://recursive-design.com/projects/jekyll-plugins/
#
# Version: 0.1.4 (201101061053)
#
# Copyright (c) 2010 Dave Perrett, http://recursive-design.com/
# Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
#
# A generator that creates tag pages for jekyll sites.
#
# Included filters :
# - tag_links: Outputs the list of tags as comma-separated <a> links.
# - date_to_html_string: Outputs the post.date as formatted html, with hooks for CSS styling.
#
# Available _config.yml settings :
# - tag_dir: The subfolder to build tag pages in (default is 'tags').
# - tag_title_prefix: The string used before the tag name in the page title (default is
# 'Tag: ').
require 'stringex'
module Jekyll
# The TagIndex class creates a single tag page for the specified tag.
class TagIndex < Page
# Initializes a new TagIndex.
#
# +base+ is the String path to the <source>.
# +tag_dir+ is the String path between <source> and the tag folder.
# +tag+ is the tag currently being processed.
def initialize(site, base, tag_dir, tag)
@site = site
@base = base
@dir = tag_dir
@name = 'index.html'
self.process(@name)
# Read the YAML data from the layout page.
self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
self.data['tag'] = tag
# Set the title for this page.
title_prefix = site.config['tag_title_prefix'] || 'Tag: '
self.data['title'] = "#{title_prefix}#{tag}"
# Set the meta-description for this page.
meta_description_prefix = site.config['tag_meta_description_prefix'] || 'Tag: '
self.data['description'] = "#{meta_description_prefix}#{tag}"
end
end
# The TagFeed class creates an Atom feed for the specified tag.
class TagFeed < Page
# Initializes a new TagFeed.
#
# +base+ is the String path to the <source>.
# +tag_dir+ is the String path between <source> and the tag folder.
# +tag+ is the tag currently being processed.
def initialize(site, base, tag_dir, tag)
@site = site
@base = base
@dir = tag_dir
@name = 'atom.xml'
self.process(@name)
# Read the YAML data from the layout page.
self.read_yaml(File.join(base, '_includes/custom'), 'tag_feed.xml')
self.data['tag'] = tag
# Set the title for this page.
title_prefix = site.config['tag_title_prefix'] || 'Tag: '
self.data['title'] = "#{title_prefix}#{tag}"
# Set the meta-description for this page.
meta_description_prefix = site.config['tag_meta_description_prefix'] || 'Tag: '
self.data['description'] = "#{meta_description_prefix}#{tag}"
# Set the correct feed URL.
self.data['feed_url'] = "#{tag_dir}/#{name}"
end
end
# The Site class is a built-in Jekyll class with access to global site config information.
class Site
# Creates an instance of TagIndex for each tag page, renders it, and
# writes the output to a file.
#
# +tag_dir+ is the String path to the tag folder.
# +tag+ is the tag currently being processed.
def write_tag_index(tag_dir, tag)
index = TagIndex.new(self, self.source, tag_dir, tag)
index.render(self.layouts, site_payload)
index.write(self.dest)
# Record the fact that this page has been added, otherwise Site::cleanup will remove it.
self.pages << index
# Create an Atom-feed for each index.
feed = TagFeed.new(self, self.source, tag_dir, tag)
feed.render(self.layouts, site_payload)
feed.write(self.dest)
# Record the fact that this page has been added, otherwise Site::cleanup will remove it.
self.pages << feed
end
# Loops through the list of tag pages and processes each one.
def write_tag_indexes
if self.layouts.key? 'tag_index'
dir = self.config['tag_dir'] || 'tags'
self.tags.keys.each do |tag|
self.write_tag_index(File.join(dir, tag.to_url), tag)
end
# Throw an exception if the layout couldn't be found.
else
raise <<-ERR
===============================================
Error for tag_generator.rb plugin
-----------------------------------------------
No 'tag_index.hmtl' in source/_layouts/
Perhaps you haven't installed a theme yet.
===============================================
ERR
end
end
end
# Jekyll hook - the generate method is called by jekyll, and generates all of the tag pages.
class GenerateTags < Generator
safe true
priority :low
def generate(site)
site.write_tag_indexes
end
end
# Adds some extra filters used during the tag creation process.
module Filters
# Outputs a list of tags as comma-separated <a> links. This is used
# to output the tag list for each post on a tag page.
#
# +tags+ is the list of tags to format.
#
# Returns string
#
def tag_links(tags)
tags = tags.sort!.map { |c| tag_link c }
case tags.length
when 0
""
when 1
tags[0].to_s
else
"#{tags[0...-1].join(', ')}, #{tags[-1]}"
end
end
# Outputs a single tag as an <a> link.
#
# +tag+ is a tag string to format as an <a> link
#
# Returns string
#
def tag_link(tag)
dir = @context.registers[:site].config['tag_dir']
"<a class='tag' href='/#{dir}/#{tag.to_url}/'>#{tag}</a>"
end
# Outputs the post.date as formatted html, with hooks for CSS styling.
#
# +date+ is the date object to format as HTML.
#
# Returns string
def date_to_html_string(date)
result = '<span class="month">' + date.strftime('%b').upcase + '</span> '
result += date.strftime('<span class="day">%d</span> ')
result += date.strftime('<span class="year">%Y</span> ')
result
end
end
end
---
layout: page
footer: false
---
<div id="blog-archives" class="tag">
{% for post in site.tags[page.tag] %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
<div class="row-fluid">
<div class="span1">
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% unless year == this_year %}
{% assign year = this_year %}
<h2>{{ year }}</h2>
{% endunless %}
</div>
<div class="span11">
<article>
{% include archive_post_tags.html %}
</article>
</div>
</div>
{% endfor %}
</div>
{% capture tag %}{% if post %}{{ post.tags | tag_links | size }}{% else %}{{ page.tags | tag_links | size }}{% endif %}{% endcapture %}
{% unless tag == '0' %}
{% if post %}
{% for tag in post.tags %}
<a class="tag" href="{{ root_url }}/{{ site.tag_dir }}/{{ tag | to_url }}/"><span class="badge">{{ tag }}</span></a>
{% endfor %}
{% else %}
{% for tag in page.tags %}
<a class="tag" href="{{ root_url }}/{{ site.tag_dir }}/{{ tag | to_url }}/"><span class="badge">{{ tag }}</span></a>
{% endfor %}
{% endif %}
{% endunless %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment