Load config file from within current theme-gem (#7304)
Merge pull request 7304
This commit is contained in:
parent
56c35f1a7d
commit
d67cbb4e5f
|
@ -274,6 +274,24 @@ Jekyll will automatically require all whitelisted `runtime_dependencies` of your
|
|||
|
||||
With this, the end-user need not keep track of the plugins required to be included in their config file for their theme-gem to work as intended.
|
||||
|
||||
{% if site.version == '4.0.0' %}
|
||||
{% comment %} Remove this encapsulation when `v4.0` ships {% endcomment %}
|
||||
|
||||
### Pre-configuring Theme-gems {%- include docs_version_badge.html version="4.0.0" -%}
|
||||
|
||||
Jekyll will read-in a `_config.yml` at the root of the theme-gem and merge its data into the site's existing configuration data.
|
||||
|
||||
But unlike other entities loaded from within the theme, loading the config file comes with a few restrictions, as summarized below:
|
||||
* Jekyll's default settings cannot be overridden by a theme-config. That *ball is still in the user's court.*
|
||||
* The theme-config-file cannot be a symlink, irrespective of `safe mode` and whether the file pointed to by the symlink is a legitimate file within the theme-gem.
|
||||
* The theme-config should be a set of key-value pairs. An empty config file, a config file that simply *lists items* under a key, or a config file with just a simple string of text will simply be ignored silently. Users will not get a warning or any log output regarding this discrepancy.
|
||||
* Any settings defined by the theme-config can be overridden by the user.
|
||||
|
||||
While this feature is to enable easier adoption of a theme, the restrictions ensure that a theme-config cannot affect the build in a concerning manner. Any plugins required by the theme will have to be listed manually by the user or provided by the theme's `gemspec` file.
|
||||
|
||||
This feature will let the theme-gem to work with *theme-specific config variables* out-of-the-box.
|
||||
{% endif %}
|
||||
|
||||
### 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?
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
Feature: Bundling Config file with Theme gems
|
||||
As a web developer who likes to share my expertise
|
||||
I want to be able to pre-configure my gemified theme
|
||||
In order to make it easier for other Jekyllites to use my theme
|
||||
|
||||
Scenario: Easy onboarding with a pre-configured theme
|
||||
Given I have a configuration file with "theme" set to "test-theme"
|
||||
And I have an "index.md" page that contains "{{ site.test_theme.skin }}"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And I should see "aero" in "_site/index.html"
|
||||
|
||||
Scenario: A pre-configured theme with valid config file overriding Jekyll defaults
|
||||
Given I have a configuration file with "theme" set to "test-theme"
|
||||
And I have an "index.md" page that contains "{{ site.baseurl }}"
|
||||
And I have a node_modules directory
|
||||
And I have a "node_modules/alert.js" file that contains "alert('foo');"
|
||||
When I run jekyll build
|
||||
Then I should get a zero exit status
|
||||
And the _site directory should exist
|
||||
And the "_site/index.html" file should exist
|
||||
But the "_site/node_modules/alert.js" file should not exist
|
||||
And the "_site/extras/banner.html" file should not exist
|
||||
And I should not see "/test-theme" in "_site/index.html"
|
|
@ -59,6 +59,8 @@ module Jekyll
|
|||
|
||||
self.permalink_style = config["permalink"].to_sym
|
||||
|
||||
# Read in a _config.yml from the current theme-gem at the very end.
|
||||
@config = load_theme_configuration(config) if theme
|
||||
@config
|
||||
end
|
||||
|
||||
|
@ -409,6 +411,25 @@ module Jekyll
|
|||
|
||||
private
|
||||
|
||||
def load_theme_configuration(config)
|
||||
theme_config_file = in_theme_dir("_config.yml")
|
||||
return config unless File.exist?(theme_config_file)
|
||||
|
||||
# Bail out if the theme_config_file is a symlink file irrespective of safe mode
|
||||
return config if File.symlink?(theme_config_file)
|
||||
|
||||
theme_config = SafeYAML.load_file(theme_config_file)
|
||||
return config unless theme_config.is_a?(Hash)
|
||||
|
||||
Jekyll.logger.info "Theme Config file:", theme_config_file
|
||||
|
||||
# theme_config should not be overriding Jekyll's defaults
|
||||
theme_config.delete_if { |key, _| Configuration::DEFAULTS.key?(key) }
|
||||
|
||||
# Override theme_config with existing config and return the result.
|
||||
Utils.deep_merge_hashes(theme_config, config)
|
||||
end
|
||||
|
||||
# Limits the current posts; removes the posts which exceed the limit_posts
|
||||
#
|
||||
# Returns nothing
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
title: Hello World
|
||||
baseurl: "/test-theme"
|
||||
include: ["_extras/banner.md"]
|
||||
exclude:
|
||||
- README.md
|
||||
- CHANGELOG.md
|
||||
- Rakefile
|
||||
- test/**/*
|
||||
|
||||
# theme-specific settings
|
||||
test_theme:
|
||||
skin: aero # aero / chrome / dark / neon
|
||||
date_format: "%b -d %Y" # any format supported by strftime
|
||||
header_links: true # generate header links automatically
|
|
@ -588,7 +588,11 @@ class TestSite < JekyllUnitTest
|
|||
|
||||
should "set a theme if the config is a string" do
|
||||
[:debug, :info, :warn, :error].each do |level|
|
||||
expect(Jekyll.logger.writer).not_to receive(level)
|
||||
if level == :info
|
||||
expect(Jekyll.logger.writer).to receive(level)
|
||||
else
|
||||
expect(Jekyll.logger.writer).not_to receive(level)
|
||||
end
|
||||
end
|
||||
site = fixture_site("theme" => "test-theme")
|
||||
assert_instance_of Jekyll::Theme, site.theme
|
||||
|
|
Loading…
Reference in New Issue