├── _layouts
└── category_archive.html
├── README.md
└── _plugins
└── category_archive_plugin.rb
/_layouts/category_archive.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
6 | Category archive for {{ page.category }}
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Category archive plugin for Jekyll
2 |
3 | Generate a category archive like MovableType does.
4 |
5 | This code is based on following hacks:
6 |
7 | - https://gist.github.com/ilkka/707909
8 | - https://gist.github.com/ilkka/707020
9 | - https://gist.github.com/nlindley/6409459
10 |
11 |
12 | # Installation
13 |
14 | To use this plugin,
15 |
16 | - Place the file `category_archive_plugin.rb` into `_plugins`
17 | directory of Jekyll site working directory.
18 |
19 | - Copy `_layouts/category_archive.html` into `_layouts` directory of
20 | Jekyll site working directory, then edit it appropriately.
21 |
22 |
23 | # Parameter configuration
24 |
25 | Archive layout can be specified by `layout` key in the `category_archive`
26 | site configuration. Default is `category_archive`.
27 |
28 | Archive generation directory prefix can be specified by `path` key in the `category_archive`
29 | site configuration. If specified, archive will be generated in
30 | `PATH/CATEGORY/index.html`, where `PATH` is substituted by `path`, `CATEGORY` is the category
31 | the archive for. Default is null string.
32 |
33 | If the `slugify` key is set to `true`, then category URLs will be slugified.
34 | ie: the url for "My Category" will be 'categories/my-category' not
35 | 'categories/My%20Category'
36 |
37 | # Liquid variables for template
38 |
39 | `page.category` contains the category name.
40 |
41 | # Linking to a category archive
42 |
43 | This plugin provides the custom liquid block tag, `categorylink`, which can be used to render a
44 | link to a category's archive. For example:
45 |
46 | ```
47 | {% categorylink foo %}This is a link to foo{% endcategorylink %}
48 | ```
49 |
50 | Would create a link to the category archive of `foo` with the content "This is a link to foo". In
51 | addition, if the name of a variable is specified instead of a category, the variable will be
52 | expanded every time the tag block is rendered.
53 |
54 |
55 | # Copyright
56 |
57 | The MIT License (MIT)
58 |
59 | Copyright (c) 2013 Shigeya Suzuki
60 |
61 | Permission is hereby granted, free of charge, to any person obtaining a copy
62 | of this software and associated documentation files (the "Software"), to deal
63 | in the Software without restriction, including without limitation the rights
64 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65 | copies of the Software, and to permit persons to whom the Software is
66 | furnished to do so, subject to the following conditions:
67 |
68 | The above copyright notice and this permission notice shall be included in all
69 | copies or substantial portions of the Software.
70 |
71 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
72 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
73 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
75 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
76 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
77 | SOFTWARE.
78 |
--------------------------------------------------------------------------------
/_plugins/category_archive_plugin.rb:
--------------------------------------------------------------------------------
1 | # Jekyll Module to create category archive pages
2 | #
3 | # Shigeya Suzuki, November 2013
4 | # Copyright notice (MIT License) attached at the end of this file
5 | #
6 |
7 | #
8 | # This code is based on the following works:
9 | # https://gist.github.com/ilkka/707909
10 | # https://gist.github.com/ilkka/707020
11 | # https://gist.github.com/nlindley/6409459
12 | #
13 |
14 | #
15 | # Archive will be written as #{archive_path}/#{category_name}/index.html
16 | # archive_path can be configured in 'path' key in 'category_archive' of
17 | # site configuration file. 'path' is default null.
18 | #
19 |
20 | module Jekyll
21 |
22 | module CategoryArchiveUtil
23 | def self.archive_base(site)
24 | site.config['category_archive'] && site.config['category_archive']['path'] || ''
25 | end
26 | end
27 |
28 | # Generator class invoked from Jekyll
29 | class CategoryArchiveGenerator < Generator
30 | def generate(site)
31 | posts_group_by_category(site).each do |category, list|
32 | site.pages << CategoryArchivePage.new(site, CategoryArchiveUtil.archive_base(site), category, list)
33 | end
34 | end
35 |
36 | def posts_group_by_category(site)
37 | category_map = {}
38 | site.posts.each {|p| p.categories.each {|c| (category_map[c] ||= []) << p } }
39 | category_map
40 | end
41 | end
42 |
43 | # Tag for generating a link to a category archive page
44 | class CategoryArchiveLinkTag < Liquid::Block
45 |
46 | def initialize(tag_name, category, tokens)
47 | super
48 | @category = category.split(' ').first || category
49 | end
50 |
51 | def render(context)
52 | # If the category is a variable in the current context, expand it
53 | if context.has_key?(@category)
54 | category = context[@category]
55 | else
56 | category = @category
57 | end
58 |
59 |
60 | if context.registers[:site].config['category_archive'] && context.registers[:site].config['category_archive']['slugify']
61 | category = Utils.slugify(category)
62 | end
63 |
64 | href = File.join('/', context.registers[:site].baseurl, context.environments.first['site']['category_archive']['path'],
65 | category, 'index.html')
66 | "#{super}"
67 | end
68 | end
69 |
70 | # Actual page instances
71 | class CategoryArchivePage < Page
72 | ATTRIBUTES_FOR_LIQUID = %w[
73 | category,
74 | content
75 | ]
76 |
77 | def initialize(site, dir, category, posts)
78 | @site = site
79 | @dir = dir
80 | @category = category
81 |
82 | if site.config['category_archive'] && site.config['category_archive']['slugify']
83 | @category_dir_name = Utils.slugify(@category) # require sanitize here
84 | else
85 | @category_dir_name = @category
86 | end
87 |
88 | @layout = site.config['category_archive'] && site.config['category_archive']['layout'] || 'category_archive'
89 | self.ext = '.html'
90 | self.basename = 'index'
91 | self.content = <<-EOS
92 | {% for post in page.posts %}{{ post.title }}
93 | {% endfor %}
94 | EOS
95 | self.data = {
96 | 'layout' => @layout,
97 | 'type' => 'archive',
98 | 'title' => "Category archive for #{@category}",
99 | 'posts' => posts,
100 | 'url' => File.join('/',
101 | CategoryArchiveUtil.archive_base(site),
102 | @category_dir_name, 'index.html')
103 | }
104 | end
105 |
106 | def render(layouts, site_payload)
107 | payload = {
108 | 'page' => self.to_liquid,
109 | 'paginator' => pager.to_liquid
110 | }.merge(site_payload)
111 | do_layout(payload, layouts)
112 | end
113 |
114 | def to_liquid(attr = nil)
115 | self.data.merge({
116 | 'content' => self.content,
117 | 'category' => @category
118 | })
119 | end
120 |
121 | def destination(dest)
122 | File.join('/', dest, @dir, @category_dir_name, 'index.html')
123 | end
124 |
125 | end
126 | end
127 |
128 | Liquid::Template.register_tag('categorylink', Jekyll::CategoryArchiveLinkTag)
129 |
130 | # The MIT License (MIT)
131 | #
132 | # Copyright (c) 2013 Shigeya Suzuki
133 | #
134 | # Permission is hereby granted, free of charge, to any person obtaining a copy
135 | # of this software and associated documentation files (the "Software"), to deal
136 | # in the Software without restriction, including without limitation the rights
137 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
138 | # copies of the Software, and to permit persons to whom the Software is
139 | # furnished to do so, subject to the following conditions:
140 | #
141 | # The above copyright notice and this permission notice shall be included in all
142 | # copies or substantial portions of the Software.
143 | #
144 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
145 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
146 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
147 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
148 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
149 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
150 | # SOFTWARE.
151 |
--------------------------------------------------------------------------------