jekyll-liquid-plus 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZWFkMjM5ZjE1MjA3YzI1ODQyNTk0NWViYmE3YzA1ODA0NjgzYjJiOA==
5
+ data.tar.gz: !binary |-
6
+ ZDVkNzU2NDk2NjVlYWFmNGZmOGM1OTBjODFjMGYyN2I2ZTI0ODE2MA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YWVmZDc5YzEyY2FmMDg2M2NiN2E5M2QyZGQ2N2ZiZWM0ZmJhODNmMTk5N2Rl
10
+ ZGE3ZGFkMGZkNmM5Y2UxZmQ2M2MyYjJkM2E0ZDU0MDNjZTliMTllYjdiYzU0
11
+ Y2VhNzQ5MGZlNGVkYjk5NDZhZmFiY2Q0ZWMyM2JhZDkyMzc5MTI=
12
+ data.tar.gz: !binary |-
13
+ NzZjM2Q5ZjMxMGEyNjE4M2UyMGY1NWY0OGIyYzFhZjcwOWRjMTE3NmMyZTU2
14
+ ZWRjNDgwZjFmNDJiN2ZhNGMzY2I2ZjQ0MzJkZTMyOGIxZTc0Zjc3MDU2Y2Q0
15
+ Zjk5MGM5OTI3OTVlYjIzYTJmOTU5ZDdiOWY0M2I4ZmE0YzNlOGM=
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ _site
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in liquid-plus.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Brandon Mathis
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,345 @@
1
+ # Jekyll Liquid Plus
2
+
3
+ Super powered Liquid tags for smarter Jekyll templating.
4
+
5
+ Redesigned, but backwards compatible: include, assign, capture.
6
+ All new: render, wrap, wrap_include, return.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'jekyll-liquid-plus'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install jekyll-liquid-plus
21
+
22
+ Next create a plugin in your Jekyll plugins directory called something like "liquid-plus.rb" (the name doesn't matter). Then add the following line to the top.
23
+
24
+ ```ruby
25
+ require 'jekyll-liquid-plus'
26
+ ```
27
+
28
+ ## Include Tag
29
+
30
+ The new include tag accepts multiple paths as strings or variables and searches the file system, including the first file found. It allows you to write ternary expressions and post conditions to control what file to include and whether to include a file at all. It can even fail gracefully. Have a look.
31
+
32
+ First, here's the standard `include` in action. It can embed a file from Jekyll's `_includes` directory, and optionally create local variables.
33
+
34
+ ```
35
+ {% include article.html %}
36
+ {% include article.html type='linkpost' %} # in article.html {{ include.type }} outputs 'linkpost'
37
+ ```
38
+
39
+ #### Include syntax
40
+
41
+ The new syntax may seem a bit crazy out of context of use, but the examples below are nice.
42
+
43
+ ```
44
+ Cascade and/or ternary exp post condition local vars
45
+ {% include [file1.md || file2.md || var] [unless 2 + 2 == 6] [var=value] %}
46
+ ```
47
+
48
+ #### Cascading paths
49
+
50
+ Now include can cascade file paths, embedding the first file which exists.
51
+
52
+ ```
53
+ {% include custom/article.html || theme/article.html %}
54
+ ```
55
+
56
+ Cascading makes it possible for theme and plugin creators to easily allow users to override template components, customizing a template without editing the original source.
57
+
58
+ Passing `none` will tell include to fail gracefully, rather than outputting an error if no file path exists.
59
+
60
+ ```
61
+ {% include custom/comments.html || none %}
62
+ ```
63
+
64
+ This shows how a theme creator might make it easy to inject a script for comments at the bottom of a post.
65
+
66
+ #### Ternary paths
67
+
68
+ Sometimes this is just simpler.
69
+
70
+ ```
71
+ {% include (post ? theme/post.html : theme/page.html) %}
72
+ {% include (post ? theme/post.html : theme/page.html) || none %}
73
+ ```
74
+
75
+ The second example will fail gracefully and shows how you might use a ternary expression and cascading paths together.
76
+
77
+ #### Conditional includes
78
+
79
+ Conditional includes make it easy to pick the right partial without a nest of `{% if %}` blocks.
80
+
81
+ ```
82
+ {% include theme/post/date.html if post.date or page.date %}
83
+ {% include custom/comments.html unless post.comments == false %}
84
+ ```
85
+
86
+ #### Include accepts variables
87
+
88
+ Include even allows variables to be passed instead of string paths.
89
+
90
+ For this example, we'll assuse a user has set a default sidebar path in their Jekyll config file like this:
91
+
92
+ ```yaml
93
+ sidebar:
94
+ default: sidebar.html
95
+ ```
96
+
97
+ Then on a per page basis they could override their default sidebar in the page's YAML front-matter.
98
+
99
+ ```yaml
100
+ sidebar: page_sidebar.html
101
+ ```
102
+
103
+ Now we can include the correct sidebar by cascading them. Using a post condition, we can even allow users to disable the sidebar by setting `sidebar: false` in their YAML front matter.
104
+
105
+ ```
106
+ {% include page.sidebar || site.sidebar.default || none unless page.sidebar == false %}
107
+ ```
108
+
109
+ Of course you can combine cascades, ternary expressions, post conditions and local variable passing, but you probably shouldn't.
110
+
111
+ #### Error reporting
112
+
113
+ Finally, the new `include` has better error reporting. When attempting to include a file which doesn't exist, an error message will be written to the file and output to the terminal. Here's an example.
114
+
115
+ ```
116
+ From theme/article.html: File 'not_there.html' not found in '_includes/' directory
117
+ ```
118
+
119
+ ## Render Tag
120
+
121
+ Everything you can do with `include`, you can also do with `render`, However there are a few differences. If you haven't read about include, [do it](#include-tag).
122
+
123
+ #### Render syntax
124
+
125
+ ```
126
+ Cascade and/or ternary exp post condition local vars
127
+ {% render [raw] [file1.md || file2.md || var] [unless 2 + 2 == 6] [var=value] %}
128
+ ```
129
+
130
+ #### Differences from include
131
+
132
+ 1. Paths are relative to Jekyll's source directory, not the `_includes` directory.
133
+ 2. Embed adjacent files by adding `./` to the beginning of a path.
134
+ 3. When passing local template variables, they are accessed as `{{ render.var }}` instead of `{{ include.var }}`
135
+ 5. YAML front-matter is stripped from partials, but local page variables are rendered.
136
+
137
+ This is the standard include example from above, but when using render it searches for files starting at Jekyll's source directory (./ by default).
138
+
139
+ ```
140
+ {% render _article.html %} # embeds _article.html from the source directory
141
+ {% render _article.html type='linkpost' %} # in _article.html {{ render.type }} outputs 'linkpost'
142
+ ```
143
+ Note I'm using underscores in the file names to tell Jekyll to ignore them as partials, however you can embed any other file, including full Jekyll posts and pages.
144
+
145
+ This great for when you are writing a bunch of pages and would like to break things up into partials without have to keep everything in the _includes directory.
146
+
147
+ #### Rendering raw unprocessed files
148
+
149
+ To embed a file without parsing it through Liquid and (if appropriate, markdown or textile) add `raw` to the beginning of your render tag.
150
+
151
+ ```
152
+ {% render raw _test.md %} # outputs bare markdown and unprocessed liquid tags
153
+ ```
154
+
155
+ ## Wrap Include Tag
156
+
157
+ This tag is also like include, but it allows you to wrap the contents of an included file in a block.
158
+
159
+ #### Wrap include syntax
160
+
161
+ Use the `{= yield }` tag to indicate where the partial's content will be rendered.
162
+
163
+ ```
164
+ Cascade and/or ternary exp post condition local vars
165
+ {% wrap_include [file1.md || file2.md || var] [unless 2 + 2 == 6] [var=value] %}
166
+ <div>{= yield }</div>
167
+ {% endwrap_include %}
168
+ ```
169
+
170
+ Here's an example.
171
+
172
+ ```
173
+ {% wrap_include date.html %}
174
+ <p class='post-date'>{= yield }</p>
175
+ {% endwrap_include %}
176
+ ```
177
+
178
+ Here's another useful example.
179
+
180
+ {% wrap_include custom/comments.html || theme/comments.html unless page.comments == false %}
181
+ <div id='comments'>{= yield }</div>
182
+ {% endwrap_include %}
183
+
184
+ As above, all the cool stuff you can do with include applies here.
185
+
186
+ ## Wrap Tag
187
+
188
+ Wrap is just like wrap_include except it uses the render tag instead of the include tag. This means paths start at Jekyll's source directory and you can do everything listed under render.
189
+
190
+ #### Wrap syntax
191
+
192
+ Use the `{= yield }` tag to indicate where the partial's content will be rendered.
193
+
194
+ ```
195
+ Cascade and/or ternary exp post condition local vars
196
+ {% wrap [raw] [file1.md || file2.md || var] [unless 2 + 2 == 6] [var=value] %}
197
+ <div>{= yield }</div>
198
+ {% endwrap_include %}
199
+ ```
200
+
201
+ Here's an example.
202
+
203
+ ```
204
+ {% wrap _nav.html %}
205
+ <nav role='navigation'>{= yield }</nav>
206
+ {% endwrap %}
207
+ ```
208
+
209
+ As above, all the cool stuff you can do with render applies here.
210
+
211
+ ## Assign Tag
212
+
213
+ The new assign tag can accept the `+=` and `||=` operators and allows cascading variable assignment and post conditions.
214
+
215
+ #### Assign syntax
216
+
217
+ ```
218
+ cascade or ternary filters post condition
219
+ {% assign var = [some_var or 'bar'] [| upcase] [unless 2 + 2 == 6] %}
220
+ ```
221
+
222
+ Operators work as you'd expect.
223
+
224
+ ```
225
+ {% assign var = 'hi' %} # {{ var }} yields 'hi'
226
+ {% assign var ||= 'yo' %} # {{ var }} yields 'hi'
227
+ {% assign var += ', man.' %} # {{ var }} yields 'hi, man.'
228
+ ```
229
+
230
+ You can do cascading assignment like this.
231
+
232
+ ```
233
+ {% assign date = post.date or page.date or nil %}
234
+ ```
235
+
236
+ And ternary assignment too.
237
+
238
+ ```
239
+ {% assign url = (post ? post.url : page.url) %}
240
+ ```
241
+
242
+ Post conditions work like this.
243
+
244
+ ```
245
+ {% assign date = post.date or page.date or nil %}
246
+ {% assign date = date | datetime | date_to_xmlschema if date != nil %}
247
+ ```
248
+
249
+ ## Capture Tag
250
+
251
+ The new capture tag allows `+=`, `||=` assignment and evaluates post conditions.
252
+
253
+ #### Capture syntax
254
+
255
+ ```
256
+ post condition
257
+ {% capture var [+=] [unless 2 + 2 == 6] %}
258
+ [value]
259
+ {% endcapture %}
260
+ ```
261
+
262
+ It's pretty straightforward, but here are some examples.
263
+
264
+ ```
265
+ {% assign var = 'hi' %}
266
+ {% capture var ||= %} yo {% endcapture %} # {{ var }} yields 'hi'
267
+ {% capture var += %}, man.{% endcapture %} # {{ var }} yields 'hi, man.'
268
+ ```
269
+
270
+ Here's an example of how you might generate a semantic `<time>` tag.
271
+
272
+ ```
273
+ {% assign date = page.date or post.date or nil %}
274
+
275
+ {% capture date if date %}
276
+ <time datetime="{{ date | datetime | date_to_xmlschema }}" pubdate>{{ date | format_date }}</time>
277
+ {% endcapture %}
278
+ ```
279
+
280
+ ## Return Tag
281
+
282
+ Return is useful when you want to conditionally output a variable without having to write an `{% if %}` block. Yes its utility is pretty limited, but in Liquid, anything that helps you use fewer conditional blocks, makes code easier to read.
283
+
284
+ #### Return syntax
285
+
286
+ ```
287
+ Cascade and/or ternary exp filters post condition
288
+ {% return [file1.md || file2.md || var] [| upcase] [unless 2 + 2 == 6] %}
289
+ ```
290
+
291
+ Below each example shows how return can be used, followed by something that works the same, but with only standard liquid tags.
292
+
293
+ ```
294
+ new: {% return (post ? post.content : page.content) %}
295
+ old: {% if post %}{{ post.content }}{% else %}{{ page.content }}{% endif %}
296
+ ```
297
+ ```
298
+ new: <a href="{% return post.external-url || post.url %}">{{ post.title }}</a>
299
+ old: <a href="{% if post.external-url %}{{ post.external-url }}{% else %}{{ post.url }}{% endif %}">{{ post.title }}</a>
300
+ ```
301
+ ```
302
+ new: <div class="post {% return 'linklog' if post.external-url %}">...
303
+ old: <div class="post {% if post.external-url %} linklog {% endif %}">
304
+ ```
305
+ ```
306
+ new: {% return post.date or page.date | datetime | date_to_xmlschema if post.date or page.date %}
307
+ old: {% capture date %}{{ post.date }}{{ page.date }}{% endcapture %}
308
+ {% if date != '' %}{{ date | datetime | date_to_xmlschema }}{% endif %}
309
+ ```
310
+
311
+ It's not amazing, but it may come in handy.
312
+
313
+ ## Contributing
314
+
315
+ 1. Fork it
316
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
317
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
318
+ 4. Push to the branch (`git push origin my-new-feature`)
319
+ 5. Create new Pull Request
320
+
321
+ ## License
322
+
323
+ Copyright (c) 2013 Brandon Mathis
324
+
325
+ MIT License
326
+
327
+ Permission is hereby granted, free of charge, to any person obtaining
328
+ a copy of this software and associated documentation files (the
329
+ "Software"), to deal in the Software without restriction, including
330
+ without limitation the rights to use, copy, modify, merge, publish,
331
+ distribute, sublicense, and/or sell copies of the Software, and to
332
+ permit persons to whom the Software is furnished to do so, subject to
333
+ the following conditions:
334
+
335
+ The above copyright notice and this permission notice shall be
336
+ included in all copies or substantial portions of the Software.
337
+
338
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
339
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
340
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
341
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
342
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
343
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
344
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
345
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jekyll-liquid-plus/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jekyll-liquid-plus"
8
+ spec.version = LiquidPlus::VERSION
9
+ spec.authors = ["Brandon Mathis"]
10
+ spec.email = ["brandon@imathis.com"]
11
+ spec.description = %q{Super powered Liquid tags for smarter Jekyll templating.}
12
+ spec.summary = %q{Do things easier with better versions of common liquid tags: include, capture, assign, and introducing: render, wrap, wrap_include, and more. }
13
+ spec.homepage = "https://github.com/imathis/jekyll-liquid-plus"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_runtime_dependency "jekyll", "~> 1.1.2"
20
+ spec.add_runtime_dependency "liquid", "~> 2.5.1"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,20 @@
1
+ require "liquid"
2
+
3
+ module LiquidPlus
4
+ autoload :IncludeTag, 'jekyll-liquid-plus/tags/include'
5
+ autoload :WrapTag, 'jekyll-liquid-plus/tags/wrap'
6
+ autoload :RenderTag, 'jekyll-liquid-plus/tags/render'
7
+ autoload :AssignTag, 'jekyll-liquid-plus/tags/assign'
8
+ autoload :CaptureTag, 'jekyll-liquid-plus/tags/capture'
9
+ autoload :ReturnTag, 'jekyll-liquid-plus/tags/return'
10
+ end
11
+
12
+ Liquid::Template.register_tag('include', LiquidPlus::IncludeTag)
13
+ Liquid::Template.register_tag('wrap', LiquidPlus::WrapTag)
14
+ Liquid::Template.register_tag('wrap_include', LiquidPlus::WrapTag)
15
+ Liquid::Template.register_tag('render', LiquidPlus::RenderTag)
16
+ Liquid::Template.register_tag('render_partial', LiquidPlus::RenderTag)
17
+ Liquid::Template.register_tag('assign', LiquidPlus::AssignTag)
18
+ Liquid::Template.register_tag('capture', LiquidPlus::CaptureTag)
19
+ Liquid::Template.register_tag('return', LiquidPlus::ReturnTag)
20
+