WordPress-Fetch-Posts/blog.js

140 lines
4.8 KiB
JavaScript
Raw Normal View History

2023-09-30 14:45:32 +02:00
/**
* The base URI for the WordPress API. Don't forget `http(s)://`!
* Depending on where your WordPress blog is hosted, this could be something like: `https://example.wordpress.com`
*
* @type {String}
*/
const wordPressBaseUri = 'https://wptest.decicus.com';
/**
* Fetches 10 posts from WordPress API.
* Uses: https://developer.wordpress.org/rest-api/reference/posts/#list-posts
*
* @param {Number} page Which page to fetch, by default the first page (1)
* @param {Number} perPage How many posts to fetch per page, by default 10
* @returns {Array}
*/
async function fetchPosts(page = 1, perPage = 10)
{
const response = await fetch(`${wordPressBaseUri}/wp-json/wp/v2/posts?page=${page}&per_page=${perPage}`);
const json = await response.json();
return json;
}
/**
* Used for tracking what "page" from the WordPress API we should be fetching.
* You should generally not change this value.
*/
let nextPage = 1;
/**
* Can be used for tweaking how many posts to get per page.
* Will also affect how many times you have to click "View more" to get all posts
*/
const perPage = 10;
const viewMoreButton = document.querySelector('#view-more');
async function getPosts()
{
// Disable the "View More" button while we're fetching posts, to avoid people spamming the button
viewMoreButton.setAttribute('disabled', '1');
// Get the first set of posts from the API
const posts = await fetchPosts(nextPage, perPage);
// Get the container where we want to put the posts. By default this can just be an empty div.
const postsContainer = document.querySelector('#blog-posts');
/**
* Style points only
*/
let firstPostId = null;
// Loop though the posts and create the HTML elements for each post
for (const post of posts)
{
/**
* Style points only
*
* Since `firstPostId` is still `null`, we set it to the post's ID.
* Any further posts in this batch will *not* override it.
* Meaning it will in fact be "the first post" (of this batch).
*/
if (firstPostId === null)
{
firstPostId = post.id;
}
// Create post's parent div
const postElement = document.createElement('div');
postElement.setAttribute('data-post-id', post.id);
postElement.classList.add('post');
// Purely for styling, can ignore this part
postElement.classList.add('bg-rose-900');
postElement.classList.add('p-4');
postElement.classList.add('my-4');
// Create post's title as a h2
const postTitle = document.createElement('h2');
postTitle.textContent = post.title.rendered;
// Purely for styling, can ignore this part
postTitle.classList.add('text-xl');
postTitle.classList.add('font-bold');
postTitle.classList.add('mb-2');
// Create post's content. This is a div because WordPress will give you a lot of HTML tags in the content (e.g. `p`).
const postContent = document.createElement('div');
postContent.innerHTML = post.content.rendered;
// Append the title and content to the post's parent div
postElement.appendChild(postTitle);
postElement.appendChild(postContent);
// Append the post's parent div to the container
postsContainer.appendChild(postElement);
}
/**
* Style points only
* Only trigger this logic after the "view more" button has been pressed
*/
if (nextPage > 1) {
/**
* Style points only
* Scroll to the first post we got from the API.
* This will scroll to the first post of the current batch of posts
*/
const firstPost = document.querySelector(`[data-post-id="${firstPostId}"]`);
firstPost.scrollIntoView({ behavior: 'smooth' });
}
/**
* If the amount of posts we got from the API is less than the amount of posts we requested,
* then we know that we have reached the end of the posts and we can hide the "View More" button.
*/
const viewMoreClasses = viewMoreButton.classList;
if (posts.length >= perPage)
{
viewMoreClasses.remove('hidden');
// Increase `nextPage` by 1 so that the next time we fetch posts, we get the next page
nextPage++;
}
/**
* If the amount of posts we got from the API is less than the amount of posts we requested,
* then we know that we have reached the end of the posts and we can hide the "View More" button.
*/
else {
viewMoreClasses.add('hidden');
}
// Re-enable the "View More" button
viewMoreButton.removeAttribute('disabled');
}
// Add an event listener to the "View More" button so that we can fetch more posts when it's clicked
viewMoreButton.addEventListener('click', getPosts);
getPosts();