为什么这个 Jekyll 插件抛出异常?
Why is this Jekyll plugin throwing an exception?
我有一个 Jekyll 网站,我需要在其中显示网站内各种文件的来源。为此,我尝试在我的模板中使用 {% include filename %}
。然而,Liquid 标签 include
只接受 _includes
下的路径。最初,我将我的项目根链接到 _includes
下的路径。这行得通,但它使构建速度非常慢,因为 Jekyll 需要很长时间才能确定项目中存在无限递归符号链接。
现在,我决定更好的方法是编写一个插件来制作一个 full_include
标签,该标签将接受相对于项目基目录的任何路径。这是代码:
#!/usr/bin/env ruby
module MyIncludes
class FullIncludeTag < Liquid::Tag
def initialize(tag_name, filename, other)
super
$stderr.puts "===DEBUG=== Plugin FullIncludeTag initialized. Arguments:\n\ttag_name:\t#{tag_name}\n\tfilename:\t#{filename}\n\tother:\t#{other}"
items = Dir.children(Dir.pwd)
unless items.include?('_config.yml') and items.include('_includes')
raise RuntimeError, "The working directory doesn't appear to be Jekyll's base directory!"
end
@filename = "#{Dir.pwd}/#{filename}"
end
def render(context)
$stderr.puts "===DEBUG=== Plugin FullIncludeTag render beginning.\n\tcontext:\t#{context}\n\tfilename:\t#{@filename}"
# The following two lines produce the exact same output the first time the plugin is called.
$stderr.puts "#{Dir.pwd}/resume/portfolio_entries/raw/dice.py"
$stderr.puts @filename
# File.open "#{Dir.pwd}/resume/portfolio_entries/raw/dice.py" do |f|
# return f.read
# end
File.open @filename do |f|
return f.read.chomp
end
end
end
end
Liquid::Template.register_tag('full_include', MyIncludes::FullIncludeTag)
我的Ruby技能已经生疏得令人难以置信,因为我已经写了很多年了,但我似乎找不到这里的问题。这是正在发生的事情:
使用提供的代码,Jekyll 产生以下输出:
===DEBUG=== Plugin FullIncludeTag render beginning.
context: #<Liquid::Context:0x018ee008>
filename: /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py
/home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py
/home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py
Liquid Exception: No such file or directory @ rb_sysopen - /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py in resume/portfolio_entries/dice.html
jekyll 3.8.4 | Error: No such file or directory @ rb_sysopen - /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py
如果我切换哪个 File.open
块被注释掉,那么异常就会消失。当然,由于路径是硬编码的,所以我只在第一次使用 {% full_include %}
时得到正确的内容,但这是可以预料的。
请特别注意,代码注释中突出显示的两个 $stderr.puts
调用在任一变体中产生相同的输出(至少对于使用硬编码路径调用的 liquid 标签)。因此,我想不出为什么一个调用有效而另一个失败的原因。有什么想法吗?
我唯一能想到的是你在@filename 的末尾有 space。
我有一个 Jekyll 网站,我需要在其中显示网站内各种文件的来源。为此,我尝试在我的模板中使用 {% include filename %}
。然而,Liquid 标签 include
只接受 _includes
下的路径。最初,我将我的项目根链接到 _includes
下的路径。这行得通,但它使构建速度非常慢,因为 Jekyll 需要很长时间才能确定项目中存在无限递归符号链接。
现在,我决定更好的方法是编写一个插件来制作一个 full_include
标签,该标签将接受相对于项目基目录的任何路径。这是代码:
#!/usr/bin/env ruby
module MyIncludes
class FullIncludeTag < Liquid::Tag
def initialize(tag_name, filename, other)
super
$stderr.puts "===DEBUG=== Plugin FullIncludeTag initialized. Arguments:\n\ttag_name:\t#{tag_name}\n\tfilename:\t#{filename}\n\tother:\t#{other}"
items = Dir.children(Dir.pwd)
unless items.include?('_config.yml') and items.include('_includes')
raise RuntimeError, "The working directory doesn't appear to be Jekyll's base directory!"
end
@filename = "#{Dir.pwd}/#{filename}"
end
def render(context)
$stderr.puts "===DEBUG=== Plugin FullIncludeTag render beginning.\n\tcontext:\t#{context}\n\tfilename:\t#{@filename}"
# The following two lines produce the exact same output the first time the plugin is called.
$stderr.puts "#{Dir.pwd}/resume/portfolio_entries/raw/dice.py"
$stderr.puts @filename
# File.open "#{Dir.pwd}/resume/portfolio_entries/raw/dice.py" do |f|
# return f.read
# end
File.open @filename do |f|
return f.read.chomp
end
end
end
end
Liquid::Template.register_tag('full_include', MyIncludes::FullIncludeTag)
我的Ruby技能已经生疏得令人难以置信,因为我已经写了很多年了,但我似乎找不到这里的问题。这是正在发生的事情:
使用提供的代码,Jekyll 产生以下输出:
===DEBUG=== Plugin FullIncludeTag render beginning. context: #<Liquid::Context:0x018ee008> filename: /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py Liquid Exception: No such file or directory @ rb_sysopen - /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py in resume/portfolio_entries/dice.html jekyll 3.8.4 | Error: No such file or directory @ rb_sysopen - /home/scott/Main Sync/websites/scottseverance.mss/resume/portfolio_entries/raw/dice.py
如果我切换哪个
File.open
块被注释掉,那么异常就会消失。当然,由于路径是硬编码的,所以我只在第一次使用{% full_include %}
时得到正确的内容,但这是可以预料的。
请特别注意,代码注释中突出显示的两个 $stderr.puts
调用在任一变体中产生相同的输出(至少对于使用硬编码路径调用的 liquid 标签)。因此,我想不出为什么一个调用有效而另一个失败的原因。有什么想法吗?
我唯一能想到的是你在@filename 的末尾有 space。