Почему этот плагин Jekyll выбрасывает исключение? - PullRequest
0 голосов
/ 08 января 2019

У меня есть сайт 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 невероятно ржавые, так как прошло много лет с тех пор, как я их написал, но, похоже, я не могу найти здесь проблему. Вот что происходит:

  1. С представленным кодом 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 
    
  2. Если я переключу, какой блок File.open закомментирован, исключения исчезнут. Конечно, поскольку путь жестко закодирован, я получаю только правильное содержимое для первого использования {% full_include %}, но этого следовало ожидать.

Обратите внимание, в частности, что два вызова $stderr.puts, выделенные в комментариях к коду, дают идентичный вывод в любом варианте (по крайней мере для тега liquid, вызываемого с жестко закодированным путем). Поэтому я не могу представить себе причину, по которой один вызов будет работать, а другой не удастся. Есть идеи?

1 Ответ

0 голосов
/ 08 января 2019

Единственное, о чем я могу думать, это то, что у вас есть пробел в конце @ filename.

...