monad 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.markdown +91 -0
  3. data/Gemfile +1 -1
  4. data/History.markdown +772 -0
  5. data/{README.md → README.markdown} +5 -2
  6. data/Rakefile +163 -1
  7. data/bin/monad +86 -30
  8. data/features/create_sites.feature +54 -25
  9. data/features/data.feature +65 -0
  10. data/features/data_sources.feature +10 -10
  11. data/features/drafts.feature +5 -5
  12. data/features/embed_filters.feature +10 -10
  13. data/features/include_tag.feature +48 -0
  14. data/features/markdown.feature +5 -5
  15. data/features/pagination.feature +38 -10
  16. data/features/permalinks.feature +31 -11
  17. data/features/post_data.feature +41 -41
  18. data/features/post_excerpts.feature +50 -0
  19. data/features/site_configuration.feature +47 -26
  20. data/features/site_data.feature +30 -24
  21. data/features/step_definitions/{monad_steps.rb → jekyll_steps.rb} +66 -52
  22. data/features/support/env.rb +27 -8
  23. data/lib/jekyll.rb +99 -0
  24. data/lib/jekyll/cleaner.rb +73 -0
  25. data/lib/{monad → jekyll}/command.rb +6 -6
  26. data/lib/{monad → jekyll}/commands/build.rb +9 -9
  27. data/lib/jekyll/commands/doctor.rb +67 -0
  28. data/lib/jekyll/commands/new.rb +67 -0
  29. data/lib/jekyll/commands/serve.rb +65 -0
  30. data/lib/{monad → jekyll}/configuration.rb +60 -18
  31. data/lib/{monad → jekyll}/converter.rb +1 -1
  32. data/lib/{monad → jekyll}/converters/identity.rb +1 -1
  33. data/lib/{monad → jekyll}/converters/markdown.rb +2 -2
  34. data/lib/jekyll/converters/markdown/kramdown_parser.rb +29 -0
  35. data/lib/{monad → jekyll}/converters/markdown/maruku_parser.rb +12 -8
  36. data/lib/{monad → jekyll}/converters/markdown/rdiscount_parser.rb +4 -2
  37. data/lib/{monad → jekyll}/converters/markdown/redcarpet_parser.rb +1 -1
  38. data/lib/{monad → jekyll}/converters/textile.rb +1 -1
  39. data/lib/{monad → jekyll}/convertible.rb +39 -17
  40. data/lib/{monad → jekyll}/core_ext.rb +22 -4
  41. data/lib/jekyll/deprecator.rb +36 -0
  42. data/lib/{monad → jekyll}/draft.rb +1 -1
  43. data/lib/{monad → jekyll}/drivers/json_driver.rb +1 -1
  44. data/lib/{monad → jekyll}/drivers/yaml_driver.rb +1 -1
  45. data/lib/{monad → jekyll}/errors.rb +1 -1
  46. data/lib/jekyll/excerpt.rb +113 -0
  47. data/lib/{monad → jekyll}/filters.rb +16 -6
  48. data/lib/{monad → jekyll}/generator.rb +1 -1
  49. data/lib/jekyll/generators/pagination.rb +214 -0
  50. data/lib/{monad → jekyll}/layout.rb +4 -1
  51. data/lib/{monad → jekyll}/mime.types +0 -0
  52. data/lib/{monad → jekyll}/page.rb +36 -39
  53. data/lib/{monad → jekyll}/plugin.rb +1 -1
  54. data/lib/{monad → jekyll}/post.rb +58 -123
  55. data/lib/jekyll/related_posts.rb +59 -0
  56. data/lib/{monad → jekyll}/site.rb +120 -123
  57. data/lib/{monad → jekyll}/static_file.rb +1 -1
  58. data/lib/jekyll/stevenson.rb +89 -0
  59. data/lib/jekyll/tags/gist.rb +48 -0
  60. data/lib/{monad → jekyll}/tags/highlight.rb +3 -3
  61. data/lib/jekyll/tags/include.rb +135 -0
  62. data/lib/{monad → jekyll}/tags/post_url.rb +8 -6
  63. data/lib/jekyll/url.rb +67 -0
  64. data/lib/monad.rb +36 -27
  65. data/lib/site_template/_config.yml +2 -1
  66. data/lib/site_template/_layouts/default.html +21 -23
  67. data/lib/site_template/_layouts/post.html +1 -1
  68. data/lib/site_template/_posts/{0000-00-00-welcome-to-monad.markdown.erb → 0000-00-00-welcome-to-jekyll.markdown.erb} +6 -6
  69. data/lib/site_template/css/main.css +22 -27
  70. data/lib/site_template/index.html +2 -2
  71. data/monad.gemspec +153 -52
  72. data/site/.gitignore +4 -0
  73. data/site/CNAME +1 -0
  74. data/site/README +1 -0
  75. data/site/_config.yml +6 -0
  76. data/site/_includes/analytics.html +32 -0
  77. data/site/_includes/docs_contents.html +16 -0
  78. data/site/_includes/docs_contents_mobile.html +23 -0
  79. data/site/_includes/docs_option.html +11 -0
  80. data/site/_includes/docs_ul.html +20 -0
  81. data/site/_includes/footer.html +15 -0
  82. data/site/_includes/header.html +18 -0
  83. data/site/_includes/news_contents.html +23 -0
  84. data/site/_includes/news_contents_mobile.html +11 -0
  85. data/site/_includes/news_item.html +24 -0
  86. data/site/_includes/primary-nav-items.html +14 -0
  87. data/site/_includes/section_nav.html +22 -0
  88. data/site/_includes/top.html +17 -0
  89. data/site/_layouts/default.html +12 -0
  90. data/site/_layouts/docs.html +23 -0
  91. data/site/_layouts/news.html +19 -0
  92. data/site/_layouts/news_item.html +27 -0
  93. data/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown +23 -0
  94. data/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown +27 -0
  95. data/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown +28 -0
  96. data/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown +25 -0
  97. data/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown +27 -0
  98. data/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown +31 -0
  99. data/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown +20 -0
  100. data/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown +20 -0
  101. data/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown +23 -0
  102. data/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown +19 -0
  103. data/site/css/gridism.css +110 -0
  104. data/site/css/normalize.css +1 -0
  105. data/site/css/pygments.css +70 -0
  106. data/site/css/style.css +946 -0
  107. data/site/docs/configuration.md +373 -0
  108. data/site/docs/contributing.md +128 -0
  109. data/site/docs/datafiles.md +63 -0
  110. data/site/docs/deployment-methods.md +109 -0
  111. data/site/docs/drafts.md +20 -0
  112. data/site/docs/extras.md +56 -0
  113. data/site/docs/frontmatter.md +180 -0
  114. data/site/docs/github-pages.md +91 -0
  115. data/site/docs/heroku.md +9 -0
  116. data/site/docs/history.md +722 -0
  117. data/site/docs/index.md +52 -0
  118. data/site/docs/installation.md +76 -0
  119. data/site/docs/migrations.md +257 -0
  120. data/site/docs/pages.md +86 -0
  121. data/site/docs/pagination.md +211 -0
  122. data/site/docs/permalinks.md +180 -0
  123. data/site/docs/plugins.md +508 -0
  124. data/site/docs/posts.md +181 -0
  125. data/site/docs/quickstart.md +32 -0
  126. data/site/docs/resources.md +46 -0
  127. data/site/docs/sites.md +29 -0
  128. data/site/docs/structure.md +190 -0
  129. data/site/docs/templates.md +319 -0
  130. data/site/docs/troubleshooting.md +150 -0
  131. data/site/docs/upgrading.md +146 -0
  132. data/site/docs/usage.md +63 -0
  133. data/site/docs/variables.md +322 -0
  134. data/site/favicon.png +0 -0
  135. data/site/feed.xml +36 -0
  136. data/site/freenode.txt +1 -0
  137. data/site/img/article-footer.png +0 -0
  138. data/site/img/footer-arrow.png +0 -0
  139. data/site/img/footer-logo.png +0 -0
  140. data/site/img/logo-2x.png +0 -0
  141. data/site/img/octojekyll.png +0 -0
  142. data/site/img/tube.png +0 -0
  143. data/site/img/tube1x.png +0 -0
  144. data/site/index.html +90 -0
  145. data/site/js/modernizr-2.5.3.min.js +4 -0
  146. data/site/news/index.html +10 -0
  147. data/site/news/releases/index.html +10 -0
  148. data/test/helper.rb +6 -3
  149. data/test/source/+/foo.md +7 -0
  150. data/test/source/_data/languages.yml +2 -0
  151. data/test/source/_data/members.yaml +7 -0
  152. data/test/source/_data/products.yml +4 -0
  153. data/test/source/_includes/params.html +7 -0
  154. data/test/source/_layouts/default.html +1 -1
  155. data/test/source/_layouts/post/simple.html +1 -0
  156. data/test/source/_plugins/dummy.rb +1 -1
  157. data/test/source/_posts/2013-01-02-post-excerpt.markdown +1 -1
  158. data/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown +23 -0
  159. data/test/source/_posts/2013-08-01-mkdn-extension.mkdn +0 -0
  160. data/test/source/deal.with.dots.html +1 -1
  161. data/test/source/products.yml +4 -0
  162. data/test/test_configuration.rb +46 -11
  163. data/test/test_convertible.rb +2 -2
  164. data/test/test_excerpt.rb +78 -0
  165. data/test/test_filters.rb +4 -4
  166. data/test/test_generated_site.rb +13 -13
  167. data/test/test_json_driver.rb +9 -9
  168. data/test/test_kramdown.rb +32 -5
  169. data/test/test_new_command.rb +8 -8
  170. data/test/test_page.rb +12 -3
  171. data/test/test_pager.rb +34 -33
  172. data/test/test_post.rb +34 -26
  173. data/test/test_redcloth.rb +3 -3
  174. data/test/test_related_posts.rb +47 -0
  175. data/test/test_site.rb +102 -44
  176. data/test/test_tags.rb +168 -23
  177. data/test/test_url.rb +28 -0
  178. data/test/test_yaml_driver.rb +6 -6
  179. metadata +215 -137
  180. data/lib/monad/commands/doctor.rb +0 -29
  181. data/lib/monad/commands/new.rb +0 -50
  182. data/lib/monad/commands/serve.rb +0 -33
  183. data/lib/monad/converters/markdown/kramdown_parser.rb +0 -44
  184. data/lib/monad/deprecator.rb +0 -32
  185. data/lib/monad/generators/pagination.rb +0 -143
  186. data/lib/monad/logger.rb +0 -54
  187. data/lib/monad/tags/gist.rb +0 -30
  188. data/lib/monad/tags/include.rb +0 -37
