contentful / contentful_middleman

Contentful Middleman is an extension to use the Middleman static site generator (Ruby) together with the API-driven Contentful CMS.
https://www.contentful.com
MIT License
146 stars 35 forks source link

Method Missing when calling middleman contentful #84

Closed philipjabenton closed 8 years ago

philipjabenton commented 8 years ago

@dlitvakb

Here is the content of my config.rb file, it is fairly standard as I am just learning how to integrate Contentful with Middleman -

page '/*.xml', layout: false
page '/*.json', layout: false
page '/*.txt', layout: false

activate :autoprefixer do |prefix|
  prefix.browsers = ['last 2 versions']
end

configure :build do
end

activate :contentful do |f|
  f.access_token  = ''
  f.space         = { content: '' }
  f.content_types = { post: '', author: '' }
end

config[:css_dir] = 'assets/stylesheets'

config[:images_dir] = 'assets/images'

config[:js_dir] = 'assets/javascripts'

if data.respond_to? :content
  data.content.post.each do |id,post|
    proxy "post/#{post.slug}.html", "post/template.html", :locals => { :post => post }, :ignore => true
  end
end

As you will see above I have altered the code to include the respond_to? you suggested but this has not solved the problem.

What I am trying to do is leave my data folder out of git so before development or build I run middleman contentful to pull down the latest content and populate the data folder. However as you have said the config.rb file gets processed before contentful runs so results in a method missing error.

Any suggestions?

dlitvakb commented 8 years ago

Hey @philipbenton,

I'll be looking into it.

Cheers

dlitvakb commented 8 years ago

Hey @philipbenton,

Sorry I took so long to reply, was sunk on work.

Have you managed to fix this? Or should I still take a look?

philipjabenton commented 8 years ago

Hi @dlitvakb,

Please take a look if you could.

dlitvakb commented 8 years ago

Hey @philipbenton,

I tried with this config file, it's using the default blog template:

require 'contentful_middleman'

# These keys are read-only, and contain no sensible data, so try them at your will
activate :contentful do |f|
  f.access_token = "08396486ecccb80a209b598de29980d8c2b34b836f0dd0f9d3b39d26b31f03f2"
  f.space = {blog: "2yri4oy2f26b"}
  f.cda_query = {content_type: "2wKn6yEnZewu2SCCkus4as", include: 2}
  f.content_types = {post: "2wKn6yEnZewu2SCCkus4as"}
end

if data.respond_to? :blog
  data.blog.post.each do |id, post|
    proxy "post/#{post.slug}.html", "post/template.html", :locals => { :post => post }, :ignore => true
  end
end

set :css_dir, 'stylesheets'

set :js_dir, 'javascripts'

set :images_dir, 'images'

configure :build do
end

The output produced by the bundle exec middleman contentful --rebuild command is:

      create  data/blog/post/A96usFSlY4G0W4kwAqswk.yaml
      create  data/blog/post/1asN98Ph3mUiCYIYiiqwko.yaml
      create  build/images/middleman-logo.svg
      create  build/javascripts/all.js
      create  build/stylesheets/site.css.scss
== Instrument (render.resource): 3.591ms
      create  build/index.html
      create  build/post/down-the-rabbit-hole.html
      create  build/post/seven-tips-from-ernest-hemingway-on-how-to-write-fiction.html
Contentful Import: Done!

All that I needed to make it work, was in the /source directory, create a /posts sub directory with a file called template.html inside, in which I could use the Post as expected.

Please let me know if this helps.

philipjabenton commented 8 years ago

Hi @dlitvakb,

It is still not working for me. I have even tried with your config.rb file replacing mine and I still have the method missing error:

/Users/philipbenton/.rvm/gems/ruby-2.3.0/gems/middleman-core-4.1.6/lib/middleman-core/core_extensions/data.rb:176:in `method_missing': undefined method `blog' for #<Middleman::CoreExtensions::Data::DataStore:0x007ff32e1019f8> (NoMethodError)
dlitvakb commented 8 years ago

Ok, found a solution, this was a change introduced in Middleman v4, and I was unaware of it.

To fix, replace the data.respond_to? :content line to: Dir.exist?(config.data_dir)

Hope this helps

Cheers

philipjabenton commented 8 years ago

@dlitvakb Genius! Works perfectly.

Where did you discover the change?

dlitvakb commented 8 years ago

I looked through the middleman codebase 😅

wanderingcrow commented 7 years ago

Hello @dlitvakb, this used to work, but no longer seems to be. To use the example above, let's say I have no content entries for purplePenguins yet, but I will at some point, and I have this in my config file:

if Dir.exist?(config.data_dir)
  data.purplePenguins.post.each do |id, post|
    # whatever
  end
end

In this case, executing middleman contentful just throws errors. Additionally, even if I have content for purplePenguins and I execute middleman contentful, this will throw errors unless I comment out the above code, import the data, then uncomment the code.

Does that make sense? Any help would be appreciated.

middleman-core (4.2.1) contentful_middleman (1.5.0)

dlitvakb commented 7 years ago

Hey @javaporter,

You'll have to do a Dir.exist? for every subfolder in the config.data_dir.

You can do something similar to the following:

['content_type_1', 'content_type_2', 'content_type_etc'].each do |content_type|
  if Dir.exist?(File.join(config.data_dir, 'your_space_alias', content_type))
    data.space_alias.send(content_type).each do |id, entry|
      # do stuff here
    end
  end
end

I'm not aware if there's any other way currently to achieve this in v4.

Hope this helps,

Cheers

wanderingcrow commented 7 years ago

@dlitvakb Works like a charm man, thanks for getting back to me so quickly and with such detailed instructions.