@lexho111/plainblog 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Article.js CHANGED
@@ -3,4 +3,14 @@ export default class Article {
3
3
  this.title = title;
4
4
  this.content = content;
5
5
  }
6
+
7
+ getContent() {
8
+ return this.content;
9
+ }
10
+
11
+ getContentShort() {
12
+ let contentShort = this.content.substring(0, 400);
13
+ contentShort += "...";
14
+ return contentShort;
15
+ }
6
16
  }
package/Blog.js CHANGED
@@ -1,10 +1,14 @@
1
1
  import http from "http";
2
+ import { promises as fs } from "fs";
3
+ import { URLSearchParams } from "url";
4
+ import Article from "./Article.js";
2
5
 
3
6
  export default class Blog {
4
7
  constructor() {
5
8
  this.title = "";
6
9
  this.articles = [];
7
10
  this.style = "body { font-family: Arial; }";
11
+ this.filename = null;
8
12
  }
9
13
 
10
14
  setTitle(title) {
@@ -21,8 +25,32 @@ export default class Blog {
21
25
 
22
26
  startServer(port = 8080) {
23
27
  const server = http.createServer((req, res) => {
24
- res.writeHead(200, { "Content-Type": "text/html" });
25
- res.end(this.toHTML());
28
+ if (req.method === "POST") {
29
+ let body = "";
30
+ req.on("data", (chunk) => {
31
+ body += chunk.toString();
32
+ });
33
+ req.on("end", async () => {
34
+ const params = new URLSearchParams(body);
35
+ const title = params.get("title");
36
+ const content = params.get("content");
37
+
38
+ if (title && content) {
39
+ this.addArticle(new Article(title, content));
40
+ // Auto-save if a file has been loaded or saved before
41
+ if (this.filename) {
42
+ await this.save();
43
+ }
44
+ }
45
+
46
+ // Redirect to the homepage to show the new article
47
+ res.writeHead(303, { Location: "/" });
48
+ res.end();
49
+ });
50
+ } else {
51
+ res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8" });
52
+ res.end(this.toHTML());
53
+ }
26
54
  });
27
55
 
28
56
  server.listen(port, () => {
@@ -30,6 +58,33 @@ export default class Blog {
30
58
  });
31
59
  }
32
60
 
61
+ async save(filename = this.filename) {
62
+ if (!filename) {
63
+ console.error("Error: Filename not provided and not set previously.");
64
+ return;
65
+ }
66
+ this.filename = filename;
67
+ const data = {
68
+ title: this.title,
69
+ articles: this.articles,
70
+ };
71
+
72
+ try {
73
+ await fs.writeFile(filename, JSON.stringify(data, null, 2));
74
+ console.log(`Blog data saved to ${filename}`);
75
+ } catch (err) {
76
+ console.error("Error saving blog data:", err);
77
+ }
78
+ }
79
+
80
+ async load(filename) {
81
+ this.filename = filename;
82
+ const data = await fs.readFile(filename, "utf8");
83
+ const { title, articles } = JSON.parse(data);
84
+ this.title = title;
85
+ this.articles = articles;
86
+ }
87
+
33
88
  print() {
34
89
  console.log(`# ${this.title}`);
35
90
  for (const article of this.articles) {
@@ -39,17 +94,36 @@ export default class Blog {
39
94
  }
40
95
 
41
96
  toHTML() {
42
- let html = `<style>${this.style}</style>`;
43
- html += `<h1>${this.title}</h1>`;
97
+ let html = `
98
+ <!DOCTYPE html>
99
+ <html lang="de">
100
+ <head>
101
+ <meta charset="UTF-8">
102
+ <title>${this.title}</title>
103
+ <style>${this.style}</style>
104
+ </head>
105
+ <body>`;
106
+ html += `<h1>${this.title}</h1><div style="width: 500px;">`;
107
+
108
+ html += `
109
+ <form action="/" method="POST">
110
+ <h3>Add a New Article</h3>
111
+ <input type="text" name="title" placeholder="Article Title" required style="display: block; width: 300px; margin-bottom: 10px;">
112
+ <textarea name="content" placeholder="Article Content" required style="display: block; width: 300px; height: 100px; margin-bottom: 10px;"></textarea>
113
+ <button type="submit">Add Article</button>
114
+ </form>
115
+ <hr>`;
44
116
 
45
117
  for (const article of this.articles) {
46
118
  html += `
47
119
  <article>
48
120
  <h2>${article.title}</h2>
49
- <p>${article.content}</p>
121
+ <p>${article.getContentShort()}</p>
50
122
  </article>`;
51
123
  }
52
124
 
125
+ html += `</div></body></html>`;
126
+
53
127
  return html;
54
128
  }
55
129
  }
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ```
2
2
  import { Blog, Article } from "@lexho111/plainblog";
3
3
 
4
- const blog = new Blog();
4
+ const bl og = new Blog();
5
5
  blog.setTitle("My Blog");
6
6
  blog.setStyle("body { font-family: Arial, sans-serif; } h1 { color: #333; }");
7
7
 
@@ -15,3 +15,11 @@ const article2 = new Article(
15
15
  blog.addArticle(article2);
16
16
  blog.startServer(8080);
17
17
  ```
18
+
19
+ ```
20
+ # save your blog to 'myblog.json'
21
+ await blog.save("myblog.json");
22
+
23
+ # load data from 'myblog.json'
24
+ await blog.load("myblog.json");
25
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexho111/plainblog",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "A tool for creating and serving a minimalist, single-page blog.",
5
5
  "main": "index.js",
6
6
  "type": "module",