@@ -0,0 +1,211 @@
1
+ ---
2
+ layout: docs
3
+ title: Pagination
4
+ prev_section: permalinks
5
+ next_section: plugins
6
+ permalink: /docs/pagination/
7
+ ---
8
+
9
+ With many websites—especially blogs—it’s very common to break the main listing
10
+ of posts up into smaller lists and display them over multiple pages. Jekyll has
11
+ pagination built-in, so you can automatically generate the appropriate files and
12
+ folders you need for paginated listings.
13
+
14
+ <div class="note info">
15
+ <h5>Pagination only works within HTML files</h5>
16
+ <p>
17
+ Pagination does not work with Markdown or Textile files in your Jekyll site.
18
+ It will only work when used within HTML files. Since you’ll likely be using
19
+ this for the list of Posts, this shouldn’t be an issue.
20
+ </p>
21
+ </div>
22
+
23
+ ## Enable pagination
24
+
25
+ To enable pagination for your blog, add a line to the `_config.yml` file that
26
+ specifies how many items should be displayed per page:
27
+
28
+ {% highlight yaml %}
29
+ paginate: 5
30
+ {% endhighlight %}
31
+
32
+ The number should be the maximum number of Posts you’d like to be displayed per-
33
+ page in the generated site.
34
+
35
+ You may also specify where the destination of the pagination pages:
36
+
37
+ {% highlight yaml %}
38
+ paginate_path: "blog/page:num"
39
+ {% endhighlight %}
40
+
41
+ This will read in `blog/index.html`, send it each pagination page in Liquid as `paginator`
42
+ and write the output to `blog/page:num`, where `:num` is the pagination page number,
43
+ starting with `2`. If a site has 12 posts and specifies `paginate: 5`, Jekyll will write
44
+ `blog/index.html` with the first 5 posts, `blog/page2/index.html` with the next 5 posts
45
+ and `blog/page3/index.html` with the last 2 posts into the destination directory.
46
+
47
+ ## Liquid Attributes Available
48
+
49
+ The pagination plugin exposes the `paginator` liquid object with the following
50
+ attributes:
51
+
52
+ <div class="mobile-side-scroller">
53
+ <table>
54
+ <thead>
55
+ <tr>
56
+ <th>Attribute</th>
57
+ <th>Description</th>
58
+ </tr>
59
+ </thead>
60
+ <tbody>
61
+ <tr>
62
+ <td><p><code>page</code></p></td>
63
+ <td><p>current page number</p></td>
64
+ </tr>
65
+ <tr>
66
+ <td><p><code>per_page</code></p></td>
67
+ <td><p>number of posts per page</p></td>
68
+ </tr>
69
+ <tr>
70
+ <td><p><code>posts</code></p></td>
71
+ <td><p>a list of posts for the current page</p></td>
72
+ </tr>
73
+ <tr>
74
+ <td><p><code>total_posts</code></p></td>
75
+ <td><p>total number of posts in the site</p></td>
76
+ </tr>
77
+ <tr>
78
+ <td><p><code>total_pages</code></p></td>
79
+ <td><p>number of pagination pages</p></td>
80
+ </tr>
81
+ <tr>
82
+ <td><p><code>previous_page</code></p></td>
83
+ <td>
84
+ <p>
85
+ page number of the previous pagination page,
86
+ or <code>nil</code> if no previous page exists
87
+ </p>
88
+ </td>
89
+ </tr>
90
+ <tr>
91
+ <td><p><code>previous_page_path</code></p></td>
92
+ <td>
93
+ <p>
94
+ path of previous pagination page,
95
+ or <code>nil</code> if no previous page exists
96
+ </p>
97
+ </td>
98
+ </tr>
99
+ <tr>
100
+ <td><p><code>next_page</code></p></td>
101
+ <td>
102
+ <p>
103
+ page number of the next pagination page,
104
+ or <code>nil</code> if no subsequent page exists
105
+ </p>
106
+ </td>
107
+ </tr>
108
+ <tr>
109
+ <td><p><code>next_page_path</code></p></td>
110
+ <td>
111
+ <p>
112
+ path of next pagination page,
113
+ or <code>nil</code> if no subsequent page exists
114
+ </p>
115
+ </td>
116
+ </tr>
117
+ </tbody>
118
+ </table>
119
+ </div>
120
+
121
+ <div class="note info">
122
+ <h5>Pagination does not support tags or categories</h5>
123
+ <p>Pagination pages through every post in the <code>posts</code>
124
+ variable regardless of variables defined in the YAML Front Matter of
125
+ each. It does not currently allow paging over groups of posts linked
126
+ by a common tag or category.</p>
127
+ </div>
128
+
129
+ ## Render the paginated Posts
130
+
131
+ The next thing you need to do is to actually display your posts in a list using
132
+ the `paginator` variable that will now be available to you. You’ll probably want
133
+ to do this in one of the main pages of your site. Here’s one example of a simple
134
+ way of rendering paginated Posts in a HTML file:
135
+
136
+ {% highlight html %}
137
+ {% raw %}
138
+ ---
139
+ layout: default
140
+ title: My Blog
141
+ ---
142
+
143
+ <!-- This loops through the paginated posts -->
144
+ {% for post in paginator.posts %}
145
+ <h1><a href="{{ post.url }}">{{ post.title }}</a></h1>
146
+ <p class="author">
147
+ <span class="date">{{ post.date }}</span>
148
+ </p>
149
+ <div class="content">
150
+ {{ post.content }}
151
+ </div>
152
+ {% endfor %}
153
+
154
+ <!-- Pagination links -->
155
+ <div class="pagination">
156
+ {% if paginator.previous_page %}
157
+ <a href="/page{{ paginator.previous_page }}" class="previous">Previous</a>
158
+ {% else %}
159
+ <span class="previous">Previous</span>
160
+ {% endif %}
161
+ <span class="page_number ">Page: {{ paginator.page }} of {{ paginator.total_pages }}</span>
162
+ {% if paginator.next_page %}
163
+ <a href="/page{{ paginator.next_page }}" class="next">Next</a>
164
+ {% else %}
165
+ <span class="next ">Next</span>
166
+ {% endif %}
167
+ </div>
168
+ {% endraw %}
169
+ {% endhighlight %}
170
+
171
+ <div class="note warning">
172
+ <h5>Beware the page one edge-case</h5>
173
+ <p>
174
+ Jekyll does not generate a ‘page1’ folder, so the above code will not work
175
+ when a <code>/page1</code> link is produced. See below for a way to handle
176
+ this if it’s a problem for you.
177
+ </p>
178
+ </div>
179
+
180
+ The following HTML snippet should handle page one, and render a list of each
181
+ page with links to all but the current page.
182
+
183
+ {% highlight html %}
184
+ {% raw %}
185
+ {% if paginator.total_pages > 1 %}
186
+ <div class="pagination">
187
+ {% if paginator.previous_page %}
188
+ <a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">&laquo; Prev</a>
189
+ {% else %}
190
+ <span>&laquo; Prev</span>
191
+ {% endif %}
192
+
193
+ {% for page in (1..paginator.total_pages) %}
194
+ {% if page == paginator.page %}
195
+ <em>{{ page }}</em>
196
+ {% elsif page == 1 %}
197
+ <a href="{{ '/index.html' | prepend: site.baseurl | replace: '//', '/' }}">{{ page }}</a>
198
+ {% else %}
199
+ <a href="{{ site.paginate_path | prepend: site.baseurl | replace: '//', '/' | replace: ':num', page }}">{{ page }}</a>
200
+ {% endif %}
201
+ {% endfor %}
202
+
203
+ {% if paginator.next_page %}
204
+ <a href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}">Next &raquo;</a>
205
+ {% else %}
206
+ <span>Next &raquo;</span>
207
+ {% endif %}
208
+ </div>
209
+ {% endif %}
210
+ {% endraw %}
211
+ {% endhighlight %}
@@ -0,0 +1,180 @@
1
+ ---
2
+ layout: docs
3
+ title: Permalinks
4
+ prev_section: templates
5
+ next_section: pagination
6
+ permalink: /docs/permalinks/
7
+ ---
8
+
9
+ Jekyll supports a flexible way to build your site’s URLs. You can specify the
10
+ permalinks for your site through the [Configuration](../configuration/) or in the
11
+ [YAML Front Matter](../frontmatter/) for each post. You’re free to choose one of
12
+ the built-in styles to create your links or craft your own. The default style is
13
+ `date`.
14
+
15
+ Permalinks are constructed by creating a template URL where dynamic elements are
16
+ represented by colon-prefixed keywords. For example, the default `date`
17
+ permalink is defined as `/:categories/:year/:month/:day/:title.html`.
18
+
19
+ ## Template variables
20
+
21
+ <div class="mobile-side-scroller">
22
+ <table>
23
+ <thead>
24
+ <tr>
25
+ <th>Variable</th>
26
+ <th>Description</th>
27
+ </tr>
28
+ </thead>
29
+ <tbody>
30
+ <tr>
31
+ <td>
32
+ <p><code>year</code></p>
33
+ </td>
34
+ <td>
35
+ <p>Year from the Post’s filename</p>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <td>
40
+ <p><code>month</code></p>
41
+ </td>
42
+ <td>
43
+ <p>Month from the Post’s filename</p>
44
+ </td>
45
+ </tr>
46
+ <tr>
47
+ <td>
48
+ <p><code>i_month</code></p>
49
+ </td>
50
+ <td>
51
+ <p>Month from the Post’s filename without leading zeros.</p>
52
+ </td>
53
+ </tr>
54
+ <tr>
55
+ <td>
56
+ <p><code>day</code></p>
57
+ </td>
58
+ <td>
59
+ <p>Day from the Post’s filename</p>
60
+ </td>
61
+ </tr>
62
+ <tr>
63
+ <td>
64
+ <p><code>i_day</code></p>
65
+ </td>
66
+ <td>
67
+ <p>Day from the Post’s filename without leading zeros.</p>
68
+ </td>
69
+ </tr>
70
+ <tr>
71
+ <td>
72
+ <p><code>title</code></p>
73
+ </td>
74
+ <td>
75
+ <p>Title from the Post’s filename</p>
76
+ </td>
77
+ </tr>
78
+ <tr>
79
+ <td>
80
+ <p><code>categories</code></p>
81
+ </td>
82
+ <td>
83
+ <p>
84
+ The specified categories for this Post. Jekyll automatically parses
85
+ out double slashes in the URLs, so if no categories are present, it
86
+ will ignore this.
87
+ </p>
88
+ </td>
89
+ </tr>
90
+ </tbody>
91
+ </table>
92
+ </div>
93
+
94
+ ## Built-in permalink styles
95
+
96
+ <div class="mobile-side-scroller">
97
+ <table>
98
+ <thead>
99
+ <tr>
100
+ <th>Permalink Style</th>
101
+ <th>URL Template</th>
102
+ </tr>
103
+ </thead>
104
+ <tbody>
105
+ <tr>
106
+ <td>
107
+ <p><code>date</code></p>
108
+ </td>
109
+ <td>
110
+ <p><code>/:categories/:year/:month/:day/:title.html</code></p>
111
+ </td>
112
+ </tr>
113
+ <tr>
114
+ <td>
115
+ <p><code>pretty</code></p>
116
+ </td>
117
+ <td>
118
+ <p><code>/:categories/:year/:month/:day/:title/</code></p>
119
+ </td>
120
+ </tr>
121
+ <tr>
122
+ <td>
123
+ <p><code>none</code></p>
124
+ </td>
125
+ <td>
126
+ <p><code>/:categories/:title.html</code></p>
127
+ </td>
128
+ </tr>
129
+ </tbody>
130
+ </table>
131
+ </div>
132
+
133
+ ## Permalink style examples
134
+
135
+ Given a post named: `/2009-04-29-slap-chop.textile`
136
+
137
+ <div class="mobile-side-scroller">
138
+ <table>
139
+ <thead>
140
+ <tr>
141
+ <th>Permalink Setting</th>
142
+ <th>Resulting Permalink URL</th>
143
+ </tr>
144
+ </thead>
145
+ <tbody>
146
+ <tr>
147
+ <td>
148
+ <p>None specified, or <code>permalink: date</code></p>
149
+ </td>
150
+ <td>
151
+ <p><code>/2009/04/29/slap-chop.html</code></p>
152
+ </td>
153
+ </tr>
154
+ <tr>
155
+ <td>
156
+ <p><code>permalink: pretty</code></p>
157
+ </td>
158
+ <td>
159
+ <p><code>/2009/04/29/slap-chop/index.html</code></p>
160
+ </td>
161
+ </tr>
162
+ <tr>
163
+ <td>
164
+ <p><code>permalink: /:month-:day-:year/:title.html</code></p>
165
+ </td>
166
+ <td>
167
+ <p><code>/04-29-2009/slap-chop.html</code></p>
168
+ </td>
169
+ </tr>
170
+ <tr>
171
+ <td>
172
+ <p><code>permalink: /blog/:year/:month/:day/:title</code></p>
173
+ </td>
174
+ <td>
175
+ <p><code>/blog/2009/04/29/slap-chop/index.html</code></p>
176
+ </td>
177
+ </tr>
178
+ </tbody>
179
+ </table>
180
+ </div>
@@ -0,0 +1,508 @@
1
+ ---
2
+ layout: docs
3
+ title: Plugins
4
+ prev_section: assets
5
+ next_section: extras
6
+ permalink: /docs/plugins/
7
+ ---
8
+
9
+ Jekyll has a plugin system with hooks that allow you to create custom generated
10
+ content specific to your site. You can run custom code for your site without
11
+ having to modify the Jekyll source itself.
12
+
13
+ <div class="note info">
14
+ <h5>Plugins on GitHub Pages</h5>
15
+ <p>
16
+ <a href="http://pages.github.com/">GitHub Pages</a> is powered by Jekyll,
17
+ however all Pages sites are generated using the <code>--safe</code> option
18
+ to disable custom plugins for security reasons. Unfortunately, this means
19
+ your plugins won’t work if you’re deploying to GitHub Pages.<br><br>
20
+ You can still use GitHub Pages to publish your site, but you’ll need to
21
+ convert the site locally and push the generated static files to your GitHub
22
+ repository instead of the Jekyll source files.
23
+ </p>
24
+ </div>
25
+
26
+ ## Installing a plugin
27
+
28
+ In your site source root, make a `_plugins` directory. Place your plugins here.
29
+ Any file ending in `*.rb` inside this directory will be loaded before Jekyll
30
+ generates your site.
31
+
32
+ In general, plugins you make will fall into one of three categories:
33
+
34
+ 1. Generators
35
+ 2. Converters
36
+ 3. Tags
37
+
38
+ ## Generators
39
+
40
+ You can create a generator when you need Jekyll to create additional content
41
+ based on your own rules.
42
+
43
+ A generator is a subclass of `Jekyll::Generator` that defines a `generate`
44
+ method, which receives an instance of
45
+ [`Jekyll::Site`]({{ site.repository }}/blob/master/lib/jekyll/site.rb).
46
+
47
+ Generation is triggered for its side-effects, the return value of `generate` is
48
+ ignored. Jekyll does not assume any particular side-effect to happen, it just
49
+ runs the method.
50
+
51
+ Generators run after Jekyll has made an inventory of the existing content, and
52
+ before the site is generated. Pages with YAML front-matters are stored as
53
+ instances of
54
+ [`Jekyll::Page`]({{ site.repository }}/blob/master/lib/jekyll/page.rb)
55
+ and are available via `site.pages`. Static files become instances of
56
+ [`Jekyll::StaticFile`]({{ site.repository }}/blob/master/lib/jekyll/static_file.rb)
57
+ and are available via `site.static_files`. See
58
+ [`Jekyll::Site`]({{ site.repository }}/blob/master/lib/jekyll/site.rb)
59
+ for more details.
60
+
61
+ For instance, a generator can inject values computed at build time for template
62
+ variables. In the following example the template `reading.html` has two
63
+ variables `ongoing` and `done` that we fill in the generator:
64
+
65
+ {% highlight ruby %}
66
+ module Reading
67
+ class Generator < Jekyll::Generator
68
+ def generate(site)
69
+ ongoing, done = Book.all.partition(&:ongoing?)
70
+
71
+ reading = site.pages.detect {|page| page.name == 'reading.html'}
72
+ reading.data['ongoing'] = ongoing
73
+ reading.data['done'] = done
74
+ end
75
+ end
76
+ end
77
+ {% endhighlight %}
78
+
79
+ This is a more complex generator that generates new pages:
80
+
81
+ {% highlight ruby %}
82
+ module Jekyll
83
+
84
+ class CategoryPage < Page
85
+ def initialize(site, base, dir, category)
86
+ @site = site
87
+ @base = base
88
+ @dir = dir
89
+ @name = 'index.html'
90
+
91
+ self.process(@name)
92
+ self.read_yaml(File.join(base, '_layouts'), 'category_index.html')
93
+ self.data['category'] = category
94
+
95
+ category_title_prefix = site.config['category_title_prefix'] || 'Category: '
96
+ self.data['title'] = "#{category_title_prefix}#{category}"
97
+ end
98
+ end
99
+
100
+ class CategoryPageGenerator < Generator
101
+ safe true
102
+
103
+ def generate(site)
104
+ if site.layouts.key? 'category_index'
105
+ dir = site.config['category_dir'] || 'categories'
106
+ site.categories.keys.each do |category|
107
+ site.pages << CategoryPage.new(site, site.source, File.join(dir, category), category)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ end
114
+ {% endhighlight %}
115
+
116
+ In this example, our generator will create a series of files under the
117
+ `categories` directory for each category, listing the posts in each category
118
+ using the `category_index.html` layout.
119
+
120
+ Generators are only required to implement one method:
121
+
122
+ <div class="mobile-side-scroller">
123
+ <table>
124
+ <thead>
125
+ <tr>
126
+ <th>Method</th>
127
+ <th>Description</th>
128
+ </tr>
129
+ </thead>
130
+ <tbody>
131
+ <tr>
132
+ <td>
133
+ <p><code>generate</code></p>
134
+ </td>
135
+ <td>
136
+ <p>Generates content as a side-effect.</p>
137
+ </td>
138
+ </tr>
139
+ </tbody>
140
+ </table>
141
+ </div>
142
+
143
+ ## Converters
144
+
145
+ If you have a new markup language you’d like to use with your site, you can
146
+ include it by implementing your own converter. Both the Markdown and Textile
147
+ markup languages are implemented using this method.
148
+
149
+ <div class="note info">
150
+ <h5>Remember your YAML front-matter</h5>
151
+ <p>
152
+ Jekyll will only convert files that have a YAML header at the top, even for
153
+ converters you add using a plugin.
154
+ </p>
155
+ </div>
156
+
157
+ Below is a converter that will take all posts ending in `.upcase` and process
158
+ them using the `UpcaseConverter`:
159
+
160
+ {% highlight ruby %}
161
+ module Jekyll
162
+ class UpcaseConverter < Converter
163
+ safe true
164
+ priority :low
165
+
166
+ def matches(ext)
167
+ ext =~ /^\.upcase$/i
168
+ end
169
+
170
+ def output_ext(ext)
171
+ ".html"
172
+ end
173
+
174
+ def convert(content)
175
+ content.upcase
176
+ end
177
+ end
178
+ end
179
+ {% endhighlight %}
180
+
181
+ Converters should implement at a minimum 3 methods:
182
+
183
+ <div class="mobile-side-scroller">
184
+ <table>
185
+ <thead>
186
+ <tr>
187
+ <th>Method</th>
188
+ <th>Description</th>
189
+ </tr>
190
+ </thead>
191
+ <tbody>
192
+ <tr>
193
+ <td>
194
+ <p><code>matches</code></p>
195
+ </td>
196
+ <td><p>
197
+ Does the given extension match this converter’s list of acceptable
198
+ extensions? Takes one argument: the file’s extension (including the
199
+ dot). Must return <code>true</code> if it matches, <code>false</code>
200
+ otherwise.
201
+ </p></td>
202
+ </tr>
203
+ <tr>
204
+ <td>
205
+ <p><code>output_ext</code></p>
206
+ </td>
207
+ <td><p>
208
+ The extension to be given to the output file (including the dot).
209
+ Usually this will be <code>".html"</code>.
210
+ </p></td>
211
+ </tr>
212
+ <tr>
213
+ <td>
214
+ <p><code>convert</code></p>
215
+ </td>
216
+ <td><p>
217
+ Logic to do the content conversion. Takes one argument: the raw content
218
+ of the file (without YAML front matter). Must return a String.
219
+ </p></td>
220
+ </tr>
221
+ </tbody>
222
+ </table>
223
+ </div>
224
+
225
+ In our example, `UpcaseConverter#matches` checks if our filename extension is
226
+ `.upcase`, and will render using the converter if it is. It will call
227
+ `UpcaseConverter#convert` to process the content. In our simple converter we’re
228
+ simply uppercasing the entire content string. Finally, when it saves the page,
229
+ it will do so with a `.html` extension.
230
+
231
+ ## Tags
232
+
233
+ If you’d like to include custom liquid tags in your site, you can do so by
234
+ hooking into the tagging system. Built-in examples added by Jekyll include the
235
+ `highlight` and `include` tags. Below is an example of a custom liquid tag that
236
+ will output the time the page was rendered:
237
+
238
+ {% highlight ruby %}
239
+ module Jekyll
240
+ class RenderTimeTag < Liquid::Tag
241
+
242
+ def initialize(tag_name, text, tokens)
243
+ super
244
+ @text = text
245
+ end
246
+
247
+ def render(context)
248
+ "#{@text} #{Time.now}"
249
+ end
250
+ end
251
+ end
252
+
253
+ Liquid::Template.register_tag('render_time', Jekyll::RenderTimeTag)
254
+ {% endhighlight %}
255
+
256
+ At a minimum, liquid tags must implement:
257
+
258
+ <div class="mobile-side-scroller">
259
+ <table>
260
+ <thead>
261
+ <tr>
262
+ <th>Method</th>
263
+ <th>Description</th>
264
+ </tr>
265
+ </thead>
266
+ <tbody>
267
+ <tr>
268
+ <td>
269
+ <p><code>render</code></p>
270
+ </td>
271
+ <td>
272
+ <p>Outputs the content of the tag.</p>
273
+ </td>
274
+ </tr>
275
+ </tbody>
276
+ </table>
277
+ </div>
278
+
279
+ You must also register the custom tag with the Liquid template engine as
280
+ follows:
281
+
282
+ {% highlight ruby %}
283
+ Liquid::Template.register_tag('render_time', Jekyll::RenderTimeTag)
284
+ {% endhighlight %}
285
+
286
+ In the example above, we can place the following tag anywhere in one of our
287
+ pages:
288
+
289
+ {% highlight ruby %}
290
+ {% raw %}
291
+ <p>{% render_time page rendered at: %}</p>
292
+ {% endraw %}
293
+ {% endhighlight %}
294
+
295
+ And we would get something like this on the page:
296
+
297
+ {% highlight html %}
298
+ <p>page rendered at: Tue June 22 23:38:47 –0500 2010</p>
299
+ {% endhighlight %}
300
+
301
+ ### Liquid filters
302
+
303
+ You can add your own filters to the Liquid template system much like you can add
304
+ tags above. Filters are simply modules that export their methods to liquid. All
305
+ methods will have to take at least one parameter which represents the input of
306
+ the filter. The return value will be the output of the filter.
307
+
308
+ {% highlight ruby %}
309
+ module Jekyll
310
+ module AssetFilter
311
+ def asset_url(input)
312
+ "http://www.example.com/#{input}?#{Time.now.to_i}"
313
+ end
314
+ end
315
+ end
316
+
317
+ Liquid::Template.register_filter(Jekyll::AssetFilter)
318
+ {% endhighlight %}
319
+
320
+ <div class="note">
321
+ <h5>ProTip™: Access the site object using Liquid</h5>
322
+ <p>
323
+ Jekyll lets you access the <code>site</code> object through the
324
+ <code>context.registers</code> feature of Liquid. For example, you can
325
+ access the global configuration file <code>_config.yml</code> using
326
+ <code>context.registers.config</code>.
327
+ </p>
328
+ </div>
329
+
330
+ ### Flags
331
+
332
+ There are two flags to be aware of when writing a plugin:
333
+
334
+ <div class="mobile-side-scroller">
335
+ <table>
336
+ <thead>
337
+ <tr>
338
+ <th>Flag</th>
339
+ <th>Description</th>
340
+ </tr>
341
+ </thead>
342
+ <tbody>
343
+ <tr>
344
+ <td>
345
+ <p><code>safe</code></p>
346
+ </td>
347
+ <td>
348
+ <p>
349
+ A boolean flag that informs Jekyll whether this plugin may be safely
350
+ executed in an environment where arbitrary code execution is not
351
+ allowed. This is used by GitHub Pages to determine which core plugins
352
+ may be used, and which are unsafe to run. If your plugin does not
353
+ allow for arbitrary code, execution, set this to <code>true</code>.
354
+ GitHub Pages still won’t load your plugin, but if you submit it for
355
+ inclusion in core, it’s best for this to be correct!
356
+ </p>
357
+ </td>
358
+ </tr>
359
+ <tr>
360
+ <td>
361
+ <p><code>priority</code></p>
362
+ </td>
363
+ <td>
364
+ <p>
365
+ This flag determines what order the plugin is loaded in. Valid values
366
+ are: <code>:lowest</code>, <code>:low</code>, <code>:normal</code>,
367
+ <code>:high</code>, and <code>:highest</code>. Highest priority
368
+ matches are applied first, lowest priority are applied last.
369
+ </p>
370
+ </td>
371
+ </tr>
372
+ </tbody>
373
+ </table>
374
+ </div>
375
+
376
+ To use one of the example plugins above as an illustration, here is how you’d
377
+ specify these two flags:
378
+
379
+ {% highlight ruby %}
380
+ module Jekyll
381
+ class UpcaseConverter < Converter
382
+ safe true
383
+ priority :low
384
+ ...
385
+ end
386
+ end
387
+ {% endhighlight %}
388
+
389
+ ## Available Plugins
390
+
391
+ You can find a few useful plugins at the following locations:
392
+
393
+ #### Generators
394
+
395
+ - [ArchiveGenerator by Ilkka Laukkanen](https://gist.github.com/707909): Uses [this archive page](https://gist.github.com/707020) to generate archives.
396
+ - [LESS.js Generator by Andy Fowler](https://gist.github.com/642739): Renders LESS.js files during generation.
397
+ - [Version Reporter by Blake Smith](https://gist.github.com/449491): Creates a version.html file containing the Jekyll version.
398
+ - [Sitemap.xml Generator by Michael Levin](https://github.com/kinnetica/jekyll-plugins): Generates a sitemap.xml file by traversing all of the available posts and pages.
399
+ - [Full-text search by Pascal Widdershoven](https://github.com/PascalW/jekyll_indextank): Adds full-text search to your Jekyll site with a plugin and a bit of JavaScript.
400
+ - [AliasGenerator by Thomas Mango](https://github.com/tsmango/jekyll_alias_generator): Generates redirect pages for posts when an alias is specified in the YAML Front Matter.
401
+ - [Pageless Redirect Generator by Nick Quinlan](https://github.com/nquinlan/jekyll-pageless-redirects): Generates redirects based on files in the Jekyll root, with support for htaccess style redirects.
402
+ - [Projectlist by Frederic Hemberger](https://github.com/fhemberger/jekyll-projectlist): Renders files in a directory as a single page instead of separate posts.
403
+ - [RssGenerator by Assaf Gelber](https://github.com/agelber/jekyll-rss): Automatically creates an RSS 2.0 feed from your posts.
404
+
405
+ #### Converters
406
+
407
+ - [Jade plugin by John Papandriopoulos](https://github.com/snappylabs/jade-jekyll-plugin): Jade converter for Jekyll.
408
+ - [HAML plugin by Sam Z](https://gist.github.com/517556): HAML converter for Jekyll.
409
+ - [HAML-Sass Converter by Adam Pearson](https://gist.github.com/481456): Simple HAML-Sass converter for Jekyll. [Fork](https://gist.github.com/528642) by Sam X.
410
+ - [Sass SCSS Converter by Mark Wolfe](https://gist.github.com/960150): Sass converter which uses the new CSS compatible syntax, based Sam X’s fork above.
411
+ - [LESS Converter by Jason Graham](https://gist.github.com/639920): Convert LESS files to CSS.
412
+ - [LESS Converter by Josh Brown](https://gist.github.com/760265): Simple LESS converter.
413
+ - [Upcase Converter by Blake Smith](https://gist.github.com/449463): An example Jekyll converter.
414
+ - [CoffeeScript Converter by phaer](https://gist.github.com/959938): A [CoffeeScript](http://coffeescript.org) to Javascript converter.
415
+ - [Markdown References by Olov Lassus](https://github.com/olov/jekyll-references): Keep all your markdown reference-style link definitions in one \_references.md file.
416
+ - [Stylus Converter](https://gist.github.com/988201): Convert .styl to .css.
417
+ - [ReStructuredText Converter](https://github.com/xdissent/jekyll-rst): Converts ReST documents to HTML with Pygments syntax highlighting.
418
+ - [Jekyll-pandoc-plugin](https://github.com/dsanson/jekyll-pandoc-plugin): Use pandoc for rendering markdown.
419
+ - [Jekyll-pandoc-multiple-formats](https://github.com/fauno/jekyll-pandoc-multiple-formats) by [edsl](https://github.com/edsl): Use pandoc to generate your site in multiple formats. Supports pandoc’s markdown extensions.
420
+ - [ReStructuredText Converter](https://github.com/xdissent/jekyll-rst): Converts ReST documents to HTML with Pygments syntax highlighting.
421
+ - [Transform Layouts](https://gist.github.com/1472645): Allows HAML layouts (you need a HAML Converter plugin for this to work).
422
+
423
+ #### Filters
424
+
425
+ - [Truncate HTML](https://github.com/MattHall/truncatehtml) by [Matt Hall](http://codebeef.com): A Jekyll filter that truncates HTML while preserving markup structure.
426
+ - [Domain Name Filter by Lawrence Woodman](https://github.com/LawrenceWoodman/domain_name-liquid_filter): Filters the input text so that just the domain name is left.
427
+ - [Summarize Filter by Mathieu Arnold](https://gist.github.com/731597): Remove markup after a `<div id="extended">` tag.
428
+ - [URL encoding by James An](https://gist.github.com/919275): Percent encoding for URIs.
429
+ - [JSON Filter](https://gist.github.com/1850654) by [joelverhagen](https://github.com/joelverhagen): Filter that takes input text and outputs it as JSON. Great for rendering JavaScript.
430
+ - [i18n_filter](https://github.com/gacha/gacha.id.lv/blob/master/_plugins/i18n_filter.rb): Liquid filter to use I18n localization.
431
+ - [Smilify](https://github.com/SaswatPadhi/jekyll_smilify) by [SaswatPadhi](https://github.com/SaswatPadhi): Convert text emoticons in your content to themeable smiley pics ([Demo](http://saswatpadhi.github.com/)).
432
+ - [Read in X Minutes](https://gist.github.com/zachleat/5792681) by [zachleat](https://github.com/zachleat): Estimates the reading time of a string (for blog post content).
433
+ - [Jekyll-timeago](https://github.com/markets/jekyll-timeago): Converts a time value to the time ago in words.
434
+ - [pluralize](https://github.com/bdesham/pluralize): Easily combine a number and a word into a gramatically-correct amount like “1 minute” or “2 minute**s**”.
435
+ - [reading_time](https://github.com/bdesham/reading_time): Count words and estimate reading time for a piece of text, ignoring HTML elements that are unlikely to contain running text.
436
+ - [Table of Content Generator](https://github.com/dafi/jekyll-toc-generator): Generate the HTML code containing a table of content (TOC), the TOC can be customized in many way, for example you can decide which pages can be without TOC.
437
+
438
+ #### Tags
439
+
440
+ - [Delicious Plugin by Christian Hellsten](https://github.com/christianhellsten/jekyll-plugins): Fetches and renders bookmarks from delicious.com.
441
+ - [Ultraviolet Plugin by Steve Alex](https://gist.github.com/480380): Jekyll tag for the [Ultraviolet](http://ultraviolet.rubyforge.org/) code highligher.
442
+ - [Tag Cloud Plugin by Ilkka Laukkanen](https://gist.github.com/710577): Generate a tag cloud that links to tag pages.
443
+ - [GIT Tag by Alexandre Girard](https://gist.github.com/730347): Add Git activity inside a list.
444
+ - [MathJax Liquid Tags by Jessy Cowan-Sharp](https://gist.github.com/834610): Simple liquid tags for Jekyll that convert inline math and block equations to the appropriate MathJax script tags.
445
+ - [Non-JS Gist Tag by Brandon Tilley](https://gist.github.com/1027674) A Liquid tag that embeds Gists and shows code for non-JavaScript enabled browsers and readers.
446
+ - [Render Time Tag by Blake Smith](https://gist.github.com/449509): Displays the time a Jekyll page was generated.
447
+ - [Status.net/OStatus Tag by phaer](https://gist.github.com/912466): Displays the notices in a given status.net/ostatus feed.
448
+ - [Raw Tag by phaer](https://gist.github.com/1020852): Keeps liquid from parsing text betweeen `raw` tags.
449
+ - [Embed.ly client by Robert Böhnke](https://github.com/robb/jekyll-embedly-client): Autogenerate embeds from URLs using oEmbed.
450
+ - [Logarithmic Tag Cloud](https://gist.github.com/2290195): Flexible. Logarithmic distribution. Documentation inline.
451
+ - [oEmbed Tag by Tammo van Lessen](https://gist.github.com/1455726): Enables easy content embedding (e.g. from YouTube, Flickr, Slideshare) via oEmbed.
452
+ - [FlickrSetTag by Thomas Mango](https://github.com/tsmango/jekyll_flickr_set_tag): Generates image galleries from Flickr sets.
453
+ - [Tweet Tag by Scott W. Bradley](https://github.com/scottwb/jekyll-tweet-tag): Liquid tag for [Embedded Tweets](https://dev.twitter.com/docs/embedded-tweets) using Twitter’s shortcodes.
454
+ - [Jekyll-contentblocks](https://github.com/rustygeldmacher/jekyll-contentblocks): Lets you use Rails-like content_for tags in your templates, for passing content from your posts up to your layouts.
455
+ - [Generate YouTube Embed](https://gist.github.com/1805814) by [joelverhagen](https://github.com/joelverhagen): Jekyll plugin which allows you to embed a YouTube video in your page with the YouTube ID. Optionally specify width and height dimensions. Like “oEmbed Tag” but just for YouTube.
456
+ - [Jekyll-beastiepress](https://github.com/okeeblow/jekyll-beastiepress): FreeBSD utility tags for Jekyll sites.
457
+ - [Jsonball](https://gist.github.com/1895282): Reads json files and produces maps for use in Jekyll files.
458
+ - [Bibjekyll](https://github.com/pablooliveira/bibjekyll): Render BibTeX-formatted bibliographies/citations included in posts and pages using bibtex2html.
459
+ - [Jekyll-citation](https://github.com/archome/jekyll-citation): Render BibTeX-formatted bibliographies/citations included in posts and pages (pure Ruby).
460
+ - [Jekyll Dribbble Set Tag](https://github.com/ericdfields/Jekyll-Dribbble-Set-Tag): Builds Dribbble image galleries from any user.
461
+ - [Debbugs](https://gist.github.com/2218470): Allows posting links to Debian BTS easily.
462
+ - [Refheap_tag](https://github.com/aburdette/refheap_tag): Liquid tag that allows embedding pastes from [refheap](https://refheap.com).
463
+ - [Jekyll-devonly_tag](https://gist.github.com/2403522): A block tag for including markup only during development.
464
+ - [JekyllGalleryTag](https://github.com/redwallhp/JekyllGalleryTag) by [redwallhp](https://github.com/redwallhp): Generates thumbnails from a directory of images and displays them in a grid.
465
+ - [Youku and Tudou Embed](https://gist.github.com/Yexiaoxing/5891929): Liquid plugin for embedding Youku and Tudou videos.
466
+ - [Jekyll-swfobject](https://github.com/sectore/jekyll-swfobject): Liquid plugin for embedding Adobe Flash files (.swf) using [SWFObject](http://code.google.com/p/swfobject/).
467
+ - [Jekyll Picture Tag](https://github.com/robwierzbowski/jekyll-picture-tag): Easy responsive images for Jekyll. Based on the proposed [`<picture>`](http://picture.responsiveimages.org/) element, polyfilled with Scott Jehl’s [Picturefill](https://github.com/scottjehl/picturefill).
468
+ - [Jekyll Image Tag](https://github.com/robwierzbowski/jekyll-image-tag): Better images for Jekyll. Save image presets, generate resized images, and add classes, alt text, and other attributes.
469
+ - [Ditaa Tag](https://github.com/matze/jekyll-ditaa) by [matze](https://github.com/matze): Renders ASCII diagram art into PNG images and inserts a figure tag.
470
+ - [Good Include](https://github.com/penibelst/jekyll-good-include) by [Anatol Broder](http://penibelst.de/): Strips newlines and whitespaces from the end of include files before processing.
471
+ - [Jekyll Suggested Tweet](https://github.com/davidensinger/jekyll-suggested-tweet) by [David Ensinger](https://github.com/davidensinger/): A Liquid tag for Jekyll that allows for the embedding of suggested tweets via Twitter’s Web Intents API.
472
+
473
+ #### Collections
474
+
475
+ - [Jekyll Plugins by Recursive Design](http://recursive-design.com/projects/jekyll-plugins/): Plugins to generate Project pages from GitHub readmes, a Category page, and a Sitemap generator.
476
+ - [Company website and blog plugins](https://github.com/flatterline/jekyll-plugins) by Flatterline, a [Ruby on Rails development company](http://flatterline.com/): Portfolio/project page generator, team/individual page generator, an author bio liquid tag for use on posts, and a few other smaller plugins.
477
+ - [Jekyll plugins by Aucor](https://github.com/aucor/jekyll-plugins): Plugins for trimming unwanted newlines/whitespace and sorting pages by weight attribute.
478
+
479
+ #### Other
480
+
481
+ - [Pygments Cache Path by Raimonds Simanovskis](https://github.com/rsim/blog.rayapps.com/blob/master/_plugins/pygments_cache_patch.rb): Plugin to cache syntax-highlighted code from Pygments.
482
+ - [Draft/Publish Plugin by Michael Ivey](https://gist.github.com/49630): Save posts as drafts.
483
+ - [Growl Notification Generator by Tate Johnson](https://gist.github.com/490101): Send Jekyll notifications to Growl.
484
+ - [Growl Notification Hook by Tate Johnson](https://gist.github.com/525267): Better alternative to the above, but requires his “hook” fork.
485
+ - [Related Posts by Lawrence Woodman](https://github.com/LawrenceWoodman/related_posts-jekyll_plugin): Overrides `site.related_posts` to use categories to assess relationship.
486
+ - [Tiered Archives by Eli Naeher](https://gist.github.com/88cda643aa7e3b0ca1e5): Create tiered template variable that allows you to group archives by year and month.
487
+ - [Jekyll-localization](https://github.com/blackwinter/jekyll-localization): Jekyll plugin that adds localization features to the rendering engine.
488
+ - [Jekyll-rendering](https://github.com/blackwinter/jekyll-rendering): Jekyll plugin to provide alternative rendering engines.
489
+ - [Jekyll-pagination](https://github.com/blackwinter/jekyll-pagination): Jekyll plugin to extend the pagination generator.
490
+ - [Jekyll-tagging](https://github.com/pattex/jekyll-tagging): Jekyll plugin to automatically generate a tag cloud and tag pages.
491
+ - [Jekyll-scholar](https://github.com/inukshuk/jekyll-scholar): Jekyll extensions for the blogging scholar.
492
+ - [Jekyll-asset_bundler](https://github.com/moshen/jekyll-asset_bundler): Bundles and minifies JavaScript and CSS.
493
+ - [Jekyll-assets](http://ixti.net/jekyll-assets/) by [ixti](https://github.com/ixti): Rails-alike assets pipeline (write assets in CoffeeScript, Sass, LESS etc; specify dependencies for automatic bundling using simple declarative comments in assets; minify and compress; use JST templates; cache bust; and many-many more).
494
+ - [File compressor](https://gist.github.com/2758691) by [mytharcher](https://github.com/mytharcher): Compress HTML and JavaScript files on site build.
495
+ - [Jekyll-minibundle](https://github.com/tkareine/jekyll-minibundle): Asset bundling and cache busting using external minification tool of your choice. No gem dependencies.
496
+ - [Singlepage-jekyll](https://github.com/JCB-K/singlepage-jekyll) by [JCB-K](https://github.com/JCB-K): Turns Jekyll into a dynamic one-page website.
497
+ - [generator-jekyllrb](https://github.com/robwierzbowski/generator-jekyllrb): A generator that wraps Jekyll in [Yeoman](http://yeoman.io/), a tool collection and workflow for builing modern web apps.
498
+ - [grunt-jekyll](https://github.com/dannygarcia/grunt-jekyll): A straightforward [Grunt](http://gruntjs.com/) plugin for Jekyll.
499
+ - [jekyll-postfiles](https://github.com/indirect/jekyll-postfiles): Add `_postfiles` directory and {% raw %}`{{ postfile }}`{% endraw %} tag so the files a post refers to will always be right there inside your repo.
500
+
501
+ <div class="note info">
502
+ <h5>Jekyll Plugins Wanted</h5>
503
+ <p>
504
+ If you have a Jekyll plugin that you would like to see added to this list,
505
+ you should <a href="../contributing/">read the contributing page</a> to find
506
+ out how to make that happen.
507
+ </p>
508
+ </div>