From 051c9f76f5d60763865736cb52cb871a2cf6bf08 Mon Sep 17 00:00:00 2001 From: Alex Thomassen Date: Sat, 30 Sep 2023 12:45:32 +0000 Subject: [PATCH] Initial implementation --- LICENSE | 21 ++++++++ blog.html | 15 ++++++ blog.js | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 12 +++++ 4 files changed, 188 insertions(+) create mode 100644 LICENSE create mode 100644 blog.html create mode 100644 blog.js create mode 100644 index.html diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ac1541e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Alex Thomassen + +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. diff --git a/blog.html b/blog.html new file mode 100644 index 0000000..56e364d --- /dev/null +++ b/blog.html @@ -0,0 +1,15 @@ + + + + + + + + +

Blog

+
+ + + + + \ No newline at end of file diff --git a/blog.js b/blog.js new file mode 100644 index 0000000..c1e686e --- /dev/null +++ b/blog.js @@ -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(); \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..59feb23 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + + + +

Hello, world!

+

Visit the blog!

+ + \ No newline at end of file