1
0
mirror of https://github.com/tiyn/beaker-blog.git synced 2025-04-19 15:27:47 +02:00

Compare commits

..

9 Commits

Author SHA1 Message Date
b598b99c73 added favicon 2024-04-14 02:42:36 +02:00
1adad6762d improve style for code 2024-04-14 02:27:53 +02:00
e151dac3da make logo standard 2024-04-14 02:23:10 +02:00
98249bbbd9 added language support for german 2024-04-14 01:58:29 +02:00
1ac2ba220a improved light style for better readability 2024-04-14 00:44:27 +02:00
4679305c51 added more style and fixed a link bug 2024-04-14 00:31:07 +02:00
d83f66ab3d update automatically 2024-04-13 23:55:10 +02:00
6c586c6a89 minor style changes, added graphics volume 2024-04-13 23:41:02 +02:00
472d8c74c6 readme: fixed typo 2022-07-30 23:57:15 +02:00
16 changed files with 206 additions and 153 deletions

View File

@ -8,8 +8,20 @@ WORKDIR /blog
RUN pip3 install -r requirements.txt RUN pip3 install -r requirements.txt
RUN apt-get update && \
apt-get install -y locales && \
sed -i -e 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen && \
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
VOLUME /blog/templates/entry VOLUME /blog/templates/entry
VOLUME /blog/static/graphics
EXPOSE 5000 EXPOSE 5000
ENTRYPOINT [ "python3" ] ENTRYPOINT [ "python3" ]

View File

@ -26,6 +26,9 @@ via plain text files.
- [x] Switchable CSS - [x] Switchable CSS
- [x] CSS dark-theme - [x] CSS dark-theme
- [x] CSS light-theme - [x] CSS light-theme
- [x] Language Support
- [x] English
- [x] German
- [x] Config file - [x] Config file
- [x] Docker installation - [x] Docker installation
- [x] Logo - [x] Logo
@ -59,11 +62,12 @@ The `config.py` can be found in the `src` folder.
Set the following volumes with the -v tag. Set the following volumes with the -v tag.
| Volume-Name | Container mount | Description | | Volume-Name | Container mount | Description |
| ------------- | --------------------------- | ------------------------------------------------------------ | | ------------- | ----------------------- | ------------------------------------------------------------ |
| `config-file` | `/blog/src/config.py` | Config file | | `config-file` | `/blog/config.py` | Config file |
| `entries` | `/blog/src/templates/entry` | Directory for blog entries | | `entries` | `/blog/templates/entry` | Directory for blog entries |
| `css` | `/blog/src/static/css` | (optional) Directory for css files | | `graphics` | `/blog/static/graphics` | Directory for images needed for entries |
| `html` | `/blog/src/templates` | (optional) Directory for templates (entry-volume not needed) | | `css` | `/blog/static/css` | (optional) Directory for css files |
| `html` | `/blog/templates` | (optional) Directory for templates (entry-volume not needed) |
#### Ports #### Ports

View File

@ -6,4 +6,6 @@ docker run --name beaker-blog \
--restart unless-stopped \ --restart unless-stopped \
-p "5000:5000" \ -p "5000:5000" \
-e FLASK_ENV=development \ -e FLASK_ENV=development \
-v entries:/blog/templates/entry \
-v graphics:/blog/static/graphics \
-d tiyn/beaker-blog -d tiyn/beaker-blog

View File

@ -8,33 +8,34 @@ app = Flask(__name__)
TITLE = config.TITLE TITLE = config.TITLE
STYLE = config.STYLE STYLE = config.STYLE
LANGUAGE = config.LANGUAGE
DESCRIPTION = config.DESCRIPTION DESCRIPTION = config.DESCRIPTION
WEBSITE = config.WEBSITE WEBSITE = config.WEBSITE
@app.errorhandler(404) @app.errorhandler(404)
def page_not_found(e): def page_not_found(e):
return render_template("error.html", title=TITLE, errorcode="404", style=STYLE), 404 return render_template("error.html", title=TITLE, errorcode="404", style=STYLE, language=LANGUAGE), 404
@app.route("/") @app.route("/")
@app.route("/index.html") @app.route("/index.html")
def index(): def index():
content = con_gen.gen_index_string() content = con_gen.gen_index_string()
return render_template("index.html", title=TITLE, content_string=content, style=STYLE) return render_template("index.html", title=TITLE, content_string=content, style=STYLE, language=LANGUAGE)
@app.route("/archive") @app.route("/archive")
@app.route("/archive.html") @app.route("/archive.html")
def archive(): def archive():
content = con_gen.gen_arch_string() content = con_gen.gen_arch_string()
return render_template("archive.html", title=TITLE, content_string=content, style=STYLE) return render_template("archive.html", title=TITLE, content_string=content, style=STYLE, language=LANGUAGE)
@app.route("/entry/<path>") @app.route("/entry/<path>")
def entry(path): def entry(path):
content = con_gen.gen_stand_string(path) content = con_gen.gen_stand_string(path)
if content != "": if content != "":
return render_template("standalone.html", title=TITLE, content_string=content, style=STYLE) return render_template("standalone.html", title=TITLE, content_string=content, style=STYLE, language=LANGUAGE)
abort(404) abort(404)

