1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
|
---
title: Hooks
permalink: /docs/plugins/hooks/
---
Using hooks, your plugin can exercise fine-grained control over various aspects of the build process. If your plugin defines any hooks, Jekyll
will call them at pre-defined points.
Hooks are registered to an owner and an event name. To register one, you call `Jekyll::Hooks.register`, and pass the hook owner, event name,
and code to call whenever the hook is triggered. For example, if you want to execute some custom functionality every time Jekyll renders a
page, you could register a hook like this:
```ruby
Jekyll::Hooks.register :pages, :post_render do |page|
# code to call after Jekyll renders a page
end
```
*Note: The `:post_convert` events mentioned hereafter is a feature introduced in v4.2.0.*
Out of the box, Jekyll has pre-defined hook points for owners `:site`, `:pages`, `:documents` and `:clean`. Additionally, the hook points
defined for `:documents` can be utilized for individual collections only by invoking the collection type instead. i.e. `:posts` for documents
in collection `_posts` and `:movies` for documents in collection `_movies`. In all cases, Jekyll calls your hooks with the owner object as the
first callback parameter.
Every registered hook owner supports the following events — `:post_init`, `:pre_render`, `:post_convert`, `:post_render`, `:post_write`
— however, the `:site` owner is set up to *respond* to *special event names*. Refer to the subsequent section for details.
All `:pre_render` hooks and the `:site, :post_render` hook will also provide a `payload` hash as a second parameter. While in the case of
`:pre_render` events, the payload gives you full control over the variables that are available during rendering, with the `:site, :post_render`
event, the payload contains final values after rendering all the site (useful for sitemaps, feeds, etc).
## Built-in Hook Owners and Events
The complete list of available hooks:
<div class="mobile-side-scroller">
<table id="builtin-hooks">
<thead>
<tr>
<th>Owner</th>
<th>Event</th>
<th>Triggered at</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="6">
<p><code>:site</code></p>
<p>Encompasses the entire site</p>
</td>
<td>
<p><code>:after_init</code></p>
</td>
<td>
<p>Just after the site initializes. Good for modifying the configuration of the site. Triggered once per build / serve session</p>
</td>
</tr>
<tr>
<td>
<p><code>:after_reset</code></p>
</td>
<td>
<p>Just after the site resets during regeneration</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_read</code></p>
</td>
<td>
<p>After all source files have been read and loaded from disk</p>
</td>
</tr>
<tr>
<td>
<p><code>:pre_render</code></p>
</td>
<td>
<p>Just before rendering the whole site</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_render</code></p>
</td>
<td>
<p>After rendering the whole site, but before writing any files</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_write</code></p>
</td>
<td>
<p>After writing all of the rendered files to disk</p>
</td>
</tr>
<tr>
<td rowspan="5">
<p><code>:pages</code></p>
<p>Allows fine-grained control over all pages in the site</p>
</td>
<td>
<p><code>:post_init</code></p>
</td>
<td>
<p>Whenever a page is initialized</p>
</td>
</tr>
<tr>
<td>
<p><code>:pre_render</code></p>
</td>
<td>
<p>Just before rendering a page</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_convert</code></p>
</td>
<td>
<p>After converting the page content, but before rendering the page layout</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_render</code></p>
</td>
<td>
<p>After rendering a page, but before writing it to disk</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_write</code></p>
</td>
<td>
<p>After writing a page to disk</p>
</td>
</tr>
<tr>
<td rowspan="5">
<p><code>:documents</code></p>
<p>Allows fine-grained control over all documents in the site including posts and documents in user-defined collections</p>
</td>
<td>
<p><code>:post_init</code></p>
</td>
<td>
<p>Whenever any document is initialized</p>
</td>
</tr>
<tr>
<td>
<p><code>:pre_render</code></p>
</td>
<td>
<p>Just before rendering a document</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_convert</code></p>
</td>
<td>
<p>
After converting the document content, but before rendering the document
layout
</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_render</code></p>
</td>
<td>
<p>After rendering a document, but before writing it to disk</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_write</code></p>
</td>
<td>
<p>After writing a document to disk</p>
</td>
</tr>
<tr>
<td rowspan="5">
<p><code>:posts</code></p>
<p>Allows fine-grained control over all posts in the site without affecting documents in user-defined collections</p>
</td>
<td>
<p><code>:post_init</code></p>
</td>
<td>
<p>Whenever a post is initialized</p>
</td>
</tr>
<tr>
<td>
<p><code>:pre_render</code></p>
</td>
<td>
<p>Just before rendering a post</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_convert</code></p>
</td>
<td>
<p>After converting the post content, but before rendering the post layout</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_render</code></p>
</td>
<td>
<p>After rendering a post, but before writing it to disk</p>
</td>
</tr>
<tr>
<td>
<p><code>:post_write</code></p>
</td>
<td>
<p>After writing a post to disk</p>
</td>
</tr>
<tr>
<td>
<p><code>:clean</code></p>
<p>Fine-grained control on the list of obsolete files determined to be deleted during the site's cleanup phase.</p>
</td>
<td>
<p><code>:on_obsolete</code></p>
</td>
<td>
<p>During the cleanup of a site's destination before it is built</p>
</td>
</tr>
</tbody>
</table>
</div>
## Hooks for custom Jekyll objects
You can also register and trigger hooks for Jekyll objects introduced by your plugin. All it takes is placing `trigger` calls under a suitable
`owner` name, at positions desired within your custom class and registering the `owner` by your plugin.
To illustrate, consider the following plugin that implements custom functionality for every custom `Excerpt` object initialized:
```ruby
module Foobar
class HookedExcerpt < Jekyll::Excerpt
def initialize(doc)
super
trigger_hooks(:post_init)
end
def output
@output ||= trigger_hooks(:post_render, renderer.run)
end
def renderer
@renderer ||= Jekyll::Renderer.new(
doc.site, self, site.site_payload
)
end
def trigger_hooks(hook_name, *args)
Jekyll::Hooks.trigger :excerpts, hook_name, self, *args
end
end
end
Jekyll::Hooks.register :excerpts, :post_init do |excerpt|
Jekyll.logger.debug "Initialized:",
"Hooked Excerpt for #{excerpt.doc.inspect}"
end
Jekyll::Hooks.register :excerpts, :post_render do |excerpt, output|
return output unless excerpt.doc.type == :posts
Foobar.transform(output)
end
```
|