rubyrubygemsjekylljekyll-extensions

`render': undefined method `access' when using jekyll multiple languages plugin


I'm trying to setup jekyll-multiple-languages-plugin for the first time.

The example website works, indeed. Although, my own website does not.

This is the output, whenever I run bundle exec jekyll serve --verbose:

/var/lib/gems/2.7.0/gems/jekyll-multiple-languages-plugin-1.7.0/lib/jekyll-multiple-languages-plugin.rb:360:in `render': undefined method `access' for false:FalseClass (NoMethodError)

liquid: <div class="intro-lead-in">{% t page.header.text %}</div>

pt.yml:

---
header:
  overlay: "no"
  text: It's Nice To Meet You
  button: Tell Me More
  buttonlink: "#services"
---

gemspec:

spec.required_ruby_version = '>= 2.5.0'
spec.add_runtime_dependency "jekyll", ">= 4.0", "< 4.3"
spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "rake", "~> 13.0"

_config.yml

plugins:
  - jekyll-multiple-languages-plugin

languages: ["en", "pt"]

exclude_from_localizations: ["assets", "favicon.ico"]

Solution

  • Since the exception is raised in the "jekyll-multiple-languages-plugin" gem let's have a quick look at the source.

    # lib/jekyll-multiple-languages-plugin.rb:360
    translation = site.parsed_translations[lang].access(key) if key.is_a?(String)
    

    In order to generate the message "undefined method `access' for false:FalseClass" it means that .access is called upon false. Because the above only has one access call it means that site.parsed_translations[lang] must evaluate to false.

    So how do you as library user influence this value? We'll first have to look at how this value came to be.

    # lib/jekyll-multiple-languages-plugin.rb:25
    site.parsed_translations[lang] = YAML.load_file("#{site.source}/_i18n/#{lang}.yml")
    

    This means that the false value is the return value of parsing one of your .yml files. The YAML.load_file documentation says the following about this return value:

    load_file(filename, fallback: false)

    Load the document contained in filename. Returns the yaml contained in filename as a Ruby object, or if the file is empty, it returns the specified fallback return value, which defaults to false.

    Here we can see that an empty file results in a false return value. So either your _i18n/pt.yml or _i18n/en.yml file is empty or the content within evaluates to false. Examples are YAML.load('false') #=> false and YAML.load('no') #=> false