View File

@ -9,3 +9,6 @@ WEBSITE = "localhost:5000"
# Theme for the blog: dark, light # Theme for the blog: dark, light
STYLE = "dark" STYLE = "dark"
# Language for the titles: en-us or de-de
LANGUAGE = "en-us"

View File

@ -1,12 +1,20 @@
from datetime import datetime import locale
import markdown
import os import os
from os import path
import pathlib import pathlib
from datetime import datetime
from os import path
import config import config
import markdown
ENTRY_DIR = "templates/entry" ENTRY_DIR = "templates/entry"
LANGUAGE = config.LANGUAGE
LOCAL = "de_DE.UTF-8" if LANGUAGE == "de-de" else "en_US.UTF-8"
locale.setlocale(locale.LC_TIME, LOCAL)
standalone_str = "Artikel" if LANGUAGE == "de-de" else "standalone"
def gen_arch_string(): def gen_arch_string():
""" """
@ -23,10 +31,8 @@ def gen_arch_string():
content_string = "" content_string = ""
last_month = "" last_month = ""
for file in reversed(contents): for file in reversed(contents):
curr_date = datetime.fromtimestamp( curr_date = datetime.fromtimestamp(os.path.getctime(file)).strftime("%Y-%m-%d")
os.path.getctime(file)).strftime("%Y-%m-%d") curr_month = datetime.fromtimestamp(os.path.getctime(file)).strftime("%B %Y")
curr_month = datetime.fromtimestamp(
os.path.getctime(file)).strftime("%b %Y")
if curr_month != last_month: if curr_month != last_month:
if last_month != "": if last_month != "":
content_string += "</ul>\n" content_string += "</ul>\n"
@ -39,13 +45,11 @@ def gen_arch_string():
if filename[0] != ".": if filename[0] != ".":
filename = filename.split(".", 1)[0] filename = filename.split(".", 1)[0]
content_string += "<li>" content_string += "<li>"
content_string += curr_date + " - "
content_string += title + " ["
content_string += "<a href=\"" + "/index.html#" + \ content_string += "<a href=\"" + "/index.html#" + \
filename + "\">" + "link" + "</a> - " filename + "\">" + curr_date + "</a> - "
content_string += "<a href=\"" + "/entry/" + \ content_string += "<a href=\"" + "/entry/" + \
pathlib.PurePath(file).name + "\">" + "standalone" + "</a>" pathlib.PurePath(file).name + "\"><b>" + title + "</b></a>"
content_string += "] <br>" content_string += "<br>"
content_string += "</li>\n" content_string += "</li>\n"
content_string += "</ul>\n" content_string += "</ul>\n"
return content_string return content_string
@ -73,19 +77,19 @@ def gen_index_string():
if filename[0] != ".": if filename[0] != ".":
filename = filename.split(".", 1)[0] filename = filename.split(".", 1)[0]
content_string += "<div class=\"entry\">\n" content_string += "<div class=\"entry\">\n"
content_string += "<h2 id=\"" + filename + "\">" + title + "</h2>\n" content_string += "<h2 id=\"" + filename + "\">"
content_string += "[<a href=\"" + "/entry/" + \ content_string += "<a href=\"" + "/entry/" + \
pathlib.PurePath(file).name + "\">" + \ pathlib.PurePath(file).name + "\">" + \
"standalone" + "</a>]<br>\n" title + "</a>" +"</h2>\n"
content_string += "<small>" + \
datetime.fromtimestamp(os.path.getctime(
file)).strftime("%Y-%m-%d") + "</small><br><br>"
if file.endswith(".html"): if file.endswith(".html"):
for line in text: for line in text:
content_string += line content_string += line
content_string += "<br>" content_string += "<br>"
if file.endswith(".md"): if file.endswith(".md"):
content_string += gen_md_content(file, 2) content_string += gen_md_content(file, 2)
content_string += "<small>" + \
datetime.fromtimestamp(os.path.getctime(
file)).strftime("%Y-%m-%d") + "</small>"
content_string += "</div>" content_string += "</div>"
return content_string return content_string
@ -107,12 +111,13 @@ def gen_stand_string(path_ex):
if path.exists(filename): if path.exists(filename):
title = open(filename).readline().rstrip("\n") title = open(filename).readline().rstrip("\n")
text = open(filename).readlines()[1:] text = open(filename).readlines()[1:]
curr_date = datetime.fromtimestamp(os.path.getctime(filename)).strftime("%Y-%m-%d")
filename_no_end = filename.split(".", 1)[0] filename_no_end = filename.split(".", 1)[0]
filename_no_end = filename_no_end.split("/")[-1]
content_string += "<h1>" + title + "</h1>\n" content_string += "<h1>" + title + "</h1>\n"
content_string += "["
content_string += "<a href=\"" + "/index.html#" + \ content_string += "<a href=\"" + "/index.html#" + \
filename_no_end + "\">" + "link" + "</a>" filename_no_end + "\">" + curr_date + "</a>"
content_string += "]<br>\n" content_string += "<br>\n"
if filename.endswith(".html"): if filename.endswith(".html"):
for line in text: for line in text:
content_string += line content_string += line
@ -145,9 +150,7 @@ def gen_md_content(path_ex, depth):
markdown_text = "" markdown_text = ""
for line in markdown_lines: for line in markdown_lines:
markdown_text += line.replace("# ", header) markdown_text += line.replace("# ", header)
content_string = markdown.markdown( content_string = markdown.markdown(markdown_text, extensions=["fenced_code", "tables"])
markdown_text, extensions=["fenced_code", "tables"]
)
return content_string return content_string

