blakeembrey / metalsmith-pagination

A Metalsmith plugin for paginating arrays and collections
MIT License
34 stars 10 forks source link

Contentful Integration #26

Closed bhardy closed 7 years ago

bhardy commented 7 years ago

Thanks for the awesome plugin. I'm new to Metalsmith so please forgive any ignorance, but I've been looking through your docs, the contentful-metalsmith docs, and the metalsmith-collections docs, trying to find a way to set up pagination on content that's coming from contentful. Is Metalsmith-collections a requirement for metalsmith-pagination? I know you don't explicitly say that, but each example I've found of metalsmith-pagination uses collections. I haven't found any evidence that collections and contentful are compatible.

I'm planning on using a javascript setup. I've forked the contentful-metalsmith-example (https://github.com/contentful-labs/contentful-metalsmith-example) and done some testing using our data and everything works fine, but I haven't had much luck with your plugin. Do you have any advice?

I won't get too into the detail of our setup and what I have and haven't tried unless you think it'll help answer the question.

Thanks again!

blakeembrey commented 7 years ago

No, there's no requirement for metalsmith-collections. This plugin only requires an array-like structure. Just change the key you want to use for pagination.

bhardy commented 7 years ago

Thanks for the quick reply. Maybe you can help me out. We're pulling in the data from contentful, and I figured I may need that data in a global variable, so I've set it up like this.

Metalsmith(__dirname)
  .source('source')
  .destination('build')
  .use(contentful({
    space_id: 'xxxx',
    access_token: 'xxxx',
    common: {
      posts: {
        content_type: '2wKn6yEnZewu2SCCkus4as'
      }
    }
  }))
  .use(pagination({
    'common.posts.items': {
      perPage: 3,
      template: 'index.html',
      first: 'index.html',
      path: 'articles/:num/index.html',
      filter: function (page) {
        return !page.private
      },
      pageMetadata: {
        title: 'Archive'
      }
    }
  }))

If I log out common.posts.items I get data that looks like this (I've limited to just 1 to make the post short.)

[{
  sys: {
    space: [Object],
    id: 'A96usFSlY4G0W4kwAqswk',
    type: 'Entry',
    createdAt: '2016-11-23T18:28:17.741Z',
    updatedAt: '2016-11-23T18:28:17.741Z',
    revision: 1,
    contentType: [Object],
    locale: 'en-US'
  },
  fields: {
    title: 'Seven Tips From Ernest Hemingway on How to Write Fiction',
    slug: 'seven-tips-from-ernest-hemingway-on-how-to-write-fiction',
    author: [Getter],
    body: 'It wasn’t by accident that the Gettysburg address was so short. The laws of prose writing are as immutable as those of flight, of mathematics, of physics.\n\nThe original, unabbreviated version of the blog post can be found on the [Open Culture](http://www.openculture.com/) website.',
    category: [Getter],
    comments: false
  }
},

When I build I receive a TypeError: Collection not found (common.posts.items) error. Perhaps my object isn't formed right? Maybe putting it in common is unnecessary?

Thanks again.

blakeembrey commented 7 years ago

That looks fine, the error means it wasn't found at all (see https://github.com/blakeembrey/metalsmith-pagination/blob/master/metalsmith-pagination.js#L37). Can you make sure it's not being populated by a later middleware (opposed to beforehand)? Also, can you check data.entries instead? All the README/examples seem to use it.

bhardy commented 7 years ago

Yea I've tried data.entires as well with no luck. Nothing's being populated by later middleware, the only other Metalsmith functions I'm running are .use(layouts) (with handlebars) and .build().

If it helps, my setup is almost exactly the same as (https://github.com/contentful-labs/contentful-metalsmith-example), I could also send you an invite to my project if it helps at all. I'm not sure if this is something you're interested in covering, or if I'm somehow just missing something very obvious.

derrickpelletier commented 7 years ago

Hey @blakeembrey, I was helping @bhardy out a bit on this though my metalsmith experience is limited. I noticed that metalsmith-pagination is trying to use the metalsmith.metadata() object to find the collection. However, after metalsmith-contentful runs, _metadata remains an empty {}, so there is basically no name we could use.

Seems like essentially all that's available is the array of files (as the first param that the plugin takes) that contentful generates. Curious if we'd need to make a little plugin to sit in front of pagination to populate the metadata in a meaningful way?

blakeembrey commented 7 years ago

Ok, I see. So it only populates files and never the global metadata. Pagination has to operate on the global metadata instead of the file-based metadata. An easy workaround would be to use metalsmith-collections to get all the files from contentful into an array - does that seem reasonable? I can add a comment to the README about requiring global metadata instead of file metadata.

FWIW, if you have an idea of how to use the file metadata, you can let me know, but it seems the best approach would be to populate a collection some other way and then use this plugin to paginate the collection.

derrickpelletier commented 7 years ago

Yeah, last night I ended up pursuing the last idea I had mentioned which was populating the metadata manually and got it to work after a bit of fiddling. Seems to be working fine. I'll look into trying metalsmith-collections, thanks!

Safe to close this, i'd figure.