Skip to content

Commit 0270ccf

Browse files
committed
Add files' option to publish or save as draft
Allows publishing pages and posts right away or save to publish later
1 parent c463f5d commit 0270ccf

File tree

14 files changed

+159
-19
lines changed

14 files changed

+159
-19
lines changed

functions/blog-doc.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class Blog_Doc {
7171
const contents = new TextDecoder().decode(buffer)
7272

7373
const fileData = parseFrontMatter(contents) // Parse the front-matter of the file
74+
// Since v5.3.0 to allow publishing now or later
75+
Object.hasOwn(fileData.frontmatter, "published")
76+
? fileData.frontmatter.published
77+
: (fileData.frontmatter.published = "true")
7478
const filePath = `${file}` // Get the file path
7579
const fileDir = filePath.split("/")[0] // Get the file directory
7680
const obj = { 0: fileName, 1: fileData } // Create the object that holds the file data
@@ -129,7 +133,7 @@ class Blog_Doc {
129133

130134
// Method to count the occurrence of each tag from the posts front-matter.
131135
async postsByTagCount() {
132-
const posts = await getPosts()
136+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
133137

134138
// Create an array of the tags from all the posts and sort them alphabetically
135139
const tagsArray = posts.flatMap((post) => post[1].frontmatter.tags).sort()
@@ -142,7 +146,7 @@ class Blog_Doc {
142146

143147
// Method to return the posts of a particular tag.
144148
async postsByTagList(tag) {
145-
const posts = await getPosts()
149+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
146150
// Filter the posts to retrieve an array of post(s) including the requested tag
147151
// Check if the post have tags, otherwise define them as an empty array
148152
const postsByTagArray = posts.filter((post) =>
@@ -154,7 +158,7 @@ class Blog_Doc {
154158

155159
// Method to return the previous and next posts of a particular post.
156160
async prevNext(filename) {
157-
const posts = await getPosts()
161+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
158162
// Get the index of each post in the posts array by it's filename
159163
const actualPostIndex = posts.findIndex((post) => post[0] === filename)
160164
// Get the previous post index while the actual post index is smaller than the posts array length - 1 (posts array length - 1 is the index of the last post)
@@ -180,7 +184,7 @@ class Blog_Doc {
180184

181185
// Method to return the related posts of a particular post.
182186
async relatedPosts(filename) {
183-
const posts = await getPosts()
187+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
184188
// Get the post in the posts array by it's filename
185189
const actualPost = posts.find((post) => post[0] === filename)
186190
// Get the related posts from the front-matter of the actual post

functions/sitemap.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { getPages, getPosts } from "../functions/blog-doc.js"
22
import { getSettings } from "../functions/settings.js"
33

4-
const pages = await getPages()
5-
const posts = await getPosts()
4+
const pages = (await getPages()).filter((page) => page[1].frontmatter.published == "true")
5+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
66

77
export async function sitemap() {
88
const settings = await getSettings()

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ import { adminRoutes, adminUpdateDelete } from "./routes/admin/adminRoute.js"
3232
import { adminCreateRoute } from "./routes/admin/adminCreateRoute.js"
3333
import { adminGalleryRoute } from "./routes/admin/adminGalleryRoute.js"
3434
import { adminConfigRoute } from "./routes/admin/adminConfigRoute.js"
35+
import { adminPreviewRoute } from "./routes/admin/adminPreviewRoute.js"
3536
adminRoutes(app)
3637
adminCreateRoute(app)
3738
adminUpdateDelete(app)
3839
adminGalleryRoute(app)
3940
adminConfigRoute(app)
41+
adminPreviewRoute(app)
4042

4143
// Routes
4244
import { markdownRoute } from "./routes/markdownRoute.js"

routes/admin/adminCreateRoute.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,14 @@ export const adminCreateRoute = (app) => {
7171
postDescription,
7272
postImage,
7373
postTags,
74+
published,
7475
} = fields
7576

7677
const pageContents = `---
7778
title : ${pageTitle}
7879
description: ${pageDescription}
7980
featuredImage: ${pageImage}
81+
published: ${published}
8082
---
8183
${fileContents}`
8284

@@ -86,12 +88,15 @@ date: ${postDate.split("-").join("/")}
8688
description: ${postDescription}
8789
featuredImage: ${postImage}
8890
tags: [${postTags}]
91+
published: ${published}
8992
---
9093
${fileContents}`
9194

9295
const utf8Encoder = new TextEncoder()
9396

9497
if (fileType === "page") {
98+
const path = published == "true" ? "/pages" : "/admin-preview-page"
99+
95100
const createdPageName = pageTitle
96101
.toLowerCase()
97102
.replace(/[^a-zA-Z0-9-_ ]/g, "") // Remove special characters except hyphen and underscore
@@ -103,9 +108,12 @@ ${fileContents}`
103108

104109
const utf8Array = utf8Encoder.encode(pageContents)
105110
await drive.put(`pages/${createdPageName}.md`, { data: utf8Array })
106-
res.writeHead(302, { Location: `/pages/${createdPageName}` })
111+
res.writeHead(302, { Location: `${path}/${createdPageName}` })
107112
res.end()
113+
return
108114
} else {
115+
const path = published == "true" ? "/posts" : "/admin-preview-post"
116+
109117
const createdPostName = postTitle
110118
.toLowerCase()
111119
.replace(/[^a-zA-Z0-9-_ ]/g, "") // Remove special characters except hyphen and underscore
@@ -117,8 +125,9 @@ ${fileContents}`
117125

118126
const utf8Array = utf8Encoder.encode(postContents)
119127
await drive.put(`posts/${createdPostName}.md`, { data: utf8Array })
120-
res.writeHead(302, { Location: `/posts/${createdPostName}` })
128+
res.writeHead(302, { Location: `${path}/${createdPostName}` })
121129
res.end()
130+
return
122131
}
123132
})
124133
})

routes/admin/adminPreviewRoute.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { getPages, getPosts, prevNext } from "../../functions/blog-doc.js"
2+
import { initializeApp } from "../../functions/initialize.js"
3+
import { idsInHeadings } from "../../functions/helpers.js"
4+
import { getSettings } from "../../functions/settings.js"
5+
import { marked } from "marked"
6+
7+
const { eta } = initializeApp()
8+
9+
// Markdown Route
10+
export function adminPreviewRoute(app) {
11+
/**
12+
* Due to Velocy architecture, a route without a defined start point cannot be reached.
13+
* This is why two routes are created, one for the pages and the other for posts.
14+
* In short, the following route "/:folder/:filename" doesn't work in Velocy.
15+
*/
16+
app.get("/admin-preview-page/:filename", async (req, res) => {
17+
const settings = await getSettings()
18+
19+
const pages = await getPages()
20+
const unpublishedPages = pages.filter((page) => page[1].frontmatter.published == "false")
21+
const currentFile = unpublishedPages.find((file) => file.path === `pages/${req.params.filename}.md`)
22+
23+
if (currentFile) {
24+
const fileData = currentFile[1].frontmatter
25+
fileData.favicon = settings.favicon
26+
const fileContent = marked.parse(currentFile[1].content)
27+
const response = eta.render(`themes/${settings.currentTheme}/layouts/base.html`, {
28+
// Passing Route data
29+
mdRoute: true,
30+
// Passing Markdown file data
31+
data: fileData,
32+
content: settings.addIdsToHeadings ? idsInHeadings(fileContent) : fileContent,
33+
// Passing data to edit the file
34+
editable: true,
35+
filename: req.params.filename,
36+
// Passing needed settings for the template
37+
siteTitle: settings.siteTitle,
38+
menuLinks: settings.menuLinks,
39+
footerCopyright: settings.footerCopyright,
40+
})
41+
res.writeHead(200, { "Content-Type": "text/html" })
42+
res.end(response)
43+
} else {
44+
// Proceed to the 404 route if no file is found
45+
res.writeHead(302, { Location: "/404" })
46+
res.end()
47+
}
48+
})
49+
50+
app.get("/admin-preview-post/:filename", async (req, res) => {
51+
const settings = await getSettings()
52+
53+
const posts = await getPosts()
54+
const unpublishedPosts = posts.filter((post) => post[1].frontmatter.published == "false")
55+
const currentFile = unpublishedPosts.find((file) => file.path === `posts/${req.params.filename}.md`)
56+
57+
if (currentFile) {
58+
const fileData = currentFile[1].frontmatter
59+
fileData.favicon = settings.favicon
60+
const fileContent = marked.parse(currentFile[1].content)
61+
const response = eta.render(`themes/${settings.currentTheme}/layouts/base.html`, {
62+
// Passing Route data
63+
mdRoute: true,
64+
// Passing Markdown file data
65+
data: fileData,
66+
content: settings.addIdsToHeadings ? idsInHeadings(fileContent) : fileContent,
67+
prevNext: currentFile.dir === "posts" ? await prevNext(`${req.params.filename}.md`) : null,
68+
// Passing data to edit the file
69+
editable: true,
70+
filename: req.params.filename,
71+
// Passing needed settings for the template
72+
siteTitle: settings.siteTitle,
73+
menuLinks: settings.menuLinks,
74+
footerCopyright: settings.footerCopyright,
75+
})
76+
res.writeHead(200, { "Content-Type": "text/html" })
77+
res.end(response)
78+
} else {
79+
// Proceed to the 404 route if no file is found
80+
res.writeHead(302, { Location: "/404" })
81+
res.end()
82+
}
83+
})
84+
}

routes/admin/adminRoute.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const adminUpdateDelete = (app) => {
133133
postImage,
134134
postTags,
135135
fileContents,
136+
published,
136137
} = fields
137138

138139
const updatedFile = filePath.split("/").pop().replace(".md", "")
@@ -142,14 +143,17 @@ const adminUpdateDelete = (app) => {
142143
title: ${pageTitle}
143144
description: ${pageDescription}
144145
featuredImage: ${pageImage}
146+
published: ${published}
145147
---
146148
${fileContents}`
147149

148150
const utf8Encoder = new TextEncoder()
149151
const utf8Array = utf8Encoder.encode(pageContents)
152+
const path = published == "true" ? "/pages" : "/admin-preview-page"
150153

151154
await drive.put(`${filePath}`, { data: utf8Array })
152-
res.writeHead(302, { Location: `/pages/${updatedFile}` })
155+
156+
res.writeHead(302, { Location: `${path}/${updatedFile}` })
153157
res.end()
154158
return
155159
} else {
@@ -159,14 +163,17 @@ date: ${postDate.split("-").join("/")}
159163
description: ${postDescription}
160164
featuredImage: ${postImage}
161165
tags: [${postTags}]
166+
published: ${published}
162167
---
163168
${fileContents}`
164169

165170
const utf8Encoder = new TextEncoder()
166171
const utf8Array = utf8Encoder.encode(postContents)
172+
const path = published == "true" ? "/posts" : "/admin-preview-post"
167173

168174
await drive.put(`${filePath}`, { data: utf8Array })
169-
res.writeHead(302, { Location: `/posts/${updatedFile}` })
175+
176+
res.writeHead(302, { Location: `${path}/${updatedFile}` })
170177
res.end()
171178
return
172179
}

routes/archiveRoute.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export function archiveRoute(app) {
99
app.get("/posts", async (req, res) => {
1010
const settings = await getSettings()
1111

12-
const posts = await getPosts()
12+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
1313

1414
const data = {
1515
title: "Archive",

routes/mainRoute.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export function mainRoute(app) {
99
app.get("/", async (req, res) => {
1010
const settings = await getSettings()
1111

12-
const posts = await getPosts()
12+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
1313
const paginatedPosts = paginator(posts, 1, settings.postsPerPage) // Paginate all the posts. Set the first page to 1 and X posts per page.
1414
const newestPosts = paginatedPosts.data // Get the first X posts.
1515
const lastPage = paginatedPosts.total_pages - 1 // Get the last page number by removing 1 from the total number of pages.
@@ -47,7 +47,7 @@ export function mainRoute(app) {
4747
app.get("/page/:actualBlogPage", async (req, res) => {
4848
const settings = await getSettings()
4949

50-
const posts = await getPosts()
50+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
5151
const paginatedPosts = paginator(posts, 1, settings.postsPerPage) // Paginate all the posts. Set the first page to 1 and X posts per page.
5252
const lastPage = paginatedPosts.total_pages - 1 // Get the last page number by removing 1 from the total number of pages.
5353

routes/markdownRoute.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export function markdownRoute(app) {
1717
const settings = await getSettings()
1818

1919
const pages = await getPages()
20-
21-
const currentFile = pages.find((file) => file.path === `pages/${req.params.filename}.md`)
20+
const publishedPages = pages.filter((page) => page[1].frontmatter.published == "true")
21+
const currentFile = publishedPages.find((file) => file.path === `pages/${req.params.filename}.md`)
2222

2323
if (currentFile) {
2424
const fileData = currentFile[1].frontmatter
@@ -51,8 +51,8 @@ export function markdownRoute(app) {
5151
const settings = await getSettings()
5252

5353
const posts = await getPosts()
54-
55-
const currentFile = posts.find((file) => file.path === `posts/${req.params.filename}.md`)
54+
const publishedPosts = posts.filter((post) => post[1].frontmatter.published == "true")
55+
const currentFile = publishedPosts.find((file) => file.path === `posts/${req.params.filename}.md`)
5656

5757
if (currentFile) {
5858
const fileData = currentFile[1].frontmatter

routes/rssRoute.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function rssRoute(app) {
1010
const settings = await getSettings()
1111

1212
// Get the posts array
13-
const posts = await getPosts()
13+
const posts = (await getPosts()).filter((post) => post[1].frontmatter.published == "true")
1414

1515
const response = eta.render(`themes/${settings.currentTheme}/layouts/rss.html`, {
1616
// Passing needed settings for the template

0 commit comments

Comments
 (0)