View File

@ -1,2 +1,2 @@
Flask==1.1.2 Flask
Markdown==3.1.1 Markdown

View File

@ -6,7 +6,7 @@
--error: rgb(255,0,0); --error: rgb(255,0,0);
--footerbg0: rgb(192,192,192); --footerbg0: rgb(192,192,192);
--link0: rgb(0,0,120); --link0: rgb(0,0,120);
--link1: rgb(255,255,255); --link1: rgb(0,0,0);
--menulink0: rgb(0,0,120); --menulink0: rgb(0,0,120);
--menulink1: rgb(255,255,255); --menulink1: rgb(255,255,255);
--menubg0: rgb(192,192,192); --menubg0: rgb(192,192,192);

View File

@ -76,6 +76,10 @@ footer .center {
padding-top: 10px; padding-top: 10px;
} }
.main-menu-dropdown img {
float: left;
}
.main-menu-dropdown span { .main-menu-dropdown span {
float: left; float: left;
font-family: monospace; font-family: monospace;
@ -167,3 +171,24 @@ footer .center {
padding-left: 20; padding-left: 20;
} }
figure {
padding:20px;
}
ul {
padding-left:20px;
}
ol {
padding-left:20px;
}
code {
border-radius: 25px;
padding-left: 20px;
padding-right: 20px;
page-break-inside: avoid;
font-family: monospace;
white-space: pre;
display: inline-block
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<div class="blogarchive"> <div class="blogarchive">
<h1>Archive</h1><br> <h1>{% if language=="de-de" %}Archiv{% else %}Archive{% endif %}</h1><br>
{% autoescape off %} {% autoescape off %}
{{ content_string }} {{ content_string }}
{% endautoescape %} {% endautoescape %}

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<div class="important"> <div class="important">
Error<br> {% if language=="de-de" %}Fehler{% else %}Error{% endif %}<br>
<span>{{ errorcode }}</span> <span>{{ errorcode }}</span>
</div> </div>
</div> </div>

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<div class="blog"> <div class="blog">
<h1>Index</h1><br> <h1>Feed</h1><br>
{% autoescape off %} {% autoescape off %}
{{ content_string }} {{ content_string }}
{% endautoescape %} {% endautoescape %}

View File

@ -4,7 +4,7 @@
<channel> <channel>
<title>{{ title }}</title> <title>{{ title }}</title>
<description>{{ description }}</description> <description>{{ description }}</description>
<language>en-us</language> <language>{{ language }}</language>
<link>{{ website }}/feed.xml</link> <link>{{ website }}/feed.xml</link>
<atom:link href="/feed.xml" rel="self" type="application/rss+xml" /> <atom:link href="/feed.xml" rel="self" type="application/rss+xml" />

View File

@ -2,19 +2,22 @@
<head> <head>
<title>{{ title }}</title> <title>{{ title }}</title>
<link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css"> <link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='graphics/logo.png') }}">
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width" initial-scale=1.0> <meta name="viewport" content="width=device-width" initial-scale=1.0>
</head> </head>
<body> <body>
<!-- Menu --> <!-- Menu -->
<div class="main-menu-dropdown"> <div class="main-menu-dropdown">
<!-- <img class="logo" src="/static/images/logo.png"> --> <a href="{{ url_for('index') }}">
<img class="logo" src="{{ url_for('static', filename='graphics/logo.png') }}">
<span>{{ title }}</span> <span>{{ title }}</span>
</a>
<input type="checkbox" id="main-menu-check"> <input type="checkbox" id="main-menu-check">
<label for="main-menu-check" class="show-menu">&#9776;</label> <label for="main-menu-check" class="show-menu">&#9776;</label>
<div class="main-menu"> <div class="main-menu">
<a href="{{ url_for('index') }}">Blog</a> <a href="{{ url_for('index') }}">Blog</a>
<a href="{{ url_for('archive') }}">Archive</a> <a href="{{ url_for('archive') }}">{% if language=="de-de" %}Archiv{% else %}Archive{% endif %}</a>
<label for="main-menu-check" class="hide-menu">X</label> <label for="main-menu-check" class="hide-menu">X</label>
</div> </div>
</div> </div>