Posts/pages pagination

Description

I want to be able to paginate my posts as I do with the lists of posts. There is a Gutenberg block named Page Break that add pagination for the posts/pages.

User Stories

As a Frontity user
I want to use the WP posts pagination
so that I can split long posts

Examples

You can find and example of one post splitted using Page Break Gutenberg block at this url.

Possible solution

It seems that in the WP REST API, the only information you can find about the post pagination is a comment <!--nextpage--> included in the content. I guess we should process the content and add some logic or create different REST API endpoints splitting the post.

Interesting… Does the <!--nextpage--> remain in the content.rendered field? I thought all the comments were stripped out.

Yes, it does! You can look at it at this endpoint of our test site -> https://test.frontity.io/?rest_route=/wp/v2/posts&slug=test-multiple-blocks.

I see. This is interesting. I wonder why the other comments are removed…

I have an idea to solve this once we introduce the Frontity hooks.

Thanks to the hooks, we could hook into state.source.get() and actions.source.fetch() to change their arguments and point all the post-paginated URLs to the same data object. Something like this:

  • actions.source.fetch("/some-post/2") -> actions.source.fetch("/some-post/")
  • actions.source.fetch("/some-post/3") -> actions.source.fetch("/some-post/")
  • actions.source.fetch("/some-post/4") -> actions.source.fetch("/some-post/")

And

  • state.source.get("/some-post/2") -> state.source.get("/some-post/")
  • state.source.get("/some-post/3") -> state.source.get("/some-post/")
  • state.source.get("/some-post/4") -> state.source.get("/some-post/")

But even though this is a clear example of multiple links that should point to the same data object, that means we couldn’t have data.page information returned in that data. That information would have to be outside of the data, added on the fly by the hook.

Imagine this hook (code only) for the state.source.get() derived state function:

const postPagination = async ({ args, isExecuted, result }) => {
  // Extract the page.
  const [_, page] = /\/(\d{1,2})(\/|#|\?|$)/.exec(args[0]);
  // Remove it from the link.
  const args[0] = args[0].replace(/\/\d{1,2}(\/|#|\?|$)/, "");
  // Then wait until the derived state function is executed.
  if (await isExecuted) {
    // If the derived state function was executed sucessfully, add the page to
    // the returned result.
    result.page = page;
  }
};

Themes would have to support <!--nextpage--> with something like this:

const Post = ({ state }) => {
  const data = state.source.get(state.router.link);
  const post = state.source.postTypes[data.type][data.id];

  // Divide the content between pages and get the correct one.
  const html = post.content.rendered.split("<!--nextpage-->")[data.page - 1];

  return (
    <>
      {/* Use it in Html2React */}
      <Html2React html={html} />
    </>
  );
};
2 Likes

Hey Hard-Working developers of Frontity,

I see I am 9 months late to the party, but I recently was implementing pagination on the post, when I got stuck on a problem.

The thing is post is breaking and paginating when I implemented the feature/code as given by @luisherranz, but the problem is that I can’t figure out a way to find the totalPages (or anything of that sort, basically, a way to find the last paginated page of the post), which is required to post ‘Previous/Next’ links, in order to not go to page which does not exists.

I am attaching a link where I have implemented the pagination. Let me know if I forget something.

Thanks, as always,
Pranav.

Hey @pranav.v, thanks for sharing! I got a 404 though. Is the link still valid?

By the way, how was your approach to solving this?

Another thing: @david is currently working on a Feature Discussion so we can start talking about how we can solve this. Not post pagination per se, but what I explained about having multiple links pointing to the same data object in state.source.data.

EDIT: I didn’t noticed he had already published the FD WpSource: Define a map of `allowedQueries` to only preserve them in data references (links) :smile:

Hey @luisherranz

Sorry, the above link is not valid anymore.

Try this page

As I follow your solution, we get the current page of post

and whole post content

which we can split according to the page the user is on

Now with the split, we can have how much pages the post have. So I send that information to the post pagination component via props, which helped me calculate the last page of the post.

Thanks for all your help,
Pranav.

Awesome. Thanks Pranav :slightly_smiling_face: