Skip to content

Commit

Permalink
Initialize include-files as Jekyll objects (#8158)
Browse files Browse the repository at this point in the history
Merge pull request 8158
  • Loading branch information
ashmaroli committed May 25, 2020
1 parent 2f4c73f commit 1292dcc
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 4 deletions.
1 change: 1 addition & 0 deletions lib/jekyll.rb
Expand Up @@ -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"
Expand Down
32 changes: 32 additions & 0 deletions lib/jekyll/inclusion.rb
@@ -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
5 changes: 4 additions & 1 deletion lib/jekyll/site.rb
Expand Up @@ -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,
Expand Down Expand Up @@ -86,6 +86,7 @@ def print_stats
Jekyll.logger.info @liquid_renderer.stats_table
end

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
#
# Reset Site details.
Expand All @@ -98,6 +99,7 @@ def reset
Time.now
end
self.layouts = {}
self.inclusions = {}
self.pages = []
self.static_files = []
self.data = {}
Expand All @@ -117,6 +119,7 @@ def reset
Jekyll::Hooks.trigger :site, :after_reset, self
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize

# Load necessary libraries, plugins, converters, and generators.
#
Expand Down
61 changes: 58 additions & 3 deletions lib/jekyll/tags/include.rb
Expand Up @@ -18,12 +18,13 @@ class IncludeTag < Liquid::Tag

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
Expand Down Expand Up @@ -192,6 +193,60 @@ def could_not_locate_message(file, includes_dirs, safe)
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
Expand All @@ -217,5 +272,5 @@ def page_path(context)
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)

0 comments on commit 1292dcc

Please sign in to comment.