jekyll 2.0.0.alpha.3 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of jekyll might be problematic. Click here for more details.

Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.markdown +1 -1
  3. data/History.markdown +10 -0
  4. data/features/collections.feature +49 -15
  5. data/features/create_sites.feature +16 -16
  6. data/features/data.feature +4 -4
  7. data/features/drafts.feature +4 -4
  8. data/features/embed_filters.feature +6 -6
  9. data/features/frontmatter_defaults.feature +79 -0
  10. data/features/include_tag.feature +4 -4
  11. data/features/markdown.feature +4 -4
  12. data/features/pagination.feature +3 -3
  13. data/features/permalinks.feature +8 -8
  14. data/features/post_data.feature +18 -18
  15. data/features/post_excerpts.feature +3 -3
  16. data/features/site_configuration.feature +21 -21
  17. data/features/site_data.feature +11 -11
  18. data/features/step_definitions/jekyll_steps.rb +5 -18
  19. data/features/support/env.rb +2 -15
  20. data/lib/jekyll.rb +2 -0
  21. data/lib/jekyll/collection.rb +30 -4
  22. data/lib/jekyll/configuration.rb +2 -1
  23. data/lib/jekyll/convertible.rb +15 -1
  24. data/lib/jekyll/document.rb +11 -7
  25. data/lib/jekyll/filters.rb +1 -1
  26. data/lib/jekyll/frontmatter_defaults.rb +148 -0
  27. data/lib/jekyll/liquid_extensions.rb +22 -0
  28. data/lib/jekyll/page.rb +5 -0
  29. data/lib/jekyll/post.rb +12 -0
  30. data/lib/jekyll/site.rb +42 -27
  31. data/lib/jekyll/version.rb +1 -1
  32. data/script/test +11 -0
  33. data/site/docs/collections.md +78 -5
  34. data/site/docs/configuration.md +49 -0
  35. data/site/docs/frontmatter.md +10 -0
  36. data/site/docs/plugins.md +1 -0
  37. data/site/docs/posts.md +9 -0
  38. data/site/docs/sites.md +2 -2
  39. data/site/docs/templates.md +1 -1
  40. data/test/test_collections.rb +50 -4
  41. data/test/test_filters.rb +4 -0
  42. data/test/test_liquid_extensions.rb +31 -0
  43. data/test/test_utils.rb +1 -0
  44. metadata +9 -2
@@ -0,0 +1,22 @@
1
+ module Jekyll
2
+ module LiquidExtensions
3
+
4
+ # Lookup a Liquid variable in the given context.
5
+ #
6
+ # context - the Liquid context in question.
7
+ # variable - the variable name, as a string.
8
+ #
9
+ # Returns the value of the variable in the context
10
+ # or the variable name if not found.
11
+ def lookup_variable(context, variable)
12
+ lookup = context
13
+
14
+ variable.split(".").each do |value|
15
+ lookup = lookup[value]
16
+ end
17
+
18
+ lookup || variable
19
+ end
20
+
21
+ end
22
+ end
@@ -28,8 +28,13 @@ module Jekyll
28
28
  @dir = dir
29
29
  @name = name
30
30
 
31
+
31
32
  process(name)
32
33
  read_yaml(File.join(base, dir), name)
34
+
35
+ data.default_proc = proc do |hash, key|
36
+ site.frontmatter_defaults.find(File.join(dir, name), type, key)
37
+ end
33
38
  end
34
39
 
35
40
  # The generated directory into which the page will be placed
@@ -56,6 +56,10 @@ module Jekyll
56
56
  process(name)
57
57
  read_yaml(@base, name)
58
58
 
59
+ data.default_proc = proc do |hash, key|
60
+ site.frontmatter_defaults.find(File.join(dir, name), type, key)
61
+ end
62
+
59
63
  if data.has_key?('date')
60
64
  self.date = Time.parse(data["date"].to_s)
61
65
  end
@@ -64,6 +68,14 @@ module Jekyll
64
68
  populate_tags
65
69
  end
66
70
 
71
+ def published?
72
+ if data.has_key?('published') && data['published'] == false
73
+ false
74
+ else
75
+ true
76
+ end
77
+ end
78
+
67
79
  def populate_categories
