Warning: The magic method NinjaFormsAddonManager\WordPress\Plugin::__wakeup() must have public visibility in /www/frowarecom_769/public/current/web/app/plugins/ninja-forms-addon-manager/lib/wordpress/plugin.php on line 22

Deprecated: Creation of dynamic property NinjaFormsAddonManager\Plugin::$service is deprecated in /www/frowarecom_769/public/current/web/app/plugins/ninja-forms-addon-manager/includes/plugin.php on line 19

Deprecated: Creation of dynamic property SearchAndFilter::$frmqreserved is deprecated in /www/frowarecom_769/public/current/web/app/plugins/search-filter/search-filter.php on line 71

Deprecated: Creation of dynamic property Tribe__Events__Community__PUE::$pue_instance is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/PUE.php on line 47

Deprecated: Creation of dynamic property Tribe__Events__Community__Main::$eventListDateFormat is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/Main.php on line 305

Deprecated: Creation of dynamic property Tribe__Events__Community__Main::$users_can_create is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/Main.php on line 313

Deprecated: Creation of dynamic property Tribe__Events__Community__Main::$emailAlertsEnabled is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/Main.php on line 316

Deprecated: Creation of dynamic property Tribe__Events__Community__Main::$emailAlertsList is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/Main.php on line 319

Deprecated: Creation of dynamic property Tribe__Events__Community__Main::$blockRolesFromAdmin is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/Main.php on line 321

Deprecated: Creation of dynamic property Tribe__Events__Community__Main::$blockRolesList is deprecated in /www/frowarecom_769/public/current/web/app/plugins/the-events-calendar-community-events/src/Tribe/Main.php on line 322

Deprecated: Implicit conversion from float 11.5 to int loses precision in /www/frowarecom_769/public/current/web/wp/wp-includes/class-wp-hook.php on line 85

Deprecated: Implicit conversion from float 11.5 to int loses precision in /www/frowarecom_769/public/current/web/wp/wp-includes/class-wp-hook.php on line 87

Deprecated: Creation of dynamic property EAddonsForElementor\Plugin::$controls_manager is deprecated in /www/frowarecom_769/public/current/web/app/plugins/e-addons-for-elementor/core/plugin.php on line 175

Deprecated: Creation of dynamic property Kinsta\Cache_Purge::$kinsta_cache is deprecated in /www/frowarecom_769/public/current/web/app/mu-plugins/kinsta-mu-plugins/cache/class-cache-purge.php on line 84

Deprecated: Creation of dynamic property Kinsta\KMP::$wp_cli is deprecated in /www/frowarecom_769/public/current/web/app/mu-plugins/kinsta-mu-plugins/class-kmp.php on line 93

Deprecated: Use of "self" in callables is deprecated in /www/frowarecom_769/public/current/web/app/plugins/wp-discourse/lib/discourse.php on line 225
Let’s Learn 11ty Part 10: Bringing It All Together | Frocentric Tech
Deprecated: Automatic conversion of false to array is deprecated in /www/frowarecom_769/public/current/web/app/plugins/ele-custom-skin/includes/enqueue-styles.php on line 22

Let’s Learn 11ty Part 10: Bringing It All Together

In our last article we used external data to render posts on our site.

If you noticed, we don’t have that cool Previous/Next Post that was at the bottom of our posts before.

Wouldn’t it be nice to have that back? That is the main focus of this article.

Let’s first look at what our post pagination looked like before with local posts

 {% set previousPost = collections.post | getPreviousCollectionItem(page) %}
 {% set nextPost = collections.post | getNextCollectionItem(page) %}

 {% if previousPost %}Previous: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a>{% endif %}
 <br>
 {% if nextPost %}Next: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a>{% endif %}

Above, we were making use of what I called one of the cornerstones of Eleventy – collections.

This method will not work for the posts we’ve fetched from Hashnode because they aren’t part of a collection like the posts we had.

To bring that functionality back we will need to add a couple things to our .eleventy.js

A Collection

When we started this series we made a collection – for our pages. We are going to employ that same knowledge to make a collection from our Hashnode posts.

In .eleventy.js add this:

 eleventyConfig.addCollection("articles", async () => {
    const endpoint = `https://api.hashnode.com/`;
    const { GraphQLClient, gql } = require("graphql-request");

    const client = new GraphQLClient(endpoint);

    const query = gql`
      {
        user(username: "Psypher1") {
          publication {
            posts {
              title
              coverImage
              brief
              slug
              dateAdded
              contentMarkdown
            }
          }
        }
      }
    `;

    const articles = await client.request(query);

    return articles.user.publication.posts;
  });

We have used the same piece of code that we had in our posts.js file, but this time to create a collection.

A Filter

In our original code we also had this filter: getPreviousCollectionItem(page) – this is what gets us the next and previous functionality.

For that, we will also make a filter in the same .eleventy.js file

elevntyConfig.addFilter("nextArticle", (articles, page, modifier = 1) => {
    const parts = page.outputPath.split("/");
    parts.pop(); // get rid of `index.html`
    const slug = parts.pop();
    for (const [index, article] of articles.entries()) {
      const target = index + modifier;
      if (article.slug === slug && target >= 0 && target < articles.length) {
        return articles[target];
      }
    }
  });

What we have done now works beacuse:
The data (articles) returned in the collection sort of guides how next/previous are going to work

Paginate Partial

Then we will change/create our _paginate.njk file to look like this:

{% set previousPost = collections.articles | nextArticle(page) %}
{% set nextPost = collections.articles | nextArticle(page, -1) %}

 {% if previousPost %}Previous: <a href="/blog/{{ previousPost.slug }}">{{ previousPost.title }}</a>{% endif %}
 <br>
 {% if nextPost %}Next: <a href="/blog/{{ nextPost.slug }}">{{ nextPost.title }}</a>{% endif %}

Then we come into our postLayout.njk file and include it at the bottom

{% include "partials/_paginate.njk" %}

And there we go. We are back where we were.

Special thanks goes to Shiv Jha-Mathur from the Eleventy Discord who provided the guidance and solution to this particular conundrum.

My Quest For You

Now that we’ve seen how we can fetch articles from an API and still have the same functionality we had with local ones. Try to see how you can combine everyhing we’ve learnt in the series into one complete site.

In the meantime, I will work on updating the series repo – do the different branches per part thing.

Wish me luck 😄

Thank you for reading, let’s connect!

Thank you for visiting this little corner of mine. Let’s connect on Twitter, Polywork and LinkedIn