Created blog post page and updated a few things here and there to work with the blog post page. Has comments and a sidebar.

Signed-off-by: rodude123 <rodude123@gmail.com>
This commit is contained in:
2023-10-18 00:28:34 +01:00
parent 74d1ea35c1
commit 57aa831cdf
159 changed files with 3476 additions and 11912 deletions
+347 -11
View File
@@ -1,3 +1,5 @@
// nav bar scroll effect
const scrollLimit = 150;
document.addEventListener('DOMContentLoaded', () =>
{
@@ -9,6 +11,14 @@ window.addEventListener('popstate', _ =>
goToURL(window.history.state);
});
window.onscroll = () => {
// check if scrolled past limit if so add scrolled class to change background of nav
if (document.body.scrollTop >= scrollLimit || document.documentElement.scrollTop >= scrollLimit) {
document.querySelector("nav").classList.add("scrolled");
} else {
document.querySelector("nav").classList.remove("scrolled");
}
};
/**
* goToURL tries to go to the specified URL if not shows the error page (not yet implemented)
@@ -19,23 +29,349 @@ function goToURL(url)
// Get the current URL and split it into an array
let urlArray = url.split('/');
let newUrl = "";
if (urlArray.includes('blog'))
if (url === "/blog/" || url === "/blog")
{
newUrl = url;
loadHomeContent();
// window.history.pushState(null, null, url);
return;
}
// Check if the URL is a post page
if (urlArray[0] === 'post')
if (urlArray[2] === 'post')
{
// Create a new URL with the dynamic part
newUrl = "/blog/" + url;
// window.history.pushState(null, null, url);
loadIndividualPost(urlArray[urlArray.length - 1]).catch(err => console.log(err));
return;
}
// Update the URL in the browser without reloading the page
window.history.pushState(null, null, newUrl);
if (urlArray[2] === 'category') {
// Create a new URL with the dynamic part
// window.history.pushState(null, null, url);
if (urlArray[3]) {
loadPostsByCategory(urlArray[urlArray.length - 1]);
return;
}
// Get the dynamic part of the URL
document.querySelector("#url").innerHTML = decodeURI(urlArray[urlArray.length - 1]);
}
loadAllCategories();
return;
}
show404();
}
/**
* Creates a large post element
* @param post the post object
* @returns {HTMLDivElement} the outer content of the post
*/
function createLargePost(post) {
let outerContent = document.createElement("div");
outerContent.classList.add("outerContent");
let img = document.createElement("img");
img.className = "banner";
img.src = post.headerImg;
img.alt = post.title;
outerContent.appendChild(img);
let content = document.createElement("div");
content.classList.add("content");
let postContent = document.createElement("div");
postContent.classList.add("postContent");
let categories = "";
post.categories.split(", ").forEach(category => {
categories += `<a href="/blog/category/${category}" class="link">${category}</a>`
if (post.categories.split(", ").length > 1) {
categories += ", ";
}
});
window.categories = categories;
postContent.innerHTML = `
<h2>${post.title}</h2>
<h3>Last updated: ${post.dateModified} | ${categories}</h3>
<p>${post.abstract}</p>
<a href="/blog/post/${post.title}#disqus_thread" class="btn btnPrimary">See Post</a>
`;
content.appendChild(postContent);
outerContent.appendChild(content);
return outerContent;
}
/**
* Loads the home content
*/
function loadHomeContent() {
fetch("/api/blog/post").then(res => res.json().then(json => {
for (let i = 0; i < json.length; i++) {
if (json[i].featured === 1) {
let featuredPost = document.createElement("section");
featuredPost.classList.add("largePost");
featuredPost.id = "featuredPost";
let h1 = document.createElement("h1");
h1.innerHTML = "featured post";
featuredPost.appendChild(h1);
let outerContent = createLargePost(json[i]);
featuredPost.appendChild(outerContent);
document.querySelector("#main").prepend(featuredPost);
}
if (i === 0) {
let latestPost = document.createElement("section");
latestPost.classList.add("largePost");
latestPost.id = "latestPost";
let h1 = document.createElement("h1");
h1.innerHTML = "latest post";
latestPost.appendChild(h1);
let outerContent = createLargePost(json[i]);
latestPost.appendChild(outerContent);
document.querySelector("#main").prepend(latestPost);
}
}
}))
}
/**
* Gets the latest and featured posts
* @returns {Promise<any[]>} the latest and featured posts
*/
async function getLatestAndFeaturedPosts() {
let latestPost = await fetch("/api/blog/post/latest").then(res => res.json());
let featuredPost = await fetch("/api/blog/post/featured").then(res => res.json());
return [latestPost, featuredPost];
}
/**
* Converts a csv to an array
* @param text the csv text
* @returns {string[]} the array
*/
function csvToArray(text) {
let p = '';
let arr = [''];
let i = 0;
let s = true;
let l = null;
for (l of text) {
if ('"' === l) {
if (s && l === p) {
arr[i] += l;
}
s = !s;
} else if (',' === l && s) {
l = arr[++i] = '';
} else if ('\n' === l && s) {
if ('\r' === p) row[i] = row[i].slice(0, -1);
arr = arr[++r] = [l = ''];
i = 0;
} else {
arr[i] += l;
}
p = l;
}
return arr;
}
/**
* Gets the categories
* @returns {Promise<*[]>} the categories
*/
async function getCategories() {
let categories = await fetch("/api/blog/categories").then(res => res.json());
let modifiedCategories = [];
categories.forEach(category => modifiedCategories.push(csvToArray(category.categories)));
return modifiedCategories;
}
/**
* Creates the categories
* @param {*[]} categoriesList the categories
*/
function createCategories(categoriesList) {
let categories = "";
categoriesList.forEach(lst => lst.forEach(category => categories += `<a href="/blog/category/${category}" class="link">${category}</a>`));
return categories;
}
/**
* Creates the button categories
* @param {string[][]} categoriesList - the categories
*/
function createButtonCategories(categoriesList) {
let categories = "";
categoriesList.forEach(lst => lst.forEach(category => categories += `<a href="/blog/category/${category}" class="btn btnOutline">${category}</a>`));
return categories;
}
/**
* Creates the side content
* @returns {HTMLElement} the aside element
*/
async function createSideContent() {
let posts = await getLatestAndFeaturedPosts();
let latestPost = posts[0];
let featuredPost = posts[1];
let categoriesList = await getCategories();
let categories = createCategories(categoriesList);
let sideContent = document.createElement("aside");
sideContent.classList.add("sideContent");
sideContent.innerHTML = `
<div class="authorInfo">
<div class="picture">
<img src="/imgs/profile.jpg"
alt="My professional picture taken in brighton near
north street at night wearing a beige jacket and checkered shirt"
class="profile">
<p>Rohit Pai</p>
</div>
<a href="https://linkedin.com/in/rohitpai98">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-2 16h-2v-6h2v6zm-1-6.891c-.607 0-1.1-.496-1.1-1.109 0-.612.492-1.109 1.1-1.109s1.1.497 1.1 1.109c0 .613-.493 1.109-1.1 1.109zm8 6.891h-1.998v-2.861c0-1.881-2.002-1.722-2.002 0v2.861h-2v-6h2v1.093c.872-1.616 4-1.736 4 1.548v3.359z"/>
</svg>
</a>
<a href="mailto:rohit@rohitpai.co.uk">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13.718 10.528c0 .792-.268 1.829-.684 2.642-1.009 1.98-3.063 1.967-3.063-.14 0-.786.27-1.799.687-2.58 1.021-1.925 3.06-1.624 3.06.078zm10.282 1.472c0 6.627-5.373 12-12 12s-12-5.373-12-12 5.373-12 12-12 12 5.373 12 12zm-5-1.194c0-3.246-2.631-5.601-6.256-5.601-4.967 0-7.744 3.149-7.744 7.073 0 3.672 2.467 6.517 7.024 6.517 2.52 0 4.124-.726 5.122-1.288l-.687-.991c-1.022.593-2.251 1.136-4.256 1.136-3.429 0-5.733-2.199-5.733-5.473 0-5.714 6.401-6.758 9.214-5.071 2.624 1.642 2.524 5.578.582 7.083-1.034.826-2.199.799-1.821-.756 0 0 1.212-4.489 1.354-4.975h-1.364l-.271.952c-.278-.785-.943-1.295-1.911-1.295-2.018 0-3.722 2.19-3.722 4.783 0 1.73.913 2.804 2.38 2.804 1.283 0 1.95-.726 2.364-1.373-.3 2.898 5.725 1.557 5.725-3.525z"/>
</svg>
</a>
<a href="https://gitea.rohitpai.co.uk/rodude123">
<svg xmlns="http://www.w3.org/2000/svg"
x="0px" y="0px" viewBox="0 0 1024 1024"
style="enable-background:new -1 0 1024 1024;" xml:space="preserve">
<style type="text/css">.st1 {fill: #FFFFFF;}</style>
<g id="Guides"></g>
<g id="Icon"><circle class="st0" cx="512" cy="512" r="512"/>
<g><path class="st1" d="M762.2,350.3c-100.9,5.3-160.7,8-212,8.5v114.1l-16-7.9l-0.1-106.1c-58.9,0-110.7-3.1-209.1-8.6 c-12.3-0.1-29.5-2.4-47.9-2.5c-47.1-0.1-110.2,33.5-106.7,118C175.8,597.6,296,609.9,344,610.9c5.3,24.7,61.8,110.1,103.6,114.6 H631C740.9,717.3,823.3,351.7,762.2,350.3z M216.2,467.6c-4.7-36.6,11.8-74.8,73.2-73.2C296.1,462,307,501.5,329,561.9 C272.8,554.5,225,536.2,216.2,467.6z M631.8,551.1l-51.3,105.6c-6.5,13.4-22.7,19-36.2,12.5l-105.6-51.3 c-13.4-6.5-19-22.7-12.5-36.2l51.3-105.6c6.5-13.4,22.7-19,36.2-12.5l105.6,51.3C632.7,521.5,638.3,537.7,631.8,551.1z"/>
<path class="st1"
d="M555,609.9c0.1-0.2,0.2-0.3,0.2-0.5c17.2-35.2,24.3-49.8,19.8-62.4c-3.9-11.1-15.5-16.6-36.7-26.6 c-0.8-0.4-1.7-0.8-2.5-1.2c0.2-2.3-0.1-4.7-1-7c-0.8-2.3-2.1-4.3-3.7-6l13.6-27.8l-11.9-5.8L519.1,501c-2,0-4.1,0.3-6.2,1 c-8.9,3.2-13.5,13-10.3,21.9c0.7,1.9,1.7,3.5,2.8,5l-23.6,48.4c-1.9,0-3.8,0.3-5.7,1c-8.9,3.2-13.5,13-10.3,21.9 c3.2,8.9,13,13.5,21.9,10.3c8.9-3.2,13.5-13,10.3-21.9c-0.9-2.5-2.3-4.6-4-6.3l23-47.2c2.5,0.2,5,0,7.5-0.9 c2.1-0.8,3.9-1.9,5.5-3.3c0.9,0.4,1.9,0.9,2.7,1.3c17.4,8.2,27.9,13.2,30,19.1c2.6,7.5-5.1,23.4-19.3,52.3 c-0.1,0.2-0.2,0.5-0.4,0.7c-2.2-0.1-4.4,0.2-6.5,1c-8.9,3.2-13.5,13-10.3,21.9c3.2,8.9,13,13.5,21.9,10.3 c8.9-3.2,13.5-13,10.3-21.9C557.8,613.6,556.5,611.6,555,609.9z"/>
</g>
</g>
</svg>
</a>
<h3>Avid Full Stack Dev | Uni of Notts Grad | Amateur Blogger</h3>
</div>
<div class="otherPosts">
<h2>latest post</h2>
<h3>${latestPost.title}</h3>
<p>${latestPost.abstract}</p>
<a href="/blog/post/${latestPost.title}" class="btn btnPrimary boxShadowIn boxShadowOut">See Post</a>
</div>
<div class="otherPosts">
<h2>featured post</h2>
<h3>${featuredPost.title}</h3>
<p>${featuredPost.abstract}</p>
<a href="/blog/post/${featuredPost.title}" class="btn btnPrimary boxShadowIn boxShadowOut">See Post</a>
</div>
<div class="categories">
<h2>categories</h2>
${categories}
</div>
`;
return sideContent;
}
/**
* Trys to load the individual post if not runs the 404 function
* @param title
*/
async function loadIndividualPost(title) {
document.title = "Rohit Pai - " + decodeURI(title);
await fetch(`/api/blog/post/${title}`).then(async res => {
if (!res.ok) {
show404();
return;
}
await res.json().then(async json => {
// create the post
let post = document.createElement("section");
post.classList.add("post");
post.id = "individualPost";
let mainContent = document.createElement("div");
mainContent.classList.add("mainContent");
let article = document.createElement("article");
article.innerHTML = `
<h1>${json.title}</h1>
<div class="byLine">
<h3>Last updated: ${json.dateModified}</h3>
<h3>${createButtonCategories([csvToArray(json.categories)])}</h3>
</div>
<div class="cover" style="background-image: url('${json.headerImg}')"></div>
${json.body}
`;
let comments = document.createElement("section");
comments.classList.add("comments");
comments.innerHTML = `<h2>Comments</h2>
<div id="disqus_thread"></div>
`;
mainContent.appendChild(article);
mainContent.appendChild(comments);
let sideContent = await createSideContent();
post.appendChild(mainContent);
post.appendChild(sideContent);
document.querySelector("#main").appendChild(post);
let disqus_config = _ => {
this.page.url = window.location.href; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = window.location.href.substring(window.location.href.lastIndexOf("/") + 1); // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};
(function () { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = 'https://rohitpaiportfolio.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
d.body.appendChild(s);
})();
});
});
}
function loadAllCategories() {
}
/**
* Loads the posts by category
* @param category the category
*/
function loadPostsByCategory(category) {
document.title = "Rohit Pai - " + decodeURI(category);
fetch(`/api/blog/post/category/${category}`).then(res => res.json().then(json => {
let posts = document.createElement("section");
posts.classList.add("posts");
posts.id = "postsByCategory";
let h1 = document.createElement("h1");
h1.innerHTML = category;
posts.appendChild(h1);
for (let i = 0; i < json.length; i++) {
let outerContent = createLargePost(json[i]);
posts.appendChild(outerContent);
}
document.querySelector("#main").appendChild(posts);
}));
}
/**
* Shows the 404 page
*/
function show404() {
document.querySelector("#main").innerHTML = `
<div class="error">
<div class="fof">
<h1>Blog post, Category or page not found</h1>
<a href="/blog/" class="btn btnPrimary">See all blog posts</a>
</div>
</div>
`;
}