Initialize include-files as Jekyll objects (#8158)
Merge pull request 8158
This commit is contained in:
parent
2f4c73f38c
commit
1292dcc24a
|
@ -55,6 +55,7 @@ module Jekyll
|
|||
autoload :FrontmatterDefaults, "jekyll/frontmatter_defaults"
|
||||
autoload :Hooks, "jekyll/hooks"
|
||||
autoload :Layout, "jekyll/layout"
|
||||
autoload :Inclusion, "jekyll/inclusion"
|
||||
autoload :Cache, "jekyll/cache"
|
||||
autoload :CollectionReader, "jekyll/readers/collection_reader"
|
||||
autoload :DataReader, "jekyll/readers/data_reader"
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Inclusion
|
||||
attr_reader :site, :name, :path
|
||||
private :site
|
||||
|
||||
def initialize(site, base, name)
|
||||
@site = site
|
||||
@name = name
|
||||
@path = PathManager.join(base, name)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
@template ||= site.liquid_renderer.file(path).parse(content)
|
||||
@template.render!(context)
|
||||
rescue Liquid::Error => e
|
||||
e.template_name = path
|
||||
e.markup_context = "included " if e.markup_context.nil?
|
||||
raise e
|
||||
end
|
||||
|
||||
def content
|
||||
@content ||= File.read(path, **site.file_read_opts)
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#{self.class} #{path.inspect}"
|
||||
end
|
||||
alias_method :to_s, :inspect
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@
|
|||
module Jekyll
|
||||
class Site
|
||||
attr_reader :source, :dest, :cache_dir, :config
|
||||
attr_accessor :layouts, :pages, :static_files, :drafts,
|
||||
attr_accessor :layouts, :pages, :static_files, :drafts, :inclusions,
|
||||
:exclude, :include, :lsi, :highlighter, :permalink_style,
|
||||
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
|
||||
|
@ -86,6 +86,7 @@ module Jekyll
|
|||
Jekyll.logger.info @liquid_renderer.stats_table
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
#
|
||||
# Reset Site details.
|
||||
|
@ -98,6 +99,7 @@ module Jekyll
|
|||
Time.now
|
||||
end
|
||||
self.layouts = {}
|
||||
self.inclusions = {}
|
||||
self.pages = []
|
||||
self.static_files = []
|
||||
self.data = {}
|
||||
|
@ -117,6 +119,7 @@ module Jekyll
|
|||
Jekyll::Hooks.trigger :site, :after_reset, self
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
# Load necessary libraries, plugins, converters, and generators.
|
||||
#
|
||||
|
|
|
@ -18,12 +18,13 @@ module Jekyll
|
|||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
matched = markup.strip.match(VARIABLE_SYNTAX)
|
||||
markup = markup.strip
|
||||
matched = markup.match(VARIABLE_SYNTAX)
|
||||
if matched
|
||||
@file = matched["variable"].strip
|
||||
@params = matched["params"].strip
|
||||
else
|
||||
@file, @params = markup.strip.split(%r!\s+!, 2)
|
||||
@file, @params = markup.split(%r!\s+!, 2)
|
||||
end
|
||||
validate_params if @params
|
||||
@tag_name = tag_name
|
||||
|
@ -192,6 +193,60 @@ module Jekyll
|
|||
end
|
||||
end
|
||||
|
||||
# Do not inherit from this class.
|
||||
# TODO: Merge into the `Jekyll::Tags::IncludeTag` in v5.0
|
||||
class OptimizedIncludeTag < IncludeTag
|
||||
def render(context)
|
||||
@site ||= context.registers[:site]
|
||||
|
||||
file = render_variable(context) || @file
|
||||
validate_file_name(file)
|
||||
|
||||
@site.inclusions[file] ||= locate_include_file(file)
|
||||
inclusion = @site.inclusions[file]
|
||||
|
||||
add_include_to_dependency(inclusion, context) if @site.incremental?
|
||||
|
||||
context.stack do
|
||||
context["include"] = parse_params(context) if @params
|
||||
inclusion.render(context)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def locate_include_file(file)
|
||||
@site.includes_load_paths.each do |dir|
|
||||
path = PathManager.join(dir, file)
|
||||
return Inclusion.new(@site, dir, file) if valid_include_file?(path, dir)
|
||||
end
|
||||
raise IOError, could_not_locate_message(file, @site.includes_load_paths, @site.safe)
|
||||
end
|
||||
|
||||
def valid_include_file?(path, dir)
|
||||
File.file?(path) && !outside_scope?(path, dir)
|
||||
end
|
||||
|
||||
def outside_scope?(path, dir)
|
||||
@site.safe && !realpath_prefixed_with?(path, dir)
|
||||
end
|
||||
|
||||
def realpath_prefixed_with?(path, dir)
|
||||
File.realpath(path).start_with?(dir)
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
|
||||
def add_include_to_dependency(inclusion, context)
|
||||
return unless context.registers[:page]&.key?("path")
|
||||
|
||||
@site.regenerator.add_dependency(
|
||||
@site.in_source_dir(context.registers[:page]["path"]),
|
||||
inclusion.path
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class IncludeRelativeTag < IncludeTag
|
||||
def tag_includes_dirs(context)
|
||||
Array(page_path(context)).freeze
|
||||
|
@ -217,5 +272,5 @@ module Jekyll
|
|||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("include", Jekyll::Tags::IncludeTag)
|
||||
Liquid::Template.register_tag("include", Jekyll::Tags::OptimizedIncludeTag)
|
||||
Liquid::Template.register_tag("include_relative", Jekyll::Tags::IncludeRelativeTag)
|
||||
|
|
Loading…
Reference in New Issue