commit
30f2bdff5b
|
@ -25,6 +25,7 @@ env:
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- themes
|
||||
|
||||
notifications:
|
||||
irc:
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -22,6 +22,7 @@ group :test do
|
|||
gem "rspec-mocks"
|
||||
gem "nokogiri"
|
||||
gem "rspec"
|
||||
gem "test-theme", path: File.expand_path("./test/fixtures/test-theme", File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
Feature: Writing themes
|
||||
As a hacker who likes to share my expertise
|
||||
I want to be able to make a gemified theme
|
||||
In order to share my awesome style skillz with other Jekyllites
|
||||
|
||||
Scenario: A theme with SCSS
|
||||
Given I have a configuration file with "theme" set to "test-theme"
|
||||
And I have a css directory
|
||||
And I have a "css/main.scss" page that contains "@import 'style';"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see ".sample {\n color: black; }" in "_site/css/main.css"
|
||||
|
||||
Scenario: A theme with an include
|
||||
Given I have a configuration file with "theme" set to "test-theme"
|
||||
And I have an _includes directory
|
||||
And I have an "_includes/in_project.html" file that contains "I'm in the project."
|
||||
And I have an "index.html" page that contains "{% include in_project.html %} {% include include.html %}"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "I'm in the project." in "_site/index.html"
|
||||
And I should see "<span class=\"sample\">include.html from test-theme</span>" in "_site/index.html"
|
||||
|
||||
Scenario: A theme with a layout
|
||||
Given I have a configuration file with "theme" set to "test-theme"
|
||||
And I have an _layouts directory
|
||||
And I have an "_layouts/post.html" file that contains "post.html from the project: {{ content }}"
|
||||
And I have an "index.html" page with layout "default" that contains "I'm content."
|
||||
And I have a "post.html" page with layout "post" that contains "I'm more content."
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "default.html from test-theme: I'm content." in "_site/index.html"
|
||||
And I should see "post.html from the project: I'm more content." in "_site/post.html"
|
||||
|
||||
Scenario: Complicated site that puts it all together
|
||||
Given I have a configuration file with "theme" set to "test-theme"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2016-04-21 | post | I am using a local layout. {% include include.html %} |
|
||||
| entry2 | 2016-04-21 | default | I am using a themed layout. {% include include.html %} {% include in_project.html %} |
|
||||
And I have a _layouts directory
|
||||
And I have a "_layouts/post.html" page with layout "default" that contains "I am a post layout! {{ content }}"
|
||||
And I have an _includes directory
|
||||
And I have an "_includes/in_project.html" file that contains "I am in the project, not the theme."
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "I am in the project, not the theme." in "_site/2016/04/21/entry2.html"
|
||||
And I should see "<span class=\"sample\">include.html from test-theme</span>" in "_site/2016/04/21/entry2.html"
|
||||
And I should see "default.html from test-theme:" in "_site/2016/04/21/entry2.html"
|
||||
And I should see "I am using a themed layout." in "_site/2016/04/21/entry2.html"
|
||||
And I should not see "I am a post layout!" in "_site/2016/04/21/entry2.html"
|
||||
And I should not see "I am in the project, not the theme." in "_site/2016/04/21/entry1.html"
|
||||
And I should see "<span class=\"sample\">include.html from test-theme</span>" in "_site/2016/04/21/entry1.html"
|
||||
And I should see "default.html from test-theme:" in "_site/2016/04/21/entry1.html"
|
||||
And I should see "I am using a local layout." in "_site/2016/04/21/entry1.html"
|
||||
And I should see "I am a post layout!" in "_site/2016/04/21/entry1.html"
|
|
@ -66,6 +66,7 @@ module Jekyll
|
|||
autoload :Site, 'jekyll/site'
|
||||
autoload :StaticFile, 'jekyll/static_file'
|
||||
autoload :Stevenson, 'jekyll/stevenson'
|
||||
autoload :Theme, 'jekyll/theme'
|
||||
autoload :URL, 'jekyll/url'
|
||||
autoload :Utils, 'jekyll/utils'
|
||||
autoload :VERSION, 'jekyll/version'
|
||||
|
|
|
@ -39,7 +39,7 @@ module Jekyll
|
|||
filename = File.join(base, name)
|
||||
|
||||
begin
|
||||
self.content = File.read(site.in_source_dir(base, name),
|
||||
self.content = File.read(@path || site.in_source_dir(base, name),
|
||||
Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ Document::YAML_FRONT_MATTER_REGEXP
|
||||
self.content = $POSTMATCH
|
||||
|
@ -215,9 +215,9 @@ module Jekyll
|
|||
payload["layout"] = Utils.deep_merge_hashes(payload["layout"] || {}, layout.data)
|
||||
|
||||
self.output = render_liquid(layout.content,
|
||||
payload,
|
||||
info,
|
||||
File.join(site.config['layouts_dir'], layout.name))
|
||||
payload,
|
||||
info,
|
||||
layout.relative_path)
|
||||
|
||||
# Add layout to dependency tree
|
||||
site.regenerator.add_dependency(
|
||||
|
|
|
@ -29,7 +29,14 @@ module Jekyll
|
|||
@site = site
|
||||
@base = base
|
||||
@name = name
|
||||
@path = site.in_source_dir(base, name)
|
||||
|
||||
if site.theme && site.theme.layouts_path.eql?(base)
|
||||
@base_dir = site.theme.root
|
||||
@path = site.in_theme_dir(base, name)
|
||||
else
|
||||
@base_dir = site.source
|
||||
@path = site.in_source_dir(base, name)
|
||||
end
|
||||
|
||||
self.data = {}
|
||||
|
||||
|
@ -45,5 +52,13 @@ module Jekyll
|
|||
def process(name)
|
||||
self.ext = File.extname(name)
|
||||
end
|
||||
|
||||
# The path to the layout, relative to the site source.
|
||||
#
|
||||
# Returns a String path which represents the relative path
|
||||
# from the site source to this layout
|
||||
def relative_path
|
||||
@relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(@base_dir)).to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,6 +40,7 @@ module Jekyll
|
|||
@base = base
|
||||
@dir = dir
|
||||
@name = name
|
||||
@path = site.in_source_dir(base, dir, name)
|
||||
|
||||
process(name)
|
||||
read_yaml(File.join(base, dir), name)
|
||||
|
|
|
@ -7,8 +7,12 @@ module Jekyll
|
|||
end
|
||||
|
||||
def read
|
||||
layout_entries.each do |f|
|
||||
@layouts[layout_name(f)] = Layout.new(site, layout_directory, f)
|
||||
layout_entries.each do |layout_file|
|
||||
@layouts[layout_name(layout_file)] = Layout.new(site, layout_directory, layout_file)
|
||||
end
|
||||
|
||||
theme_layout_entries.each do |layout_file|
|
||||
@layouts[layout_name(layout_file)] ||= Layout.new(site, theme_layout_directory, layout_file)
|
||||
end
|
||||
|
||||
@layouts
|
||||
|
@ -18,11 +22,23 @@ module Jekyll
|
|||
@layout_directory ||= (layout_directory_in_cwd || layout_directory_inside_source)
|
||||
end
|
||||
|
||||
def theme_layout_directory
|
||||
@theme_layout_directory ||= site.theme.layouts_path if site.theme
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def layout_entries
|
||||
entries_in layout_directory
|
||||
end
|
||||
|
||||
def theme_layout_entries
|
||||
theme_layout_directory ? entries_in(theme_layout_directory) : []
|
||||
end
|
||||
|
||||
def entries_in(dir)
|
||||
entries = []
|
||||
within(layout_directory) do
|
||||
within(dir) do
|
||||
entries = EntryFilter.new(site).filter(Dir['**/*.*'])
|
||||
end
|
||||
entries
|
||||
|
|
|
@ -145,7 +145,7 @@ module Jekyll
|
|||
layout.content,
|
||||
payload,
|
||||
info,
|
||||
File.join(site.config['layouts_dir'], layout.name)
|
||||
layout.relative_path
|
||||
)
|
||||
|
||||
# Add layout to dependency tree
|
||||
|
|
|
@ -8,10 +8,10 @@ module Jekyll
|
|||
:exclude, :include, :lsi, :highlighter, :permalink_style,
|
||||
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
|
||||
:gems, :plugin_manager
|
||||
:gems, :plugin_manager, :theme
|
||||
|
||||
attr_accessor :converters, :generators, :reader
|
||||
attr_reader :regenerator, :liquid_renderer
|
||||
attr_reader :regenerator, :liquid_renderer, :includes_load_paths
|
||||
|
||||
# Public: Initialize a new Site.
|
||||
#
|
||||
|
@ -52,6 +52,12 @@ module Jekyll
|
|||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||
self.plugins = plugin_manager.plugins_path
|
||||
|
||||
self.theme = nil
|
||||
self.theme = Jekyll::Theme.new(config["theme"]) if config["theme"]
|
||||
|
||||
@includes_load_paths = Array(in_source_dir(config["includes_dir"].to_s))
|
||||
@includes_load_paths << theme.includes_path if self.theme
|
||||
|
||||
self.file_read_opts = {}
|
||||
self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
|
||||
|
||||
|
@ -367,6 +373,19 @@ module Jekyll
|
|||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the theme directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# theme directory
|
||||
#
|
||||
# Returns a path which is prefixed with the theme root directory.
|
||||
def in_theme_dir(*paths)
|
||||
return nil unless theme
|
||||
paths.reduce(theme.root) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the destination directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
|
|
|
@ -12,8 +12,6 @@ module Jekyll
|
|||
end
|
||||
|
||||
class IncludeTag < Liquid::Tag
|
||||
attr_reader :includes_dir
|
||||
|
||||
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
||||
VARIABLE_SYNTAX = /(?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)(?<params>.*)/
|
||||
|
||||
|
@ -98,20 +96,29 @@ eos
|
|||
end
|
||||
end
|
||||
|
||||
def tag_includes_dir(context)
|
||||
context.registers[:site].config['includes_dir'].freeze
|
||||
def tag_includes_dirs(context)
|
||||
context.registers[:site].includes_load_paths.freeze
|
||||
end
|
||||
|
||||
def locate_include_file(context, file, safe)
|
||||
includes_dirs = tag_includes_dirs(context)
|
||||
includes_dirs.each do |dir|
|
||||
path = File.join(dir, file)
|
||||
return path if valid_include_file?(path, dir, safe)
|
||||
end
|
||||
raise IOError, "Could not locate the included file '#{file}' in any of #{includes_dirs}." \
|
||||
" Ensure it exists in one of those directories and, if it is a symlink, " \
|
||||
"does not point outside your site source."
|
||||
end
|
||||
|
||||
def render(context)
|
||||
site = context.registers[:site]
|
||||
@includes_dir = tag_includes_dir(context)
|
||||
dir = resolved_includes_dir(context)
|
||||
|
||||
file = render_variable(context) || @file
|
||||
validate_file_name(file)
|
||||
|
||||
path = File.join(dir, file)
|
||||
validate_path(path, dir, site.safe)
|
||||
path = locate_include_file(context, file, site.safe)
|
||||
return unless path
|
||||
|
||||
# Add include to dependency tree
|
||||
if context.registers[:page] && context.registers[:page].key?("path")
|
||||
|
@ -121,16 +128,16 @@ eos
|
|||
)
|
||||
end
|
||||
|
||||
begin
|
||||
#begin
|
||||
partial = load_cached_partial(path, context)
|
||||
|
||||
context.stack do
|
||||
context['include'] = parse_params(context) if @params
|
||||
partial.render!(context)
|
||||
end
|
||||
rescue => e
|
||||
raise IncludeTagError.new e.message, File.join(@includes_dir, @file)
|
||||
end
|
||||
#rescue => e
|
||||
#raise IncludeTagError.new e.message, path
|
||||
#end
|
||||
end
|
||||
|
||||
def load_cached_partial(path, context)
|
||||
|
@ -144,24 +151,18 @@ eos
|
|||
end
|
||||
end
|
||||
|
||||
def resolved_includes_dir(context)
|
||||
context.registers[:site].in_source_dir(@includes_dir)
|
||||
def valid_include_file?(path, dir, safe)
|
||||
!(outside_site_source?(path, dir, safe) || !File.exist?(path))
|
||||
end
|
||||
|
||||
def validate_path(path, dir, safe)
|
||||
if safe && !realpath_prefixed_with?(path, dir)
|
||||
raise IOError.new "The included file '#{path}' should exist and should not be a symlink"
|
||||
elsif !File.exist?(path)
|
||||
raise IOError.new "Included file '#{path_relative_to_source(dir, path)}' not found"
|
||||
end
|
||||
end
|
||||
|
||||
def path_relative_to_source(dir, path)
|
||||
File.join(@includes_dir, path.sub(Regexp.new("^#{dir}"), ""))
|
||||
def outside_site_source?(path, dir, safe)
|
||||
safe && !realpath_prefixed_with?(path, dir)
|
||||
end
|
||||
|
||||
def realpath_prefixed_with?(path, dir)
|
||||
File.exist?(path) && File.realpath(path).start_with?(dir)
|
||||
rescue
|
||||
false
|
||||
end
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
|
@ -171,16 +172,17 @@ eos
|
|||
end
|
||||
|
||||
class IncludeRelativeTag < IncludeTag
|
||||
def tag_includes_dir(context)
|
||||
'.'.freeze
|
||||
def tag_includes_dirs(context)
|
||||
Array(page_path(context)).freeze
|
||||
end
|
||||
|
||||
def page_path(context)
|
||||
context.registers[:page].nil? ? includes_dir : File.dirname(context.registers[:page]["path"])
|
||||
end
|
||||
|
||||
def resolved_includes_dir(context)
|
||||
context.registers[:site].in_source_dir(page_path(context))
|
||||
if context.registers[:page].nil?
|
||||
context.registers[:site].source
|
||||
else
|
||||
current_doc_dir = File.dirname(context.registers[:page]["path"])
|
||||
context.registers[:site].in_source_dir current_doc_dir
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
module Jekyll
|
||||
class Theme
|
||||
extend Forwardable
|
||||
attr_reader :name
|
||||
def_delegator :gemspec, :version, :version
|
||||
|
||||
def initialize(name)
|
||||
@name = name.downcase.strip
|
||||
configure_sass
|
||||
end
|
||||
|
||||
def root
|
||||
@root ||= gemspec.full_gem_path
|
||||
end
|
||||
|
||||
def includes_path
|
||||
path_for :includes
|
||||
end
|
||||
|
||||
def layouts_path
|
||||
path_for :layouts
|
||||
end
|
||||
|
||||
def sass_path
|
||||
path_for :sass
|
||||
end
|
||||
|
||||
def configure_sass
|
||||
return unless sass_path
|
||||
require 'sass'
|
||||
Sass.load_paths << sass_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def path_for(folder)
|
||||
resolved_dir = realpath_for(folder)
|
||||
return unless resolved_dir
|
||||
|
||||
path = Jekyll.sanitized_path(root, resolved_dir)
|
||||
path if Dir.exists?(path)
|
||||
end
|
||||
|
||||
def realpath_for(folder)
|
||||
File.realpath(Jekyll.sanitized_path(root, "_#{folder}"))
|
||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
|
||||
nil
|
||||
end
|
||||
|
||||
def gemspec
|
||||
@gemspec ||= Gem::Specification.find_by_name(name)
|
||||
rescue Gem::LoadError
|
||||
raise Jekyll::Errors::MissingDependencyException, "The #{name} theme could not be found."
|
||||
end
|
||||
end
|
||||
end
|
|
@ -103,7 +103,7 @@ namespace :site do
|
|||
|
||||
desc "Create a nicely formatted history page for the jekyll site based on the repo history."
|
||||
task :history do
|
||||
siteify_file('History.markdown')
|
||||
siteify_file('History.markdown', { "title" => "History" })
|
||||
end
|
||||
|
||||
desc "Copy the Code of Conduct"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
- permalinks
|
||||
- pagination
|
||||
- plugins
|
||||
- themes
|
||||
- extras
|
||||
|
||||
- title: Deployment
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
---
|
||||
layout: docs
|
||||
title: Themes
|
||||
permalink: /docs/themes/
|
||||
---
|
||||
|
||||
Jekyll has an extensive theme system, which allows you to leverage community-maintained templates and styles to customize your site's presentation. Jekyll themes package layouts, includes, and stylesheets in a way that can be overridden by your site's content.
|
||||
|
||||
## Installing a theme
|
||||
|
||||
1. To install a theme, first, add the theme to your site's `Gemfile`:
|
||||
|
||||
gem 'my-awesome-jekyll-theme'
|
||||
|
||||
2. Save the changes to your `Gemfile`
|
||||
3. Run the command `bundle install` to install the theme
|
||||
4. Finally, activate the theme by adding the following to your site's `_config.yml`:
|
||||
|
||||
theme: my-awesome-jekyll-theme
|
||||
|
||||
You can have multiple themes listed in your site's Gemfile, but only one theme can be selected in your site's `_config.yml`.
|
||||
{: .note .info }
|
||||
|
||||
## Overriding theme defaults
|
||||
|
||||
Jekyll themes set default layouts, includes, and stylesheets, that can be overridden by your site's content. For example, if your selected theme has a `page` layout, you can override the theme's layout by creating your own `page` layout in the `_layouts` folder (e.g., `_layouts/page.html`).
|
||||
|
||||
Jekyll will look first to your site's content, before looking to the theme's defaults, for any requested file in the following folders:
|
||||
|
||||
* `/_layouts`
|
||||
* `/_includes`
|
||||
* `/_sass`
|
||||
|
||||
Refer to your selected theme's documentation and source repository for more information on what files you can override.
|
||||
{: .note .info}
|
||||
|
||||
## Creating a theme
|
||||
|
||||
Jekyll themes are distributed as Ruby gems. The only required file is the [Ruby Gemspec](http://guides.rubygems.org/specification-reference/). Here's an example of a minimal Gemspec for the `my-awesome-jekyll-theme` theme, saved as `/my-awsome-jekyll-theme.gemspec`:
|
||||
|
||||
{% highlight ruby %}
|
||||
Gem::Specification.new do |s|
|
||||
s.name = '<THEME TITLE>'
|
||||
s.version = '0.1.0'
|
||||
s.license = 'MIT'
|
||||
s.summary = '<THEME DESCRIPTION>'
|
||||
s.author = '<YOUR NAME>'
|
||||
s.email = '<YOUR EMAIL>'
|
||||
s.homepage = 'https://github.com/jekyll/my-awesome-jekyll-theme'
|
||||
s.files = `git ls-files -z`.split("\x0").grep(%r{^_(sass|includes|layouts)/})
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
### Layouts and includes
|
||||
|
||||
Theme layouts and includes work just like they work in any Jekyll site. Place layouts in your theme's `/_layouts` folder, and place includes in your themes `/_includes` folder.
|
||||
|
||||
For example, if your theme has a `/_layouts/page.html` file, and a page has `layout: page` in its YAML front matter, Jekyll will first look to the site's `_layouts` folder for a the `page` layout, and if none exists, will use your theme's `page` layout.
|
||||
|
||||
### Stylesheets
|
||||
|
||||
Your theme's stylesheets should be placed in your theme's `/_sass` folder, again, just as you would when authoring a Jekyll site. Your theme's styles can be included in the user's stylesheet using the `@import` directive.
|
||||
|
||||
### Documenting your theme
|
||||
|
||||
Your theme should include a `/README.md` file, which explains how site authors can install and use your theme. What layouts are included? What includes? Do they need to add anything special to their site's configuration file?
|
||||
|
||||
### Adding a screenshot
|
||||
|
||||
Themes are visual. Show users what your theme looks like by including a screenshot as `/screenshot.png` within your theme's repository where it can be retrieved programatically. You can also include this screenshot within your theme's documentation.
|
||||
|
||||
### Previewing your theme
|
||||
|
||||
To preview your theme as you're authoring it, it may be helpful to add dummy content in, for example, `/index.html` and `/page.html` files. This will allow you to use the `jekyll build` and `jekyll serve` commands to preview your theme, just as you'd preview a Jekyll site.
|
||||
|
||||
If you do preview your theme locally, be sure to add `/_site` to your theme's `.gitignore` file to prevent the compiled site from also being included when you distribute your theme.
|
||||
{: .info .note}
|
||||
|
||||
### Publishing your theme
|
||||
|
||||
Themes are published via [RubyGems.org](https://rubygems.org). You'll need a RubyGems account, which you can [create for free](https://rubygems.org/sign_up).
|
||||
|
||||
1. First, package your theme, by running the following command, replacing `my-awesome-jekyll-theme` with the name of your theme:
|
||||
|
||||
gem build my-awesome-jekyll-theme.gemspec
|
||||
|
||||
2. Next, push your packaged theme up to the RubyGems service, by running the following command, again replacing `my-awesome-jekyll-theme` with the name of your theme:
|
||||
|
||||
gem push my-awesome-jekyll-theme-*.gem
|
|
@ -0,0 +1 @@
|
|||
<span class="sample">include.html from test-theme</span>
|
|
@ -0,0 +1 @@
|
|||
default.html from test-theme: {{ content }}
|
|
@ -0,0 +1,3 @@
|
|||
.sample {
|
||||
color: black;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
_layouts
|
|
@ -0,0 +1,9 @@
|
|||
Gem::Specification.new do |s|
|
||||
s.name = 'test-theme'
|
||||
s.version = '0.1.0'
|
||||
s.licenses = ['MIT']
|
||||
s.summary = "This is a theme used to test Jekyll"
|
||||
s.authors = ["Jekyll"]
|
||||
s.files = ["lib/example.rb"]
|
||||
s.homepage = 'https://github.com/jekyll/jekyll'
|
||||
end
|
|
@ -616,7 +616,7 @@ title: Include symlink
|
|||
CONTENT
|
||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true, 'safe' => true })
|
||||
end
|
||||
assert_match(/should exist and should not be a symlink/, ex.message)
|
||||
assert_match "Could not locate the included file 'tmp/pages-test-does-not-exist' in any of [\"#{source_dir}/_includes\"].", ex.message
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -757,7 +757,7 @@ CONTENT
|
|||
exception = assert_raises IOError do
|
||||
create_post(@content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||
end
|
||||
assert_equal 'Included file \'_includes/missing.html\' not found', exception.message
|
||||
assert_match "Could not locate the included file 'missing.html' in any of [\"#{source_dir}/_includes\"].", exception.message
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -839,7 +839,7 @@ CONTENT
|
|||
exception = assert_raises IOError do
|
||||
create_post(@content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
|
||||
end
|
||||
assert_equal 'Included file \'./missing.html\' not found', exception.message
|
||||
assert_match "Could not locate the included file 'missing.html' in any of [\"#{source_dir}\"].", exception.message
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -894,7 +894,7 @@ title: Include symlink
|
|||
CONTENT
|
||||
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true, 'safe' => true })
|
||||
end
|
||||
assert_match(/should exist and should not be a symlink/, ex.message)
|
||||
assert_match /Ensure it exists in one of those directories and, if it is a symlink, does not point outside your site source./, ex.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
require 'helper'
|
||||
|
||||
class TestTheme < JekyllUnitTest
|
||||
def setup
|
||||
@theme = Theme.new('test-theme')
|
||||
@expected_root = File.expand_path "./fixtures/test-theme", File.dirname(__FILE__)
|
||||
end
|
||||
|
||||
context "initializing" do
|
||||
should "normalize the theme name" do
|
||||
theme = Theme.new(' Test-Theme ')
|
||||
assert_equal "test-theme", theme.name
|
||||
end
|
||||
|
||||
should "know the theme root" do
|
||||
assert_equal @expected_root, @theme.root
|
||||
end
|
||||
|
||||
should "know the theme version" do
|
||||
assert_equal Gem::Version.new("0.1.0"), @theme.version
|
||||
end
|
||||
|
||||
should "raise an error for invalid themes" do
|
||||
assert_raises Jekyll::Errors::MissingDependencyException do
|
||||
Theme.new("foo").version
|
||||
end
|
||||
end
|
||||
|
||||
should "add itself to sass's load path" do
|
||||
@theme.configure_sass
|
||||
assert Sass.load_paths.include?(@theme.sass_path), "Sass load paths should include the theme sass dir"
|
||||
end
|
||||
end
|
||||
|
||||
context "path generation" do
|
||||
[:layouts, :includes, :sass].each do |folder|
|
||||
should "know the #{folder} path" do
|
||||
expected = File.expand_path("_#{folder}", @expected_root)
|
||||
assert_equal expected, @theme.public_send("#{folder}_path")
|
||||
end
|
||||
end
|
||||
|
||||
should "generate folder paths" do
|
||||
expected = File.expand_path("./_sass", @expected_root)
|
||||
assert_equal expected, @theme.send(:path_for, :sass)
|
||||
end
|
||||
|
||||
should "not allow paths outside of the theme root" do
|
||||
assert_equal nil, @theme.send(:path_for, "../../source")
|
||||
end
|
||||
|
||||
should "return nil for paths that don't exist" do
|
||||
assert_equal nil, @theme.send(:path_for, "foo")
|
||||
end
|
||||
|
||||
should "return the resolved path when a symlink & resolved path exists" do
|
||||
expected = File.expand_path("./_layouts", @expected_root)
|
||||
assert_equal expected, @theme.send(:path_for, :symlink)
|
||||
end
|
||||
end
|
||||
|
||||
should "retrieve the gemspec" do
|
||||
assert_equal "test-theme-0.1.0", @theme.send(:gemspec).full_name
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue