Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jekyll Page data does not persist

Jekyll version 2.5.3

We are trying to write a plugin to promote content that is agnostic as to whether or not its a page or a post. However there is some difference between pages and posts that is not clear.

  # this does not work
  site.pages.each do |page|
    # this does not show up in liquid
    page.data['baz'] = 'Foo'
  end

  # this does work
  site.posts.each do |post|
    # this does show up in liquid
    post.data['baz'] = 'Bar'
  end

Any ideas as to why mutating the .data hash for posts is accessible in liquid, but mutating the .data hash for pages has no effect?

We've also tested this with .data["title"] and it has an effect on posts but page titles are uneffected.


{% for post in site.posts %}
   <div class="postbaz">{{ post.baz }}</div>
{% endfor %}

{% for page in site.pages %}
   <div class="pagebaz">{{ page.baz }}</div>
{% endfor %}

yields

<div class="postbaz">Foo</div>
<div class="postbaz">Foo</div>
<div class="postbaz">Foo</div>
<div class="pagebaz"></div>
<div class="pagebaz"></div>
like image 539
Fresheyeball Avatar asked Jul 24 '15 22:07

Fresheyeball


1 Answers

You are missing something. Adding values to data works perfectly fine both for pages and posts.

See my repository for reference.

Here I add 'foo' attribute to all pages and posts

_plugins/foo.rb

module Foo
  class Generator < Jekyll::Generator
    def generate(site)
      puts "Our plugin is running"
      puts site.pages.inspect
      puts site.posts.inspect
      site.pages.each do |page|
        page.data['foo'] = 'bar'
      end
      site.posts.each do |post|
        post.data['foo'] = 'bar'
      end
    end
  end
end

Here I add 'foo' to posts layout:

post.html

<article class="post-content">
  {{ content }}
  {{ page.foo }}
</article>

And to pages layout:

page.html

<article class="post-content">
  {{ content }}
  {{ page.foo }}
</article>

After I ran jekyll b I can see output in both post and page, just where I expect them to be.

In separate branch I re-created your setup, where you iterate over all pages and posts:

default.html (source)

{% for post in site.posts %}
   <div class="postbaz">{{ post.foo }}</div>
{% endfor %}

{% for page in site.pages %}
   <div class="pagebaz">{{ page.foo }}</div>
{% endfor %}

_plugins/foo.rb (source)

site.pages.each do |page|
  page.data['foo'] = 'bar'
end
site.posts.each do |post|
  post.data['foo'] = 'baz'
end

(Notice the property is 'bar' for page, and 'baz' for post.)

It renders as expected:

site/index.html (source)

<div class="postbaz">baz</div>



<div class="pagebaz">bar</div>

<div class="pagebaz">bar</div>

<div class="pagebaz">bar</div>

<div class="pagebaz">bar</div>
like image 162
EugZol Avatar answered Oct 21 '22 03:10

EugZol