Add PageDrop to provide Liquid templates with data (#7992)
Merge pull request 7992
This commit is contained in:
parent
a011579fe4
commit
b84ba5accc
|
@ -34,3 +34,38 @@ If you have a lot of pages, you can organize them into subfolders. The same subf
|
||||||
## Changing the output URL
|
## Changing the output URL
|
||||||
|
|
||||||
You might want to have a particular folder structure for your source files that changes for the built site. With [permalinks](/docs/permalinks) you have full control of the output URL.
|
You might want to have a particular folder structure for your source files that changes for the built site. With [permalinks](/docs/permalinks) you have full control of the output URL.
|
||||||
|
|
||||||
|
## Liquid Representation
|
||||||
|
|
||||||
|
From Jekyll 4.1 onwards, there is a minor change in how instances of `Jekyll::Page` are exposed to layouts and other Liquid
|
||||||
|
templates. `Jekyll::Page` instances now use a `Liquid::Drop` instead of a `Hash`. This change results in greater performance
|
||||||
|
for a site with numerous *standlone pages not within a collection*.
|
||||||
|
|
||||||
|
### For plugin developers
|
||||||
|
|
||||||
|
While end-users do not need to take any extra action due to this change, plugin authors depending on the existing behavior *may*
|
||||||
|
need to make minor changes to their plugins.
|
||||||
|
|
||||||
|
If a `Jekyll::Page` subclass' `to_liquid` method calls `super`, it will have to be slightly modified.
|
||||||
|
```ruby
|
||||||
|
class Foo::BarPage < Jekyll::Page
|
||||||
|
def to_liquid(*)
|
||||||
|
payload = super # This needs to be changed to `super.to_h`
|
||||||
|
# to obtain a Hash as in v4.0.0.
|
||||||
|
|
||||||
|
do_something(payload) # Logic specific to `Foo::BarPage` objects
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
`Jekyll::Page` subclasses won't inherit the optimization automatically until the next major version. However, plugin authors
|
||||||
|
can opt-in to the optimization in their subclasses by wrapping the temporary `liquid_drop` method if the subclass doesn't
|
||||||
|
override the superclass method:
|
||||||
|
```ruby
|
||||||
|
class Foo::BarPage < Jekyll::Page
|
||||||
|
def to_liquid(*)
|
||||||
|
liquid_drop # Returns an instance of `Jekyll::Drops::PageDrop`.
|
||||||
|
# Will be removed in Jekyll 5.0.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Jekyll
|
||||||
|
module Drops
|
||||||
|
class PageDrop < Drop
|
||||||
|
extend Forwardable
|
||||||
|
|
||||||
|
mutable false
|
||||||
|
|
||||||
|
def_delegators :@obj, :content, :dir, :name, :path, :url
|
||||||
|
private def_delegator :@obj, :data, :fallback_data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -70,6 +70,38 @@ module Jekyll
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# For backwards-compatibility in subclasses that do not redefine
|
||||||
|
# the `:to_liquid` method, stash existing definition under a new name
|
||||||
|
#
|
||||||
|
# TODO: Remove in Jekyll 5.0
|
||||||
|
alias_method :legacy_to_liquid, :to_liquid
|
||||||
|
private :legacy_to_liquid
|
||||||
|
|
||||||
|
# Private
|
||||||
|
# Subclasses can choose to optimize their `:to_liquid` method by wrapping
|
||||||
|
# it around this definition.
|
||||||
|
#
|
||||||
|
# TODO: Remove in Jekyll 5.0
|
||||||
|
def liquid_drop
|
||||||
|
@liquid_drop ||= begin
|
||||||
|
defaults = site.frontmatter_defaults.all(relative_path, type)
|
||||||
|
unless defaults.empty?
|
||||||
|
Utils.deep_merge_hashes!(data, Utils.deep_merge_hashes!(defaults, data))
|
||||||
|
end
|
||||||
|
Drops::PageDrop.new(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :liquid_drop
|
||||||
|
|
||||||
|
# Public
|
||||||
|
#
|
||||||
|
# Liquid representation of current page
|
||||||
|
#
|
||||||
|
# TODO: Remove optional parameter in Jekyll 5.0
|
||||||
|
def to_liquid(attrs = nil)
|
||||||
|
self.class == Jekyll::Page ? liquid_drop : legacy_to_liquid(attrs)
|
||||||
|
end
|
||||||
|
|
||||||
# The full path and filename of the post. Defined in the YAML of the post
|
# The full path and filename of the post. Defined in the YAML of the post
|
||||||
# body.
|
# body.
|
||||||
#
|
#
|
||||||
|
|
|
@ -50,6 +50,42 @@ class TestPage < JekyllUnitTest
|
||||||
assert_equal "/+/%25%23%20+.html", @page.url
|
assert_equal "/+/%25%23%20+.html", @page.url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "be exposed to Liquid as a Liquid::Drop subclass" do
|
||||||
|
page = setup_page("properties.html")
|
||||||
|
liquid_rep = page.to_liquid
|
||||||
|
refute_equal Hash, liquid_rep.class
|
||||||
|
assert_equal true, liquid_rep.is_a?(Liquid::Drop)
|
||||||
|
assert_equal Jekyll::Drops::PageDrop, liquid_rep.class
|
||||||
|
end
|
||||||
|
|
||||||
|
should "make attributes accessible for use in Liquid templates" do
|
||||||
|
page = setup_page("/contacts", "index.html")
|
||||||
|
template = Liquid::Template.parse(<<~TEXT)
|
||||||
|
Name: {{ page.name }}
|
||||||
|
Path: {{ page.path }}
|
||||||
|
URL: {{ page.url }}
|
||||||
|
TEXT
|
||||||
|
expected = <<~TEXT
|
||||||
|
Name: index.html
|
||||||
|
Path: contacts/index.html
|
||||||
|
URL: /contacts/
|
||||||
|
TEXT
|
||||||
|
assert_equal(expected, template.render!("page" => page.to_liquid))
|
||||||
|
end
|
||||||
|
|
||||||
|
should "make front matter data accessible for use in Liquid templates" do
|
||||||
|
page = setup_page("properties.html")
|
||||||
|
template = Liquid::Template.parse(<<~TEXT)
|
||||||
|
TITLE: {{ page.title }}
|
||||||
|
FOO: {{ page.foo }}
|
||||||
|
TEXT
|
||||||
|
expected = <<~TEXT
|
||||||
|
TITLE: Properties Page
|
||||||
|
FOO: bar
|
||||||
|
TEXT
|
||||||
|
assert_equal expected, template.render!("page" => page.to_liquid)
|
||||||
|
end
|
||||||
|
|
||||||
context "in a directory hierarchy" do
|
context "in a directory hierarchy" do
|
||||||
should "create URL based on filename" do
|
should "create URL based on filename" do
|
||||||
@page = setup_page("/contacts", "bar.html")
|
@page = setup_page("/contacts", "bar.html")
|
||||||
|
|
|
@ -76,6 +76,12 @@ class TestPageWithoutAFile < JekyllUnitTest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "be exposed to Liquid as a Hash" do
|
||||||
|
liquid_rep = @page.to_liquid
|
||||||
|
refute_equal Jekyll::Drops::PageDrop, liquid_rep.class
|
||||||
|
assert_equal Hash, liquid_rep.class
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with site-wide permalink configuration" do
|
context "with site-wide permalink configuration" do
|
||||||
|
|
Loading…
Reference in New Issue