Add target config setting and front matter variables so one could create multiple outputs from a single site codebase with various target site included files

This commit is contained in:
Dan Ballard 2025-08-17 09:35:02 -05:00
parent 40ac06ed3e
commit af57ed4871
9 changed files with 63 additions and 10 deletions

View File

@ -43,6 +43,7 @@ show_drafts : null
limit_posts : 0
future : false
unpublished : false
target : "default"
# Plugins
whitelist : []

View File

@ -9,3 +9,4 @@ Sites built using Jekyll can be deployed in a large number of ways due to the st
* [Manually]({{ '/docs/deployment/manual/' | relative_url }})
* [Automated]({{ '/docs/deployment/automated/' | relative_url }})
* [Third Party]({{ '/docs/deployment/third-party/' | relative_url }})
* [Multiple Sites and Target]({{ '/docs/deployment/multiple-sites' | relative_url }})

View File

@ -0,0 +1,44 @@
---
title: Multiple Sites and Target
permalink: /docs/deployment/multiple-sites/
---
The `target` setting in `_config.yml` and frontmatter in conjunction with config stacking allows multiple sites with varitation to be built from one codebase.
## Use Case
You may have multiple access paths to your site, and want to offer unique content on some of them, for examples you may have a open web version of your site at `https://foo.com` and you may also have an [onion service](https://community.torproject.org/onion-services/setup/) version of your site accesible via `http://foo000...abc.onion`. Alternately you may have a public facing version of the site, and an internal network or VPN accessible version that you want additional content to be included on.
## Method
By default the `target` config option is set to "default" in `_site_config.yml` and when comparing with frontmatter of content, if none is set, it inherit's the site's value. So by default all content will be published. To make content only appear on a specific version of a site, in frontmatter add `target: xVersion` where "xVersion" will be a `target` option set in a second `_site_x.yml`.
You generate the normal site the same
`bundle exec jekyll build`
For the second site, you create a mini site specific config, like
```yml
url: https://altDomain.com
destination: _site_xVersion
target: xVersion
```
and build it with
`bundle exec jekyll build --config "_config.yml,_config_xversion.yml"`
Jekyll configs stack, and overrides from additional configs override earlier ones, so this will get all the default site config options and then just change `url`, `destination` and `target`
Then any content with a frontmatter `target` of "xVersion" will be included in this build which will be output to the new `_site_xVersion`.
If there is any content you want on the default version of the site but not any alternative ones, just add `target: default` to it's frontmatter.
Then configure your webserver with a second site config with the alternative access path and pointing to `_site_xVersion` directory.
### Potential Cons
This does result in multiple builds, which is potentially the one negative of this method if you are very constrained for space or your jekyll site is very large.

View File

@ -183,9 +183,12 @@ module Jekyll
# Whether the collection's documents ought to be written as individual
# files in the output.
#
# Returns true if the 'write' metadata is true, false otherwise.
# Returns true if the 'write' metadata is true and
# if the collection's target matches the site's target,
# false otherwise.
def write?
!!metadata.fetch("output", false)
!!metadata.fetch("output", false) &&
(site.target == metadata.fetch("target", site.target))
end
# The URL template to render collection's documents at.

View File

@ -30,6 +30,7 @@ module Jekyll
"limit_posts" => 0,
"future" => false,
"unpublished" => false,
"target" => "default",
# Plugins
"whitelist" => [],

View File

@ -348,17 +348,20 @@ module Jekyll
end
# Determine whether this document should be written.
# Based on the Collection to which it belongs.
# Based on the Collection to which it belongs
# and site and document target.
#
# True if the document has a collection and if that collection's #write?
# method returns true, and if the site's Publisher will publish the document.
# method returns true, and if the site's Publisher will publish the document,
# and if the document's target matches the site target or is undefined.
# False otherwise.
#
# rubocop:disable Naming/MemoizedInstanceVariableName
def write?
return @write_p if defined?(@write_p)
@write_p = collection&.write? && site.publisher.publish?(self)
@write_p = collection&.write? && site.publisher.publish?(self) &&
(site.target == data.fetch("target", site.target))
end
# rubocop:enable Naming/MemoizedInstanceVariableName

View File

@ -15,7 +15,7 @@ module Jekyll
private delegate_method_as :data, :fallback_data
delegate_methods :id, :output, :content, :to_s, :relative_path, :url, :date
data_delegators "title", "categories", "tags"
data_delegators "title", "categories", "tags", :target
def collection
@obj.collection.label

View File

@ -180,7 +180,7 @@ module Jekyll
end
def write?
true
site.config["target"] == data.fetch("target", site.config["target"])
end
def excerpt_separator

View File

@ -6,7 +6,7 @@ module Jekyll
:file_read_opts, :future, :gems, :generators, :highlighter,
:include, :inclusions, :keep_files, :layouts, :limit_posts,
:lsi, :pages, :permalink_style, :plugin_manager, :plugins,
:reader, :safe, :show_drafts, :static_files, :theme, :time,
:reader, :safe, :target, :show_drafts, :static_files, :theme, :time,
:unpublished
attr_reader :cache_dir, :config, :dest, :filter_cache, :includes_load_paths,
@ -47,7 +47,7 @@ module Jekyll
def config=(config)
@config = config.clone
%w(safe lsi highlighter baseurl exclude include future unpublished
%w(safe lsi highlighter baseurl exclude include future unpublished target
show_drafts limit_posts keep_files).each do |opt|
send(:"#{opt}=", config[opt])
end
@ -360,7 +360,7 @@ module Jekyll
end
def each_site_file
pages.each { |page| yield page }
pages.each { |page| yield (page) if page.write? }
static_files.each { |file| yield(file) if file.write? }
collections.each_value { |coll| coll.docs.each { |doc| yield(doc) if doc.write? } }
end