added reading mode for blog posts

This commit is contained in:
Ellpeck 2019-10-09 15:51:43 +02:00
parent 71916a7f6f
commit 30b3dec0fa
7 changed files with 185 additions and 80 deletions

5
.gitignore vendored
View file

@ -1,2 +1,7 @@
node_modules node_modules
package-lock.json package-lock.json
sitemap.xml
feed.json
rss.xml
atom.xml
blog-*.html

View file

@ -51,7 +51,7 @@
<!-- Navbar content --> <!-- Navbar content -->
<div class="collapse navbar-collapse" id="navbar-content"> <div class="collapse navbar-collapse" id="navbar-content">
<div class="navbar-nav mr-auto"> <div class="navbar-nav mr-auto" id="nav-items">
<a class="nav-item nav-link" href="#projects">Projects</a> <a class="nav-item nav-link" href="#projects">Projects</a>
<a class="nav-item nav-link" href="#social">Social</a> <a class="nav-item nav-link" href="#social">Social</a>
<a class="nav-item nav-link" href="#about">About</a> <a class="nav-item nav-link" href="#about">About</a>
@ -68,6 +68,10 @@
<!-- Content --> <!-- Content -->
<div class="container main"> <div class="container main">
<!-- Cookie notification -->
<script src="scripts/cookies.js"></script>
<div id="main">
<!-- Home --> <!-- Home -->
<div class="jumbotron"> <div class="jumbotron">
<div class="container"> <div class="container">
@ -85,9 +89,6 @@
</div> </div>
</div> </div>
<!-- Cookie notification -->
<script src="scripts/cookies.js"></script>
<!-- Projects --> <!-- Projects -->
<a class="anchor" id="projects"></a> <a class="anchor" id="projects"></a>
<div class="list-display rounded"> <div class="list-display rounded">
@ -156,6 +157,7 @@
<script src="scripts/blog.js"></script> <script src="scripts/blog.js"></script>
</div> </div>
</div> </div>
</div>
<!-- Footer --> <!-- Footer -->
<div class="footer rounded-top"> <div class="footer rounded-top">

62
node/blog.js Normal file
View file

@ -0,0 +1,62 @@
const {
JSDOM
} = require("jsdom");
const fs = require("fs");
require("showdown-prettify");
const showdown = require("showdown");
const converter = new showdown.Converter({
parseImgDimensions: true,
headerLevelStart: 3,
extensions: ["prettify"]
});
module.exports = function () {
let folder = __dirname + "/../";
fs.watchFile(folder + "blog/posts.json", function (curr, prev) {
if (curr.mtime == prev.mtime)
return;
console.log("Refreshing blog sub-sites...");
fs.readFile(folder + "index.html", function (_, data) {
// set up the template
let templateDom = new JSDOM(data);
var templateDoc = templateDom.window.document;
templateDoc.getElementById("main").innerHTML = "";
let template = templateDom.serialize();
fs.readFile(folder + "blog/posts.json", function (_, data) {
let json = JSON.parse(data);
for (let post of json) {
let id = post["id"];
fs.readFile(folder + "blog/" + id + ".md", function (_, content) {
let dom = new JSDOM(template);
var document = dom.window.document;
document.title += " - " + post["name"];
document.querySelector('meta[property="og:title"]').setAttribute("content", post["name"]);
document.querySelector('meta[name="description"]').setAttribute("content", post["summary"]);
document.querySelector('meta[property="og:description"]').setAttribute("content", post["summary"]);
document.getElementById("nav-items").innerHTML = '<a class="nav-item nav-link" href="/#blog-' + id + '">Back to Main Page</a>'
var c = "";
c += '<div class="list-display rounded">';
c += '<div class="blog-isolated">'
c += '<h2 class="card-title">' + post["name"] + '</h2>';
c += '<div class="card-text" id="blog-post-' + id + '">'
c += converter.makeHtml(content.toString());
c += '</div>';
c += '<span class="text-muted project-status blog-isolated-status">' + post["date"] + "</span>";
var discussLink = post["discuss"];
if (discussLink)
c += '<a href="' + discussLink + '" class="blog-discuss" id="blog-discuss-' + id + '">Discuss this post</a>'
c += '</div></div>';
document.getElementById("main").innerHTML = c;
let html = dom.serialize();
fs.writeFile(folder + "blog-" + id + ".html", html, function (_, _) {});
});
}
});
});
});
}

