Created individual categories page
Signed-off-by: rodude123 <rodude123@gmail.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
|
||||
main > h1 {
|
||||
padding-left: 3em;
|
||||
}
|
||||
|
||||
section.catPosts .largePost {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ section.largePost {
|
||||
padding: 0 5em 1em;
|
||||
}
|
||||
|
||||
section.largePost:first-child {
|
||||
section.largePost:not(:last-child) {
|
||||
border-bottom: 5px solid var(--mutedGrey);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
@import "../../css/footer.css";
|
||||
@import "blogPosts.css";
|
||||
@import "home.css";
|
||||
@import "category.css";
|
||||
@import "prism.css";
|
||||
|
||||
|
||||
+265
-212
@@ -3,21 +3,25 @@ const scrollLimit = 150;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () =>
|
||||
{
|
||||
goToURL(window.location.pathname);
|
||||
goToURL(window.location.pathname);
|
||||
});
|
||||
|
||||
window.addEventListener('popstate', _ =>
|
||||
{
|
||||
goToURL(window.history.state);
|
||||
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");
|
||||
}
|
||||
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');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -26,39 +30,41 @@ window.onscroll = () => {
|
||||
*/
|
||||
function goToURL(url)
|
||||
{
|
||||
// Get the current URL and split it into an array
|
||||
let urlArray = url.split('/');
|
||||
|
||||
if (url === "/blog/" || url === "/blog")
|
||||
{
|
||||
loadHomeContent();
|
||||
// window.history.pushState(null, null, url);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the URL is a post page
|
||||
if (urlArray[2] === 'post')
|
||||
{
|
||||
// Create a new URL with the dynamic part
|
||||
// window.history.pushState(null, null, url);
|
||||
loadIndividualPost(urlArray[urlArray.length - 1]).catch(err => console.log(err));
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
loadAllCategories();
|
||||
return;
|
||||
}
|
||||
|
||||
show404();
|
||||
|
||||
// Get the current URL and split it into an array
|
||||
let urlArray = url.split('/');
|
||||
|
||||
if (url === '/blog/' || url === '/blog')
|
||||
{
|
||||
loadHomeContent();
|
||||
// window.history.pushState(null, null, url);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the URL is a post page
|
||||
if (urlArray[2] === 'post')
|
||||
{
|
||||
// Create a new URL with the dynamic part
|
||||
// window.history.pushState(null, null, url);
|
||||
loadIndividualPost(urlArray[urlArray.length - 1]).catch(err => console.log(err));
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
loadAllCategories();
|
||||
return;
|
||||
}
|
||||
|
||||
show404();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,80 +72,92 @@ function goToURL(url)
|
||||
* @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 = `
|
||||
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 += ', ';
|
||||
}
|
||||
});
|
||||
|
||||
if (categories.endsWith(', '))
|
||||
{
|
||||
categories = categories.substring(0, categories.length - 2);
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}))
|
||||
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];
|
||||
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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,80 +165,95 @@ async function getLatestAndFeaturedPosts() {
|
||||
* @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;
|
||||
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;
|
||||
|
||||
async function getCategories()
|
||||
{
|
||||
let categories = await fetch('/api/blog/categories').then(res => res.json());
|
||||
let modifiedCategories = [];
|
||||
categories.forEach(category => modifiedCategories = modifiedCategories.concat(csvToArray(category.categories.replace(/\s*,\s*/g, ','))));
|
||||
return [...new Set(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;
|
||||
function createCategories(categoriesList)
|
||||
{
|
||||
let categories = '';
|
||||
categoriesList.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;
|
||||
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 = `
|
||||
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"
|
||||
@@ -276,68 +309,75 @@ async function createSideContent() {
|
||||
${categories}
|
||||
</div>
|
||||
`;
|
||||
return sideContent;
|
||||
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 = `
|
||||
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>
|
||||
<h3>${createButtonCategories([csvToArray(json.categories.replace(/\s*,\s*/g, ','))])}</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>
|
||||
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);
|
||||
})();
|
||||
});
|
||||
});
|
||||
|
||||
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() {
|
||||
function loadAllCategories()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -345,28 +385,41 @@ 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);
|
||||
}));
|
||||
function loadPostsByCategory(category)
|
||||
{
|
||||
document.title = 'Rohit Pai - ' + decodeURI(category);
|
||||
fetch(`/api/blog/categories/${category}`).then(res => res.json().then(json =>
|
||||
{
|
||||
let main = document.querySelector('#main');
|
||||
let posts = document.createElement('section');
|
||||
posts.classList.add('catPosts');
|
||||
posts.id = 'postsByCategory';
|
||||
let h1 = document.createElement('h1');
|
||||
h1.innerHTML = decodeURI(category);
|
||||
main.appendChild(h1);
|
||||
for (let i = 0; i < json.length; i++)
|
||||
{
|
||||
let largePost = document.createElement('section');
|
||||
largePost.classList.add('largePost');
|
||||
if (i < json.length - 1)
|
||||
{
|
||||
largePost.classList.add('categoryPost');
|
||||
}
|
||||
largePost.id = `lp-${i + 1}`;
|
||||
let outerContent = createLargePost(json[i]);
|
||||
largePost.appendChild(outerContent);
|
||||
posts.appendChild(largePost);
|
||||
}
|
||||
main.appendChild(posts);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the 404 page
|
||||
*/
|
||||
function show404() {
|
||||
document.querySelector("#main").innerHTML = `
|
||||
function show404()
|
||||
{
|
||||
document.querySelector('#main').innerHTML = `
|
||||
<div class="error">
|
||||
<div class="fof">
|
||||
<h1>Blog post, Category or page not found</h1>
|
||||
|
||||
Reference in New Issue
Block a user