68
80
  if categories.empty?
69
81
  self.categories = Utils.pluralized_array_from_hash(data, 'category', 'categories').map {|c| c.to_s.downcase}
@@ -4,7 +4,7 @@ module Jekyll
4
4
  :exclude, :include, :source, :dest, :lsi, :highlighter,
5
5
  :permalink_style, :time, :future, :unpublished, :safe, :plugins, :limit_posts,
6
6
  :show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems,
7
- :plugin_manager, :collections
7
+ :plugin_manager
8
8
 
9
9
  attr_accessor :converters, :generators
10
10
 
@@ -55,6 +55,7 @@ module Jekyll
55
55
  self.pages = []
56
56
  self.static_files = []
57
57
  self.data = {}
58
+ @collections = nil
58
59
 
59
60
  if limit_posts < 0
60
61
  raise ArgumentError, "limit_posts must be a non-negative number"
@@ -90,18 +91,24 @@ module Jekyll
90
91
  #
91
92
  # Returns a Hash containing collection name-to-instance pairs.
92
93
  def collections
93
- @collections ||= if config['collections']
94
- Hash[config['collections'].map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
95
- else
96
- Hash.new
97
- end
94
+ @collections ||= Hash[collection_names.map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
98
95
  end
99
96
 
100
- # The list of collections to render.
97
+ # The list of collection names.
101
98
  #
102
- # The array of collection labels to render.
103
- def to_render
104
- @to_render ||= (config['render'] || Array.new)
99
+ # Returns an array of collection names from the configuration,
100
+ # or an empty array if the `collections` key is not set.
101
+ def collection_names
102
+ case config['collections']
103
+ when Hash
104
+ config['collections'].keys
105
+ when Array
106
+ config['collections']
107
+ when nil
108
+ []
109
+ else
110
+ raise ArgumentError, "Your `collections` key must be a hash or an array."
111
+ end
105
112
  end
106
113
 
107
114
  # Read Site data from disk and load it into internal data structures.
@@ -188,17 +195,18 @@ module Jekyll
188
195
  #
189
196
  # Returns nothing
190
197
  def read_data(dir)
191
- unless dir.to_s.eql?("_data")
192
- Jekyll.logger.error "Error:", "Data source directories other than '_data' have been removed.\n" +
193
- "Please move your YAML files to `_data` and remove the `data_source` key from your `_config.yml`."
194
- end
198
+ base = File.join(source, dir)
199
+ return unless File.directory?(base) && (!safe || !File.symlink?(base))
195
200
 
196
- collections['data'] = Jekyll::Collection.new(self, "data")
197
- collections['data'].read
201
+ entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
202
+ entries.delete_if { |e| File.directory?(File.join(base, e)) }
203
+
204
+ entries.each do |entry|
205
+ path = File.join(source, dir, entry)
206
+ next if File.symlink?(path) && safe
198
207
 
199
- collections['data'].docs.each do |doc|
200
- key = sanitize_filename(doc.basename(".*"))
201
- self.data[key] = doc.data
208
+ key = sanitize_filename(File.basename(entry, '.*'))
209
+ self.data[key] = SafeYAML.load_file(path)
202
210
  end
203
211
  end
204
212
 
@@ -206,7 +214,9 @@ module Jekyll
206
214
  #
207
215
  # Returns nothing.
208
216
  def read_collections
209
- collections.each { |_, collection| collection.read }
217
+ collections.each do |_, collection|
218
+ collection.read unless collection.label.eql?("data")
219
+ end
210
220
  end
211
221
 
212
222
  # Run each of the Generators.
@@ -224,8 +234,8 @@ module Jekyll
224
234
  def render
225
235
  relative_permalinks_deprecation_method
226
236
 
227
- to_render.each do |label|
228
- collections[label].docs.each do |document|
237
+ collections.each do |label, collection|
238
+ collection.docs.each do |document|
229
239
  document.output = Jekyll::Renderer.new(self, document).run
230
240
  end
231
241
  end
@@ -306,7 +316,7 @@ module Jekyll
306
316
  def site_payload
307
317
  {"jekyll" => { "version" => Jekyll::VERSION },
308
318
  "site" => Utils.deep_merge_hashes(config,
309
- Utils.deep_merge_hashes(collections, {
319
+ Utils.deep_merge_hashes(Hash[collections.map{|label, coll| [label, coll.docs]}], {
310
320
  "time" => time,
311
321
  "posts" => posts.sort { |a, b| b <=> a },
312
322
  "pages" => pages,
@@ -314,6 +324,7 @@ module Jekyll
314
324
  "html_pages" => pages.reject { |page| !page.html? },
315
325
  "categories" => post_attr_hash('categories'),
316
326
  "tags" => post_attr_hash('tags'),
327
+ "collections" => collections,
317
328
  "data" => site_data
318
329
  }))
319
330
  }
@@ -395,9 +406,9 @@ module Jekyll
395
406
  end
396
407
 
397
408
  def documents
398
- collections.reduce(Set.new) do |docs, (label, coll)|
399
- if to_render.include?(label)
400
- docs.merge(coll.docs)
409
+ collections.reduce(Set.new) do |docs, (_, collection)|
410
+ if collection.write?
411
+ docs.merge(collection.docs)
401
412
  else
402
413
  docs
403
414
  end
@@ -412,6 +423,10 @@ module Jekyll
412
423
  end
413
424
  end
414
425
 
426
+ def frontmatter_defaults
427
+ @frontmatter_defaults ||= Configuration::FrontmatterDefaults.new(self)
428
+ end
429
+
415
430
  private
416
431
 
417
432
  def has_relative_page?
@@ -419,7 +434,7 @@ module Jekyll
419
434
  end
420
435
 
421
436
  def has_yaml_header?(file)
422
- !!(File.open(file).read =~ /\A---\r?\n/)
437
+ !!(File.open(file, "rb").read(5) =~ /\A---\r?\n/)
423
438
  end
424
439
 
425
440
  def limit_posts!
@@ -1,3 +1,3 @@
1
1
  module Jekyll
2
- VERSION = '2.0.0.alpha.3'
2
+ VERSION = '2.0.0.rc1'
3
3
  end
@@ -0,0 +1,11 @@
1
+ #! /bin/bash
2
+
3
+ set -x
4
+
5
+ if [ -z "$1" ]; then
6
+ TEST_FILES="test/test*.rb"
7
+ else
8
+ TEST_FILES="$@"
9
+ fi
10
+
11
+ /usr/bin/env bundle exec ruby -I"lib:test" -r rake -r rake/rake_test_loader ${TEST_FILES}
@@ -21,8 +21,6 @@ permalink: /docs/collections/
21
21
  </p>
22
22
  </div>
23
23
 
24
- Put some things in a folder and add the folder to your config. It's simple...
25
-
26
24
  Not everything is a post or a page. Maybe you want to document the various methods in your open source project, members of a team, or talks at a conference. Collections allow you to define a new type of document that behave like Pages or Posts do normally, but also have their own unique properties and namespace.
27
25
 
28
26
  ## Using Collections
@@ -36,6 +34,14 @@ collections:
36
34
  - my_collection
37
35
  {% endhighlight %}
38
36
 
37
+ You can optionally specify metadata for your collection in the configuration:
38
+
39
+ {% highlight yaml %}
40
+ collections:
41
+ my_collection:
42
+ foo: bar
43
+ {% endhighlight %}
44
+
39
45
  ### Step 2: Add your content
40
46
 
41
47
  Create a corresponding folder (e.g. `<source>/_my_collection`) and add documents.
@@ -45,11 +51,12 @@ Note: the folder must be named identical to the collection you defined in you co
45
51
 
46
52
  ### Step 3: Optionally render your collection's documents into independent files
47
53
 
48
- If you'd like Jekyll to create a public-facing, rendered version of each document in your collection, add your collection name to the `render` config key in your `_config.yml`:
54
+ If you'd like Jekyll to create a public-facing, rendered version of each document in your collection, set the `output` key to `true` in your collection metadata in your `_config.yml`:
49
55
 
50
56
  {% highlight yaml %}
51
- render:
52
- - my_collection
57
+ collections:
58
+ my_collection:
59
+ output: true
53
60
  {% endhighlight %}
54
61
 
55
62
  This will produce a file for each document in the collection.
@@ -63,6 +70,72 @@ choice and written out to `<dest>/my_collection/some_subdir/some_doc.html`.
63
70
 
64
71
  Each collection is accessible via the `site` Liquid variable. For example, if you want to access the `albums` collection found in `_albums`, you'd use `site.albums`. Each collection is itself an array of documents (e.g. `site.albums` is an array of documents, much like `site.pages` and `site.posts`). See below for how to access attributes of those documents.
65
72
 
73
+ The collections are also available under `site.collections`, with the metadata you specified in your `_config.yml` (if present) and the following information:
74
+
75
+ <div class="mobile-side-scroller">
76
+ <table>
77
+ <thead>
78
+ <tr>
79
+ <th>Variable</th>
80
+ <th>Description</th>
81
+ </tr>
82
+ </thead>
83
+ <tbody>
84
+ <tr>
85
+ <td>
86
+ <p><code>label</code></p>
87
+ </td>
88
+ <td>
89
+ <p>
90
+ The name of your collection, e.g. <code>my_collection</code>.
91
+ </p>
92
+ </td>
93
+ </tr>
94
+ <tr>
95
+ <td>
96
+ <p><code>docs</code></p>
97
+ </td>
98
+ <td>
99
+ <p>
100
+ An array of <a href="#documents">documents</a>.
101
+ </p>
102
+ </td>
103
+ </tr>
104
+ <tr>
105
+ <td>
106
+ <p><code>relative_directory</code></p>
107
+ </td>
108
+ <td>
109
+ <p>
110
+ The path to the collections's source directory, relative to the site source.
111
+ </p>
112
+ </td>
113
+ </tr>
114
+ <tr>
115
+ <td>
116
+ <p><code>directory</code></p>
117
+ </td>
118
+ <td>
119
+ <p>
120
+ The full path to the collections's source directory..
121
+ </p>
122
+ </td>
123
+ </tr>
124
+ <tr>
125
+ <td>
126
+ <p><code>output</code></p>
127
+ </td>
128
+ <td>
129
+ <p>
130
+ Whether the collection's documents will be output as individual files.
131
+ </p>
132
+ </td>
133
+ </tr>
134
+ </tbody>
135
+ </table>
136
+ </div>
137
+
138
+
66
139
  ### Documents
67
140
 
68
141
  In addition to any YAML front-matter provided in the document's corresponding file, each document has the following attributes:
@@ -121,6 +121,18 @@ class="flag">flags</code> (specified on the command-line) that control them.
121
121
  <p><code class="option">encoding: ENCODING</code></p>
122
122
  </td>
123
123
  </tr>
124
+ <tr>
125
+ <td>
126
+ <p class='name'><strong>Defaults</strong></p>
127
+ <p class='description'>
128
+ Set defaults for <a href="../frontmatter/" title="YAML frontmatter">YAML frontmatter</a>
129
+ variables.
130
+ </p>
131
+ </td>
132
+ <td class='align-center'>
133
+ <p>see <a href="#frontmatter_defaults" title="details">below</a></p>
134
+ </td>
135
+ </tr>
124
136
  </tbody>
125
137
  </table>
126
138
  </div>
@@ -264,6 +276,43 @@ before your site is served.
264
276
  </p>
265
277
  </div>
266
278
 
279
+ ## Frontmatter defaults
280
+
281
+ You can set default values for your [YAML frontmatter](../frontmatter/) variables
282
+ in your configuration. This way, you can for example set default layouts or define
283
+ defaults for your custom variables. Of course, any variable actually specified in
284
+ the front matter overrides the defaults.
285
+
286
+ All defaults go under the `defaults` key, which holds a list of scope-values combinations ("default sets").
287
+ The `scope` key defines for which files the defaults apply, limiting them by their `path` and
288
+ optionally by their `type` (`page`, `post` or `draft`). The `values` key holds the actual list of defaults.
289
+
290
+ For example:
291
+ {% highlight yaml %}
292
+ defaults:
293
+ -
294
+ scope:
295
+ path: "" # empty string for all files
296
+ values:
297
+ layout: "my-site"
298
+ -
299
+ scope:
300
+ path: "about/blog"
301
+ type: "post"
302
+ values:
303
+ layout: "meta-blog" # overrides previous default layout
304
+ author: "Dr. Hyde"
305
+ {% endhighlight %}
306
+
307
+ With these defaults, all pages and posts would default to the `my-site` layout except for the posts under `about/blog`,
308
+ who would default to the `meta-blog` layout and also have the `page.author` [liquid variable](../variables/) set to `Dr. Hyde` by default.
309
+
310
+ ### Precedence
311
+ You can have multiple sets of frontmatter defaults that specify defaults for the same setting. In this case, for each page or post,
312
+ the default set with the more specific scope takes precedence. This way, you can specify defaults for a path like `/site/blog` that would
313
+ override any defaults for `/site`. Also, if the paths are equal, a scope with a specified type is more specific. If two sets are equally
314
+ specific, the bottom-most takes precedence.
315
+
267
316
  ## Default Configuration
268
317
 
269
318
  Jekyll runs with the following configuration options by default. Unless
@@ -179,3 +179,13 @@ These are available out-of-the-box to be used in the front-matter for a post.
179
179
  </tbody>
180
180
  </table>
181
181
  </div>
182
+
183
+ <div class="note">
184
+ <h5>ProTip™: Don't repeat yourself</h5>
185
+ <p>
186
+ If you don't want to repeat your frequently used front-matter variables over and over,
187
+ just define <a href="../configuration/#frontmatter_defaults" title="frontmatter defaults">defaults</a>
188
+ for them and only override them where necessary (or not at all). This works both for predefined
189
+ and custom variables.
190
+ </p>
191
+ </div>
@@ -426,6 +426,7 @@ You can find a few useful plugins at the following locations:
426
426
  - [Compass integration for Jekyll](https://github.com/mscharley/jekyll-compass): Easily integrate Compass and Sass with your Jekyll website.
427
427
  - [Pages Directory by Ben Baker-Smith](https://github.com/bbakersmith/jekyll-pages-directory): Defines a `_pages` directory for page files which routes its output relative to the project root.
428
428
  - [Page Collections by Jeff Kolesky](https://github.com/jeffkole/jekyll-page-collections): Generates collections of pages with functionality that resembles posts.
429
+ - [Windows 8.1 Live Tile Generation by Matt Sheehan](https://github.com/sheehamj13/jekyll-live-tiles): Generates Internet Explorer 11 config.xml file and Tile Templates for pinning your site to Windows 8.1.
429
430
 
430
431
  #### Converters
431
432
 
@@ -41,6 +41,15 @@ file. For example, the following are examples of valid post filenames:
41
41
  2012-09-12-how-to-write-a-blog.textile
42
42
  {% endhighlight %}
43
43
 
44
+ <div class="note">
45
+ <h5>ProTip™: Link to other posts</h5>
46
+ <p>
47
+ Use the <a href="../templates#post_url"><code>post_url</code></a>
48
+ tag to link to other posts without having to worry about the URL's
49
+ breaking when the site permalink style changes.
50
+ </p>
51
+ </div>
52
+
44
53
  ### Content Formats
45
54
 
46
55
  All blog post files must begin with [YAML front-matter](../frontmatter/). After
@@ -16,8 +16,8 @@ learning purposes.
16
16
  ([source](https://github.com/qrush/qrush.github.com))
17
17
  - [Roger Chapman](http://rogchap.com/)
18
18
  ([source](https://github.com/rogchap/rogchap.github.com))
19
- - [GitHub Official Teaching Materials](http://teach.github.com)
20
- ([source](https://github.com/github/teach.github.com))
19
+ - [GitHub Official Teaching Materials](http://training.github.com)
20
+ ([source](https://github.com/github/training.github.com/tree/7049d7532a6856411e34046aedfce43a4afaf424))
21
21
  - [Rasmus Andersson](http://rsms.me/)
22
22
  ([source](https://github.com/rsms/rsms.github.com))
23
23
  - [Scott Chacon](http://schacon.github.com)