Skip to content

Commit

Permalink
feat: replacing drafts and published: false by underscore files
Browse files Browse the repository at this point in the history
  • Loading branch information
TayzenDev committed Nov 18, 2024
1 parent 57b0fb1 commit df9b1aa
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 80 deletions.
17 changes: 8 additions & 9 deletions article_generator.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import * as path from "@std/path";
import * as fs from "@std/fs";

const DEFAULT_CONTENT = `This is my first article. This is an image:
![RSS](first-article/exampleImage.svg)
`

function generateArticle(
title: string = "My first article",
content: string = "This is my first article",
published: boolean = true,
tags: string[] = ["markdown", "test"],
authors: string[] = ["Default author"],
date: string = new Date().toISOString().split("T")[0],
Expand All @@ -17,7 +21,6 @@ function generateArticle(
- ${authors.join("\n - ")}
tags:
- ${tags.join("\n - ")}
published: ${published}
date: ${date}
section: ${section}
---
Expand All @@ -29,25 +32,22 @@ function generateArticle(
}

export function storeArticle(
folder: string,
folder: string = "",
filename: string = "first-article.md",
params: {
title?: string;
content?: string;
preview?: string;
description?: string;
published?: boolean;
tags?: string[];
authors?: string[];
date?: string;
section?: string;
} = {
title: "My first article",
content:
"This is my first article. This is an image:\n\n![RSS](first-article/exampleImage.svg)",
content: DEFAULT_CONTENT,
preview: "This is the first article of this blog.",
description: "A post which contains the first article of this blog.",
published: true,
tags: ["markdown", "test"],
authors: ["Default author"],
date: new Date().toISOString().split("T")[0],
Expand All @@ -58,7 +58,6 @@ export function storeArticle(
const article = generateArticle(
params.title,
params.content,
params.published,
params.tags,
params.authors,
params.date,
Expand All @@ -70,7 +69,7 @@ export function storeArticle(
}
}

const svgExample = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rss"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>`;
const svgExample = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rss"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>`;

function createCompanionFolder(folder: string, filename: string) {
const ext = path.extname(filename);
Expand Down
7 changes: 1 addition & 6 deletions blog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function getArticles(
): Article[] {
let postsNames: string[] = [];
try {
for (const entry of fs.expandGlobSync(path.join(postsFolder, "*.md"))) {
for (const entry of fs.expandGlobSync(path.join(postsFolder, "[!_]*.md"))) {
postsNames = postsNames.concat(entry.name);
}
} catch (e) {
Expand All @@ -48,7 +48,6 @@ export function getArticles(
defaultAuthors,
);
})
.filter((article) => article.metadata.published !== false)
.filter((article) => article.content !== "");

return articles.sort((a, b) => {
Expand Down Expand Up @@ -167,7 +166,6 @@ type MetadataProps = {
authors?: string | string[];
tag?: string | string[];
tags?: string | string[];
published?: boolean;
date?: Date;
modificationDate?: Date;
redirect?: string;
Expand All @@ -181,7 +179,6 @@ export class Metadata {
description?: string;
authors?: string[];
tags?: string[];
published?: boolean;
date?: Date;
modificationDate?: Date;
redirect?: string;
Expand All @@ -198,7 +195,6 @@ export class Metadata {
author,
tags,
tag,
published,
date,
modificationDate,
redirect,
Expand Down Expand Up @@ -231,7 +227,6 @@ export class Metadata {
this.tags = actualTags;
}

this.published = published;
this.date = date || fileStats?.birthtime || undefined;
this.modificationDate = modificationDate || fileStats?.mtime || undefined;
this.redirect = redirect;
Expand Down
43 changes: 13 additions & 30 deletions cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import manifest from "./deno.json" with { type: "json" };

type CLI = (args: string[]) => void;

export function createCli(postsFolder: string, draftsFolder: string): CLI {
export function createCli(postsFolder: string): CLI {
const program = new Command();

program
Expand Down Expand Up @@ -34,7 +34,9 @@ export function createCli(postsFolder: string, draftsFolder: string): CLI {
.action((fileId, options) => {
console.log("Creating post...");
try {
const folder = options.published ? postsFolder : draftsFolder;
const underscoreToAdd = options.published ? false : !fileId.startsWith("_");
const filename = path.join(postsFolder, (underscoreToAdd ? "_" : "") + fileId + ".md");
const folder = postsFolder;
const params = {
title: options.title as string,
content: options.content as string,
Expand All @@ -45,7 +47,7 @@ export function createCli(postsFolder: string, draftsFolder: string): CLI {
date: options.date as string,
section: options.section as string,
};
storeArticle(folder, fileId + ".md", params);
storeArticle(folder, filename, params);
console.log("Post created.");
} catch (e) {
console.error("Error while creating post:", e);
Expand All @@ -62,12 +64,8 @@ export function createCli(postsFolder: string, draftsFolder: string): CLI {
console.log("Publishing post...");
try {
fs.moveSync(
path.join(draftsFolder, fileId + ".md"),
path.join(postsFolder, fileId + ".md"),
);
fs.moveSync(
path.join(draftsFolder, fileId),
path.join(postsFolder, fileId),
path.join(fileId + ".md"),
path.join((!fileId.startsWith("_") ? fileId : fileId.substring(1)) + ".md"),
);
console.log("Post published.");
} catch (e) {
Expand All @@ -88,15 +86,15 @@ export function createCli(postsFolder: string, draftsFolder: string): CLI {
if (options.all || options.published || !options.drafts) {
console.log("");
console.log("Published:");
for (const file of fs.expandGlobSync(path.join(postsFolder, "*.md"))) {
for (const file of fs.expandGlobSync(path.join(postsFolder, "[!_]*.md"))) {
console.log(" - ", file.name.replace(".md", ""));
}
}
if (options.all || options.drafts || !options.published) {
console.log("");
console.log("Drafts:");
for (const file of fs.expandGlobSync(path.join(draftsFolder, "*.md"))) {
console.log(" - ", file.name.replace(".md", ""));
for (const file of fs.expandGlobSync(path.join(postsFolder, "_*.md"))) {
console.log(" - ", file.name.replace(".md", "").replace("_", ""));
}
}
console.log("");
Expand All @@ -112,11 +110,7 @@ export function createCli(postsFolder: string, draftsFolder: string): CLI {
try {
fs.moveSync(
path.join(postsFolder, fileId + ".md"),
path.join(draftsFolder, fileId + ".md"),
);
fs.moveSync(
path.join(postsFolder, fileId),
path.join(draftsFolder, fileId),
path.join((fileId.startsWith("_") ? fileId : "_" + fileId) + ".md"),
);
console.log("Post archived.");
} catch (e) {
Expand All @@ -129,27 +123,16 @@ export function createCli(postsFolder: string, draftsFolder: string): CLI {
.command("remove")
.alias("rm")
.description(
"Remove a blog post. You can only delete a draft post. If you want to delete a published post, use `smallblog archive` first.",
"Remove a blog post. You can only delete a draft post. If you want to delete a published post, use `smallblog archive` first. This does NOT delete the images or videos of the post, You should delete them manually.",
)
.argument("<name>", "The id of the post (no space allowed)")
.action((fileId) => {
console.log("Removing post...");
let errors = 0;
try {
Deno.removeSync(path.join(draftsFolder, fileId + ".md"));
Deno.removeSync(path.join(postsFolder, "_" + fileId + ".md"));
console.log("Post removed.");
} catch {
console.log("Post not found.");
errors++;
}
try {
Deno.removeSync(path.join(draftsFolder, fileId), { recursive: true });
console.log("Resources folder removed.");
} catch {
console.log("Resources folder not found.");
errors++;
}
if (errors == 2) {
Deno.exit(1);
}
});
Expand Down
Empty file removed data/drafts/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions data/posts/_hidden.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Hidden post

This is a hidden post
1 change: 0 additions & 1 deletion data/posts/post_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ tags:
- test
- markdown
- id123abc
published: true
date: 2024-10-08
---

Expand Down
4 changes: 1 addition & 3 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export class Smallblog {
constructor(config: Partial<SmallblogConfig> = {}) {
const {
postsFolder = "data/posts/",
draftsFolder = "data/drafts/",
pagesFolder = "data/pages/",
favicon,
siteTitle = "Smallblog",
Expand All @@ -33,7 +32,6 @@ export class Smallblog {

this.server = createServer({
postsFolder,
draftsFolder,
pagesFolder,
favicon,
siteTitle,
Expand All @@ -45,7 +43,7 @@ export class Smallblog {
customBodyScript,
customHeaderScript,
});
this.cli = createCli(postsFolder, draftsFolder);
this.cli = createCli(postsFolder);
}

/**
Expand Down
31 changes: 4 additions & 27 deletions server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export function createServer(config: SmallblogConfig) {
const server = new Hono();

const postsRoute = path.join("/", config.postsFolder);
const draftsRoute = path.join("/", config.draftsFolder);
const faviconIsUrl = isUrl(config.favicon || "");

const customPages = getArticles(config.pagesFolder, "/")
Expand Down Expand Up @@ -120,27 +119,6 @@ export function createServer(config: SmallblogConfig) {
);
});

server.get(path.join(draftsRoute, ":filename{.+$}"), (c) => {
const filename = c.req.param("filename");

if (!filename) {
// if the route is /article/
return new Response("Not found", { status: 404 });
}
if (path.extname(filename)) {
// if the name contains an ext this is not an article
return serveStaticFile(filename, config.draftsFolder);
}
return servePage(
c,
filename,
config.draftsFolder,
faviconIsUrl,
customPages,
config,
);
});

server.get("/rss.xml", (c) => {
const baseUrl = getBaseUrl(c);
const articles = getArticles(
Expand Down Expand Up @@ -181,7 +159,7 @@ export function createServer(config: SmallblogConfig) {
const baseUrl = getBaseUrl(c);
const robotTxt = `
User-agent: *
Disallow: /drafts
Disallow: ${new URL(path.join(postsRoute, "_*"), baseUrl).href}
Sitemap: ${new URL("/sitemap.xml", baseUrl).href}
`
.replace(/ +/g, "")
Expand All @@ -198,7 +176,6 @@ export function createServer(config: SmallblogConfig) {
});

server.get("/init", async (c) => {
fs.ensureDirSync(config.draftsFolder);
fs.ensureDirSync(config.postsFolder);
fs.ensureDirSync(config.pagesFolder);
if (await isDirectoryEmpty(config.postsFolder)) {
Expand Down Expand Up @@ -367,17 +344,17 @@ function serveStaticFile(name?: string, folder?: string) {
}

async function getNoArticlesMessage(opts: SmallblogConfig) {
const { noArticlesMessage, postsFolder, draftsFolder } = opts;
const { noArticlesMessage, postsFolder, pagesFolder } = opts;

if (noArticlesMessage) {
return noArticlesMessage;
}

const baseMessage = `<p>You have no articles yet, you can add them by creating a folder <code>${postsFolder}</code> and adding markdown files in it. Don't forget to also add a <code>${draftsFolder}</code> folder for your drafts.</p><p>Read the README for more informations.</p>`;
const baseMessage = `<p>You have no articles yet, you can add them by creating a folder <code>${postsFolder}</code> and adding markdown files in it. Don't forget to also add a <code>${pagesFolder}</code> folder if you want to add custom pages inside your navbar.</p><p>Read the README for more informations.</p>`;

const writePermission = await Deno.permissions.query({
name: "write",
path: ".",
path: postsFolder,
});

if (writePermission.state === "granted") {
Expand Down
4 changes: 0 additions & 4 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ export type SmallblogConfig = {
* used for the routes (ex: of you named your folder `abcd`, the route to a post will be
* `/abcd/my_post`). */
postsFolder: string;
/** The folder where your drafts are located (default: `drafts/`). The name of the folder will be
* used for the routes (ex: of you named your folder `abcd`, the route to a post will be
* `/abcd/my_post`). */
draftsFolder: string;
/** The folder where your custom pages are located (default: `pages/`). These pages are displayed
* inside the navbar and their route starts with `/`, following by the name of the file without
* extension. */
Expand Down

0 comments on commit df9b1aa

Please sign in to comment.