jekyll_plugin_support 0.7.2 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +63 -50
- data/CHANGELOG.md +19 -0
- data/README.md +306 -132
- data/jekyll_plugin_support.gemspec +3 -2
- data/lib/jekyll_custom_error.rb +55 -0
- data/lib/jekyll_plugin_error_handling.rb +51 -0
- data/lib/jekyll_plugin_helper.rb +20 -134
- data/lib/jekyll_plugin_helper_attribution.rb +72 -0
- data/lib/jekyll_plugin_helper_class.rb +73 -0
- data/lib/jekyll_plugin_support/version.rb +1 -1
- data/lib/jekyll_plugin_support.rb +6 -202
- data/lib/jekyll_plugin_support_block.rb +94 -0
- data/lib/jekyll_plugin_support_block_noarg.rb +30 -0
- data/lib/jekyll_plugin_support_class.rb +88 -0
- data/lib/jekyll_plugin_support_tag.rb +91 -0
- data/lib/jekyll_plugin_support_tag_noarg.rb +26 -0
- data/spec/custom_error_spec.rb +39 -0
- data/spec/liquid_variable_parsing_spec.rb +34 -0
- data/spec/spec_helper.rb +1 -2
- data/spec/status_persistence.txt +6 -0
- metadata +31 -6
- data/lib/call_chain.rb +0 -54
- data/lib/gem_support.rb +0 -19
data/README.md
CHANGED
@@ -1,155 +1,182 @@
|
|
1
1
|
# `jekyll_plugin_support` [](https://badge.fury.io/rb/jekyll_plugin_support)
|
2
2
|
|
3
|
-
`Jekyll_plugin_support` is a Ruby gem that
|
3
|
+
`Jekyll_plugin_support` is a Ruby gem that provides a framework for writing and testing Jekyll plugins.
|
4
|
+
|
5
|
+
`Jekyll_plugin_support` can be used to create simple Jekyll plugins in
|
6
|
+
the `_plugins/` directory of your Jekyll project, or gem-based Jekyll plugins.
|
7
|
+
|
4
8
|
At present, only Jekyll tags and blocks are supported.
|
5
9
|
|
10
|
+
Plugins that use `jekyll_plugin_support` include:
|
6
11
|
|
7
|
-
|
12
|
+
<ul style="columns: 2">
|
13
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_all_collections'><code>jekyll_all_collections</code></a></li>
|
14
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_badge'><code>jekyll_badge</code></a></li>
|
15
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_emoji'><code>jekyll_emoji</code></a></li>
|
16
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_flexible_include.html'><code>jekyll_flexible_include</code></a></li>
|
17
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_href.html'><code>jekyll_href</code></a></li>
|
18
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_img.html'><code>jekyll_img</code></a></li>
|
19
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_plugin_template.html'><code>jekyll_plugin_template</code></a></li>
|
20
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_outline.html'><code>jekyll_outline</code></a></li>
|
21
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_pre.html'><code>jekyll_pre</code></a></li>
|
22
|
+
<li><a href='https://www.mslinn.com/jekyll_plugins/jekyll_quote.html'><code>jekyll_quote</code></a></li>
|
23
|
+
</ul>
|
8
24
|
|
9
|
-
|
25
|
+
... and also the demonstration plugins in
|
26
|
+
[`jekyll_plugin_support`](https://github.com/mslinn/jekyll_plugin_support/tree/master/demo/_plugins)
|
10
27
|
|
11
|
-
### Simple Plugins
|
12
28
|
|
13
|
-
|
14
|
-
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
`Jekyll_plugin_support` is packaged as a Ruby gem.
|
32
|
+
If your project is a custom plugin that will reside in a Jekyll project’s `_plugins` directory,
|
33
|
+
add the following line to your Jekyll plugin’s `Gemfile`.
|
15
34
|
|
16
35
|
```ruby
|
17
36
|
group :jekyll_plugins do
|
18
|
-
|
37
|
+
...
|
38
|
+
gem 'jekyll_plugin_support', '>= 0.8.0'
|
39
|
+
...
|
19
40
|
end
|
20
41
|
```
|
21
42
|
|
22
|
-
|
43
|
+
Otherwise, if your custom plugin will be packaged into a gem, add the following to your plugin’s `.gemspec`:
|
23
44
|
|
24
|
-
```
|
25
|
-
|
45
|
+
```ruby
|
46
|
+
Gem::Specification.new do |spec|
|
47
|
+
...
|
48
|
+
spec.add_dependency 'jekyll_plugin_support', '>= 0.8.0'
|
49
|
+
...
|
50
|
+
end
|
26
51
|
```
|
27
52
|
|
53
|
+
Install the `jekyll_plugin_support` Ruby gem and mark it as a dependency of your project by typing:
|
28
54
|
|
29
|
-
|
55
|
+
```shell
|
56
|
+
$ bundle
|
57
|
+
```
|
30
58
|
|
31
|
-
|
59
|
+
Copy the CSS classes from `demo/assets/css/jekyll_plugin_support.css` to your Jekyll project’s CSS file.
|
32
60
|
|
33
|
-
```ruby
|
34
|
-
spec.add_dependency 'jekyll_plugin_support'
|
35
|
-
```
|
36
61
|
|
37
|
-
|
62
|
+
## About `jekyll_plugin_support`
|
38
63
|
|
39
|
-
|
40
|
-
|
41
|
-
|
64
|
+
`JekyllSupport::JekyllBlock` and `JekyllSupport::JekyllTag`
|
65
|
+
provide support for [Jekyll tag block plugins](https://jekyllrb.com/docs/plugins/tags/#tag-blocks)
|
66
|
+
and [Jekyll inline tag plugins](https://jekyllrb.com/docs/plugins/tags/), respectively.
|
67
|
+
They are very similar in construction and usage.
|
68
|
+
|
69
|
+
Instead of subclassing your custom Jekyll block tag class from `Liquid::Block`,
|
70
|
+
subclass from `JekyllSupport::JekyllBlock`.
|
71
|
+
Similarly, instead of subclassing your custom Jekyll tag class from `Liquid::Tag`,
|
72
|
+
subclass from `JekyllSupport::JekyllTag`.
|
73
|
+
|
74
|
+
Both JekyllSupport classes instantiate new instances of
|
75
|
+
[`PluginMetaLogger`](https://github.com/mslinn/jekyll_plugin_logger) (called `@logger`) and
|
76
|
+
[`JekyllPluginHelper`](https://github.com/mslinn/jekyll_plugin_support/blob/master/lib/jekyll_plugin_support_helper.rb)
|
77
|
+
(called `@helper`).
|
78
|
+
|
79
|
+
`JekyllPluginHelper` defines a generic initialize method, and your tag or block tag class should not need to override it.
|
80
|
+
Also, your tag or block tag class should not define a method called render, because `jekyll_plugin_support` defines one.
|
81
|
+
|
82
|
+
Instead, define a method called `render_impl`.
|
83
|
+
For inline tags, `render_impl` does not accept any parameters.
|
84
|
+
For block tags, a single parameter is required, which contains text passed from your block in the page.
|
85
|
+
|
86
|
+
Your implementation of render_impl can parse parameters passed to the tag / block tag, as described in
|
87
|
+
[Tag Parameter Parsing](http://mslinn.com/jekyll/10100-jekyll-plugin-background.html#params).
|
88
|
+
|
89
|
+
The following variables are predefined within `render`.
|
90
|
+
See the [Jekyll documentation](https://jekyllrb.com/docs/variables/) for more information.
|
91
|
+
|
92
|
+
* `@argument_string` – Original unparsed string from the tag in the web page
|
93
|
+
* `@config` – Jekyll [configuration data](https://jekyllrb.com/docs/configuration/)
|
94
|
+
* `@layout` – Front matter specified in layouts
|
95
|
+
* `@mode` – [possible values](https://jekyllrb.com/docs/configuration/environments/)
|
96
|
+
are `development`, `production`, or `test`
|
97
|
+
* `@page` – Jekyll [page variable](https://jekyllrb.com/docs/variables/#page-variables)
|
98
|
+
* `@paginator` – Only has a value when a paginator is active; they are only available in index files.
|
99
|
+
* `@site` – Jekyll [site variable](https://jekyllrb.com/docs/variables/#site-variables)
|
100
|
+
* `@tag_name` – Name of the inline tag or block plugin
|
101
|
+
* `@theme` – Theme variables (introduced in Jekyll 4.3.0)
|
42
102
|
|
43
103
|
|
44
104
|
## General Usage
|
45
105
|
|
106
|
+
Please see the [`demo/`](demo/) project for a well-documented set of demonstration Jekyll plugins that are built from `jekyll_plugin_support`.
|
107
|
+
Additional information is available [here](https://mslinn.com/jekyll/10200-jekyll-plugin-background.html) and the
|
108
|
+
[`jekyll_plugin_support`](https://www.mslinn.com/jekyll_plugins/jekyll_plugin_support.html) documentation.
|
109
|
+
|
46
110
|
`JekyllSupport::JekyllBlock` and `JekyllSupport::JekyllTag`
|
47
|
-
provide support for Jekyll
|
48
|
-
They are
|
111
|
+
provide support for Jekyll block tags and Jekyll inline tags, respectively.
|
112
|
+
They are similar in construction and usage.
|
49
113
|
|
50
114
|
Instead of subclassing your Jekyll block tag class from `Liquid::Block`,
|
51
115
|
subclass from `JekyllSupport::JekyllBlock` instead.
|
52
116
|
|
53
|
-
|
117
|
+
Likewise, instead of subclassing your Jekyll inline tag class from `Liquid::Tag`,
|
54
118
|
subclass from `JekyllSupport::JekyllTag` instead.
|
55
119
|
|
56
120
|
Both `JekyllSupport` classes instantiate new instances of
|
57
121
|
[`PluginMetaLogger`](https://github.com/mslinn/jekyll_plugin_logger) (called `@logger`) and
|
58
|
-
[`JekyllPluginHelper`](lib/
|
122
|
+
[`JekyllPluginHelper`](lib/jekyll_plugin_helper.rb) (called `@helper`).
|
123
|
+
|
124
|
+
|
125
|
+
### Inline and Block Tag Plugin Implementation
|
126
|
+
|
127
|
+
Both `JekyllSupport` classes define a generic `initialize` method,
|
128
|
+
and your inline tag or block tag class should not override it.
|
129
|
+
|
130
|
+
Also, your inline tag or block tag class should not define a method called `render`,
|
131
|
+
because both `JekyllSupport` classes define this method.
|
59
132
|
|
60
|
-
`JekyllPluginHelper` defines a generic `initialize` method,
|
61
|
-
and your tag or block tag class should not override it.
|
62
|
-
Also, your tag or block tag class should not define a method called `render`,
|
63
|
-
because `JekyllBlock.initialize` defines one, which creates variables called
|
64
|
-
[`@page`](https://jekyllrb.com/docs/variables/#page-variables) and
|
65
|
-
[`@site`](https://jekyllrb.com/docs/variables/#site-variables).
|
66
133
|
|
67
134
|
Instead, define a method called `render_impl`.
|
68
|
-
For tags, `render_impl` does not accept any parameters.
|
135
|
+
For inline tags, `render_impl` does not accept any parameters.
|
69
136
|
For block tags, a single parameter is required, which contains any text enclosed within your block.
|
70
137
|
|
71
|
-
Your implementation of `render_impl` can access `@page` and `@site`,
|
72
|
-
and can parse parameters passed to the tag / block tag, [as described here](https://mslinn.com/jekyll/10100-jekyll-plugin-background.html#params):
|
73
138
|
|
74
|
-
|
139
|
+
## Predefined Plugin Variables
|
75
140
|
|
76
|
-
|
77
|
-
require 'jekyll_plugin_support'
|
141
|
+
`Jekyll_plugin_support` defines the following Ruby variables that you can use in your plugin’s `render_impl` method:
|
78
142
|
|
79
|
-
|
80
|
-
class MyTag < JekyllSupport::JekyllTag
|
81
|
-
VERSION = '0.1.0'.freeze
|
143
|
+
* `@argument_string` Unparsed markup passed as a parameter to your block tag and inline tag.
|
82
144
|
|
83
|
-
|
84
|
-
my_output = "<p>blah blah</p>"
|
85
|
-
<<~END_OUTPUT
|
86
|
-
#{my_output}
|
87
|
-
END_OUTPUT
|
88
|
-
end
|
145
|
+
* [`@attribution`](#subclass-attribution) Attribution markup
|
89
146
|
|
90
|
-
|
91
|
-
|
92
|
-
end
|
93
|
-
```
|
147
|
+
* [`@config`](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll#configuring-jekyll-in-your-github-pages-site)
|
148
|
+
[YAML](https://yaml.org/) Jekyll site configuration file
|
94
149
|
|
95
|
-
|
150
|
+
* [`@helper`](https://github.com/mslinn/jekyll_plugin_support/blob/master/lib/jekyll_plugin_helper.rb)
|
151
|
+
`JekyllPluginHelper` instance for your plugin.
|
96
152
|
|
97
|
-
|
98
|
-
require 'jekyll_plugin_support'
|
99
|
-
|
100
|
-
module Jekyll
|
101
|
-
class MyBlock < JekyllSupport::JekyllBlock
|
102
|
-
VERSION = '0.1.0'.freeze
|
103
|
-
|
104
|
-
def render_impl(content)
|
105
|
-
@helper.gem_file __FILE__ # Enables attribution
|
106
|
-
my_output = "<p>blah blah</p>"
|
107
|
-
<<~END_OUTPUT
|
108
|
-
#{my_output}
|
109
|
-
#{@helper.attribute if @helper.attribution}
|
110
|
-
END_OUTPUT
|
111
|
-
end
|
112
|
-
|
113
|
-
JekyllPluginHelper.register(self, 'demo_block')
|
114
|
-
end
|
115
|
-
end
|
116
|
-
```
|
153
|
+
* [`@layout`](https://jekyllrb.com/docs/variables/#global-variables) Layout information
|
117
154
|
|
118
|
-
|
119
|
-
If your plugin is packaged as a gem, then you might need to include `version.rb` into the plugin class.
|
120
|
-
For example, if `lib/my_plugin/version.rb` looks like this:
|
155
|
+
* [`@logger`](jekyll_plugin_logger) `jekyll_plugin_logger` instance for your Jekyll plugin.
|
121
156
|
|
122
|
-
|
123
|
-
|
124
|
-
VERSION = '0.5.1'.freeze
|
125
|
-
end
|
126
|
-
```
|
157
|
+
* [`@mode`](https://jekyllrb.com/docs/configuration/environments/)
|
158
|
+
Indicates `production` or `development` mode.
|
127
159
|
|
128
|
-
|
160
|
+
* [`@page`](https://jekyllrb.com/docs/variables/#page-variables) Page variables
|
161
|
+
|
162
|
+
* [`@paginator`](https://jekyllrb.com/docs/variables/#page-variables) Pagination variables
|
163
|
+
|
164
|
+
* [`@scopes`](https://jekyllrb.com/docs/variables/)
|
165
|
+
See the [`jekyll_plugin_support` demo project](demo/variables.html)
|
166
|
+
|
167
|
+
* [`@site`](https://jekyllrb.com/docs/variables/#site-variables) Site variables
|
168
|
+
|
169
|
+
* [`@tag_config`](lib/jekyll_plugin_support_tag.rb)
|
170
|
+
Contents of the section of `_config.yml` named after your plugin.
|
171
|
+
|
172
|
+
* `@tag_name` Name of your Jekyll block tag or inline tag plugin.
|
173
|
+
|
174
|
+
* [`@theme`](https://jekyllrb.com/docs/variables/#global-variables) Theme variables
|
175
|
+
|
176
|
+
* `text` Content provided to your block tag.
|
129
177
|
|
130
|
-
```ruby
|
131
|
-
require 'jekyll_plugin_support'
|
132
|
-
require_relative 'my_block/version'
|
133
|
-
|
134
|
-
module Jekyll
|
135
|
-
class MyBlock < JekyllSupport::JekyllBlock
|
136
|
-
include MyPluginVersion
|
137
|
-
|
138
|
-
def render_impl(text)
|
139
|
-
@helper.gem_file __FILE__ # Enables attribution
|
140
|
-
my_output = "<p>blah blah</p>"
|
141
|
-
<<~END_OUTPUT
|
142
|
-
#{my_output}
|
143
|
-
#{@helper.attribute if @helper.attribution}
|
144
|
-
END_OUTPUT
|
145
|
-
end
|
146
|
-
|
147
|
-
JekyllPluginHelper.register(self, 'demo_tag')
|
148
|
-
end
|
149
|
-
end
|
150
|
-
```
|
151
178
|
|
152
|
-
|
179
|
+
## Argument Parsing
|
153
180
|
|
154
181
|
Tag arguments can be obtained within `render_impl`.
|
155
182
|
Both keyword options and name/value parameters are supported.
|
@@ -158,24 +185,29 @@ Both `JekyllTag` and `JekyllBlock` use the standard Ruby mechanism for parsing c
|
|
158
185
|
[`shellwords`](https://ruby-doc.org/stdlib-2.5.1/libdoc/shellwords/rdoc/Shellwords.html) and
|
159
186
|
[`key_value_parser`](https://www.rubydoc.info/gems/key-value-parser).
|
160
187
|
|
161
|
-
All your code has to do is to specify the keywords to search for in the string
|
162
|
-
|
163
|
-
|
188
|
+
All your code has to do is to specify the keywords to search for in the string
|
189
|
+
passed from the HTML page that your tag is embedded in.
|
190
|
+
The included `demo` website has examples;
|
191
|
+
both [`demo/_plugins/demo_inline_tag.rb`](demo/_plugins/demo_inline_tag.rb) and
|
192
|
+
[`demo/_plugins/demo_block_tag.rb`](demo/_plugins/demo_block_tag.rb) contain the following:
|
164
193
|
|
165
194
|
```ruby
|
166
195
|
@keyword1 = @helper.parameter_specified? 'keyword1'
|
167
196
|
@keyword2 = @helper.parameter_specified? 'keyword2'
|
168
|
-
@name1
|
169
|
-
@name2
|
197
|
+
@name1 = @helper.parameter_specified? 'name1'
|
198
|
+
@name2 = @helper.parameter_specified? 'name2'
|
170
199
|
```
|
171
200
|
|
172
|
-
|
201
|
+
|
202
|
+
### Example
|
203
|
+
|
204
|
+
[`demo/index.html`](demo/index.html), contains the following inline tag invocation:
|
173
205
|
|
174
206
|
```html
|
175
|
-
{%
|
207
|
+
{% demo_inline_tag keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value" %}
|
176
208
|
```
|
177
209
|
|
178
|
-
The `demo/_plugins/
|
210
|
+
The `demo/_plugins/demo_inline_tag.rb` plugin uses `@helper.parameter_specified?` provided by
|
179
211
|
`jekyll_support_plugin` to parse the string passed to the tag, which is
|
180
212
|
`keyword1 name1='value1' unreferenced_key unreferenced_name="unreferenced_value"`.
|
181
213
|
|
@@ -185,7 +217,12 @@ The `demo/_plugins/demo_tag.rb` plugin uses `@helper.parameter_specified?` provi
|
|
185
217
|
that name/value pair is removed from the argument string.
|
186
218
|
* The remainder of the argument string is now `unreferenced_key unreferenced_name="unreferenced_value"`.
|
187
219
|
|
188
|
-
|
220
|
+
|
221
|
+
### To Quote Or Not To Quote
|
222
|
+
|
223
|
+
Parameter values can be quoted.
|
224
|
+
|
225
|
+
If the value consists of only one token then quoting is optional.
|
189
226
|
The following name/value parameters all have the same result:
|
190
227
|
|
191
228
|
* `pay_tuesday="true"`
|
@@ -193,18 +230,117 @@ The following name/value parameters all have the same result:
|
|
193
230
|
* `pay_tuesday=true`
|
194
231
|
* `pay_tuesday`
|
195
232
|
|
196
|
-
|
233
|
+
If the values consist of more than one token, quotes must be used.
|
234
|
+
The following examples both yield the same result:
|
197
235
|
|
198
236
|
* `pay_tuesday="maybe not"`
|
199
237
|
* `pay_tuesday='maybe not'`
|
200
238
|
|
201
|
-
|
239
|
+
### Remaining Markup
|
202
240
|
|
203
241
|
After your plugin has parsed all the keyword options and name/value parameters,
|
204
242
|
call `@helper.remaining_markup` to obtain the remaining markup that was passed to your plugin.
|
205
243
|
|
206
244
|
|
207
|
-
|
245
|
+
## Liquid Variable Definitions
|
246
|
+
|
247
|
+
`jekyll_plugin_support` provides support for
|
248
|
+
[Liquid variables](https://shopify.github.io/liquid/tags/variable/)
|
249
|
+
to be defined in `_config.yml`, in a section called `liquid-vars`.
|
250
|
+
The following `_config.yml` fragment defines 3 variables called `var1`, `var2` and `var3`:
|
251
|
+
|
252
|
+
```yaml
|
253
|
+
liquid-vars:
|
254
|
+
var1: value1
|
255
|
+
var2: 'value 2'
|
256
|
+
var3: value3
|
257
|
+
```
|
258
|
+
|
259
|
+
Liquid variables defined in this manner are intended to be embedded in a webpage.
|
260
|
+
They are expanded transparently, and can be referenced like any other Liquid variable.
|
261
|
+
These Liquid variables can be passed as parameters to other plugins and includes.
|
262
|
+
|
263
|
+
In the following example web page, the Liquid variable called `var1` is expanded as part of the displayed page.
|
264
|
+
Liquid variables `var1` and `var2` are expanded and passed to the `my_plugin` plugin.
|
265
|
+
|
266
|
+
```html
|
267
|
+
This is the value of <code>var1</code>: {{var1}}.
|
268
|
+
|
269
|
+
{% my_plugin param1="{{var1}}" param2="{{var2}}" %}
|
270
|
+
```
|
271
|
+
|
272
|
+
`Jekyll_plugin_support` expands all but one of the
|
273
|
+
[plugin variables described above](#predefined-variables),
|
274
|
+
replacing Liquid variable references with their values.
|
275
|
+
The exception is `@argument_string`, which is not expanded.
|
276
|
+
|
277
|
+
|
278
|
+
### Liquid Variable Values Specific To Production And Development Modes
|
279
|
+
|
280
|
+
`jekyll_plugin_support` allows Liquid variables defined in `_config.yml` to have different values
|
281
|
+
when Jekyll is running in `development`, `production` and `test` modes.
|
282
|
+
When injecting variables into your Jekyll website, `Jekyll_plugin_support`
|
283
|
+
refers to definitions specific to the current environment,
|
284
|
+
and then refers to other definitions that are not overridden.
|
285
|
+
|
286
|
+
Here is an example:
|
287
|
+
|
288
|
+
```yaml
|
289
|
+
liquid-vars:
|
290
|
+
development:
|
291
|
+
var1: 'http://localhost:4444/demo_block_tag.html'
|
292
|
+
var2: 'http://localhost:4444/demo_inline_tag.html'
|
293
|
+
production:
|
294
|
+
var1: 'https://github.com/django/django/blob/3.1.7'
|
295
|
+
var2: 'https://github.com/django-oscar/django-oscar/blob/3.0.2'
|
296
|
+
var3: 'https://github.com/mslinn'
|
297
|
+
```
|
298
|
+
|
299
|
+
For the above, the following variable values are set in `development` mode:
|
300
|
+
|
301
|
+
* `var1`: `http://localhost:4444/demo_block_tag.html`
|
302
|
+
* `var2`: `http://localhost:4444/demo_inline_tag.html`
|
303
|
+
* `var3`: `https://github.com/mslinn`
|
304
|
+
|
305
|
+
... and the following variable values are set in `production` and `test` modes:
|
306
|
+
|
307
|
+
* `var1`: `https://github.com/django/django/blob/3.1.7`
|
308
|
+
* `var2`: `https://github.com/django-oscar/django-oscar/blob/3.0.2`
|
309
|
+
* `var3`: `https://github.com/mslinn`
|
310
|
+
|
311
|
+
|
312
|
+
### Liquid Variables in `jekyll_plugin_support` Subclasses
|
313
|
+
|
314
|
+
You can define additional Liquid variables in plugins built using `jekyll_plugin_support`.
|
315
|
+
To do this, make entries in `_config.yml` under a key named after the value of `@tag_name`.
|
316
|
+
|
317
|
+
For example, let’s imagine you create a plugin using `jekyll_plugin_support`,
|
318
|
+
and hou register it with the name `phonetic_alphabet`.
|
319
|
+
You could define Liquid variables that would be made available to content pages in web applications that
|
320
|
+
incorporate the `phonetic_alphabet` plugin.
|
321
|
+
The following section in `_config.yml` defines variables called `x`, `y` and `z`,
|
322
|
+
with values `xray`, `yankee` and `zulu`, respectively:
|
323
|
+
|
324
|
+
```yaml
|
325
|
+
phonetic_alphabet:
|
326
|
+
x: xray
|
327
|
+
y: yankee
|
328
|
+
z: zulu
|
329
|
+
```
|
330
|
+
|
331
|
+
The above definitions allow you to write content pages that use those variables, like the following page containing markup:
|
332
|
+
|
333
|
+
```html
|
334
|
+
---
|
335
|
+
layout: default
|
336
|
+
title: Variable demo
|
337
|
+
---
|
338
|
+
The letter `x` is pronounced {{x}}.
|
339
|
+
Similarly, the letters `y` and `z` are pronounced {{y}} and {{z}}.
|
340
|
+
```
|
341
|
+
|
342
|
+
|
343
|
+
## `no_arg_parsing` Optimization
|
208
344
|
|
209
345
|
If your tag or block plugin only needs access to the raw arguments passed from the web page,
|
210
346
|
without tokenization, and you expect that the plugin might be invoked with large amounts of text,
|
@@ -213,8 +349,10 @@ derive your plugin from `JekyllBlockNoArgParsing` or `JekyllTagNoArgParsing`.
|
|
213
349
|
|
214
350
|
## Subclass Attribution
|
215
351
|
|
216
|
-
`JekyllTag` and `JekyllBlock` subclasses of `jekyll_plugin_support` can utilize the `attribution`
|
352
|
+
`JekyllTag` and `JekyllBlock` subclasses of `jekyll_plugin_support` can utilize the `attribution`
|
353
|
+
option if they are published as a gem.
|
217
354
|
`JekyllTagNoArgParsing` and `JekyllBlockNoArgParsing` subclasses cannot.
|
355
|
+
This feature is usually only desired for `JekyllBlock` subclasses.
|
218
356
|
|
219
357
|
* When used as a keyword option, a default value is used for the attribution string.
|
220
358
|
* When used as a name/value option, the attribution string can be specified.
|
@@ -237,10 +375,12 @@ The `id` attribute is in the sample HTML above is randomized so more than one at
|
|
237
375
|
Typical usage for the `attribution` tag is:
|
238
376
|
|
239
377
|
```html
|
240
|
-
{%
|
378
|
+
{% my_block_tag attribution %}
|
379
|
+
Content of my_block_tag.
|
380
|
+
{% endmy_block_tag %}
|
241
381
|
```
|
242
382
|
|
243
|
-
Normal processing of `
|
383
|
+
Normal processing of `my_block_tag` is augmented by interpolating the attribution format string,
|
244
384
|
which is a Ruby-compatible interpolated string.
|
245
385
|
|
246
386
|
The default attribution format string is:
|
@@ -275,17 +415,11 @@ HEREDOC
|
|
275
415
|
```
|
276
416
|
|
277
417
|
|
278
|
-
## Additional Information
|
279
|
-
|
280
|
-
More information is available on
|
281
|
-
[Mike Slinn’s website](https://www.mslinn.com/jekyll_plugins/jekyll_plugin_support.html).
|
282
|
-
|
283
|
-
|
284
418
|
## Development
|
285
419
|
|
286
|
-
After checking out the
|
420
|
+
After checking out the `jekyll_plugin_suppprt` repository, run `bin/setup` to install dependencies.
|
287
421
|
|
288
|
-
|
422
|
+
`bin/console` provides an interactive prompt that allows you to experiment.
|
289
423
|
|
290
424
|
|
291
425
|
To build and install this gem onto your local machine, run:
|
@@ -314,11 +448,25 @@ jekyll_plugin_support (0.1.0)
|
|
314
448
|
```
|
315
449
|
|
316
450
|
|
317
|
-
|
451
|
+
### Pry Breakpoint On StandardError
|
452
|
+
|
453
|
+
A `pry` breakpoint will be set in the `StandardError` handler if `pry_on_standard_error: true`
|
454
|
+
is set in variable configuration section of `_config.yml`.
|
455
|
+
|
456
|
+
For example, if your plugin is called `blah`, enable the breakpoint with the following section:
|
457
|
+
|
458
|
+
```yml
|
459
|
+
blah:
|
460
|
+
pry_on_standard_error: true
|
461
|
+
```
|
462
|
+
|
463
|
+
|
464
|
+
## Demonstration Plugins and Website
|
318
465
|
|
319
466
|
A demo / test website is provided in the `demo` directory.
|
320
467
|
It can be used to debug the plugin or to run freely.
|
321
468
|
|
469
|
+
|
322
470
|
### Run Freely
|
323
471
|
|
324
472
|
1. Run from the command line:
|
@@ -327,31 +475,57 @@ It can be used to debug the plugin or to run freely.
|
|
327
475
|
$ demo/_bin/debug -r
|
328
476
|
```
|
329
477
|
|
330
|
-
2. View the generated website
|
478
|
+
2. View the generated website,
|
479
|
+
which might be at [`http://localhost:4444`](http://localhost:4444),
|
480
|
+
depending on how you configured it.
|
481
|
+
|
331
482
|
|
332
483
|
### Plugin Debugging
|
333
484
|
|
334
485
|
1. Set breakpoints in Visual Studio Code.
|
335
486
|
|
336
|
-
2. Initiate a debug session from the command line:
|
487
|
+
2. Initiate a debug session from the command line by running the `demo/_bin/debug` script:
|
337
488
|
|
338
489
|
```shell
|
339
490
|
$ demo/_bin/debug
|
491
|
+
Fetching gem metadata from https://rubygems.org/..........
|
492
|
+
Resolving dependencies...
|
493
|
+
Fetching public_suffix 5.0.4
|
494
|
+
Fetching nokogiri 1.15.5 (x86_64-linux)
|
495
|
+
Installing public_suffix 5.0.4
|
496
|
+
Installing nokogiri 1.15.5 (x86_64-linux)
|
497
|
+
Bundle complete! 17 Gemfile dependencies, 96 gems now installed.
|
498
|
+
Use `bundle info [gemname]` to see where a bundled gem is installed.
|
499
|
+
|
500
|
+
INFO PluginMetaLogger: Loaded DraftFilter plugin.
|
501
|
+
INFO PluginMetaLogger: Loaded outline_js v1.2.1 plugin.
|
502
|
+
INFO PluginMetaLogger: Loaded outline v1.2.1 plugin.
|
503
|
+
Configuration file: /mnt/f/jekyll_plugin_support/demo/_config.yml
|
504
|
+
Cleaner: Removing /mnt/f/jekyll_plugin_support/demo/_site...
|
505
|
+
Cleaner: Removing /mnt/f/jekyll_plugin_support/demo/.jekyll-metadata...
|
506
|
+
Cleaner: Removing /mnt/f/jekyll_plugin_support/demo/.jekyll-cache...
|
507
|
+
Cleaner: Nothing to do for .sass-cache.
|
508
|
+
DEBUGGER: Debugger can attach via TCP/IP (127.0.0.1:37177)
|
509
|
+
DEBUGGER: wait for debugger connection...
|
340
510
|
```
|
341
511
|
|
342
|
-
3. Once the `
|
343
|
-
|
512
|
+
3. Once the `DEBUGGER: wait for debugger connection...` message appears,
|
513
|
+
run the Visual Studio Code launch configuration called `Attach with rdbg`.
|
344
514
|
|
345
|
-
4. View the generated website
|
515
|
+
4. View the generated website,
|
516
|
+
which might be at [`http://localhost:4444`](http://localhost:4444),
|
517
|
+
depending on how you configured it.
|
346
518
|
|
347
519
|
|
348
520
|
### Build and Push to RubyGems
|
349
521
|
|
350
|
-
To release a new version
|
522
|
+
To release a new version:
|
351
523
|
|
352
524
|
1. Update the version number in `version.rb`.
|
353
|
-
2.
|
354
|
-
3.
|
525
|
+
2. Add an entry to `CHANGELOG.md` describing the changes since the previous version.
|
526
|
+
3. Commit all changes to git;
|
527
|
+
if you don't the next step might fail with an unexplainable error message.
|
528
|
+
4. Run the following:
|
355
529
|
|
356
530
|
```shell
|
357
531
|
$ bundle exec rake release
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'lib/jekyll_plugin_support/version'
|
2
2
|
|
3
|
-
Gem::Specification.new do |spec|
|
3
|
+
Gem::Specification.new do |spec|
|
4
4
|
github = 'https://github.com/mslinn/jekyll_plugin_support'
|
5
5
|
|
6
6
|
spec.bindir = 'exe'
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
24
24
|
END_MESSAGE
|
25
25
|
spec.require_paths = ['lib']
|
26
26
|
spec.required_ruby_version = '>= 2.6.0'
|
27
|
-
spec.summary = 'Provides
|
27
|
+
spec.summary = 'Provides a framework for writing and testing Jekyll plugins'
|
28
28
|
spec.test_files = spec.files.grep %r{^(test|spec|features)/}
|
29
29
|
spec.version = JekyllPluginSupportVersion::VERSION
|
30
30
|
|
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
32
32
|
spec.add_dependency 'jekyll', '>= 3.5.0'
|
33
33
|
spec.add_dependency 'jekyll_plugin_logger'
|
34
34
|
spec.add_dependency 'key-value-parser'
|
35
|
+
spec.add_dependency 'pry'
|
35
36
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'facets/string/camelcase'
|
2
|
+
require 'facets/string/snakecase'
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
# Use like this:
|
6
|
+
# CustomError.new(:MyError, 'blah', 'asdf')
|
7
|
+
class CustomError < StandardError
|
8
|
+
def self.factory(name)
|
9
|
+
return if Object.const_defined? name
|
10
|
+
|
11
|
+
puts "Defining #{name}".yellow
|
12
|
+
eval "#{name} = Class.new Jekyll::CustomError" # rubocop:disable Style/EvalWithLocation, Security/Eval
|
13
|
+
end
|
14
|
+
|
15
|
+
def error_name
|
16
|
+
self.class.name.split('::').last
|
17
|
+
end
|
18
|
+
|
19
|
+
def calling_file
|
20
|
+
file_fq, _line_number, _extra = backtrace[0].split(':')
|
21
|
+
file_fq
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return HTML <div> tag with class set to the snake_case version of the error class name.
|
25
|
+
def html_message
|
26
|
+
shorten_backtrace
|
27
|
+
line_number = self.class.class_variable_get :@@line_number
|
28
|
+
path = self.class.class_variable_get :@@path
|
29
|
+
<<~END_MSG
|
30
|
+
<div class='#{error_name.snakecase}'>
|
31
|
+
#{self.class} raised in #{calling_file} while processing line #{line_number} (after front matter) of #{path}
|
32
|
+
#{message}
|
33
|
+
</div>
|
34
|
+
END_MSG
|
35
|
+
end
|
36
|
+
|
37
|
+
def logger_message
|
38
|
+
shorten_backtrace
|
39
|
+
kaller = caller(1..1).first
|
40
|
+
line_number = self.class.class_variable_get :@@line_number
|
41
|
+
path = self.class.class_variable_get :@@path
|
42
|
+
<<~END_MSG
|
43
|
+
#{error_name} raised in #{kaller} while processing line #{line_number} (after front matter) of #{path}
|
44
|
+
#{message}
|
45
|
+
END_MSG
|
46
|
+
end
|
47
|
+
|
48
|
+
def shorten_backtrace(backtrace_element_count = 3)
|
49
|
+
b = backtrace[0..backtrace_element_count - 1].map do |x|
|
50
|
+
x.gsub(Dir.pwd + '/', './')
|
51
|
+
end
|
52
|
+
set_backtrace b
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|