Merge branch 'master' into frontmatter-defaults
This commit is contained in:
commit
20ea0c8d56
|
@ -9,6 +9,8 @@ rvm:
|
||||||
script: bundle exec rake
|
script: bundle exec rake
|
||||||
notifications:
|
notifications:
|
||||||
irc:
|
irc:
|
||||||
|
on_success: change
|
||||||
|
on_failure: change
|
||||||
channels:
|
channels:
|
||||||
- "irc.freenode.org#jekyll"
|
- "irc.freenode.org#jekyll"
|
||||||
#on_success: change
|
#on_success: change
|
||||||
|
|
|
@ -11,14 +11,20 @@ following in mind:
|
||||||
[RR](http://github.com/btakita/rr/tree/master).
|
[RR](http://github.com/btakita/rr/tree/master).
|
||||||
* If it's a brand new feature, make sure to create a new
|
* If it's a brand new feature, make sure to create a new
|
||||||
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
||||||
where appropriate. Also, whipping up some documentation in your fork's wiki
|
where appropriate. Also, whipping up some documentation in your fork's `site`
|
||||||
would be appreciated, and once merged it will be transferred over to the main
|
would be appreciated, and once merged it will be transferred over to the main
|
||||||
wiki.
|
`site`, jekyllrb.com.
|
||||||
* If your contribution changes any Jekyll behavior, make sure to update the
|
* If your contribution changes any Jekyll behavior, make sure to update the
|
||||||
documentation. It lives in `site/docs`. If the docs are missing information,
|
documentation. It lives in `site/docs`. If the docs are missing information,
|
||||||
please feel free to add it in. Great docs make a great project!
|
please feel free to add it in. Great docs make a great project!
|
||||||
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||||
when modifying Ruby code.
|
when modifying Ruby code.
|
||||||
|
* Please do your best to submit **small pull requests**. The easier the proposed
|
||||||
|
change is to review, the more likely it will be merged.
|
||||||
|
* When submitting a pull request, please make judicious use of the pull request
|
||||||
|
body. A description of what changes were made, the motivations behind the
|
||||||
|
changes and [any tasks completed or left to complete](http://git.io/gfm-tasks)
|
||||||
|
will also speed up review time.
|
||||||
|
|
||||||
Test Dependencies
|
Test Dependencies
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -32,8 +38,8 @@ you're all set!
|
||||||
Before you start, run the tests and make sure that they pass (to confirm your
|
Before you start, run the tests and make sure that they pass (to confirm your
|
||||||
environment is configured properly):
|
environment is configured properly):
|
||||||
|
|
||||||
$ rake test
|
$ bundle exec rake test
|
||||||
$ rake features
|
$ bundle exec rake features
|
||||||
|
|
||||||
Workflow
|
Workflow
|
||||||
--------
|
--------
|
||||||
|
@ -65,8 +71,7 @@ All documentation pull requests should be directed at `master`. Pull
|
||||||
requests directed at another branch will not be accepted.
|
requests directed at another branch will not be accepted.
|
||||||
|
|
||||||
The [Jekyll wiki](https://github.com/mojombo/jekyll/wiki) on GitHub
|
The [Jekyll wiki](https://github.com/mojombo/jekyll/wiki) on GitHub
|
||||||
can be freely updated without a pull request as all
|
can be freely updated without a pull request as all GitHub users have access.
|
||||||
GitHub users have access.
|
|
||||||
|
|
||||||
Gotchas
|
Gotchas
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -1,23 +1,78 @@
|
||||||
## HEAD
|
## HEAD
|
||||||
|
|
||||||
### Major Enhancements
|
### Major Enhancements
|
||||||
|
* Add support for adding data as YAML files under a site's `_data`
|
||||||
|
directory (#1003)
|
||||||
|
* Allow variables to be used with `include` tags (#1495)
|
||||||
|
|
||||||
### Minor Enhancements
|
### Minor Enhancements
|
||||||
|
* Decrease the specificity in the site template CSS (#1574)
|
||||||
|
* Add `encoding` configuration option (#1449)
|
||||||
|
* Provide better error handling for Jekyll's custom Liquid tags
|
||||||
|
(#1514)
|
||||||
|
* If an included file causes a Liquid error, add the path to the
|
||||||
|
include file that caused the error to the error message (#1596)
|
||||||
|
* If a layout causes a Liquid error, change the error message so that
|
||||||
|
we know it comes from the layout (#1601)
|
||||||
|
* Update Kramdown dependency to `~> 1.2` (#1610)
|
||||||
|
* Update `safe_yaml` dependency to `~> 0.9.7` (#1602)
|
||||||
|
* Allow layouts to be in subfolders like includes (#1622)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
* Fix up matching against source and destination when the two
|
||||||
|
locations are similar (#1556)
|
||||||
|
* Fix the missing `pathname` require in certain cases (#1255)
|
||||||
|
* Use `+` instead of `Array#concat` when building `Post` attribute list (#1571)
|
||||||
|
* Print server address when launching a server (#1586)
|
||||||
|
* Downgrade to Maruku `~> 0.6.0` in order to avoid changes in rendering (#1598)
|
||||||
|
* Fix error with failing include tag when variable was file name (#1613)
|
||||||
|
* Downcase lexers before passing them to pygments (#1615)
|
||||||
|
|
||||||
|
### Development Fixes
|
||||||
|
* Add coverage reporting with Coveralls (#1539)
|
||||||
|
* Refactor the Liquid `include` tag (#1490)
|
||||||
|
* Update launchy dependency to `~> 2.3` (#1608)
|
||||||
|
* Update rr dependency to `~> 1.1` (#1604)
|
||||||
|
* Update cucumber dependency to `~> 1.3` (#1607)
|
||||||
|
* Update coveralls dependency to `~> 0.7.0` (#1606)
|
||||||
|
* Update rake dependency to `~> 10.1` (#1603)
|
||||||
|
* Clean up `site.rb` comments to be more concise/uniform (#1616)
|
||||||
|
|
||||||
|
### Site Enhancements
|
||||||
|
* Fix params for `JekyllImport::WordPress.process` arguments (#1554)
|
||||||
|
* Add `jekyll-suggested-tweet` to list of third-party plugins (#1555)
|
||||||
|
* Link to Liquid's docs for tags and filters (#1553)
|
||||||
|
* Add note about installing Xcode on the Mac in the Installation docs (#1561)
|
||||||
|
* Simplify/generalize pagination docs (#1577)
|
||||||
|
* Add documentation for the new data sources feature (#1503)
|
||||||
|
* Add more information on how to create generators (#1590, #1592)
|
||||||
|
* Improve the instructions for mimicking GitHub Flavored Markdown
|
||||||
|
(#1614)
|
||||||
|
* Add `jekyll-import` warning note of missing dependencies (#1626)
|
||||||
|
|
||||||
|
## 1.2.1 / 2013-09-14
|
||||||
|
|
||||||
|
### Minor Enhancements
|
||||||
|
* Print better messages for detached server. Mute output on detach. (#1518)
|
||||||
* Disable reverse lookup when running `jekyll serve` (#1363)
|
* Disable reverse lookup when running `jekyll serve` (#1363)
|
||||||
* Upgrade RedCarpet dependency to `~> 2.3.0` (#1515)
|
* Upgrade RedCarpet dependency to `~> 2.3.0` (#1515)
|
||||||
|
* Upgrade to Liquid `>= 2.5.2, < 2.6` (#1536)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* Fix file discrepancy in gemspec (#1522)
|
* Fix file discrepancy in gemspec (#1522)
|
||||||
|
* Force rendering of Include tag (#1525)
|
||||||
|
|
||||||
### Development Fixes
|
### Development Fixes
|
||||||
* Add a rake task to generate a new release post (#1404)
|
* Add a rake task to generate a new release post (#1404)
|
||||||
|
* Mute LSI output in tests (#1531)
|
||||||
|
* Update contributor documentation (#1537)
|
||||||
|
|
||||||
### Site Enhancements
|
### Site Enhancements
|
||||||
* Fix a couple of validation errors on the site (#1511)
|
* Fix a couple of validation errors on the site (#1511)
|
||||||
* Make navigation menus reusable (#1507)
|
* Make navigation menus reusable (#1507)
|
||||||
* Fix link to History page from Release v1.2.0 notes post.
|
* Fix link to History page from Release v1.2.0 notes post.
|
||||||
* Fix markup in History file for command line options (#1512)
|
* Fix markup in History file for command line options (#1512)
|
||||||
|
* Expand 1.2 release post title to 1.2.0 (#1516)
|
||||||
|
|
||||||
## 1.2.0 / 2013-09-06
|
## 1.2.0 / 2013-09-06
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
[](https://travis-ci.org/mojombo/jekyll)
|
[](https://travis-ci.org/mojombo/jekyll)
|
||||||
[](https://codeclimate.com/github/mojombo/jekyll)
|
[](https://codeclimate.com/github/mojombo/jekyll)
|
||||||
[](https://gemnasium.com/mojombo/jekyll)
|
[](https://gemnasium.com/mojombo/jekyll)
|
||||||
|
[](https://coveralls.io/r/mojombo/jekyll)
|
||||||
|
|
||||||
By Tom Preston-Werner, Nick Quaranto, and many awesome contributors!
|
By Tom Preston-Werner, Nick Quaranto, and many awesome contributors!
|
||||||
|
|
||||||
|
|
10
Rakefile
10
Rakefile
|
@ -84,7 +84,14 @@ end
|
||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
task :default => [:test, :features]
|
if RUBY_VERSION > '1.9' && ENV["TRAVIS"] == "true"
|
||||||
|
require 'coveralls/rake/task'
|
||||||
|
Coveralls::RakeTask.new
|
||||||
|
|
||||||
|
task :default => [:test, :features, 'coveralls:push']
|
||||||
|
else
|
||||||
|
task :default => [:test, :features]
|
||||||
|
end
|
||||||
|
|
||||||
require 'rake/testtask'
|
require 'rake/testtask'
|
||||||
Rake::TestTask.new(:test) do |test|
|
Rake::TestTask.new(:test) do |test|
|
||||||
|
@ -217,6 +224,7 @@ namespace :site do
|
||||||
task :new, :version do |t, args|
|
task :new, :version do |t, args|
|
||||||
raise "Specify a version: rake site:releases:new['1.2.3']" unless args.version
|
raise "Specify a version: rake site:releases:new['1.2.3']" unless args.version
|
||||||
today = Time.new.strftime('%Y-%m-%d')
|
today = Time.new.strftime('%Y-%m-%d')
|
||||||
|
release = args.version.to_s
|
||||||
filename = "site/_posts/#{today}-jekyll-#{release.split('.').join('-')}-released.markdown"
|
filename = "site/_posts/#{today}-jekyll-#{release.split('.').join('-')}-released.markdown"
|
||||||
|
|
||||||
File.open(filename, "wb") do |post|
|
File.open(filename, "wb") do |post|
|
||||||
|
|
|
@ -65,6 +65,7 @@ command :build do |c|
|
||||||
c.option '-w', '--watch', 'Watch for changes and rebuild'
|
c.option '-w', '--watch', 'Watch for changes and rebuild'
|
||||||
c.option '--lsi', 'Use LSI for improved related posts'
|
c.option '--lsi', 'Use LSI for improved related posts'
|
||||||
c.option '-D', '--drafts', 'Render posts in the _drafts folder'
|
c.option '-D', '--drafts', 'Render posts in the _drafts folder'
|
||||||
|
c.option '-v', '--verbose', 'Print verbose output.'
|
||||||
|
|
||||||
c.action do |args, options|
|
c.action do |args, options|
|
||||||
options = normalize_options(options.__hash__)
|
options = normalize_options(options.__hash__)
|
||||||
|
@ -84,6 +85,7 @@ command :serve do |c|
|
||||||
c.option '--lsi', 'Use LSI for improved related posts'
|
c.option '--lsi', 'Use LSI for improved related posts'
|
||||||
c.option '-B', '--detach', 'Run the server in the background (detach)'
|
c.option '-B', '--detach', 'Run the server in the background (detach)'
|
||||||
c.option '-D', '--drafts', 'Render posts in the _drafts folder'
|
c.option '-D', '--drafts', 'Render posts in the _drafts folder'
|
||||||
|
c.option '-v', '--verbose', 'Print verbose output.'
|
||||||
|
|
||||||
c.option '-P', '--port [PORT]', 'Port to listen on'
|
c.option '-P', '--port [PORT]', 'Port to listen on'
|
||||||
c.option '-H', '--host [HOST]', 'Host to bind to'
|
c.option '-H', '--host [HOST]', 'Host to bind to'
|
||||||
|
|
|
@ -44,6 +44,17 @@ Feature: Create sites
|
||||||
Then the _site directory should exist
|
Then the _site directory should exist
|
||||||
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||||
|
|
||||||
|
Scenario: Basic site with layout inside a subfolder and a post
|
||||||
|
Given I have a _layouts directory
|
||||||
|
And I have a _posts directory
|
||||||
|
And I have the following posts:
|
||||||
|
| title | date | layout | content |
|
||||||
|
| Wargames | 2009-03-27 | post/simple | The only winning move is not to play. |
|
||||||
|
And I have a post/simple layout that contains "Post Layout: {{ content }}"
|
||||||
|
When I run jekyll
|
||||||
|
Then the _site directory should exist
|
||||||
|
And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html"
|
||||||
|
|
||||||
Scenario: Basic site with layouts, pages, posts and files
|
Scenario: Basic site with layouts, pages, posts and files
|
||||||
Given I have a _layouts directory
|
Given I have a _layouts directory
|
||||||
And I have a page layout that contains "Page {{ page.title }}: {{ content }}"
|
And I have a page layout that contains "Page {{ page.title }}: {{ content }}"
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
Feature: Data
|
||||||
|
In order to use well-formatted data in my blog
|
||||||
|
As a blog's user
|
||||||
|
I want to use _data directory in my site
|
||||||
|
|
||||||
|
Scenario: autoload *.yaml files in _data directory
|
||||||
|
Given I have a _data directory
|
||||||
|
And I have a "_data/products.yaml" file with content:
|
||||||
|
"""
|
||||||
|
- name: sugar
|
||||||
|
price: 5.3
|
||||||
|
- name: salt
|
||||||
|
price: 2.5
|
||||||
|
"""
|
||||||
|
And I have an "index.html" page that contains "{% for product in site.data.products %}{{product.name}}{% endfor %}"
|
||||||
|
When I run jekyll
|
||||||
|
Then the "_site/index.html" file should exist
|
||||||
|
And I should see "sugar" in "_site/index.html"
|
||||||
|
And I should see "salt" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: autoload *.yml files in _data directory
|
||||||
|
Given I have a _data directory
|
||||||
|
And I have a "_data/members.yml" file with content:
|
||||||
|
"""
|
||||||
|
- name: Jack
|
||||||
|
age: 28
|
||||||
|
- name: Leon
|
||||||
|
age: 34
|
||||||
|
"""
|
||||||
|
And I have an "index.html" page that contains "{% for member in site.data.members %}{{member.name}}{% endfor %}"
|
||||||
|
When I run jekyll
|
||||||
|
Then the "_site/index.html" file should exist
|
||||||
|
And I should see "Jack" in "_site/index.html"
|
||||||
|
And I should see "Leon" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: autoload *.yml files in _data directory with space in file name
|
||||||
|
Given I have a _data directory
|
||||||
|
And I have a "_data/team members.yml" file with content:
|
||||||
|
"""
|
||||||
|
- name: Jack
|
||||||
|
age: 28
|
||||||
|
- name: Leon
|
||||||
|
age: 34
|
||||||
|
"""
|
||||||
|
And I have an "index.html" page that contains "{% for member in site.data.team_members %}{{member.name}}{% endfor %}"
|
||||||
|
When I run jekyll
|
||||||
|
Then the "_site/index.html" file should exist
|
||||||
|
And I should see "Jack" in "_site/index.html"
|
||||||
|
And I should see "Leon" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: should be backward compatible with site.data in _config.yml
|
||||||
|
Given I have a "_config.yml" file with content:
|
||||||
|
"""
|
||||||
|
data:
|
||||||
|
- name: Jack
|
||||||
|
age: 28
|
||||||
|
- name: Leon
|
||||||
|
age: 34
|
||||||
|
"""
|
||||||
|
And I have an "index.html" page that contains "{% for member in site.data %}{{member.name}}{% endfor %}"
|
||||||
|
When I run jekyll
|
||||||
|
Then the "_site/index.html" file should exist
|
||||||
|
And I should see "Jack" in "_site/index.html"
|
||||||
|
And I should see "Leon" in "_site/index.html"
|
||||||
|
|
|
@ -33,3 +33,16 @@ Feature: Include tags
|
||||||
And I should see "<li>param1_or_2 = value</li>" in "_site/2013/04/12/parameter-syntax.html"
|
And I should see "<li>param1_or_2 = value</li>" in "_site/2013/04/12/parameter-syntax.html"
|
||||||
And I should see "<li>local = some text</li>" in "_site/2013/06/22/pass-a-variable.html"
|
And I should see "<li>local = some text</li>" in "_site/2013/06/22/pass-a-variable.html"
|
||||||
And I should see "<li>layout = default</li>" in "_site/2013/06/22/pass-a-variable.html"
|
And I should see "<li>layout = default</li>" in "_site/2013/06/22/pass-a-variable.html"
|
||||||
|
|
||||||
|
Scenario: Include a file from a variable
|
||||||
|
Given I have an _includes directory
|
||||||
|
And I have an "_includes/snippet.html" file that contains "a snippet"
|
||||||
|
And I have an "_includes/parametrized.html" file that contains "works with {{include.what}}"
|
||||||
|
And I have a configuration file with:
|
||||||
|
| key | value |
|
||||||
|
| include_file1 | snippet.html |
|
||||||
|
| include_file2 | parametrized.html |
|
||||||
|
And I have an "index.html" page that contains "{% include {{site.include_file1}} %} that {% include {{site.include_file2}} what='parameters' %}"
|
||||||
|
When I run jekyll
|
||||||
|
Then the _site directory should exist
|
||||||
|
And I should see "a snippet that works with parameters" in "_site/index.html"
|
||||||
|
|
|
@ -18,6 +18,27 @@ Feature: Site configuration
|
||||||
Then the _mysite directory should exist
|
Then the _mysite directory should exist
|
||||||
And I should see "Changing destination directory" in "_mysite/index.html"
|
And I should see "Changing destination directory" in "_mysite/index.html"
|
||||||
|
|
||||||
|
Scenario Outline: Similarly named source and destination
|
||||||
|
Given I have a blank site in "<source>"
|
||||||
|
And I have an "<source>/index.md" page that contains "markdown"
|
||||||
|
And I have a configuration file with:
|
||||||
|
| key | value |
|
||||||
|
| source | <source> |
|
||||||
|
| destination | <dest> |
|
||||||
|
When I run jekyll
|
||||||
|
Then the <source> directory should exist
|
||||||
|
And the "<dest>/index.html" file should <file_exist> exist
|
||||||
|
And I should see "markdown" in "<source>/index.md"
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| source | dest | file_exist |
|
||||||
|
| mysite_source | mysite | |
|
||||||
|
| mysite | mysite_dest | |
|
||||||
|
| mysite/ | mysite | not |
|
||||||
|
| mysite | ./mysite | not |
|
||||||
|
| mysite/source | mysite | not |
|
||||||
|
| mysite | mysite/dest | |
|
||||||
|
|
||||||
Scenario: Exclude files inline
|
Scenario: Exclude files inline
|
||||||
Given I have an "Rakefile" file that contains "I want to be excluded"
|
Given I have an "Rakefile" file that contains "I want to be excluded"
|
||||||
And I have an "README" file that contains "I want to be excluded"
|
And I have an "README" file that contains "I want to be excluded"
|
||||||
|
|
|
@ -7,7 +7,7 @@ end
|
||||||
World(Test::Unit::Assertions)
|
World(Test::Unit::Assertions)
|
||||||
|
|
||||||
Given /^I have a blank site in "(.*)"$/ do |path|
|
Given /^I have a blank site in "(.*)"$/ do |path|
|
||||||
FileUtils.mkdir(path)
|
FileUtils.mkdir_p(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
Given /^I do not have a "(.*)" directory$/ do |path|
|
Given /^I do not have a "(.*)" directory$/ do |path|
|
||||||
|
@ -38,7 +38,18 @@ Given /^I have an? (.*) (layout|theme) that contains "(.*)"$/ do |name, type, te
|
||||||
else
|
else
|
||||||
'_theme'
|
'_theme'
|
||||||
end
|
end
|
||||||
File.open(File.join(folder, name + '.html'), 'w') do |f|
|
destination_file = File.join(folder, name + '.html')
|
||||||
|
destination_path = File.dirname(destination_file)
|
||||||
|
unless File.exist?(destination_path)
|
||||||
|
FileUtils.mkdir_p(destination_path)
|
||||||
|
end
|
||||||
|
File.open(destination_file, 'w') do |f|
|
||||||
|
f.write(text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Given /^I have an? "(.*)" file with content:$/ do |file, text|
|
||||||
|
File.open(file, 'w') do |f|
|
||||||
f.write(text)
|
f.write(text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -137,10 +148,14 @@ When /^I delete the file "(.*)"$/ do |file|
|
||||||
File.delete(file)
|
File.delete(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^the (.*) directory should exist$/ do |dir|
|
Then /^the (.*) directory should +exist$/ do |dir|
|
||||||
assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
|
assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Then /^the (.*) directory should not exist$/ do |dir|
|
||||||
|
assert !File.directory?(dir), "The directory \"#{dir}\" exists"
|
||||||
|
end
|
||||||
|
|
||||||
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
|
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
|
||||||
assert Regexp.new(text).match(File.open(file).readlines.join)
|
assert Regexp.new(text).match(File.open(file).readlines.join)
|
||||||
end
|
end
|
||||||
|
@ -157,12 +172,12 @@ Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file|
|
||||||
assert Regexp.new(Regexp.escape(text)).match(File.open(file).readlines.join)
|
assert Regexp.new(Regexp.escape(text)).match(File.open(file).readlines.join)
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^the "(.*)" file should exist$/ do |file|
|
Then /^the "(.*)" file should +exist$/ do |file|
|
||||||
assert File.file?(file)
|
assert File.file?(file), "The file \"#{file}\" does not exist"
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^the "(.*)" file should not exist$/ do |file|
|
Then /^the "(.*)" file should not exist$/ do |file|
|
||||||
assert !File.exists?(file)
|
assert !File.exists?(file), "The file \"#{file}\" exists"
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^I should see today's time in "(.*)"$/ do |file|
|
Then /^I should see today's time in "(.*)"$/ do |file|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
if RUBY_VERSION > '1.9'
|
||||||
|
require 'coveralls'
|
||||||
|
Coveralls.wear_merged!
|
||||||
|
end
|
||||||
|
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'rr'
|
require 'rr'
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
|
|
|
@ -4,9 +4,9 @@ Gem::Specification.new do |s|
|
||||||
s.rubygems_version = '1.3.5'
|
s.rubygems_version = '1.3.5'
|
||||||
|
|
||||||
s.name = 'jekyll'
|
s.name = 'jekyll'
|
||||||
s.version = '1.2.0'
|
s.version = '1.2.1'
|
||||||
s.license = 'MIT'
|
s.license = 'MIT'
|
||||||
s.date = '2013-09-06'
|
s.date = '2013-09-14'
|
||||||
s.rubyforge_project = 'jekyll'
|
s.rubyforge_project = 'jekyll'
|
||||||
|
|
||||||
s.summary = "A simple, blog aware, static site generator."
|
s.summary = "A simple, blog aware, static site generator."
|
||||||
|
@ -23,28 +23,29 @@ Gem::Specification.new do |s|
|
||||||
s.rdoc_options = ["--charset=UTF-8"]
|
s.rdoc_options = ["--charset=UTF-8"]
|
||||||
s.extra_rdoc_files = %w[README.markdown LICENSE]
|
s.extra_rdoc_files = %w[README.markdown LICENSE]
|
||||||
|
|
||||||
s.add_runtime_dependency('liquid', "~> 2.5.1")
|
s.add_runtime_dependency('liquid', "~> 2.5.2")
|
||||||
s.add_runtime_dependency('classifier', "~> 1.3")
|
s.add_runtime_dependency('classifier', "~> 1.3")
|
||||||
s.add_runtime_dependency('directory_watcher', "~> 1.4.1")
|
s.add_runtime_dependency('directory_watcher', "~> 1.4.1")
|
||||||
s.add_runtime_dependency('maruku', "~> 0.5")
|
s.add_runtime_dependency('maruku', "~> 0.6.0")
|
||||||
s.add_runtime_dependency('pygments.rb', "~> 0.5.0")
|
s.add_runtime_dependency('pygments.rb', "~> 0.5.0")
|
||||||
s.add_runtime_dependency('commander', "~> 4.1.3")
|
s.add_runtime_dependency('commander', "~> 4.1.3")
|
||||||
s.add_runtime_dependency('safe_yaml', "~> 0.7.0")
|
s.add_runtime_dependency('safe_yaml', "~> 0.9.7")
|
||||||
s.add_runtime_dependency('colorator', "~> 0.1")
|
s.add_runtime_dependency('colorator', "~> 0.1")
|
||||||
s.add_runtime_dependency('redcarpet', "~> 2.3.0")
|
s.add_runtime_dependency('redcarpet', "~> 2.3.0")
|
||||||
|
|
||||||
s.add_development_dependency('rake', "~> 10.0.3")
|
s.add_development_dependency('rake', "~> 10.1")
|
||||||
s.add_development_dependency('rdoc', "~> 3.11")
|
s.add_development_dependency('rdoc', "~> 3.11")
|
||||||
s.add_development_dependency('redgreen', "~> 1.2")
|
s.add_development_dependency('redgreen', "~> 1.2")
|
||||||
s.add_development_dependency('shoulda', "~> 3.3.2")
|
s.add_development_dependency('shoulda', "~> 3.3.2")
|
||||||
s.add_development_dependency('rr', "~> 1.0.0")
|
s.add_development_dependency('rr', "~> 1.1")
|
||||||
s.add_development_dependency('cucumber', "~> 1.2.1", '!= 1.2.4')
|
s.add_development_dependency('cucumber', "~> 1.3")
|
||||||
s.add_development_dependency('RedCloth', "~> 4.2")
|
s.add_development_dependency('RedCloth', "~> 4.2")
|
||||||
s.add_development_dependency('kramdown', "~> 1.0.2")
|
s.add_development_dependency('kramdown', "~> 1.2")
|
||||||
s.add_development_dependency('rdiscount', "~> 1.6")
|
s.add_development_dependency('rdiscount', "~> 1.6")
|
||||||
s.add_development_dependency('launchy', "~> 2.1.2")
|
s.add_development_dependency('launchy', "~> 2.3")
|
||||||
s.add_development_dependency('simplecov', "~> 0.7")
|
s.add_development_dependency('simplecov', "~> 0.7")
|
||||||
s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
|
s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
|
||||||
|
s.add_development_dependency('coveralls', "~> 0.7.0")
|
||||||
s.add_development_dependency('activesupport', '~> 3.2.13')
|
s.add_development_dependency('activesupport', '~> 3.2.13')
|
||||||
|
|
||||||
# = MANIFEST =
|
# = MANIFEST =
|
||||||
|
@ -58,6 +59,7 @@ Gem::Specification.new do |s|
|
||||||
bin/jekyll
|
bin/jekyll
|
||||||
cucumber.yml
|
cucumber.yml
|
||||||
features/create_sites.feature
|
features/create_sites.feature
|
||||||
|
features/data.feature
|
||||||
features/drafts.feature
|
features/drafts.feature
|
||||||
features/embed_filters.feature
|
features/embed_filters.feature
|
||||||
features/include_tag.feature
|
features/include_tag.feature
|
||||||
|
@ -149,6 +151,7 @@ Gem::Specification.new do |s|
|
||||||
site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
|
site/_posts/2013-07-25-jekyll-1-0-4-released.markdown
|
||||||
site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
|
site/_posts/2013-07-25-jekyll-1-1-2-released.markdown
|
||||||
site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
|
site/_posts/2013-09-06-jekyll-1-2-0-released.markdown
|
||||||
|
site/_posts/2013-09-14-jekyll-1-2-1-released.markdown
|
||||||
site/css/gridism.css
|
site/css/gridism.css
|
||||||
site/css/normalize.css
|
site/css/normalize.css
|
||||||
site/css/pygments.css
|
site/css/pygments.css
|
||||||
|
@ -201,6 +204,7 @@ Gem::Specification.new do |s|
|
||||||
test/helper.rb
|
test/helper.rb
|
||||||
test/source/+/foo.md
|
test/source/+/foo.md
|
||||||
test/source/.htaccess
|
test/source/.htaccess
|
||||||
|
test/source/_data/members.yaml
|
||||||
test/source/_includes/params.html
|
test/source/_includes/params.html
|
||||||
test/source/_includes/sig.markdown
|
test/source/_includes/sig.markdown
|
||||||
test/source/_layouts/default.html
|
test/source/_layouts/default.html
|
||||||
|
|
|
@ -20,6 +20,7 @@ require 'fileutils'
|
||||||
require 'time'
|
require 'time'
|
||||||
require 'safe_yaml'
|
require 'safe_yaml'
|
||||||
require 'English'
|
require 'English'
|
||||||
|
require 'pathname'
|
||||||
|
|
||||||
# 3rd party
|
# 3rd party
|
||||||
require 'liquid'
|
require 'liquid'
|
||||||
|
@ -61,7 +62,7 @@ require_all 'jekyll/tags'
|
||||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||||
|
|
||||||
module Jekyll
|
module Jekyll
|
||||||
VERSION = '1.2.0'
|
VERSION = '1.2.1'
|
||||||
|
|
||||||
# Public: Generate a Jekyll configuration Hash by merging the default
|
# Public: Generate a Jekyll configuration Hash by merging the default
|
||||||
# options with anything in _config.yml, and adding the given options on top.
|
# options with anything in _config.yml, and adding the given options on top.
|
||||||
|
|
|
@ -2,7 +2,7 @@ require 'set'
|
||||||
|
|
||||||
module Jekyll
|
module Jekyll
|
||||||
class Site
|
class Site
|
||||||
# Handles the cleanup of a site's destination before the site is built.
|
# Handles the cleanup of a site's destination before it is built.
|
||||||
class Cleaner
|
class Cleaner
|
||||||
def initialize(site)
|
def initialize(site)
|
||||||
@site = site
|
@site = site
|
||||||
|
@ -15,14 +15,14 @@ module Jekyll
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Private: The list of files and directories to be deleted during the cleanup process
|
# Private: The list of files and directories to be deleted during cleanup process
|
||||||
#
|
#
|
||||||
# Returns an Array with the file and directory paths
|
# Returns an Array of the file and directory paths
|
||||||
def obsolete_files
|
def obsolete_files
|
||||||
(existing_files - new_files - new_dirs + replaced_files).to_a
|
(existing_files - new_files - new_dirs + replaced_files).to_a
|
||||||
end
|
end
|
||||||
|
|
||||||
# Private: The list of existing files, except those included in keep_files and hidden files.
|
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
||||||
#
|
#
|
||||||
# Returns a Set with the file paths
|
# Returns a Set with the file paths
|
||||||
def existing_files
|
def existing_files
|
||||||
|
@ -33,7 +33,7 @@ module Jekyll
|
||||||
files
|
files
|
||||||
end
|
end
|
||||||
|
|
||||||
# Private: The list of files to be created when the site is built.
|
# Private: The list of files to be created when site is built.
|
||||||
#
|
#
|
||||||
# Returns a Set with the file paths
|
# Returns a Set with the file paths
|
||||||
def new_files
|
def new_files
|
||||||
|
@ -42,7 +42,7 @@ module Jekyll
|
||||||
files
|
files
|
||||||
end
|
end
|
||||||
|
|
||||||
# Private: The list of directories to be created when the site is built.
|
# Private: The list of directories to be created when site is built.
|
||||||
# These are the parent directories of the files in #new_files.
|
# These are the parent directories of the files in #new_files.
|
||||||
#
|
#
|
||||||
# Returns a Set with the directory paths
|
# Returns a Set with the directory paths
|
||||||
|
@ -57,7 +57,7 @@ module Jekyll
|
||||||
new_dirs.select { |dir| File.file?(dir) }.to_set
|
new_dirs.select { |dir| File.file?(dir) }.to_set
|
||||||
end
|
end
|
||||||
|
|
||||||
# Private: creates a regular expression from the config's keep_files array
|
# Private: Creates a regular expression from the config's keep_files array
|
||||||
#
|
#
|
||||||
# Examples
|
# Examples
|
||||||
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
module Jekyll
|
module Jekyll
|
||||||
module Commands
|
module Commands
|
||||||
class Serve < Command
|
class Serve < Command
|
||||||
|
@ -10,32 +10,56 @@ module Jekyll
|
||||||
|
|
||||||
FileUtils.mkdir_p(destination)
|
FileUtils.mkdir_p(destination)
|
||||||
|
|
||||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
|
||||||
mime_types = WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
|
||||||
|
|
||||||
# recreate NondisclosureName under utf-8 circumstance
|
# recreate NondisclosureName under utf-8 circumstance
|
||||||
fh_option = WEBrick::Config::FileHandler
|
fh_option = WEBrick::Config::FileHandler
|
||||||
fh_option[:NondisclosureName] = ['.ht*','~*']
|
fh_option[:NondisclosureName] = ['.ht*','~*']
|
||||||
|
|
||||||
s = HTTPServer.new(
|
s = HTTPServer.new(webrick_options(options))
|
||||||
:Port => options['port'],
|
|
||||||
:BindAddress => options['host'],
|
|
||||||
:MimeTypes => mime_types,
|
|
||||||
:DoNotReverseLookup => true
|
|
||||||
)
|
|
||||||
|
|
||||||
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
|
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
|
||||||
|
|
||||||
|
Jekyll.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
|
||||||
|
|
||||||
if options['detach'] # detach the server
|
if options['detach'] # detach the server
|
||||||
pid = Process.fork {s.start}
|
pid = Process.fork { s.start }
|
||||||
Process.detach(pid)
|
Process.detach(pid)
|
||||||
pid
|
Jekyll.logger.info "Server detatched with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
|
||||||
else # create a new server thread, then join it with current terminal
|
else # create a new server thread, then join it with current terminal
|
||||||
t = Thread.new { s.start }
|
t = Thread.new { s.start }
|
||||||
trap("INT") { s.shutdown }
|
trap("INT") { s.shutdown }
|
||||||
t.join()
|
t.join()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.webrick_options(config)
|
||||||
|
opts = {
|
||||||
|
:Port => config['port'],
|
||||||
|
:BindAddress => config['host'],
|
||||||
|
:MimeTypes => self.mime_types,
|
||||||
|
:DoNotReverseLookup => true,
|
||||||
|
:StartCallback => start_callback(config['detach'])
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config['verbose']
|
||||||
|
opts.merge!({
|
||||||
|
:AccessLog => [],
|
||||||
|
:Logger => Log::new([], Log::WARN)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
opts
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.start_callback(detached)
|
||||||
|
unless detached
|
||||||
|
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.mime_types
|
||||||
|
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||||
|
WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,10 +10,13 @@ module Jekyll
|
||||||
'destination' => File.join(Dir.pwd, '_site'),
|
'destination' => File.join(Dir.pwd, '_site'),
|
||||||
'plugins' => '_plugins',
|
'plugins' => '_plugins',
|
||||||
'layouts' => '_layouts',
|
'layouts' => '_layouts',
|
||||||
|
'data_source' => '_data',
|
||||||
'keep_files' => ['.git','.svn'],
|
'keep_files' => ['.git','.svn'],
|
||||||
|
|
||||||
'timezone' => nil, # use the local timezone
|
'timezone' => nil, # use the local timezone
|
||||||
|
|
||||||
|
'encoding' => nil, # use the system encoding
|
||||||
|
|
||||||
'safe' => false,
|
'safe' => false,
|
||||||
'detach' => false, # default to not detaching the server
|
'detach' => false, # default to not detaching the server
|
||||||
'show_drafts' => nil,
|
'show_drafts' => nil,
|
||||||
|
|
|
@ -21,16 +21,23 @@ module Jekyll
|
||||||
self.content || ''
|
self.content || ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns merged optin hash for File.read of self.site (if exists)
|
||||||
|
# and a given param
|
||||||
|
def merged_file_read_opts(opts)
|
||||||
|
(self.site ? self.site.file_read_opts : {}).merge(opts)
|
||||||
|
end
|
||||||
|
|
||||||
# Read the YAML frontmatter.
|
# Read the YAML frontmatter.
|
||||||
#
|
#
|
||||||
# base - The String path to the dir containing the file.
|
# base - The String path to the dir containing the file.
|
||||||
# name - The String filename of the file.
|
# name - The String filename of the file.
|
||||||
|
# opts - optional parameter to File.read, default at site configs
|
||||||
#
|
#
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
def read_yaml(base, name)
|
def read_yaml(base, name, opts = {})
|
||||||
begin
|
begin
|
||||||
self.content = File.read(File.join(base, name))
|
self.content = File.read_with_options(File.join(base, name),
|
||||||
|
merged_file_read_opts(opts))
|
||||||
if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||||
self.content = $POSTMATCH
|
self.content = $POSTMATCH
|
||||||
self.data = YAML.safe_load($1)
|
self.data = YAML.safe_load($1)
|
||||||
|
@ -78,10 +85,13 @@ module Jekyll
|
||||||
# info - the info for Liquid
|
# info - the info for Liquid
|
||||||
#
|
#
|
||||||
# Returns the converted content
|
# Returns the converted content
|
||||||
def render_liquid(content, payload, info)
|
def render_liquid(content, payload, info, path = nil)
|
||||||
Liquid::Template.parse(content).render!(payload, info)
|
Liquid::Template.parse(content).render!(payload, info)
|
||||||
|
rescue Tags::IncludeTagError => e
|
||||||
|
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}"
|
||||||
|
raise e
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{self.path}"
|
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{path || self.path}"
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -113,7 +123,8 @@ module Jekyll
|
||||||
|
|
||||||
self.output = self.render_liquid(layout.content,
|
self.output = self.render_liquid(layout.content,
|
||||||
payload,
|
payload,
|
||||||
info)
|
info,
|
||||||
|
File.join(self.site.config['layouts'], layout.name))
|
||||||
|
|
||||||
if layout = layouts[layout.data["layout"]]
|
if layout = layouts[layout.data["layout"]]
|
||||||
if used.include?(layout)
|
if used.include?(layout)
|
||||||
|
|
|
@ -83,3 +83,18 @@ module Enumerable
|
||||||
any? { |exp| File.fnmatch?(exp, e) }
|
any? { |exp| File.fnmatch?(exp, e) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Ruby 1.8's File.read don't support option.
|
||||||
|
# read_with_options ignore optional parameter for 1.8,
|
||||||
|
# and act as alias for 1.9 or later.
|
||||||
|
class File
|
||||||
|
if RUBY_VERSION < '1.9'
|
||||||
|
def self.read_with_options(path, opts = {})
|
||||||
|
self.read(path)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
def self.read_with_options(path, opts = {})
|
||||||
|
self.read(path, opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -19,10 +19,10 @@ module Jekyll
|
||||||
]
|
]
|
||||||
|
|
||||||
# Attributes for Liquid templates
|
# Attributes for Liquid templates
|
||||||
ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID.concat(%w[
|
ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
|
||||||
content
|
content
|
||||||
excerpt
|
excerpt
|
||||||
])
|
]
|
||||||
|
|
||||||
# Post name validator. Post filenames must be like:
|
# Post name validator. Post filenames must be like:
|
||||||
# 2008-11-05-my-awesome-post.textile
|
# 2008-11-05-my-awesome-post.textile
|
||||||
|
|
|
@ -3,7 +3,7 @@ module Jekyll
|
||||||
attr_accessor :config, :layouts, :posts, :pages, :static_files,
|
attr_accessor :config, :layouts, :posts, :pages, :static_files,
|
||||||
:categories, :exclude, :include, :source, :dest, :lsi, :pygments,
|
:categories, :exclude, :include, :source, :dest, :lsi, :pygments,
|
||||||
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
|
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
|
||||||
:show_drafts, :keep_files, :baseurl
|
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts
|
||||||
|
|
||||||
attr_accessor :converters, :generators
|
attr_accessor :converters, :generators
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@ module Jekyll
|
||||||
self.plugins = plugins_path
|
self.plugins = plugins_path
|
||||||
self.permalink_style = config['permalink'].to_sym
|
self.permalink_style = config['permalink'].to_sym
|
||||||
|
|
||||||
|
self.file_read_opts = {}
|
||||||
|
self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
|
||||||
|
|
||||||
self.reset
|
self.reset
|
||||||
self.setup
|
self.setup
|
||||||
end
|
end
|
||||||
|
@ -53,6 +56,7 @@ module Jekyll
|
||||||
self.static_files = []
|
self.static_files = []
|
||||||
self.categories = Hash.new { |hash, key| hash[key] = [] }
|
self.categories = Hash.new { |hash, key| hash[key] = [] }
|
||||||
self.tags = Hash.new { |hash, key| hash[key] = [] }
|
self.tags = Hash.new { |hash, key| hash[key] = [] }
|
||||||
|
self.data = {}
|
||||||
|
|
||||||
if self.limit_posts < 0
|
if self.limit_posts < 0
|
||||||
raise ArgumentError, "limit_posts must be a non-negative number"
|
raise ArgumentError, "limit_posts must be a non-negative number"
|
||||||
|
@ -63,11 +67,7 @@ module Jekyll
|
||||||
#
|
#
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
def setup
|
def setup
|
||||||
# Check that the destination dir isn't the source dir or a directory
|
ensure_not_in_dest
|
||||||
# parent to the source dir.
|
|
||||||
if self.source =~ /^#{self.dest}/
|
|
||||||
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
|
||||||
end
|
|
||||||
|
|
||||||
# If safe mode is off, load in any Ruby files under the plugins
|
# If safe mode is off, load in any Ruby files under the plugins
|
||||||
# directory.
|
# directory.
|
||||||
|
@ -83,6 +83,17 @@ module Jekyll
|
||||||
self.generators = instantiate_subclasses(Jekyll::Generator)
|
self.generators = instantiate_subclasses(Jekyll::Generator)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Check that the destination dir isn't the source dir or a directory
|
||||||
|
# parent to the source dir.
|
||||||
|
def ensure_not_in_dest
|
||||||
|
dest = Pathname.new(self.dest)
|
||||||
|
Pathname.new(self.source).ascend do |path|
|
||||||
|
if path == dest
|
||||||
|
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Internal: Setup the plugin search path
|
# Internal: Setup the plugin search path
|
||||||
#
|
#
|
||||||
# Returns an Array of plugin search paths
|
# Returns an Array of plugin search paths
|
||||||
|
@ -100,6 +111,7 @@ module Jekyll
|
||||||
def read
|
def read
|
||||||
self.read_layouts
|
self.read_layouts
|
||||||
self.read_directories
|
self.read_directories
|
||||||
|
self.read_data(config['data_source'])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Read all the files in <source>/<layouts> and create a new Layout object
|
# Read all the files in <source>/<layouts> and create a new Layout object
|
||||||
|
@ -110,7 +122,7 @@ module Jekyll
|
||||||
base = File.join(self.source, self.config['layouts'])
|
base = File.join(self.source, self.config['layouts'])
|
||||||
return unless File.exists?(base)
|
return unless File.exists?(base)
|
||||||
entries = []
|
entries = []
|
||||||
Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
|
Dir.chdir(base) { entries = filter_entries(Dir['**/*.*']) }
|
||||||
|
|
||||||
entries.each do |f|
|
entries.each do |f|
|
||||||
name = f.split(".")[0..-2].join(".")
|
name = f.split(".")[0..-2].join(".")
|
||||||
|
@ -187,6 +199,25 @@ module Jekyll
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Read and parse all yaml files under <source>/<dir>
|
||||||
|
#
|
||||||
|
# Returns nothing
|
||||||
|
def read_data(dir)
|
||||||
|
base = File.join(self.source, dir)
|
||||||
|
return unless File.directory?(base) && (!self.safe || !File.symlink?(base))
|
||||||
|
|
||||||
|
entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
|
||||||
|
entries.delete_if { |e| File.directory?(File.join(base, e)) }
|
||||||
|
|
||||||
|
entries.each do |entry|
|
||||||
|
path = File.join(self.source, dir, entry)
|
||||||
|
next if File.symlink?(path) && self.safe
|
||||||
|
|
||||||
|
key = sanitize_filename(File.basename(entry, '.*'))
|
||||||
|
self.data[key] = YAML.safe_load_file(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Run each of the Generators.
|
# Run each of the Generators.
|
||||||
#
|
#
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
|
@ -252,6 +283,14 @@ module Jekyll
|
||||||
hash
|
hash
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Prepare site data for site payload. The method maintains backward compatibility
|
||||||
|
# if the key 'data' is already used in _config.yml.
|
||||||
|
#
|
||||||
|
# Returns the Hash to be hooked to site.data.
|
||||||
|
def site_data
|
||||||
|
self.config['data'] || self.data
|
||||||
|
end
|
||||||
|
|
||||||
# The Hash payload containing site-wide data.
|
# The Hash payload containing site-wide data.
|
||||||
#
|
#
|
||||||
# Returns the Hash: { "site" => data } where data is a Hash with keys:
|
# Returns the Hash: { "site" => data } where data is a Hash with keys:
|
||||||
|
@ -273,7 +312,8 @@ module Jekyll
|
||||||
"pages" => self.pages,
|
"pages" => self.pages,
|
||||||
"html_pages" => self.pages.reject { |page| !page.html? },
|
"html_pages" => self.pages.reject { |page| !page.html? },
|
||||||
"categories" => post_attr_hash('categories'),
|
"categories" => post_attr_hash('categories'),
|
||||||
"tags" => post_attr_hash('tags')})}
|
"tags" => post_attr_hash('tags'),
|
||||||
|
"data" => site_data})}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Filter out any files/directories that are hidden or backup files (start
|
# Filter out any files/directories that are hidden or backup files (start
|
||||||
|
@ -387,5 +427,11 @@ module Jekyll
|
||||||
def site_cleaner
|
def site_cleaner
|
||||||
@site_cleaner ||= Cleaner.new(self)
|
@site_cleaner ||= Cleaner.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sanitize_filename(name)
|
||||||
|
name = name.gsub(/[^\w\s_-]+/, '')
|
||||||
|
name = name.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||||
|
name = name.gsub(/\s+/, '_')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,15 @@ module Jekyll
|
||||||
gist_id, filename = tag_contents[0], tag_contents[1]
|
gist_id, filename = tag_contents[0], tag_contents[1]
|
||||||
gist_script_tag(gist_id, filename)
|
gist_script_tag(gist_id, filename)
|
||||||
else
|
else
|
||||||
"Error parsing gist id"
|
raise ArgumentError.new <<-eos
|
||||||
|
Syntax error in tag 'gist' while parsing the following markup:
|
||||||
|
|
||||||
|
#{@markup}
|
||||||
|
|
||||||
|
Valid syntax:
|
||||||
|
for public gists: {% gist 1234567 %}
|
||||||
|
for private gists: {% gist user/1234567 %}
|
||||||
|
eos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ module Jekyll
|
||||||
def initialize(tag_name, markup, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
super
|
super
|
||||||
if markup.strip =~ SYNTAX
|
if markup.strip =~ SYNTAX
|
||||||
@lang = $1
|
@lang = $1.downcase
|
||||||
@options = {}
|
@options = {}
|
||||||
if defined?($2) && $2 != ''
|
if defined?($2) && $2 != ''
|
||||||
$2.split.each do |opt|
|
$2.split.each do |opt|
|
||||||
|
|
|
@ -1,21 +1,33 @@
|
||||||
module Jekyll
|
module Jekyll
|
||||||
module Tags
|
module Tags
|
||||||
|
class IncludeTagError < StandardError
|
||||||
|
attr_accessor :path
|
||||||
|
|
||||||
|
def initialize(msg, path)
|
||||||
|
super(msg)
|
||||||
|
@path = path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class IncludeTag < Liquid::Tag
|
class IncludeTag < Liquid::Tag
|
||||||
|
|
||||||
MATCHER = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
|
||||||
|
|
||||||
|
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
||||||
|
|
||||||
|
INCLUDES_DIR = '_includes'
|
||||||
|
|
||||||
def initialize(tag_name, markup, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
super
|
super
|
||||||
@file, @params = markup.strip.split(' ', 2);
|
@file, @params = markup.strip.split(' ', 2);
|
||||||
|
validate_params if @params
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_params(context)
|
def parse_params(context)
|
||||||
validate_syntax
|
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
markup = @params
|
markup = @params
|
||||||
|
|
||||||
while match = MATCHER.match(markup) do
|
while match = VALID_SYNTAX.match(markup) do
|
||||||
markup = markup[match.end(0)..-1]
|
markup = markup[match.end(0)..-1]
|
||||||
|
|
||||||
value = if match[2]
|
value = if match[2]
|
||||||
|
@ -31,55 +43,91 @@ module Jekyll
|
||||||
params
|
params
|
||||||
end
|
end
|
||||||
|
|
||||||
# ensure the entire markup string from start to end is valid syntax, and params are separated by spaces
|
def validate_file_name
|
||||||
def validate_syntax
|
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
||||||
full_matcher = Regexp.compile('\A\s*(?:' + MATCHER.to_s + '(?=\s|\z)\s*)*\z')
|
raise ArgumentError.new <<-eos
|
||||||
unless @params =~ full_matcher
|
Invalid syntax for include tag. File contains invalid characters or sequences:
|
||||||
raise SyntaxError.new <<-eos
|
|
||||||
|
#{@file}
|
||||||
|
|
||||||
|
Valid syntax:
|
||||||
|
|
||||||
|
#{SYNTAX_EXAMPLE}
|
||||||
|
|
||||||
|
eos
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_params
|
||||||
|
full_valid_syntax = Regexp.compile('\A\s*(?:' + VALID_SYNTAX.to_s + '(?=\s|\z)\s*)*\z')
|
||||||
|
unless @params =~ full_valid_syntax
|
||||||
|
raise ArgumentError.new <<-eos
|
||||||
Invalid syntax for include tag:
|
Invalid syntax for include tag:
|
||||||
|
|
||||||
#{@params}
|
#{@params}
|
||||||
|
|
||||||
Valid syntax:
|
Valid syntax:
|
||||||
|
|
||||||
{% include file.ext param='value' param2="value" %}
|
#{SYNTAX_EXAMPLE}
|
||||||
|
|
||||||
eos
|
eos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(context)
|
# Grab file read opts in the context
|
||||||
includes_dir = File.join(context.registers[:site].source, '_includes')
|
def file_read_opts(context)
|
||||||
|
context.registers[:site].file_read_opts
|
||||||
if error = validate_file(includes_dir)
|
|
||||||
return error
|
|
||||||
end
|
end
|
||||||
|
|
||||||
source = File.read(File.join(includes_dir, @file))
|
def retrieve_variable(context)
|
||||||
partial = Liquid::Template.parse(source)
|
if /\{\{([\w\-\.]+)\}\}/ =~ @file
|
||||||
|
raise ArgumentError.new("No variable #{$1} was found in include tag") if context[$1].nil?
|
||||||
|
@file = context[$1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(context)
|
||||||
|
dir = File.join(context.registers[:site].source, INCLUDES_DIR)
|
||||||
|
validate_dir(dir, context.registers[:site].safe)
|
||||||
|
|
||||||
|
retrieve_variable(context)
|
||||||
|
validate_file_name
|
||||||
|
|
||||||
|
file = File.join(dir, @file)
|
||||||
|
validate_file(file, context.registers[:site].safe)
|
||||||
|
|
||||||
|
partial = Liquid::Template.parse(source(file, context))
|
||||||
|
|
||||||
context.stack do
|
context.stack do
|
||||||
context['include'] = parse_params(context) if @params
|
context['include'] = parse_params(context) if @params
|
||||||
partial.render(context)
|
partial.render!(context)
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
raise IncludeTagError.new e.message, File.join(INCLUDES_DIR, @file)
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_dir(dir, safe)
|
||||||
|
if File.symlink?(dir) && safe
|
||||||
|
raise IOError.new "Includes directory '#{dir}' cannot be a symlink"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_file(includes_dir)
|
def validate_file(file, safe)
|
||||||
if File.symlink?(includes_dir)
|
|
||||||
return "Includes directory '#{includes_dir}' cannot be a symlink"
|
|
||||||
end
|
|
||||||
|
|
||||||
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
|
||||||
return "Include file '#{@file}' contains invalid characters or sequences"
|
|
||||||
end
|
|
||||||
|
|
||||||
file = File.join(includes_dir, @file)
|
|
||||||
if !File.exists?(file)
|
if !File.exists?(file)
|
||||||
return "Included file #{@file} not found in _includes directory"
|
raise IOError.new "Included file '#{@file}' not found in '#{INCLUDES_DIR}' directory"
|
||||||
elsif File.symlink?(file)
|
elsif File.symlink?(file) && safe
|
||||||
return "The included file '_includes/#{@file}' should not be a symlink"
|
raise IOError.new "The included file '#{INCLUDES_DIR}/#{@file}' should not be a symlink"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def blank?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
# This method allows to modify the file content by inheriting from the class.
|
||||||
|
def source(file, context)
|
||||||
|
File.read_with_options(file, file_read_opts(context))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,9 +50,11 @@ module Jekyll
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "ERROR: post_url: \"#{@orig_post}\" could not be found"
|
raise ArgumentError.new <<-eos
|
||||||
|
Could not find post "#{@orig_post}" in tag 'post_url'.
|
||||||
|
|
||||||
return "#"
|
Make sure the post exists and the name is correct.
|
||||||
|
eos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,16 +34,16 @@ a:visited { color: #a0a; }
|
||||||
/* Home
|
/* Home
|
||||||
/*
|
/*
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
ul.posts {
|
.posts {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.posts li {
|
.posts li {
|
||||||
line-height: 1.75em;
|
line-height: 1.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.posts span {
|
.posts span {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-family: Monaco, "Courier New", monospace;
|
font-family: Monaco, "Courier New", monospace;
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
|
@ -63,38 +63,38 @@ ul.posts span {
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .header a {
|
.header a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .header h1.title {
|
.title {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .header h1.title a {
|
.title a {
|
||||||
color: #a00;
|
color: #a00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .header h1.title a:hover {
|
.title a:hover {
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .header a.extra {
|
.header a.extra {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .header a.extra:hover {
|
.header a.extra:hover {
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .meta {
|
.meta {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .footer {
|
.footer {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
color: #666;
|
color: #666;
|
||||||
border-top: 4px solid #eee;
|
border-top: 4px solid #eee;
|
||||||
|
@ -102,22 +102,22 @@ ul.posts span {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .footer .contact {
|
.footer .contact {
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 3em;
|
margin-right: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .footer .contact a {
|
.footer .contact a {
|
||||||
color: #8085C1;
|
color: #8085C1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .footer .rss {
|
.footer .rss {
|
||||||
margin-top: 1.1em;
|
margin-top: 1.1em;
|
||||||
margin-right: -.2em;
|
margin-right: -.2em;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site .footer .rss img {
|
.footer .rss img {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<h4>Getting Started</h4>
|
<h4>Getting Started</h4>
|
||||||
{% include docs_ul.html items='home quickstart installation usage structure configuration' %}
|
{% include docs_ul.html items='home quickstart installation usage structure configuration' %}
|
||||||
<h4>Your Content</h4>
|
<h4>Your Content</h4>
|
||||||
{% include docs_ul.html items='frontmatter posts drafts pages variables migrations' %}
|
{% include docs_ul.html items='frontmatter posts drafts pages variables datafiles migrations' %}
|
||||||
<h4>Customization</h4>
|
<h4>Customization</h4>
|
||||||
{% include docs_ul.html items='templates permalinks pagination plugins extras' %}
|
{% include docs_ul.html items='templates permalinks pagination plugins extras' %}
|
||||||
<h4>Deployment</h4>
|
<h4>Deployment</h4>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{% include docs_option.html items='home quickstart installation usage structure configuration' %}
|
{% include docs_option.html items='home quickstart installation usage structure configuration' %}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Your Content">
|
<optgroup label="Your Content">
|
||||||
{% include docs_option.html items='frontmatter posts drafts pages variables migrations' %}
|
{% include docs_option.html items='frontmatter posts drafts pages variables datafiles migrations' %}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Customization">
|
<optgroup label="Customization">
|
||||||
{% include docs_option.html items='templates permalinks pagination plugins extras' %}
|
{% include docs_option.html items='templates permalinks pagination plugins extras' %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
layout: news_item
|
layout: news_item
|
||||||
title: "Jekyll 1.2 Released"
|
title: "Jekyll 1.2.0 Released"
|
||||||
date: "2013-09-06 22:02:41 -0400"
|
date: "2013-09-06 22:02:41 -0400"
|
||||||
author: parkr
|
author: parkr
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
layout: news_item
|
||||||
|
title: 'Jekyll 1.2.1 Released'
|
||||||
|
date: 2013-09-14 20:46:50 -0400
|
||||||
|
author: parkr
|
||||||
|
version: 1.2.1
|
||||||
|
categories: [release]
|
||||||
|
---
|
||||||
|
|
||||||
|
Quick turnover, anyone? A [recent incompatibility with Liquid
|
||||||
|
v2.5.2](https://github.com/mojombo/jekyll/pull/1525) produced a nasty bug in
|
||||||
|
which `include` tags were not rendered properly within `if` blocks.
|
||||||
|
|
||||||
|
This release also includes a better handling of detached servers (prints pid and
|
||||||
|
the command for killing the process). **Note**: the `--detach` flag and
|
||||||
|
`--watch` flags are presently incompatible in 1.2.x. Fix for that coming soon!
|
||||||
|
|
||||||
|
For a full list of the fixes in this release, check out [the change
|
||||||
|
log](/docs/history/)!
|
|
@ -99,6 +99,22 @@ class="flag">flags</code> (specified on the command-line) that control them.
|
||||||
<p><code class="option">timezone: TIMEZONE</code></p>
|
<p><code class="option">timezone: TIMEZONE</code></p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class='setting'>
|
||||||
|
<td>
|
||||||
|
<p class='name'><strong>Encoding</strong></p>
|
||||||
|
<p class="description">
|
||||||
|
Set the encoding of files by name. Only available for Ruby
|
||||||
|
1.9 or later).
|
||||||
|
The default value is nil, which use Ruby default,
|
||||||
|
<code>ASCII-8BIT</code>.
|
||||||
|
Available encoding for the ruby in use, can be shown by
|
||||||
|
command <code>ruby -e 'puts Encoding::list.join("\n")'</code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td class='align-center'>
|
||||||
|
<p><code class="option">encoding: ENCODING</code></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p class='name'><strong>Defaults</strong></p>
|
<p class='name'><strong>Defaults</strong></p>
|
||||||
|
@ -309,6 +325,7 @@ include: ['.htaccess']
|
||||||
exclude: []
|
exclude: []
|
||||||
keep_files: ['.git','.svn']
|
keep_files: ['.git','.svn']
|
||||||
timezone: nil
|
timezone: nil
|
||||||
|
encoding: nil
|
||||||
|
|
||||||
future: true
|
future: true
|
||||||
show_drafts: nil
|
show_drafts: nil
|
||||||
|
|
|
@ -16,13 +16,19 @@ following in mind:
|
||||||
* If it's a brand new feature, make sure to create a new
|
* If it's a brand new feature, make sure to create a new
|
||||||
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
||||||
where appropriate. Also, whipping up some documentation in your fork's `site`
|
where appropriate. Also, whipping up some documentation in your fork's `site`
|
||||||
directory would be appreciated, and once merged it will also appear in
|
would be appreciated, and once merged it will be transferred over to the main
|
||||||
the next update of the main site.
|
`site`, jekyllrb.com.
|
||||||
* If your contribution adds or changes any Jekyll behavior, make sure to update
|
* If your contribution changes any Jekyll behavior, make sure to update the
|
||||||
the documentation. It lives in `site/docs`. If the docs are missing
|
documentation. It lives in `site/docs`. If the docs are missing information,
|
||||||
information, please feel free to add it in. Great docs make a great project!
|
please feel free to add it in. Great docs make a great project!
|
||||||
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||||
when modifying Ruby code.
|
when modifying Ruby code.
|
||||||
|
* Please do your best to submit **small pull requests**. The easier the proposed
|
||||||
|
change is to review, the more likely it will be merged.
|
||||||
|
* When submitting a pull request, please make judicious use of the pull request
|
||||||
|
body. A description of what changes were made, the motivations behind the
|
||||||
|
changes and [any tasks completed or left to complete](http://git.io/gfm-tasks)
|
||||||
|
will also speed up review time.
|
||||||
|
|
||||||
<div class="note warning">
|
<div class="note warning">
|
||||||
<h5>Contributions will not be accepted without tests</h5>
|
<h5>Contributions will not be accepted without tests</h5>
|
||||||
|
@ -47,8 +53,8 @@ Before you start, run the tests and make sure that they pass (to confirm your
|
||||||
environment is configured properly):
|
environment is configured properly):
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ rake test
|
$ bundle exec rake test
|
||||||
$ rake features
|
$ bundle exec rake features
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
Workflow
|
Workflow
|
||||||
|
@ -79,8 +85,8 @@ git checkout -b my_awesome_feature
|
||||||
git push origin my_awesome_feature
|
git push origin my_awesome_feature
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
* Create a pull request against mojombo/jekyll and describe what your change
|
* Create a pull request against mojombo/jekyll:master and describe what your
|
||||||
does and the why you think it should be merged.
|
change does and the why you think it should be merged.
|
||||||
|
|
||||||
Updating Documentation
|
Updating Documentation
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
layout: docs
|
||||||
|
title: Data Files
|
||||||
|
prev_section: variables
|
||||||
|
next_section: migrations
|
||||||
|
permalink: /docs/datafiles/
|
||||||
|
---
|
||||||
|
|
||||||
|
In addition to the [built-in variables](../variables/) available from Jekyll,
|
||||||
|
you can specify your own custom data that can be accessed via the [Liquid
|
||||||
|
templating system](http://wiki.github.com/shopify/liquid/liquid-for-designers).
|
||||||
|
|
||||||
|
Jekyll supports loading data from [YAML](http://yaml.org/) files located in the
|
||||||
|
`_data` directory.
|
||||||
|
|
||||||
|
This powerful features allows you to avoid repetition in your templates and to
|
||||||
|
set site specific options without changing `_config.yml`.
|
||||||
|
|
||||||
|
Plugins/themes can also leverage Data Files to set configuration variables.
|
||||||
|
|
||||||
|
## The Data Folder
|
||||||
|
|
||||||
|
As explained on the [directory structure](../structure/) page, the `_data`
|
||||||
|
folder is where you can store additional data for Jekyll to use when generating
|
||||||
|
your site. These files must be YAML files (using either the `.yml` or `.yaml`
|
||||||
|
extension) and they will be accessible via `site.data`.
|
||||||
|
|
||||||
|
## Example: List of members
|
||||||
|
|
||||||
|
Here is a basic example of using Data Files to avoid copy-pasting large chunks of
|
||||||
|
code in your Jekyll templates:
|
||||||
|
|
||||||
|
In `_data/members.yml`:
|
||||||
|
|
||||||
|
{% highlight yaml %}
|
||||||
|
- name: Tom Preston-Werner
|
||||||
|
github: mojombo
|
||||||
|
|
||||||
|
- name: Parker Moore
|
||||||
|
github: parkr
|
||||||
|
|
||||||
|
- name: Liu Fengyun
|
||||||
|
github: liufengyun
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
This data can be accessed via `site.data.members` (notice that the filename
|
||||||
|
determines the variable name).
|
||||||
|
|
||||||
|
You can now render the list of members in a template:
|
||||||
|
|
||||||
|
{% highlight html %}
|
||||||
|
{% raw %}
|
||||||
|
<ul>
|
||||||
|
{% for member in site.data.members %}
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/{{ member.github }}">
|
||||||
|
{{ member.name }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% end %}
|
||||||
|
</ul>
|
||||||
|
{% endraw %}
|
||||||
|
{% endhighlight %}
|
|
@ -5,6 +5,30 @@ permalink: /docs/history/
|
||||||
prev_section: contributing
|
prev_section: contributing
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 1.2.1 / 2013-09-14
|
||||||
|
|
||||||
|
### Minor Enhancements
|
||||||
|
- Print better messages for detached server. Mute output on detach. ([#1518]({{ site.repository }}/issues/1518))
|
||||||
|
- Disable reverse lookup when running `jekyll serve` ([#1363]({{ site.repository }}/issues/1363))
|
||||||
|
- Upgrade RedCarpet dependency to `~> 2.3.0` ([#1515]({{ site.repository }}/issues/1515))
|
||||||
|
- Upgrade to Liquid `>= 2.5.2, < 2.6` ([#1536]({{ site.repository }}/issues/1536))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- Fix file discrepancy in gemspec ([#1522]({{ site.repository }}/issues/1522))
|
||||||
|
- Force rendering of Include tag ([#1525]({{ site.repository }}/issues/1525))
|
||||||
|
|
||||||
|
### Development Fixes
|
||||||
|
- Add a rake task to generate a new release post ([#1404]({{ site.repository }}/issues/1404))
|
||||||
|
- Mute LSI output in tests ([#1531]({{ site.repository }}/issues/1531))
|
||||||
|
- Update contributor documentation ([#1537]({{ site.repository }}/issues/1537))
|
||||||
|
|
||||||
|
### Site Enhancements
|
||||||
|
- Fix a couple of validation errors on the site ([#1511]({{ site.repository }}/issues/1511))
|
||||||
|
- Make navigation menus reusable ([#1507]({{ site.repository }}/issues/1507))
|
||||||
|
- Fix link to History page from Release v1.2.0 notes post.
|
||||||
|
- Fix markup in History file for command line options ([#1512]({{ site.repository }}/issues/1512))
|
||||||
|
- Expand 1.2 release post title to 1.2.0 ([#1516]({{ site.repository }}/issues/1516))
|
||||||
|
|
||||||
## 1.2.0 / 2013-09-06
|
## 1.2.0 / 2013-09-06
|
||||||
|
|
||||||
### Major Enhancements
|
### Major Enhancements
|
||||||
|
@ -15,7 +39,7 @@ prev_section: contributing
|
||||||
- Catch and fix invalid `paginate` values ([#1390]({{ site.repository }}/issues/1390))
|
- Catch and fix invalid `paginate` values ([#1390]({{ site.repository }}/issues/1390))
|
||||||
- Remove superfluous `div.container` from the default html template for
|
- Remove superfluous `div.container` from the default html template for
|
||||||
`jekyll new` ([#1315]({{ site.repository }}/issues/1315))
|
`jekyll new` ([#1315]({{ site.repository }}/issues/1315))
|
||||||
- Add -D short-form switch for the drafts option ([#1394]({{ site.repository }}/issues/1394))
|
- Add `-D` short-form switch for the drafts option ([#1394]({{ site.repository }}/issues/1394))
|
||||||
- Update the links in the site template for Twitter and GitHub ([#1400]({{ site.repository }}/issues/1400))
|
- Update the links in the site template for Twitter and GitHub ([#1400]({{ site.repository }}/issues/1400))
|
||||||
- Update dummy email address to example.com domain ([#1408]({{ site.repository }}/issues/1408))
|
- Update dummy email address to example.com domain ([#1408]({{ site.repository }}/issues/1408))
|
||||||
- Update normalize.css to v2.1.2 and minify; add rake task to update
|
- Update normalize.css to v2.1.2 and minify; add rake task to update
|
||||||
|
@ -65,7 +89,7 @@ prev_section: contributing
|
||||||
- Fix markup for the Kramdown options ([#1445]({{ site.repository }}/issues/1445))
|
- Fix markup for the Kramdown options ([#1445]({{ site.repository }}/issues/1445))
|
||||||
- Fix typos in the History file ([#1454]({{ site.repository }}/issues/1454))
|
- Fix typos in the History file ([#1454]({{ site.repository }}/issues/1454))
|
||||||
- Add trailing slash to site's post URL ([#1462]({{ site.repository }}/issues/1462))
|
- Add trailing slash to site's post URL ([#1462]({{ site.repository }}/issues/1462))
|
||||||
- Clarify that --config will take multiple files ([#1474]({{ site.repository }}/issues/1474))
|
- Clarify that `--config` will take multiple files ([#1474]({{ site.repository }}/issues/1474))
|
||||||
- Fix docs/templates.md private gist example ([#1477]({{ site.repository }}/issues/1477))
|
- Fix docs/templates.md private gist example ([#1477]({{ site.repository }}/issues/1477))
|
||||||
- Use `site.repository` for Jekyll's GitHub URL ([#1463]({{ site.repository }}/issues/1463))
|
- Use `site.repository` for Jekyll's GitHub URL ([#1463]({{ site.repository }}/issues/1463))
|
||||||
- Add `jekyll-pageless-redirects` to list of third-party plugins ([#1486]({{ site.repository }}/issues/1486))
|
- Add `jekyll-pageless-redirects` to list of third-party plugins ([#1486]({{ site.repository }}/issues/1486))
|
||||||
|
@ -302,7 +326,7 @@ prev_section: contributing
|
||||||
- Allow symlinked files in unsafe mode ([#824]({{ site.repository }}/issues/824))
|
- Allow symlinked files in unsafe mode ([#824]({{ site.repository }}/issues/824))
|
||||||
- Add 'gist' Liquid tag to core ([#822]({{ site.repository }}/issues/822), [#861]({{ site.repository }}/issues/861))
|
- Add 'gist' Liquid tag to core ([#822]({{ site.repository }}/issues/822), [#861]({{ site.repository }}/issues/861))
|
||||||
- New format of Jekyll output ([#795]({{ site.repository }}/issues/795))
|
- New format of Jekyll output ([#795]({{ site.repository }}/issues/795))
|
||||||
- Reinstate --limit_posts and --future switches ([#788]({{ site.repository }}/issues/788))
|
- Reinstate `--limit_posts` and `--future` switches ([#788]({{ site.repository }}/issues/788))
|
||||||
- Remove ambiguity from command descriptions ([#815]({{ site.repository }}/issues/815))
|
- Remove ambiguity from command descriptions ([#815]({{ site.repository }}/issues/815))
|
||||||
- Fix SafeYAML Warnings ([#807]({{ site.repository }}/issues/807))
|
- Fix SafeYAML Warnings ([#807]({{ site.repository }}/issues/807))
|
||||||
- Relaxed Kramdown version to 0.14 ([#808]({{ site.repository }}/issues/808))
|
- Relaxed Kramdown version to 0.14 ([#808]({{ site.repository }}/issues/808))
|
||||||
|
@ -325,7 +349,7 @@ prev_section: contributing
|
||||||
- Catch all exceptions, not just StandardError descendents ([#1007]({{ site.repository }}/issues/1007))
|
- Catch all exceptions, not just StandardError descendents ([#1007]({{ site.repository }}/issues/1007))
|
||||||
- Bullet-proof limit_posts option ([#1004]({{ site.repository }}/issues/1004))
|
- Bullet-proof limit_posts option ([#1004]({{ site.repository }}/issues/1004))
|
||||||
- Read in YAML as UTF-8 to accept non-ASCII chars ([#836]({{ site.repository }}/issues/836))
|
- Read in YAML as UTF-8 to accept non-ASCII chars ([#836]({{ site.repository }}/issues/836))
|
||||||
- Fix the CLI option --plugins to actually accept dirs and files ([#993]({{ site.repository }}/issues/993))
|
- Fix the CLI option `--plugins` to actually accept dirs and files ([#993]({{ site.repository }}/issues/993))
|
||||||
- Allow 'excerpt' in YAML Front-Matter to override the extracted excerpt ([#946]({{ site.repository }}/issues/946))
|
- Allow 'excerpt' in YAML Front-Matter to override the extracted excerpt ([#946]({{ site.repository }}/issues/946))
|
||||||
- Fix cascade problem with site.baseurl, site.port and site.host. ([#935]({{ site.repository }}/issues/935))
|
- Fix cascade problem with site.baseurl, site.port and site.host. ([#935]({{ site.repository }}/issues/935))
|
||||||
- Filter out directories with valid post names ([#875]({{ site.repository }}/issues/875))
|
- Filter out directories with valid post names ([#875]({{ site.repository }}/issues/875))
|
||||||
|
|
|
@ -46,6 +46,16 @@ installing Jekyll, check out the [troubleshooting](../troubleshooting/) page or
|
||||||
[report an issue]({{ site.repository }}/issues/new) so the Jekyll
|
[report an issue]({{ site.repository }}/issues/new) so the Jekyll
|
||||||
community can improve the experience for everyone.
|
community can improve the experience for everyone.
|
||||||
|
|
||||||
|
<div class="note info">
|
||||||
|
<h5>Installing Xcode Command-Line Tools</h5>
|
||||||
|
<p>
|
||||||
|
If you run into issues installing Jekyll's dependencies which make use of
|
||||||
|
native extensions and are using Mac OS X, you will need to install Xcode
|
||||||
|
and the Command-Line Tools it ships with. Download in
|
||||||
|
<code>Preferences → Downloads → Components</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
## Optional Extras
|
## Optional Extras
|
||||||
|
|
||||||
There are a number of (optional) extra features that Jekyll supports that you
|
There are a number of (optional) extra features that Jekyll supports that you
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
layout: docs
|
layout: docs
|
||||||
title: Blog migrations
|
title: Blog migrations
|
||||||
prev_section: variables
|
prev_section: datafiles
|
||||||
next_section: templates
|
next_section: templates
|
||||||
permalink: /docs/migrations/
|
permalink: /docs/migrations/
|
||||||
---
|
---
|
||||||
|
@ -24,6 +24,15 @@ Jekyll's standard command line interface.
|
||||||
$ gem install jekyll-import --pre
|
$ gem install jekyll-import --pre
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
|
<div class="note warning">
|
||||||
|
<h5>Jekyll-import requires you to manually install some dependencies.</h5>
|
||||||
|
<p markdown="1">If you are importing your blog from Drupal 6,7, Joomla,
|
||||||
|
Mephisto, Movable Type, Textpattern, or Typo (with mysql db), you need to install
|
||||||
|
`mysql` and `sequel` gems. If you are importing from a WordPress database, you
|
||||||
|
need to install `mysql2` and `sequel` gems, and if you are importing from Enki
|
||||||
|
or Typo (with postgresql db) you need to install `pg` and `sequel` gems.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
You should now be all set to run the importers below. If you ever get stuck, you
|
You should now be all set to run the importers below. If you ever get stuck, you
|
||||||
can see help for each importer:
|
can see help for each importer:
|
||||||
|
|
||||||
|
@ -74,7 +83,7 @@ here's how:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ ruby -rubygems -e 'require "jekyll/jekyll-import/wordpress";
|
$ ruby -rubygems -e 'require "jekyll/jekyll-import/wordpress";
|
||||||
JekyllImport::WordPress.process("database", "user", "pass")'
|
JekyllImport::WordPress.process({:dbname => "database", :user => "user", :pass => "pass"})'
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
If you are using Webfaction and have to set up an [SSH
|
If you are using Webfaction and have to set up an [SSH
|
||||||
|
@ -85,7 +94,7 @@ authentication system:
|
||||||
|
|
||||||
{% highlight bash %}
|
{% highlight bash %}
|
||||||
$ ruby -rubygems -e 'require "jekyll/jekyll-import/wordpress";
|
$ ruby -rubygems -e 'require "jekyll/jekyll-import/wordpress";
|
||||||
JekyllImport::WordPress.process("database", "user", "pass", "127.0.0.1")'
|
JekyllImport::WordPress.process({:host => "127.0.0.1", :dbname => "database", :user => "user", :pass => "pass"})'
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
### Further WordPress migration alternatives
|
### Further WordPress migration alternatives
|
||||||
|
|
|
@ -182,51 +182,30 @@ page with links to all but the current page.
|
||||||
|
|
||||||
{% highlight html %}
|
{% highlight html %}
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<div id="post-pagination" class="pagination">
|
{% if paginator.total_pages > 1 %}
|
||||||
|
<div class="pagination">
|
||||||
{% if paginator.previous_page %}
|
{% if paginator.previous_page %}
|
||||||
<p class="previous">
|
<a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">« Prev</a>
|
||||||
{% if paginator.previous_page == 1 %}
|
|
||||||
<a href="/">Previous</a>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ paginator.previous_page_path }}">Previous</a>
|
<span>« Prev</span>
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
{% else %}
|
|
||||||
<p class="previous disabled">
|
|
||||||
<span>Previous</span>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<ul class="pages">
|
{% for page in (1..paginator.total_pages) %}
|
||||||
<li class="page">
|
{% if page == paginator.page %}
|
||||||
{% if paginator.page == 1 %}
|
<em>{{ page }}</em>
|
||||||
<span class="current-page">1</span>
|
{% elsif page == 1 %}
|
||||||
|
<a href="{{ '/index.html' | prepend: site.baseurl | replace: '//', '/' }}">{{ page }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/">1</a>
|
<a href="{{ site.paginate_path | prepend: site.baseurl | replace: '//', '/' | replace: ':num', page }}">{{ page }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
|
||||||
|
|
||||||
{% for count in (2..paginator.total_pages) %}
|
|
||||||
<li class="page">
|
|
||||||
{% if count == paginator.page %}
|
|
||||||
<span class="current-page">{{ count }}</span>
|
|
||||||
{% else %}
|
|
||||||
<a href="/page{{ count }}">{{ count }}</a>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% if paginator.next_page %}
|
{% if paginator.next_page %}
|
||||||
<p class="next">
|
<a href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}">Next »</a>
|
||||||
<a href="{{ paginator.next_page_path }}">Next</a>
|
|
||||||
</p>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="next disabled">
|
<span>Next »</span>
|
||||||
<span>Next</span>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endraw %}
|
{% endraw %}
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
|
@ -38,7 +38,45 @@ In general, plugins you make will fall into one of three categories:
|
||||||
## Generators
|
## Generators
|
||||||
|
|
||||||
You can create a generator when you need Jekyll to create additional content
|
You can create a generator when you need Jekyll to create additional content
|
||||||
based on your own rules. For example, a generator might look like this:
|
based on your own rules.
|
||||||
|
|
||||||
|
A generator is a subclass of `Jekyll::Generator` that defines a `generate`
|
||||||
|
method, which receives an instance of
|
||||||
|
[`Jekyll::Site`]({{ site.repository }}/blob/master/lib/jekyll/site.rb).
|
||||||
|
|
||||||
|
Generation is triggered for its side-effects, the return value of `generate` is
|
||||||
|
ignored. Jekyll does not assume any particular side-effect to happen, it just
|
||||||
|
runs the method.
|
||||||
|
|
||||||
|
Generators run after Jekyll has made an inventory of the existing content, and
|
||||||
|
before the site is generated. Pages with YAML front-matters are stored as
|
||||||
|
instances of
|
||||||
|
[`Jekyll::Page`]({{ site.repository }}/blob/master/lib/jekyll/page.rb)
|
||||||
|
and are available via `site.pages`. Static files become instances of
|
||||||
|
[`Jekyll::StaticFile`]({{ site.repository }}/blob/master/lib/jekyll/static_file.rb)
|
||||||
|
and are available via `site.static_files`. See
|
||||||
|
[`Jekyll::Site`]({{ site.repository }}/blob/master/lib/jekyll/site.rb)
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
For instance, a generator can inject values computed at build time for template
|
||||||
|
variables. In the following example the template `reading.html` has two
|
||||||
|
variables `ongoing` and `done` that we fill in the generator:
|
||||||
|
|
||||||
|
{% highlight ruby %}
|
||||||
|
module Reading
|
||||||
|
class Generator < Jekyll::Generator
|
||||||
|
def generate(site)
|
||||||
|
ongoing, done = Book.all.partition(&:ongoing?)
|
||||||
|
|
||||||
|
reading = site.pages.detect {|page| page.name == 'reading.html'}
|
||||||
|
reading.data['ongoing'] = ongoing
|
||||||
|
reading.data['done'] = done
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
This is a more complex generator that generates new pages:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
module Jekyll
|
module Jekyll
|
||||||
|
@ -95,7 +133,7 @@ Generators are only required to implement one method:
|
||||||
<p><code>generate</code></p>
|
<p><code>generate</code></p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>String output of the content being generated.</p>
|
<p>Generates content as a side-effect.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -430,6 +468,7 @@ You can find a few useful plugins at the following locations:
|
||||||
- [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.
|
- [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.
|
||||||
- [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.
|
- [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.
|
||||||
- [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.
|
- [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.
|
||||||
|
- [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.
|
||||||
|
|
||||||
#### Collections
|
#### Collections
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ A basic Jekyll site usually looks something like this:
|
||||||
├── _posts
|
├── _posts
|
||||||
| ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
|
| ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
|
||||||
| └── 2009-04-26-barcamp-boston-4-roundup.textile
|
| └── 2009-04-26-barcamp-boston-4-roundup.textile
|
||||||
|
├── _data
|
||||||
|
| └── members.yml
|
||||||
├── _site
|
├── _site
|
||||||
└── index.html
|
└── index.html
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
@ -121,6 +123,21 @@ An overview of what each of these does:
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p><code>_data</code></p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
Well-formatted site data should be placed here. The jekyll engine will
|
||||||
|
autoload all yaml files (ends with <code>.yml</code> or <code>.yaml</code>)
|
||||||
|
in this directory. If there's a file <code>members.yml</code> under the directory,
|
||||||
|
then you can access contents of the file through <code>site.data.members</code>.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<p><code>_site</code></p>
|
<p><code>_site</code></p>
|
||||||
|
|
|
@ -7,9 +7,9 @@ permalink: /docs/templates/
|
||||||
---
|
---
|
||||||
|
|
||||||
Jekyll uses the [Liquid](http://wiki.shopify.com/Liquid) templating language to
|
Jekyll uses the [Liquid](http://wiki.shopify.com/Liquid) templating language to
|
||||||
process templates. All of the [standard Liquid tags and
|
process templates. All of the standard Liquid [tags](http://wiki.shopify.com/Logic) and
|
||||||
filters](http://wiki.github.com/shopify/liquid/liquid-for-designers) are
|
[filters](http://wiki.shopify.com/Filters) are
|
||||||
supported, Jekyll even adds a few handy filters and tags of its own to make
|
supported. Jekyll even adds a few handy filters and tags of its own to make
|
||||||
common tasks easier.
|
common tasks easier.
|
||||||
|
|
||||||
## Filters
|
## Filters
|
||||||
|
@ -192,6 +192,19 @@ Jekyll expects all include files to be placed in an `_includes` directory at the
|
||||||
root of your source directory. This will embed the contents of
|
root of your source directory. This will embed the contents of
|
||||||
`<source>/_includes/footer.html` into the calling file.
|
`<source>/_includes/footer.html` into the calling file.
|
||||||
|
|
||||||
|
<div class="note">
|
||||||
|
<h5>ProTip™: Use variables as file name</h5>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
The name of the file you wish to embed can be literal (as in the example above),
|
||||||
|
or you can use a variable, using liquid-like variable syntax as in
|
||||||
|
<code>{% raw %}{% include {{my_variable}} %}{% endraw %}</code>.
|
||||||
|
|
||||||
|
Note that unlike usual liquid variable syntax, you cannot have spaces inside the curly braces.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
You can also pass parameters to an include:
|
You can also pass parameters to an include:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
layout: docs
|
layout: docs
|
||||||
title: Variables
|
title: Variables
|
||||||
prev_section: pages
|
prev_section: pages
|
||||||
next_section: migrations
|
next_section: datafiles
|
||||||
permalink: /docs/variables/
|
permalink: /docs/variables/
|
||||||
---
|
---
|
||||||
|
|
||||||
Jekyll traverses your site looking for files to process. Any files with [YAML
|
Jekyll traverses your site looking for files to process. Any files with [YAML
|
||||||
Front Matter](../frontmatter/) are subject to processing. For each of these
|
Front Matter](../frontmatter/) are subject to processing. For each of these
|
||||||
files, Jekyll makes a variety of data available via the [Liquid templating
|
files, Jekyll makes a variety of data available via the [Liquid templating
|
||||||
system](http://wiki.github.com/shopify/liquid/liquid-for-designers). The
|
system](http://wiki.shopify.com/Liquid). The
|
||||||
following is a reference of the available data.
|
following is a reference of the available data.
|
||||||
|
|
||||||
## Global Variables
|
## Global Variables
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
if RUBY_VERSION > '1.9' && ENV["COVERAGE"] == "true"
|
if RUBY_VERSION > '1.9'
|
||||||
require 'simplecov'
|
require 'simplecov'
|
||||||
require 'simplecov-gem-adapter'
|
require 'simplecov-gem-adapter'
|
||||||
SimpleCov.start('gem')
|
SimpleCov.start('gem')
|
||||||
|
|
||||||
|
require 'coveralls'
|
||||||
|
Coveralls.wear_merged!
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
- java
|
||||||
|
- ruby
|
|
@ -0,0 +1,7 @@
|
||||||
|
- name: Jack
|
||||||
|
age: 27
|
||||||
|
blog: http://example.com/jack
|
||||||
|
|
||||||
|
- name: John
|
||||||
|
age: 32
|
||||||
|
blog: http://example.com/john
|
|
@ -0,0 +1 @@
|
||||||
|
../products.yml
|
|
@ -0,0 +1 @@
|
||||||
|
<<< {{ content }} >>>
|
|
@ -0,0 +1,4 @@
|
||||||
|
- name: sugar
|
||||||
|
price: 5.3
|
||||||
|
- name: salt
|
||||||
|
price: 2.5
|
|
@ -0,0 +1 @@
|
||||||
|
../_data
|
|
@ -40,7 +40,7 @@ class TestConvertible < Test::Unit::TestCase
|
||||||
should "not parse if there is encoding error in file" do
|
should "not parse if there is encoding error in file" do
|
||||||
name = 'broken_front_matter3.erb'
|
name = 'broken_front_matter3.erb'
|
||||||
out = capture_stdout do
|
out = capture_stdout do
|
||||||
ret = @convertible.read_yaml(@base, name)
|
ret = @convertible.read_yaml(@base, name, :encoding => 'utf-8')
|
||||||
assert_equal({}, ret)
|
assert_equal({}, ret)
|
||||||
end
|
end
|
||||||
assert_match(/invalid byte sequence in UTF-8/, out)
|
assert_match(/invalid byte sequence in UTF-8/, out)
|
||||||
|
|
|
@ -29,6 +29,7 @@ class TestRelatedPosts < Test::Unit::TestCase
|
||||||
'destination' => dest_dir,
|
'destination' => dest_dir,
|
||||||
'lsi' => true})
|
'lsi' => true})
|
||||||
end
|
end
|
||||||
|
any_instance_of(Jekyll::RelatedPosts) { |i| stub(i).display }
|
||||||
@site = Site.new(Jekyll.configuration)
|
@site = Site.new(Jekyll.configuration)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ class TestSite < Test::Unit::TestCase
|
||||||
|
|
||||||
should "read layouts" do
|
should "read layouts" do
|
||||||
@site.read_layouts
|
@site.read_layouts
|
||||||
assert_equal ["default", "simple"].sort, @site.layouts.keys.sort
|
assert_equal ["default", "simple", "post/simple"].sort, @site.layouts.keys.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
should "read posts" do
|
should "read posts" do
|
||||||
|
@ -335,5 +335,62 @@ class TestSite < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'data directory' do
|
||||||
|
should 'auto load yaml files' do
|
||||||
|
site = Site.new(Jekyll.configuration)
|
||||||
|
site.process
|
||||||
|
|
||||||
|
file_content = YAML.safe_load_file(File.join(source_dir, '_data', 'members.yaml'))
|
||||||
|
|
||||||
|
assert_equal site.data['members'], file_content
|
||||||
|
assert_equal site.site_payload['site']['data']['members'], file_content
|
||||||
|
end
|
||||||
|
|
||||||
|
should 'auto load yml files' do
|
||||||
|
site = Site.new(Jekyll.configuration)
|
||||||
|
site.process
|
||||||
|
|
||||||
|
file_content = YAML.safe_load_file(File.join(source_dir, '_data', 'languages.yml'))
|
||||||
|
|
||||||
|
assert_equal site.data['languages'], file_content
|
||||||
|
assert_equal site.site_payload['site']['data']['languages'], file_content
|
||||||
|
end
|
||||||
|
|
||||||
|
should "load symlink files in unsafe mode" do
|
||||||
|
site = Site.new(Jekyll.configuration.merge({'safe' => false}))
|
||||||
|
site.process
|
||||||
|
|
||||||
|
file_content = YAML.safe_load_file(File.join(source_dir, '_data', 'products.yml'))
|
||||||
|
|
||||||
|
assert_equal site.data['products'], file_content
|
||||||
|
assert_equal site.site_payload['site']['data']['products'], file_content
|
||||||
|
end
|
||||||
|
|
||||||
|
should "not load symlink files in safe mode" do
|
||||||
|
site = Site.new(Jekyll.configuration.merge({'safe' => true}))
|
||||||
|
site.process
|
||||||
|
|
||||||
|
assert_nil site.data['products']
|
||||||
|
assert_nil site.site_payload['site']['data']['products']
|
||||||
|
end
|
||||||
|
|
||||||
|
should "load symlink directory in unsafe mode" do
|
||||||
|
site = Site.new(Jekyll.configuration.merge({'safe' => false, 'data_source' => File.join('symlink-test', '_data')}))
|
||||||
|
site.process
|
||||||
|
|
||||||
|
assert_not_nil site.data['products']
|
||||||
|
assert_not_nil site.data['languages']
|
||||||
|
assert_not_nil site.data['members']
|
||||||
|
end
|
||||||
|
|
||||||
|
should "not load symlink directory in safe mode" do
|
||||||
|
site = Site.new(Jekyll.configuration.merge({'safe' => true, 'data_source' => File.join('symlink-test', '_data')}))
|
||||||
|
site.process
|
||||||
|
|
||||||
|
assert_nil site.data['products']
|
||||||
|
assert_nil site.data['languages']
|
||||||
|
assert_nil site.data['members']
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,7 @@ class TestTags < Test::Unit::TestCase
|
||||||
payload = { "pygments_prefix" => @converter.pygments_prefix,
|
payload = { "pygments_prefix" => @converter.pygments_prefix,
|
||||||
"pygments_suffix" => @converter.pygments_suffix }
|
"pygments_suffix" => @converter.pygments_suffix }
|
||||||
|
|
||||||
@result = Liquid::Template.parse(content).render(payload, info)
|
@result = Liquid::Template.parse(content).render!(payload, info)
|
||||||
@result = @converter.convert(@result)
|
@result = @converter.convert(@result)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ CONTENT
|
||||||
|
|
||||||
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
|
||||||
assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options))
|
assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options))
|
||||||
|
|
||||||
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'Ruby ', ["test", "{% endhighlight %}", "\n"])
|
||||||
|
assert_equal "ruby", tag.instance_variable_get(:@lang), "lexers should be case insensitive"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -273,8 +276,7 @@ CONTENT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when invalid" do
|
should "raise ArgumentError when invalid" do
|
||||||
setup do
|
|
||||||
@gist = "mattr-24081a1d93d2898ecf0f"
|
@gist = "mattr-24081a1d93d2898ecf0f"
|
||||||
@filename = "myfile.ext"
|
@filename = "myfile.ext"
|
||||||
content = <<CONTENT
|
content = <<CONTENT
|
||||||
|
@ -284,11 +286,9 @@ CONTENT
|
||||||
|
|
||||||
{% gist #{@gist} #{@filename} %}
|
{% gist #{@gist} #{@filename} %}
|
||||||
CONTENT
|
CONTENT
|
||||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
|
||||||
end
|
|
||||||
|
|
||||||
should "write script tag with specific file in gist" do
|
assert_raise ArgumentError do
|
||||||
assert_match "Error parsing gist id", @result
|
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -313,7 +313,7 @@ CONTENT
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with blank gist id" do
|
context "with blank gist id" do
|
||||||
setup do
|
should "raise ArgumentError" do
|
||||||
content = <<CONTENT
|
content = <<CONTENT
|
||||||
---
|
---
|
||||||
title: My Cool Gist
|
title: My Cool Gist
|
||||||
|
@ -321,16 +321,15 @@ title: My Cool Gist
|
||||||
|
|
||||||
{% gist %}
|
{% gist %}
|
||||||
CONTENT
|
CONTENT
|
||||||
|
|
||||||
|
assert_raise ArgumentError do
|
||||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||||
end
|
end
|
||||||
|
|
||||||
should "output error message" do
|
|
||||||
assert_match "Error parsing gist id", @result
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with invalid gist id" do
|
context "with invalid gist id" do
|
||||||
setup do
|
should "raise ArgumentError" do
|
||||||
invalid_gist = 'invalid'
|
invalid_gist = 'invalid'
|
||||||
content = <<CONTENT
|
content = <<CONTENT
|
||||||
---
|
---
|
||||||
|
@ -339,11 +338,10 @@ title: My Cool Gist
|
||||||
|
|
||||||
{% gist #{invalid_gist} %}
|
{% gist #{invalid_gist} %}
|
||||||
CONTENT
|
CONTENT
|
||||||
|
|
||||||
|
assert_raise ArgumentError do
|
||||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||||
end
|
end
|
||||||
|
|
||||||
should "output error message" do
|
|
||||||
assert_match "Error parsing gist id", @result
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -373,7 +371,7 @@ CONTENT
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with invalid parameter syntax" do
|
context "with invalid parameter syntax" do
|
||||||
should "throw a SyntaxError" do
|
should "throw a ArgumentError" do
|
||||||
content = <<CONTENT
|
content = <<CONTENT
|
||||||
---
|
---
|
||||||
title: Invalid parameter syntax
|
title: Invalid parameter syntax
|
||||||
|
@ -381,7 +379,7 @@ title: Invalid parameter syntax
|
||||||
|
|
||||||
{% include params.html param s="value" %}
|
{% include params.html param s="value" %}
|
||||||
CONTENT
|
CONTENT
|
||||||
assert_raise SyntaxError, 'Did not raise exception on invalid "include" syntax' do
|
assert_raise ArgumentError, 'Did not raise exception on invalid "include" syntax' do
|
||||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -392,7 +390,7 @@ title: Invalid parameter syntax
|
||||||
|
|
||||||
{% include params.html params="value %}
|
{% include params.html params="value %}
|
||||||
CONTENT
|
CONTENT
|
||||||
assert_raise SyntaxError, 'Did not raise exception on invalid "include" syntax' do
|
assert_raise ArgumentError, 'Did not raise exception on invalid "include" syntax' do
|
||||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -436,5 +434,22 @@ CONTENT
|
||||||
assert_match "<span id='include-param' />", @result
|
assert_match "<span id='include-param' />", @result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "without parameters within if statement" do
|
||||||
|
setup do
|
||||||
|
content = <<CONTENT
|
||||||
|
---
|
||||||
|
title: without parameters within if statement
|
||||||
|
---
|
||||||
|
|
||||||
|
{% if true %}{% include params.html %}{% endif %}
|
||||||
|
CONTENT
|
||||||
|
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||||
|
end
|
||||||
|
|
||||||
|
should "include file with empty parameters within if statement" do
|
||||||
|
assert_match "<span id='include-param' />", @result
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue