Compare commits
28 Commits
v4.4.0
...
targetable
Author | SHA1 | Date |
---|---|---|
|
176fd9425c | |
|
40ac06ed3e | |
|
76982c73c0 | |
|
55024b37ae | |
|
59d5d9ae62 | |
|
a2330bb3b3 | |
|
79a8e16f22 | |
|
e2e1ee8eaa | |
|
2a37caac83 | |
|
84437a5052 | |
|
01781355ef | |
|
fa5575c806 | |
|
cc583c218c | |
|
5f877c347b | |
|
dfbd86db50 | |
|
1b617d7281 | |
|
f6d9f86e04 | |
|
148c1d395c | |
|
07a01b0bc9 | |
|
82efcc4c51 | |
|
1e4696457d | |
|
f320d0d5d7 | |
|
193d2eca7f | |
|
0db8443b41 | |
|
e4f0c58395 | |
|
1f319fb273 | |
|
c5cd1fb04f | |
|
33e8a84a00 |
|
@ -1,3 +1,4 @@
|
||||||
|
azion
|
||||||
builtins
|
builtins
|
||||||
github
|
github
|
||||||
hakiri
|
hakiri
|
||||||
|
@ -7,6 +8,7 @@ Microsoft
|
||||||
ssh
|
ssh
|
||||||
Statictastic
|
Statictastic
|
||||||
statictastic
|
statictastic
|
||||||
|
supranode
|
||||||
ubuntu
|
ubuntu
|
||||||
Wikipedia
|
Wikipedia
|
||||||
workaround
|
workaround
|
||||||
|
|
|
@ -83,6 +83,7 @@ DCEU
|
||||||
Debian
|
Debian
|
||||||
defunkt
|
defunkt
|
||||||
delegators
|
delegators
|
||||||
|
devcontainer
|
||||||
digitalocean
|
digitalocean
|
||||||
disqus
|
disqus
|
||||||
ditaa
|
ditaa
|
||||||
|
@ -360,7 +361,7 @@ shingo
|
||||||
shopify
|
shopify
|
||||||
shortlinks
|
shortlinks
|
||||||
shortlog
|
shortlog
|
||||||
Shoulda
|
shoulda
|
||||||
sieversii
|
sieversii
|
||||||
sigpipe
|
sigpipe
|
||||||
Singhaniya
|
Singhaniya
|
||||||
|
@ -446,6 +447,7 @@ vnd
|
||||||
vohedge
|
vohedge
|
||||||
vps
|
vps
|
||||||
vwochnik
|
vwochnik
|
||||||
|
WAI
|
||||||
wdm
|
wdm
|
||||||
We'd
|
We'd
|
||||||
webfonts
|
webfonts
|
||||||
|
|
|
@ -1,3 +1,34 @@
|
||||||
|
## HEAD
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Avoid caching resource when called via `include_relative` tag (#9784)
|
||||||
|
* Fix logs containing IPv6 URLs (#9813)
|
||||||
|
* Do not treat colons in `url_placeholders` as URI delimiters (#9850)
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
* Improve documentation on collections in step-by-step walkthrough (#9803)
|
||||||
|
* Add `https://form.taxi` as a third-party resource for forms (#9802)
|
||||||
|
* Add Supranode to third-party deployment guide (#9786)
|
||||||
|
* Document the need for a `Gemfile` in deployment step of step-by-step walkthrough (#9805)
|
||||||
|
* Add Azion to the 3rd party deployment docs (#9811)
|
||||||
|
* Add ruby-erb prerequisite for Arch Linux installations (#9832)
|
||||||
|
|
||||||
|
### Development Fixes
|
||||||
|
|
||||||
|
* Improve readability of `post_url` tag (#9829)
|
||||||
|
|
||||||
|
### Minor Enhancements
|
||||||
|
|
||||||
|
* feat: Allowing post_url tag to receive liquid variables (#9776)
|
||||||
|
|
||||||
|
## 4.4.1 / 2025-01-29
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Restore globbed path behavior in front matter defaults (#9762)
|
||||||
|
|
||||||
## 4.4.0 / 2025-01-27
|
## 4.4.0 / 2025-01-27
|
||||||
|
|
||||||
### Minor Enhancements
|
### Minor Enhancements
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
version: 4.4.0
|
version: 4.4.1
|
||||||
name: Jekyll • Simple, blog-aware, static sites
|
name: Jekyll • Simple, blog-aware, static sites
|
||||||
description: Transform your plain text into static websites and blogs
|
description: Transform your plain text into static websites and blogs
|
||||||
url: https://jekyllrb.com
|
url: https://jekyllrb.com
|
||||||
|
|
|
@ -47,9 +47,9 @@ Read this [Jekyll step-by-step guide](https://www.netlify.com/blog/2020/04/02/a-
|
||||||
|
|
||||||
[Render](https://render.com) provides zero config continuous deployment for static sites. The service is free under 100GB monthly bandwidth.
|
[Render](https://render.com) provides zero config continuous deployment for static sites. The service is free under 100GB monthly bandwidth.
|
||||||
|
|
||||||
## Hostman
|
## Hostman
|
||||||
|
|
||||||
[Hostman](https://hostman.com) allows you to host websites for free with no configurations. Read [this guide](https://hostman.com/docs/jekyll) to deploy your Jekyll site on Hostman.
|
[Hostman](https://hostman.com) allows you to host websites for free with no configurations. Read [this guide](https://hostman.com/docs/jekyll) to deploy your Jekyll site on Hostman.
|
||||||
|
|
||||||
## Static Publisher
|
## Static Publisher
|
||||||
|
|
||||||
|
@ -70,7 +70,17 @@ Read this [Jekyll step-by-step guide](https://www.21yunbox.com/docs/#/deploy-jek
|
||||||
[Layer0](https://www.layer0.co) is an all-in-one platform to develop, deploy, preview, experiment on, monitor, and run your headless frontend. It is focused on large, dynamic websites and best-in-class performance through EdgeJS (a JavaScript-based Content Delivery Network), predictive prefetching, and performance monitoring. Layer0 offers a free tier. Get started in just a few minutes by following [Layer0's guide to deploying Jekyll](https://docs.layer0.co/guides/jekyll).
|
[Layer0](https://www.layer0.co) is an all-in-one platform to develop, deploy, preview, experiment on, monitor, and run your headless frontend. It is focused on large, dynamic websites and best-in-class performance through EdgeJS (a JavaScript-based Content Delivery Network), predictive prefetching, and performance monitoring. Layer0 offers a free tier. Get started in just a few minutes by following [Layer0's guide to deploying Jekyll](https://docs.layer0.co/guides/jekyll).
|
||||||
|
|
||||||
## Kinsta Application Hosting
|
## Kinsta Application Hosting
|
||||||
|
|
||||||
[Kinsta Application Hosting](https://kinsta.com/application-hosting) is a Cloud Platform designed to help your company and dev teams ship web projects faster and more efficiently. You can host your apps, databases, and sites all in one place. Easily connect with GitHub and automate deployments and get 24/7 support for all your favorite languages and frameworks.
|
[Kinsta Application Hosting](https://kinsta.com/application-hosting) is a Cloud Platform designed to help your company and dev teams ship web projects faster and more efficiently. You can host your apps, databases, and sites all in one place. Easily connect with GitHub and automate deployments and get 24/7 support for all your favorite languages and frameworks.
|
||||||
|
|
||||||
Read [this guide](https://kinsta.com/docs/jekyll-static-site-example/) to learn how to deploy Jekyll site on Kinsta.
|
Read [this guide](https://kinsta.com/docs/jekyll-static-site-example/) to learn how to deploy Jekyll site on Kinsta.
|
||||||
|
|
||||||
|
## Supranode
|
||||||
|
|
||||||
|
[Supranode](https://supranode.com) offers customizable continuous deployment for static websites, featuring automatic HTTPS, a high-performance CDN, secret management, deployment previews, password protection, and more.
|
||||||
|
|
||||||
|
## Azion
|
||||||
|
|
||||||
|
[Azion](https://www.azion.com/en/) is an web platform that provides a wide range of services. It allows you to host static sites, including Jekyll-powered websites, with features like automatic HTTPS, custom domains, and real-time analytics. Azion's platform is designed for performance and scalability, making it an excellent choice for hosting global websites.
|
||||||
|
|
||||||
|
In [this guide](https://www.azion.com/en/documentation/products/guides/jekyll-boilerplate/) you can learn how to deploy a Jekyll site on Azion.
|
||||||
|
|
|
@ -4,6 +4,15 @@ permalink: "/docs/history/"
|
||||||
note: This file is autogenerated. Edit /History.markdown instead.
|
note: This file is autogenerated. Edit /History.markdown instead.
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 4.4.1 / 2025-01-29
|
||||||
|
{: #v4-4-1}
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
{: #bug-fixes-v4-4-1}
|
||||||
|
|
||||||
|
- Restore globbed path behavior in front matter defaults ([#9762]({{ site.repository }}/issues/9762))
|
||||||
|
|
||||||
|
|
||||||
## 4.4.0 / 2025-01-27
|
## 4.4.0 / 2025-01-27
|
||||||
{: #v4-4-0}
|
{: #v4-4-0}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ sudo emerge --ask --verbose jekyll
|
||||||
### ArchLinux
|
### ArchLinux
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -S ruby base-devel
|
sudo pacman -S ruby base-devel ruby-erb
|
||||||
```
|
```
|
||||||
|
|
||||||
### OpenSUSE
|
### OpenSUSE
|
||||||
|
|
|
@ -188,3 +188,25 @@ You can also use this tag to create a link to a post in Markdown as follows:
|
||||||
[Name of Link]({% post_url 2010-07-21-name-of-post %})
|
[Name of Link]({% post_url 2010-07-21-name-of-post %})
|
||||||
```
|
```
|
||||||
{% endraw %}
|
{% endraw %}
|
||||||
|
|
||||||
|
Now lets say you have a [datafile]({{ '/docs/datafiles/' | relative_url }}) `_data/cool_posts.yaml` used to keep track
|
||||||
|
of certain posts that you intend to be listed as say *Cool Posts*:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- title: "An Awesome Post"
|
||||||
|
slug: "2010-07-21-name-of-post"
|
||||||
|
- title: "Another Awesome Post"
|
||||||
|
slug: "2016-07-26-name-of-post"
|
||||||
|
```
|
||||||
|
|
||||||
|
You may list such posts using the `post_url` tag as well (from {%- include docs_version_badge.html version="4.5.0" -%}):
|
||||||
|
|
||||||
|
{% raw %}
|
||||||
|
```liquid
|
||||||
|
Cool posts:
|
||||||
|
|
||||||
|
{%- for cool_post in site.data.cool_posts %}
|
||||||
|
- [{{ cool_post.title }}]({% post_url {{ cool_post.slug }} %})
|
||||||
|
{%- endfor %}
|
||||||
|
```
|
||||||
|
{% endraw %}
|
||||||
|
|
|
@ -57,7 +57,7 @@ Ted has been eating fruit since he was baby.
|
||||||
Let's add a page which lists all the authors on the site. Jekyll makes the
|
Let's add a page which lists all the authors on the site. Jekyll makes the
|
||||||
collection available at `site.authors`.
|
collection available at `site.authors`.
|
||||||
|
|
||||||
Create `staff.html` and iterate over `site.authors` to output all the staff:
|
Create `staff.html` in the root directory and iterate over `site.authors` to output all the staff:
|
||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
```liquid
|
```liquid
|
||||||
|
|
|
@ -11,7 +11,7 @@ It's good practice to have a [Gemfile](/docs/ruby-101/#gemfile) for your site.
|
||||||
This ensures the version of Jekyll and other gems remains consistent across
|
This ensures the version of Jekyll and other gems remains consistent across
|
||||||
different environments.
|
different environments.
|
||||||
|
|
||||||
Create a `Gemfile` in the root.
|
If you completed step one in this tutorial, you have already created a Gemfile. If you skipped step one, create a `Gemfile` in the root.
|
||||||
The file should be called 'Gemfile' and should *not* have any extension.
|
The file should be called 'Gemfile' and should *not* have any extension.
|
||||||
You can create a Gemfile with Bundler and then add the `jekyll` gem:
|
You can create a Gemfile with Bundler and then add the `jekyll` gem:
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ bundle init
|
||||||
bundle add jekyll
|
bundle add jekyll
|
||||||
```
|
```
|
||||||
|
|
||||||
Your file should look something like:
|
Your `Gemfile` should look something like:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
title: 'Jekyll 4.4.1 Released'
|
||||||
|
date: 2025-01-29 18:15:32 +0530
|
||||||
|
author: ashmaroli
|
||||||
|
version: 4.4.1
|
||||||
|
category: release
|
||||||
|
---
|
||||||
|
|
||||||
|
Publishing a patch release to restore existing behavior around defining front matter defaults
|
||||||
|
where a scope with path containing glob patterns are lax in matching paths on disk.
|
|
@ -1 +1 @@
|
||||||
4.4.0
|
4.4.1
|
||||||
|
|
|
@ -62,6 +62,7 @@ Use a SaaS service as a backend for functionality on your Jekyll site
|
||||||
- [Formspark](https://formspark.io/)
|
- [Formspark](https://formspark.io/)
|
||||||
- [Formspree (open source)](https://formspree.io/)
|
- [Formspree (open source)](https://formspree.io/)
|
||||||
- [formX](https://formx.stream)
|
- [formX](https://formx.stream)
|
||||||
|
- [Form.taxi](https://form.taxi/en/backend)
|
||||||
- [Simple Form](https://getsimpleform.com/)
|
- [Simple Form](https://getsimpleform.com/)
|
||||||
- [SmartForms](https://smartforms.dev/)
|
- [SmartForms](https://smartforms.dev/)
|
||||||
- [Typeform](https://www.typeform.com/templates/c/forms/)
|
- [Typeform](https://www.typeform.com/templates/c/forms/)
|
||||||
|
|
|
@ -58,3 +58,22 @@ Feature: include_relative Tag
|
||||||
Then I should get a zero exit status
|
Then I should get a zero exit status
|
||||||
And the _site directory should exist
|
And the _site directory should exist
|
||||||
And I should see "Welcome back Dear Reader!" in "_site/index.html"
|
And I should see "Welcome back Dear Reader!" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: Include multiple files relative to a page at root
|
||||||
|
Given I have an "apple.md" page with foo "bar" that contains "{{ page.path }}, {{ page.foo }}"
|
||||||
|
And I have an "banana.md" page with content:
|
||||||
|
"""
|
||||||
|
{% include_relative apple.md %}
|
||||||
|
{% include_relative cherry.md %}
|
||||||
|
|
||||||
|
{{ page.path }}
|
||||||
|
"""
|
||||||
|
And I have an "cherry.md" page with foo "lipsum" that contains "{{ page.path }}, {{ page.foo }}"
|
||||||
|
When I run jekyll build
|
||||||
|
Then I should get a zero exit status
|
||||||
|
And the _site directory should exist
|
||||||
|
And I should see "<p>apple.md, bar</p>" in "_site/apple.html"
|
||||||
|
And I should see "<hr />\n<p>foo: bar" in "_site/banana.html"
|
||||||
|
And I should see "<hr />\n<p>foo: lipsum" in "_site/banana.html"
|
||||||
|
And I should see "<p>cherry.md, lipsum</p>" in "_site/cherry.html"
|
||||||
|
But I should not see "foo: lipsum" in "_site/cherry.html"
|
||||||
|
|
|
@ -157,3 +157,37 @@ Feature: PostUrl Tag
|
||||||
But the _site directory should exist
|
But the _site directory should exist
|
||||||
And I should see "<p><a href=\"/cats%20and%20dogs/2019/02/04/hello-world.html\">Post 1</a></p>" in "_site/index.html"
|
And I should see "<p><a href=\"/cats%20and%20dogs/2019/02/04/hello-world.html\">Post 1</a></p>" in "_site/index.html"
|
||||||
And I should see "<p><a href=\"/2019/02/05/hello-again.html\">Post 2</a></p>" in "_site/index.html"
|
And I should see "<p><a href=\"/2019/02/05/hello-again.html\">Post 2</a></p>" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: Calling for a post via a liquid variable
|
||||||
|
Given I have a _posts directory
|
||||||
|
And I have the following post:
|
||||||
|
| title | date | content |
|
||||||
|
| Hello World | 2019-02-04 | Lorem ipsum dolor |
|
||||||
|
And I have an "index.md" page with content:
|
||||||
|
"""
|
||||||
|
{% assign value='2019-02-04-hello-world' %}
|
||||||
|
[Welcome]({% post_url {{ value }} %})
|
||||||
|
"""
|
||||||
|
When I run jekyll build
|
||||||
|
Then I should get a zero exit status
|
||||||
|
And the _site directory should exist
|
||||||
|
And I should see "<p><a href=\"/2019/02/04/hello-world.html\">Welcome</a></p>" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: Calling for posts via a liquid variable in a for tag
|
||||||
|
Given I have a _posts directory
|
||||||
|
And I have the following post:
|
||||||
|
| title | date | content |
|
||||||
|
| Hello World | 2019-02-04 | Lorem ipsum dolor |
|
||||||
|
| We Meet Again | 2019-02-05 | Alpha beta gamma |
|
||||||
|
And I have an "index.md" page with content:
|
||||||
|
"""
|
||||||
|
{% assign posts = '2019-02-04-hello-world;2019-02-05-we-meet-again' | split: ';' %}
|
||||||
|
{%- for slug in posts -%}
|
||||||
|
[{{ slug }}]({% post_url {{ slug }} %})
|
||||||
|
{%- endfor %}
|
||||||
|
"""
|
||||||
|
When I run jekyll build
|
||||||
|
Then I should get a zero exit status
|
||||||
|
And the _site directory should exist
|
||||||
|
And I should see "<a href=\"/2019/02/04/hello-world.html\">2019-02-04-hello-world</a>" in "_site/index.html"
|
||||||
|
And I should see "<a href=\"/2019/02/05/we-meet-again.html\">2019-02-05-we-meet-again</a>" in "_site/index.html"
|
||||||
|
|
|
@ -185,7 +185,8 @@ module Jekyll
|
||||||
#
|
#
|
||||||
# Returns true if the 'write' metadata is true, false otherwise.
|
# Returns true if the 'write' metadata is true, false otherwise.
|
||||||
def write?
|
def write?
|
||||||
!!metadata.fetch("output", false)
|
!!metadata.fetch("output", false) &&
|
||||||
|
(site.target == metadata.fetch("target", site.target))
|
||||||
end
|
end
|
||||||
|
|
||||||
# The URL template to render collection's documents at.
|
# The URL template to render collection's documents at.
|
||||||
|
|
|
@ -243,7 +243,7 @@ module Jekyll
|
||||||
def format_url(ssl_enabled, address, port, baseurl = nil)
|
def format_url(ssl_enabled, address, port, baseurl = nil)
|
||||||
format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
|
format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
|
||||||
:prefix => ssl_enabled ? "https" : "http",
|
:prefix => ssl_enabled ? "https" : "http",
|
||||||
:address => address,
|
:address => address.include?(":") ? "[#{address}]" : address,
|
||||||
:port => port,
|
:port => port,
|
||||||
:baseurl => baseurl ? "#{baseurl}/" : "")
|
:baseurl => baseurl ? "#{baseurl}/" : "")
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,8 +55,9 @@ module Jekyll
|
||||||
EM.schedule { @started_event.set }
|
EM.schedule { @started_event.set }
|
||||||
EM.add_shutdown_hook { @stopped_event.set }
|
EM.add_shutdown_hook { @stopped_event.set }
|
||||||
|
|
||||||
|
host = opts["host"].include?(":") ? "[#{opts["host"]}]" : opts["host"]
|
||||||
Jekyll.logger.info "LiveReload address:",
|
Jekyll.logger.info "LiveReload address:",
|
||||||
"http://#{opts["host"]}:#{opts["livereload_port"]}"
|
"http://#{host}:#{opts["livereload_port"]}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@thread.abort_on_exception = true
|
@thread.abort_on_exception = true
|
||||||
|
|
|
@ -30,6 +30,7 @@ module Jekyll
|
||||||
"limit_posts" => 0,
|
"limit_posts" => 0,
|
||||||
"future" => false,
|
"future" => false,
|
||||||
"unpublished" => false,
|
"unpublished" => false,
|
||||||
|
"target" => "default",
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
"whitelist" => [],
|
"whitelist" => [],
|
||||||
|
|
|
@ -348,17 +348,20 @@ module Jekyll
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determine whether this document should be written.
|
# 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?
|
# 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.
|
# False otherwise.
|
||||||
#
|
#
|
||||||
# rubocop:disable Naming/MemoizedInstanceVariableName
|
# rubocop:disable Naming/MemoizedInstanceVariableName
|
||||||
def write?
|
def write?
|
||||||
return @write_p if defined?(@write_p)
|
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
|
end
|
||||||
# rubocop:enable Naming/MemoizedInstanceVariableName
|
# rubocop:enable Naming/MemoizedInstanceVariableName
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ module Jekyll
|
||||||
private delegate_method_as :data, :fallback_data
|
private delegate_method_as :data, :fallback_data
|
||||||
|
|
||||||
delegate_methods :id, :output, :content, :to_s, :relative_path, :url, :date
|
delegate_methods :id, :output, :content, :to_s, :relative_path, :url, :date
|
||||||
data_delegators "title", "categories", "tags"
|
data_delegators "title", "categories", "tags", :target
|
||||||
|
|
||||||
def collection
|
def collection
|
||||||
@obj.collection.label
|
@obj.collection.label
|
||||||
|
|
|
@ -109,7 +109,7 @@ module Jekyll
|
||||||
sanitized_path = sanitize_path(path)
|
sanitized_path = sanitize_path(path)
|
||||||
|
|
||||||
if rel_scope_path.include?("*")
|
if rel_scope_path.include?("*")
|
||||||
File.fnmatch?(strip_collections_dir(rel_scope_path), sanitized_path)
|
glob_scope(sanitized_path, rel_scope_path)
|
||||||
else
|
else
|
||||||
path_is_subpath?(sanitized_path, strip_collections_dir(rel_scope_path))
|
path_is_subpath?(sanitized_path, strip_collections_dir(rel_scope_path))
|
||||||
end
|
end
|
||||||
|
|
|
@ -180,7 +180,7 @@ module Jekyll
|
||||||
end
|
end
|
||||||
|
|
||||||
def write?
|
def write?
|
||||||
true
|
site.config["target"] == data.fetch("target", site.config["target"])
|
||||||
end
|
end
|
||||||
|
|
||||||
def excerpt_separator
|
def excerpt_separator
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Jekyll
|
||||||
:file_read_opts, :future, :gems, :generators, :highlighter,
|
:file_read_opts, :future, :gems, :generators, :highlighter,
|
||||||
:include, :inclusions, :keep_files, :layouts, :limit_posts,
|
:include, :inclusions, :keep_files, :layouts, :limit_posts,
|
||||||
:lsi, :pages, :permalink_style, :plugin_manager, :plugins,
|
: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
|
:unpublished
|
||||||
|
|
||||||
attr_reader :cache_dir, :config, :dest, :filter_cache, :includes_load_paths,
|
attr_reader :cache_dir, :config, :dest, :filter_cache, :includes_load_paths,
|
||||||
|
@ -47,7 +47,7 @@ module Jekyll
|
||||||
def config=(config)
|
def config=(config)
|
||||||
@config = config.clone
|
@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|
|
show_drafts limit_posts keep_files).each do |opt|
|
||||||
send(:"#{opt}=", config[opt])
|
send(:"#{opt}=", config[opt])
|
||||||
end
|
end
|
||||||
|
@ -360,7 +360,7 @@ module Jekyll
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_site_file
|
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? }
|
static_files.each { |file| yield(file) if file.write? }
|
||||||
collections.each_value { |coll| coll.docs.each { |doc| yield(doc) if doc.write? } }
|
collections.each_value { |coll| coll.docs.each { |doc| yield(doc) if doc.write? } }
|
||||||
end
|
end
|
||||||
|
|
|
@ -249,6 +249,11 @@ module Jekyll
|
||||||
end
|
end
|
||||||
|
|
||||||
class IncludeRelativeTag < IncludeTag
|
class IncludeRelativeTag < IncludeTag
|
||||||
|
def load_cached_partial(path, context)
|
||||||
|
context.registers[:cached_partials] ||= {}
|
||||||
|
context.registers[:cached_partials][path] ||= parse_partial(path, context)
|
||||||
|
end
|
||||||
|
|
||||||
def tag_includes_dirs(context)
|
def tag_includes_dirs(context)
|
||||||
Array(page_path(context)).freeze
|
Array(page_path(context)).freeze
|
||||||
end
|
end
|
||||||
|
@ -267,6 +272,17 @@ module Jekyll
|
||||||
path = File.join(site.config["collections_dir"], path) if page["collection"]
|
path = File.join(site.config["collections_dir"], path) if page["collection"]
|
||||||
path.delete_suffix("/#excerpt")
|
path.delete_suffix("/#excerpt")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Since Jekyll 4 caches convertibles based on their path within the only instance of
|
||||||
|
# `LiquidRenderer`, initialize a new LiquidRenderer instance on every render of this
|
||||||
|
# tag to bypass caching rendered output of page / document.
|
||||||
|
def parse_partial(path, context)
|
||||||
|
LiquidRenderer.new(context.registers[:site]).file(path).parse(read_file(path, context))
|
||||||
|
rescue Liquid::Error => e
|
||||||
|
e.template_name = path
|
||||||
|
e.markup_context = "included " if e.markup_context.nil?
|
||||||
|
raise e
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,34 +3,39 @@
|
||||||
module Jekyll
|
module Jekyll
|
||||||
module Tags
|
module Tags
|
||||||
class PostComparer
|
class PostComparer
|
||||||
|
# Deprecated (soft; No interpreter warnings).
|
||||||
|
# To be removed in v5.0.
|
||||||
|
# Use private constant `POST_PATH_MATCHER` instead.
|
||||||
MATCHER = %r!^(.+/)*(\d+-\d+-\d+)-(.*)$!.freeze
|
MATCHER = %r!^(.+/)*(\d+-\d+-\d+)-(.*)$!.freeze
|
||||||
|
|
||||||
|
POST_PATH_MATCHER = %r!\A(.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)\z!.freeze
|
||||||
|
private_constant :POST_PATH_MATCHER
|
||||||
|
|
||||||
attr_reader :path, :date, :slug, :name
|
attr_reader :path, :date, :slug, :name
|
||||||
|
|
||||||
def initialize(name)
|
def initialize(name)
|
||||||
@name = name
|
@name = name
|
||||||
|
|
||||||
all, @path, @date, @slug = *name.sub(%r!^/!, "").match(MATCHER)
|
all, @path, @date, @slug = *name.delete_prefix("/").match(POST_PATH_MATCHER)
|
||||||
unless all
|
unless all
|
||||||
raise Jekyll::Errors::InvalidPostNameError,
|
raise Jekyll::Errors::InvalidPostNameError,
|
||||||
"'#{name}' does not contain valid date and/or title."
|
"'#{name}' does not contain valid date and/or title."
|
||||||
end
|
end
|
||||||
|
|
||||||
basename_pattern = "#{date}-#{Regexp.escape(slug)}\\.[^.]+"
|
basename_pattern = "#{date}-#{Regexp.escape(slug)}\\.[^.]+"
|
||||||
@name_regex = %r!^_posts/#{path}#{basename_pattern}|^#{path}_posts/?#{basename_pattern}!
|
@name_regex = %r!\A_posts/#{path}#{basename_pattern}|\A#{path}_posts/?#{basename_pattern}!
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_date
|
def post_date
|
||||||
@post_date ||= Utils.parse_date(
|
@post_date ||= Utils.parse_date(date, "Path '#{name}' does not contain valid date.")
|
||||||
date,
|
|
||||||
"'#{date}' does not contain valid date and/or title."
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns `MatchData` or `nil`.
|
||||||
def ==(other)
|
def ==(other)
|
||||||
other.relative_path.match(@name_regex)
|
other.relative_path.match(@name_regex)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Deprecated. To be removed in v5.0.
|
||||||
def deprecated_equality(other)
|
def deprecated_equality(other)
|
||||||
slug == post_slug(other) &&
|
slug == post_slug(other) &&
|
||||||
post_date.year == other.date.year &&
|
post_date.year == other.date.year &&
|
||||||
|
@ -40,9 +45,9 @@ module Jekyll
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Construct the directory-aware post slug for a Jekyll::Post
|
# Construct the directory-aware post slug for a Jekyll::Document object.
|
||||||
#
|
#
|
||||||
# other - the Jekyll::Post
|
# other - the Jekyll::Document object.
|
||||||
#
|
#
|
||||||
# Returns the post slug with the subdirectory (relative to _posts)
|
# Returns the post slug with the subdirectory (relative to _posts)
|
||||||
def post_slug(other)
|
def post_slug(other)
|
||||||
|
@ -58,47 +63,71 @@ module Jekyll
|
||||||
class PostUrl < Liquid::Tag
|
class PostUrl < Liquid::Tag
|
||||||
include Jekyll::Filters::URLFilters
|
include Jekyll::Filters::URLFilters
|
||||||
|
|
||||||
def initialize(tag_name, post, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
super
|
super
|
||||||
@orig_post = post.strip
|
@markup = markup.strip
|
||||||
begin
|
@template = Liquid::Template.parse(@markup) if @markup.include?("{{")
|
||||||
@post = PostComparer.new(@orig_post)
|
|
||||||
rescue StandardError => e
|
# Deprecated instance_variables.
|
||||||
raise Jekyll::Errors::PostURLError, <<~MSG
|
# To be removed in Jekyll v5.0.
|
||||||
Could not parse name of post "#{@orig_post}" in tag 'post_url'.
|
@orig_post = @markup
|
||||||
Make sure the post exists and the name is correct.
|
@post = nil
|
||||||
#{e.class}: #{e.message}
|
|
||||||
MSG
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
@context = context
|
@context = context
|
||||||
|
@resolved_markup = @template&.render(@context) || @markup
|
||||||
site = context.registers[:site]
|
site = context.registers[:site]
|
||||||
|
|
||||||
site.posts.docs.each do |document|
|
begin
|
||||||
return relative_url(document) if @post == document
|
@post_comparer = PostComparer.new(@resolved_markup)
|
||||||
|
rescue StandardError
|
||||||
|
raise_markup_parse_error
|
||||||
|
end
|
||||||
|
# For backwards compatibility only; deprecated instance_variable.
|
||||||
|
# To be removed in Jekyll v5.0.
|
||||||
|
@post = @post_comparer
|
||||||
|
|
||||||
|
# First pass-through.
|
||||||
|
site.posts.docs.each do |post|
|
||||||
|
return relative_url(post) if @post_comparer == post
|
||||||
end
|
end
|
||||||
|
|
||||||
# New matching method did not match, fall back to old method
|
# First pass-through did not yield the requested post. Search again using legacy matching
|
||||||
# with deprecation warning if this matches
|
# method. Log deprecation warning if a post is detected via this round.
|
||||||
|
site.posts.docs.each do |post|
|
||||||
|
next unless @post_comparer.deprecated_equality(post)
|
||||||
|
|
||||||
site.posts.docs.each do |document|
|
log_legacy_usage_deprecation
|
||||||
next unless @post.deprecated_equality document
|
return relative_url(post)
|
||||||
|
|
||||||
Jekyll::Deprecator.deprecation_message(
|
|
||||||
"A call to '{% post_url #{@post.name} %}' did not match a post using the new " \
|
|
||||||
"matching method of checking name (path-date-slug) equality. Please make sure " \
|
|
||||||
"that you change this tag to match the post's name exactly."
|
|
||||||
)
|
|
||||||
return relative_url(document)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
raise_post_not_found_error
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def raise_markup_parse_error
|
||||||
raise Jekyll::Errors::PostURLError, <<~MSG
|
raise Jekyll::Errors::PostURLError, <<~MSG
|
||||||
Could not find post "#{@orig_post}" in tag 'post_url'.
|
Could not parse name of post #{@resolved_markup.inspect} in tag 'post_url'.
|
||||||
Make sure the post exists and the name is correct.
|
Make sure the correct name is given to the tag.
|
||||||
MSG
|
MSG
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def raise_post_not_found_error
|
||||||
|
raise Jekyll::Errors::PostURLError, <<~MSG
|
||||||
|
Could not find post #{@resolved_markup.inspect} in tag 'post_url'.
|
||||||
|
Make sure the post exists and the correct name is given to the tag.
|
||||||
|
MSG
|
||||||
|
end
|
||||||
|
|
||||||
|
def log_legacy_usage_deprecation
|
||||||
|
Jekyll::Deprecator.deprecation_message(
|
||||||
|
"A call to '{% post_url #{@resolved_markup} %}' did not match a post using the new " \
|
||||||
|
"matching method of checking name (path-date-slug) equality. Please make sure that " \
|
||||||
|
"you change this tag to match the post's name exactly."
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -144,7 +144,13 @@ module Jekyll
|
||||||
# pct-encoded = "%" HEXDIG HEXDIG
|
# pct-encoded = "%" HEXDIG HEXDIG
|
||||||
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
# / "*" / "+" / "," / ";" / "="
|
# / "*" / "+" / "," / ";" / "="
|
||||||
Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
|
#
|
||||||
|
# `Addressable::URI::CharacterClassesRegexps::PATH` is used to encode
|
||||||
|
# non-alphanumeric characters such as "[", "]", etc.
|
||||||
|
Addressable::URI.encode_component(
|
||||||
|
path,
|
||||||
|
Addressable::URI::CharacterClassesRegexps::PATH
|
||||||
|
).encode("utf-8").sub("#", "%23")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Unescapes a URL path segment
|
# Unescapes a URL path segment
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Jekyll
|
module Jekyll
|
||||||
VERSION = "4.4.0"
|
VERSION = "4.4.1"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<svg></svg>
|
|
Before Width: | Height: | Size: 13 B |
|
@ -1,3 +0,0 @@
|
||||||
---
|
|
||||||
speciality: Ruby
|
|
||||||
---
|
|
|
@ -1 +0,0 @@
|
||||||
<svg></svg>
|
|
Before Width: | Height: | Size: 13 B |
|
@ -1,3 +0,0 @@
|
||||||
---
|
|
||||||
speciality: JS Frameworks
|
|
||||||
---
|
|
|
@ -25,6 +25,10 @@ class TestFrontMatterDefaults < JekyllUnitTest
|
||||||
assert_equal "val", @affected.data["key"]
|
assert_equal "val", @affected.data["key"]
|
||||||
assert_nil @not_affected.data["key"]
|
assert_nil @not_affected.data["key"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "not call Dir.glob block" do
|
||||||
|
refute_includes @output, "Globbed Scope Path:"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "A site with full front matter defaults (glob)" do
|
context "A site with full front matter defaults (glob)" do
|
||||||
|
@ -49,38 +53,9 @@ class TestFrontMatterDefaults < JekyllUnitTest
|
||||||
assert_equal "val", @affected.data["key"]
|
assert_equal "val", @affected.data["key"]
|
||||||
assert_nil @not_affected.data["key"]
|
assert_nil @not_affected.data["key"]
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context "A site with collections and front matter defaults with glob patterns" do
|
should "call Dir.glob block" do
|
||||||
setup do
|
assert_includes @output, "Globbed Scope Path:"
|
||||||
site = fixture_site(
|
|
||||||
"collections_dir" => "gathering",
|
|
||||||
"collections" => { "staff" => { "output" => true } },
|
|
||||||
"defaults" => [
|
|
||||||
{
|
|
||||||
"scope" => { "path" => "_staff/**/*.md", "type" => "staff" },
|
|
||||||
"values" => { "layout" => "simple" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"scope" => { "path" => "_staff/**/*.svg" },
|
|
||||||
"values" => { "css_class" => "epilson" },
|
|
||||||
},
|
|
||||||
]
|
|
||||||
)
|
|
||||||
site.read
|
|
||||||
@staff = site.collections["staff"]
|
|
||||||
end
|
|
||||||
|
|
||||||
should "affect the appropriate items only" do
|
|
||||||
@staff.docs.each do |item|
|
|
||||||
assert_equal "simple", item.data["layout"]
|
|
||||||
assert_nil item.data["css_class"]
|
|
||||||
end
|
|
||||||
|
|
||||||
@staff.files.each do |item|
|
|
||||||
assert_equal "epilson", item.data["css_class"]
|
|
||||||
assert_nil item.data["layout"]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -80,5 +80,16 @@ class TestURL < JekyllUnitTest
|
||||||
).to_s
|
).to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "not treat colons in placeholders as uri delimiters" do
|
||||||
|
assert_equal "/foo/foo%20bar:foobar/", URL.new(
|
||||||
|
:template => "/:x/:y/",
|
||||||
|
:placeholders => { :x => "foo", :y => "foo bar:foobar" }
|
||||||
|
).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
should "unescape urls with colons" do
|
||||||
|
assert_equal "/foo/foo bar:foobar/", Jekyll::URL.unescape_path("/foo/foo%20bar:foobar/")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue