Skip to content

Commit eace3fe

Browse files
committed
first commit
0 parents  commit eace3fe

File tree

1,913 files changed

+192317
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,913 files changed

+192317
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
.DS_Store

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# ThonelJS
2+
3+
Website hosting should not be a hassle.
4+
5+
## ## About
6+
7+
I wanted to host a simple website somewhere and know that it would not go down when I forget to pay the hosting. That is why I chose Github Pages as my hosting platform. Github Pages only has one problem. I do not want to write HTML. This lead to ThonelJS creation. ThonelJS automatically generates new HTML and updates it to the git repository.
8+
9+
I also made a simple web server which made it possible to preview the website locally at [localhost:8000](http://localhost:8000).
10+
11+
[Read more...](https://thoneljs.github.io/about.html)
12+
13+
## Usage
14+
15+
As a blogger you should only focus onto the `content` folder and most specifically `articles` folder inside it. `articles` folder contains your blog posts. The title will be grabbed from the filename (`.md` suffix will be removed) so writing title inside markdown file is unnecessary (and leads to duplicate title).
16+
17+
`/content/info.json` is like your blog settings. It uses JSON to store the website title and description.
18+
19+
`/content/index.md` is the frontpage of your website. If you rename or remove it the frontpage will show a list of all the blog posts. The same applies to `/content/about.md` which will be shown only if it exists.
20+
21+
If you want to preview the changes before pushing them (very much RECOMMENDED) you can do that by running `node .` in the ThonelJS folder. This although requires Node.JS to be installed on your machine.
22+
23+
## Bugs
24+
25+
See them [here](https://thoneljs.github.io/Common%20bugs.md)

about.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const fs = require('fs');
2+
3+
exports.exists = () => {
4+
if (fs.existsSync('./content/about.md'))
5+
return true;
6+
return false;
7+
}
8+
9+
exports.read = () => {
10+
const content = fs
11+
.readFileSync(`./content/about.md`)
12+
.toString();
13+
14+
return content;
15+
};

app.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const fs = require('fs');
2+
const express = require('express');
3+
const showdown = require('showdown');
4+
5+
const articles = require('./articles');
6+
const frontpage = require('./frontpage');
7+
const about = require('./about');
8+
9+
const app = express();
10+
app.set('view engine', 'pug');
11+
const port = 8000;
12+
const converter = new showdown.Converter();
13+
14+
if (about.exists()) {
15+
app.locals.about = true;
16+
}
17+
18+
app.locals.info = JSON.parse(fs.readFileSync('./content/info.json'));
19+
20+
app.get('/', (req, res) => {
21+
if (frontpage.exists()) {
22+
const html = converter.makeHtml(frontpage.read());
23+
return res.render('index', { content: html });
24+
}
25+
26+
return res.render('list', { articles: articles.list() });
27+
});
28+
29+
app.get('/blog.html', (req, res) => {
30+
return res.render('list', { articles: articles.list() });
31+
});
32+
33+
app.get('/about.html', (req, res) => {
34+
const html = converter.makeHtml(about.read());
35+
return res.render('about', { content: html });
36+
});
37+
38+
app.get('/:article', (req, res) => {
39+
const article = req.params.article;
40+
if (articles.exists(article)) {
41+
const html = articles.read(article, 0, true);
42+
return res.render('article', { content: html, title: article });
43+
} else {
44+
res.redirect('/');
45+
}
46+
});
47+
48+
app.listen(port, () => {
49+
console.log(`Web server at http://localhost:${port}`);
50+
});

articles.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const fs = require('fs');
2+
const showdown = require('showdown');
3+
4+
// TODO: Do not use filename as title. Instead use the first h1.
5+
6+
const converter = new showdown.Converter();
7+
8+
exports.read = (name, truncate = 0, outputHtml = false) => {
9+
if (!name.includes('.md'))
10+
name = `${name}.md`;
11+
12+
const content = fs
13+
.readFileSync(`./content/articles/${name}`)
14+
.toString();
15+
16+
const truncated = content
17+
.substring(0, truncate == 0 ? content.length : truncate);
18+
19+
if (outputHtml)
20+
return converter.makeHtml(truncated)
21+
22+
return truncated;
23+
};
24+
25+
exports.list = (outputHtml = false) => {
26+
articleList = fs.readdirSync(`./content/articles`);
27+
28+
let articles = [];
29+
30+
articleList.forEach(article => {
31+
articles.push({
32+
"name": article.replace('.md', ''),
33+
"caption": this.read(article, 200, outputHtml)
34+
});
35+
});
36+
37+
return articles;
38+
};
39+
40+
exports.exists = (name) => {
41+
console.log(name)
42+
if (!name.includes('.md'))
43+
name = `${name}.md`;
44+
45+
return fs.existsSync(`./content/articles/${name}`)
46+
};

content/about.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## Project
2+
3+
I wanted to host a simple website somewhere and know that it would not go down when I forget to pay the hosting. That is why I chose Github Pages as my hosting platform. Github Pages only has one problem. I do not want to write HTML. This lead to ThonelJS creation. ThonelJS automatically generates new HTML and updates it to the git repository.
4+
5+
I also made a simple web server which made it possible to preview the website locally at [localhost:8000](http://localhost:8000).
6+
7+
## Creator
8+
9+
[Roy Takanen](https://github.com/RoyTakanen/)
10+
11+
Web development and server management have always been important for me. I also follow actively activities on the cyber security field and try to understand them. The fascinating idea that code will be deployed automatically after it is finished has pushed me to learn more about Github Actions. I currentely use Docker to self-host email, password manager and file storage but I am looking forward to examine Kubernetes and Docker swarm.
12+
13+
## Tech stack
14+
15+
- Node.JS with following packages:
16+
- Showdown.JS
17+
- Pug
18+
- ExpressJS

content/articles/Choosing the name.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Choosing the name for a project has always been very difficult to me. First I tried to read other [static site generator](https://jamstack.org/generators/) names to find my own. This was not a success.
2+
3+
I continued searching and found two websites. These websites generated names for projects. They were [codenames.herokuapp.com](http://codenames.herokuapp.com/) and [foswig.js](https://mrsharpoblunto.github.io/foswig.js/). I used the latter to find the current name, ThanolJS. Originally it suggested thanol which was already reserver so added suffix JS into it.
4+
5+
The next problem was icon. I did not want the organization to look like some random new Github profile. That is why I went to [favicon.io](https://favicon.io/favicon-generator/). I was able to generate a pretty looking white `T` on black background with following settings:
6+
7+
----
8+
9+
**Text:** *T*
10+
11+
**Background:** *Rounded*
12+
13+
**Font Family:** *Leckerli One*
14+
15+
**Font Variant:** *Regular 400 Normal*
16+
17+
**Font Size:** *110*
18+
19+
**Font Color:** `#FFFFFF`
20+
21+
**Background Color:** `#222`
22+
23+
----

content/articles/Common bugs.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
This project was made in a hurry so bugs are common here. I will try to fix them as soon as possible, though.
2+
3+
**List of bugs**
4+
5+
- No `?`-character in article names (it is handled as GET parameter and does not work)
6+
- Caption generation contains raw markdown

content/index.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## About
2+
3+
I wanted to host a simple website somewhere and know that it would not go down when I forget to pay the hosting. That is why I chose Github Pages as my hosting platform. Github Pages only has one problem. I do not want to write HTML. This lead to ThonelJS creation. ThonelJS automatically generates new HTML and updates it to the git repository.
4+
5+
I also made a simple web server which made it possible to preview the website locally at [localhost:8000](http://localhost:8000).
6+
7+
[Read more...](about.html)
8+
9+
## Usage
10+
11+
As a blogger you should only focus onto the `content` folder and most specifically `articles` folder inside it. `articles` folder contains your blog posts. The title will be grabbed from the filename (`.md` suffix will be removed) so writing title inside markdown file is unnecessary (and leads to duplicate title).
12+
13+
`/content/info.json` is like your blog settings. It uses JSON to store the website title and description.
14+
15+
`/content/index.md` is the frontpage of your website. If you rename or remove it the frontpage will show a list of all the blog posts. The same applies to `/content/about.md` which will be shown only if it exists.
16+
17+
If you want to preview the changes before pushing them (very much RECOMMENDED) you can do that by running `node .` in the ThonelJS folder. This although requires Node.JS to be installed on your machine.
18+
19+
## Bugs
20+
21+
See them [here](Common%20bugs)

content/info.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "ThonelJS",
3+
"description": "Website hosting should not be a hassle."
4+
}

docs/Initial release.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<html><head><title>HimosCMS</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"/></head><body><header><nav> <a href="index.html">Home</a><a href="blog.html">Blog</a><h1>HimosCMS</h1><p>Static blog generator for Github pages (free hosting).</p></nav></header><article><h1>Initial release</h1><div><p>This is just an example blog post to demonstrate this…</p></div></article><hr/></body></html>

docs/about.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<html><head><title>HimosCMS</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"/></head><body><header><nav> <a href="index.html">Home</a><a href="blog.html">Blog</a><h1>HimosCMS</h1><p>Static blog generator for Github pages (free hosting).</p></nav></header><div><h1 id="aboutthistool">About this tool</h1>
2+
<h2 id="whytouse">Why to use</h2>
3+
<ul>
4+
<li>Free</li>
5+
<li>Simple</li>
6+
</ul>
7+
<h2 id="howitismade">How it is made?</h2>
8+
<p>The stack that we are using here consists of:</p>
9+
<ul>
10+
<li>Node.JS with following packages:</li>
11+
<li>Showdown.JS</li>
12+
<li>Pug</li>
13+
<li>ExpressJS</li>
14+
</ul></div></body></html>

docs/blog.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<html><head><title>HimosCMS</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"/></head><body><header><nav> <a href="index.html">Home</a><a href="blog.html">Blog</a><h1>HimosCMS</h1><p>Static blog generator for Github pages (free hosting).</p></nav></header><article><a href="Initial release"><h2>Initial release</h2></a><i>This is just an example blog post to demonstrate this...</i><hr/></article></body></html>

docs/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<html><head><title>HimosCMS</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css"/></head><body><header><nav> <a href="index.html">Home</a><a href="blog.html">Blog</a><h1>HimosCMS</h1><p>Static blog generator for Github pages (free hosting).</p></nav></header><div><h1 id="himoscms">HimosCMS</h1>
2+
<p>This is HimosCMS. Our goal is to be a simple, elegant and tiny blog solution for Github pages.</p></div></body></html>

frontpage.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const fs = require('fs');
2+
3+
exports.exists = () => {
4+
if (fs.existsSync('./content/index.md'))
5+
return true;
6+
return false;
7+
}
8+
9+
exports.read = () => {
10+
const content = fs
11+
.readFileSync(`./content/index.md`)
12+
.toString();
13+
14+
return content;
15+
};

generate.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const fs = require('fs');
2+
const showdown = require('showdown');
3+
const pug = require('pug');
4+
5+
const articles = require('./articles');
6+
const frontpage = require('./frontpage');
7+
const about = require('./about');
8+
9+
converter = new showdown.Converter();
10+
11+
fs.rmSync('./docs', { recursive: true, force: true });
12+
fs.mkdirSync('./docs');
13+
14+
const info = JSON.parse(fs.readFileSync('./content/info.json'));
15+
16+
// About page
17+
const aboutHtml = pug.renderFile('./views/about.pug', {
18+
info,
19+
content: converter.makeHtml(about.read())
20+
});
21+
22+
fs.writeFileSync('./docs/about.html', aboutHtml);
23+
24+
// Frontpage
25+
if (frontpage.exists()) {
26+
const frontpageHtml = pug.renderFile('./views/index.pug', {
27+
info,
28+
content: converter.makeHtml(frontpage.read())
29+
});
30+
} else {
31+
const frontpageHtml = pug.renderFile('./views/list.pug', {
32+
info,
33+
articles: articles.list()
34+
});
35+
}
36+
37+
fs.writeFileSync('./docs/index.html', frontpageHtml);
38+
39+
// Blog
40+
const blogHtml = pug.renderFile('./views/list.pug', {
41+
info,
42+
articles: articles.list()
43+
});
44+
45+
fs.writeFileSync('./docs/blog.html', blogHtml);
46+
47+
48+
// Individual articles
49+
console.log(`Generating pages for ${articles.list().length} articles...`);
50+
51+
articles.list().forEach((article) => {
52+
const articleHtml = pug.renderFile('./views/article.pug', {
53+
info,
54+
content: articles.read(article.name, 0, true),
55+
title: article.name
56+
});
57+
58+
fs.writeFileSync(`./docs/${article.name}.html`, articleHtml);
59+
});

node_modules/.bin/acorn

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/commonmark

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/mime

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/parser

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/resolve

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/showdown

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)