View file

@ -1,2 +1,3 @@
require("./rss")(); require("./rss")();
require("./blog")();
require("./sitemap")(); require("./sitemap")();

View file

@ -41,7 +41,7 @@ module.exports = function () {
for (let post of json) { for (let post of json) {
sitemap.add({ sitemap.add({
url: "/#blog-" + post["id"], url: "/blog-" + post["id"],
priority: 0.4 priority: 0.4
}); });
} }

View file

@ -19,6 +19,7 @@ $.ajax({
p += '<div class="card bg-light blog-entry rounded-0">'; p += '<div class="card bg-light blog-entry rounded-0">';
p += '<div class="card-body">'; p += '<div class="card-body">';
p += '<a class="blog-button" id="blog-button-' + id + '"><h2 class="card-title">' + obj["name"] + '</h2></a>'; p += '<a class="blog-button" id="blog-button-' + id + '"><h2 class="card-title">' + obj["name"] + '</h2></a>';
p += '<a class="reading-mode" href="/blog-' + id + '" id="reading-mode-' + id + '"></a>';
p += '<div class="card-text text-muted blog-summary" id="blog-summary-' + id + '">' + obj["summary"] + '</div>'; p += '<div class="card-text text-muted blog-summary" id="blog-summary-' + id + '">' + obj["summary"] + '</div>';
p += '<div class="card-text" id="blog-post-' + id + '"></div>'; p += '<div class="card-text" id="blog-post-' + id + '"></div>';
p += '<span class="text-muted project-status">' + obj["date"] + "</span>"; p += '<span class="text-muted project-status">' + obj["date"] + "</span>";
@ -36,6 +37,7 @@ $.ajax({
if (discuss.length) if (discuss.length)
discuss.html(""); discuss.html("");
$("#blog-summary-" + id).show(); $("#blog-summary-" + id).show();
$("#reading-mode-" + id).html("");
history.pushState(null, null, "#blog"); history.pushState(null, null, "#blog");
} else { } else {
openBlogPost(id); openBlogPost(id);
@ -66,6 +68,7 @@ function openBlogPost(id, onDone) {
if (discuss.length) if (discuss.length)
discuss.html("Discuss this post"); discuss.html("Discuss this post");
$("#blog-summary-" + id).hide(); $("#blog-summary-" + id).hide();
$("#reading-mode-" + id).html("Reading Mode");
PR.prettyPrint(); PR.prettyPrint();
if (onDone) if (onDone)

View file

@ -1,8 +1,13 @@
html {
position: relative;
min-height: 100%;
}
body { body {
margin-top: 106px; margin-top: 106px;
position: relative;
font-family: Roboto; font-family: Roboto;
background-color: #404142; background-color: #404142;
margin-bottom: 100px;
} }
.main { .main {
@ -28,7 +33,8 @@ body {
} }
.jumbotron { .jumbotron {
margin-bottom: 0; margin-bottom: 40px;
margin-top: 40px;
} }
.project-image { .project-image {
@ -98,11 +104,16 @@ body {
} }
.footer { .footer {
position: absolute;
left: 0;
right: 0;
bottom: 0; bottom: 0;
line-height: 30px;
background-color: #f5f5f5; background-color: #f5f5f5;
padding: 15px; padding-left: 15px;
padding-right: 15px;
overflow: auto; overflow: auto;
height: 60px;
line-height: 60px;
} }
.impressum-data { .impressum-data {
@ -138,6 +149,21 @@ body {
margin: auto; margin: auto;
} }
.blog-isolated {
position: relative;
}
.blog-isolated-status {
bottom: 0 !important;
right: 0 !important;
}
.reading-mode {
position: absolute;
right: 20px;
top: 15px;
}
@media (min-width: 1200px) { @media (min-width: 1200px) {
.navbar { .navbar {
width: 1200px; width: 1200px;
@ -162,6 +188,12 @@ body {
padding-left: 20px; padding-left: 20px;
padding-right: 20px; padding-right: 20px;
} }
.reading-mode {
position: relative;
right: auto;
top: auto;
}
} }
@media (max-width: 510px) { @media (max-width: 510px) {