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`
|
|
|
|
*/
|
|
|
|
const wordPressBaseUri = 'https://wptest.decicus.com';
|
|
|
|
|
2023-09-30 15:01:29 +02:00
|
|
|
/**
|
|
|
|
* The selector for the container where we want to put the posts.
|
|
|
|
* By default it is `#blog-posts` (element with ID "blog-posts"), which you can find in `blog.html`
|
|
|
|
*/
|
|
|
|
const postsContainerSelector = '#blog-posts';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The selector for the "View More" button.
|
|
|
|
* By default it is `#view-more` (element with ID "view-more"), which you can find in `blog.html`
|
|
|
|
*/
|
|
|
|
const viewMoreButtonSelector = '#view-more';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Classes to add to the post's parent div.
|
|
|
|
* By default these are Tailwind CSS classes: https://tailwindcss.com/
|
|
|
|
*/
|
|
|
|
const postElementClasses = ['bg-rose-900', 'p-4', 'my-4'];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Classes to add to the post's title.
|
|
|
|
* By default these are Tailwind CSS classes: https://tailwindcss.com/
|
|
|
|
*/
|
|
|
|
const postTitleClasses = ['text-xl', 'font-bold', 'mb-2'];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class to add to the "View More" button when there are no more posts to fetch.
|
|
|
|
* By default this is a Tailwind CSS class called `hidden`: https://tailwindcss.com/docs/display#hidden
|
|
|
|
*/
|
|
|
|
const hideClass = 'hidden';
|
|
|
|
|
2023-09-30 14:45:32 +02:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
|
2023-09-30 15:01:29 +02:00
|
|
|
const viewMoreButton = document.querySelector(viewMoreButtonSelector);
|
2023-09-30 14:45:32 +02:00
|
|
|
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.
|
2023-09-30 15:01:29 +02:00
|
|
|
const postsContainer = document.querySelector(postsContainerSelector);
|
2023-09-30 14:45:32 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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');
|
|
|
|
|
2023-09-30 15:01:29 +02:00
|
|
|
/**
|
|
|
|
* Adding classes to the post's parent div.
|
|
|
|
* Primarily for styling purposes.
|
|
|
|
*/
|
|
|
|
for (const postElementClass of postElementClasses)
|
|
|
|
{
|
|
|
|
postElement.classList.add(postElementClass);
|
|
|
|
}
|
2023-09-30 14:45:32 +02:00
|
|
|
|
|
|
|
// Create post's title as a h2
|
|
|
|
const postTitle = document.createElement('h2');
|
|
|
|
postTitle.textContent = post.title.rendered;
|
|
|
|
|
2023-09-30 15:01:29 +02:00
|
|
|
/**
|
|
|
|
* Adding classes to the post's title.
|
|
|
|
* Primarily for styling purposes.
|
|
|
|
*/
|
|
|
|
for (const postTitleClass of postTitleClasses)
|
|
|
|
{
|
|
|
|
postTitle.classList.add(postTitleClass);
|
|
|
|
}
|
2023-09-30 14:45:32 +02:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
{
|
2023-09-30 15:01:29 +02:00
|
|
|
viewMoreClasses.remove(hideClass);
|
2023-09-30 14:45:32 +02:00
|
|
|
|
|
|
|
// 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 {
|
2023-09-30 15:01:29 +02:00
|
|
|
viewMoreClasses.add(hideClass);
|
2023-09-30 14:45:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
2023-09-30 15:01:29 +02:00
|
|
|
// Run the `getPosts` function once when the page loads
|
2023-09-30 14:45:32 +02:00
|
|
|
getPosts();
|