Initial implementation

This commit is contained in:
Alex Thomassen 2023-09-30 12:45:32 +00:00
commit 051c9f76f5
Signed by: Alex
GPG Key ID: 10BD786B5F6FF5DE
4 changed files with 188 additions and 0 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Alex Thomassen <alex@thomassen.sh>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

15
blog.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-slate-800 text-white py-6 px-8">
<h1 class="text-3xl font-bold underline">Blog</h1>
<div id="blog-posts"></div>
<button id="view-more" class="hidden bg-orange-500 hover:bg-orange-700 text-white font-bold py-2 px-4 rounded">View More</button>
</body>
<script src="/blog.js"></script>
</html>

140
blog.js Normal file
View File

@ -0,0 +1,140 @@
/**
* 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();

12
index.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-slate-800 text-white py-6 px-8">
<h1 class="text-3xl font-bold underline">Hello, world!</h1>
<p>Visit the <a href="/blog.html" class="text-orange-300">blog</a>!</p>
</body>
</html>