mirror of
				https://github.com/tiyn/beaker-blog.git
				synced 2025-10-31 02:41:17 +01:00 
			
		
		
		
	added language support for german
This commit is contained in:
		
							
								
								
									
										10
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -8,6 +8,16 @@ 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 | VOLUME /blog/static/graphics | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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" | ||||||
|   | |||||||
							
								
								
									
										268
									
								
								src/content.py
									
									
									
									
									
								
							
							
						
						
									
										268
									
								
								src/content.py
									
									
									
									
									
								
							| @@ -1,97 +1,101 @@ | |||||||
| 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(): | ||||||
|     """ |   """ | ||||||
|     Creates and returns a archive string of every file in ENTRY_DIR. |     Creates and returns a archive string of every file in ENTRY_DIR. | ||||||
|  |  | ||||||
|     Returns: |     Returns: | ||||||
|     string: html-formatted archive-string |     string: html-formatted archive-string | ||||||
|     """ |     """ | ||||||
|     path_ex = ENTRY_DIR |   path_ex = ENTRY_DIR | ||||||
|     if path.exists(path_ex): |   if path.exists(path_ex): | ||||||
|         name_list = os.listdir(path_ex) |     name_list = os.listdir(path_ex) | ||||||
|         full_list = [os.path.join(path_ex, i) for i in name_list] |     full_list = [os.path.join(path_ex, i) for i in name_list] | ||||||
|         contents = sorted(full_list, key=os.path.getctime) |     contents = sorted(full_list, key=os.path.getctime) | ||||||
|         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( |       if curr_month != last_month: | ||||||
|                 os.path.getctime(file)).strftime("%b %Y") |         if last_month != "": | ||||||
|             if curr_month != last_month: |           content_string += "</ul>\n" | ||||||
|                 if last_month != "": |         content_string += "<h2>" + curr_month + "</h2>\n" | ||||||
|                     content_string += "</ul>\n" |         content_string += "<ul>\n" | ||||||
|                 content_string += "<h2>" + curr_month + "</h2>\n" |         last_month = curr_month | ||||||
|                 content_string += "<ul>\n" |       filename = pathlib.PurePath(file) | ||||||
|                 last_month = curr_month |       title = open(filename).readline().rstrip("\n") | ||||||
|             filename = pathlib.PurePath(file) |       filename = filename.name | ||||||
|             title = open(filename).readline().rstrip("\n") |       if filename[0] != ".": | ||||||
|             filename = filename.name |         filename = filename.split(".", 1)[0] | ||||||
|             if filename[0] != ".": |       content_string += "<li>" | ||||||
|                 filename = filename.split(".", 1)[0] |       content_string += "<a href=\"" + "/index.html#" + \ | ||||||
|             content_string += "<li>" |           filename + "\">" + curr_date + "</a> - " | ||||||
|             content_string += curr_date + " - " |       content_string += "<a href=\"" + "/entry/" + \ | ||||||
|             content_string += title + " [" |           pathlib.PurePath(file).name + "\"><b>" + title + "</b></a>" | ||||||
|             content_string += "<a href=\"" + "/index.html#" + \ |       content_string += "<br>" | ||||||
|                 filename + "\">" + "link" + "</a> - " |       content_string += "</li>\n" | ||||||
|             content_string += "<a href=\"" + "/entry/" + \ |     content_string += "</ul>\n" | ||||||
|                 pathlib.PurePath(file).name + "\">" + "standalone" + "</a>" |     return content_string | ||||||
|             content_string += "] <br>" |  | ||||||
|             content_string += "</li>\n" |  | ||||||
|         content_string += "</ul>\n" |  | ||||||
|         return content_string |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def gen_index_string(): | def gen_index_string(): | ||||||
|     """ |   """ | ||||||
|     Create and returns a string including every file in the ENTRY_DIR as an index. |     Create and returns a string including every file in the ENTRY_DIR as an index. | ||||||
|  |  | ||||||
|     Returns: |     Returns: | ||||||
|     string: html-formatted index string |     string: html-formatted index string | ||||||
|     """ |     """ | ||||||
|     path_ex = ENTRY_DIR |   path_ex = ENTRY_DIR | ||||||
|     content_string = "" |   content_string = "" | ||||||
|     if path.exists(path_ex): |   if path.exists(path_ex): | ||||||
|         name_list = os.listdir(path_ex) |     name_list = os.listdir(path_ex) | ||||||
|         full_list = [os.path.join(path_ex, i) for i in name_list] |     full_list = [os.path.join(path_ex, i) for i in name_list] | ||||||
|         contents = sorted(full_list, key=os.path.getctime) |     contents = sorted(full_list, key=os.path.getctime) | ||||||
|         for file in reversed(contents): |     for file in reversed(contents): | ||||||
|             filename = pathlib.PurePath(file) |       filename = pathlib.PurePath(file) | ||||||
|             purefile = filename |       purefile = filename | ||||||
|             title = open(filename).readline().rstrip("\n") |       title = open(filename).readline().rstrip("\n") | ||||||
|             text = open(filename).readlines()[1:] |       text = open(filename).readlines()[1:] | ||||||
|             filename = filename.name |       filename = filename.name | ||||||
|             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" | ||||||
|             if file.endswith(".html"): |       content_string += "<small>" + \ | ||||||
|                 for line in text: |           datetime.fromtimestamp(os.path.getctime( | ||||||
|                     content_string += line |               file)).strftime("%Y-%m-%d") + "</small><br><br>" | ||||||
|                 content_string += "<br>" |       if file.endswith(".html"): | ||||||
|             if file.endswith(".md"): |         for line in text: | ||||||
|                 content_string += gen_md_content(file, 2) |           content_string += line | ||||||
|             content_string += "<small>" + \ |         content_string += "<br>" | ||||||
|                 datetime.fromtimestamp(os.path.getctime( |       if file.endswith(".md"): | ||||||
|                     file)).strftime("%Y-%m-%d") + "</small>" |         content_string += gen_md_content(file, 2) | ||||||
|             content_string += "</div>" |       content_string += "</div>" | ||||||
|     return content_string |   return content_string | ||||||
|  |  | ||||||
|  |  | ||||||
| def gen_stand_string(path_ex): | def gen_stand_string(path_ex): | ||||||
|     """ |   """ | ||||||
|     Creates a html-string for a file. |     Creates a html-string for a file. | ||||||
|     If the file is markdown it will convert it. |     If the file is markdown it will convert it. | ||||||
|     This functions ensures upscaling for future formats. |     This functions ensures upscaling for future formats. | ||||||
| @@ -102,29 +106,29 @@ def gen_stand_string(path_ex): | |||||||
|     Returns: |     Returns: | ||||||
|     string: html-formatted string string equivalent to the file |     string: html-formatted string string equivalent to the file | ||||||
|     """ |     """ | ||||||
|     filename = os.path.join(ENTRY_DIR, path_ex) |   filename = os.path.join(ENTRY_DIR, path_ex) | ||||||
|     content_string = "" |   content_string = "" | ||||||
|     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:] | ||||||
|         filename_no_end = filename.split(".", 1)[0] |     curr_date = datetime.fromtimestamp(os.path.getctime(filename)).strftime("%Y-%m-%d") | ||||||
|         filename_no_end = filename_no_end.split("/")[-1] |     filename_no_end = filename.split(".", 1)[0] | ||||||
|         content_string += "<h1>" + title + "</h1>\n" |     filename_no_end = filename_no_end.split("/")[-1] | ||||||
|         content_string += "[" |     content_string += "<h1>" + title + "</h1>\n" | ||||||
|         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 | ||||||
|             content_string += "<br>" |       content_string += "<br>" | ||||||
|         if filename.endswith(".md"): |     if filename.endswith(".md"): | ||||||
|             content_string += gen_md_content(filename, 1) |       content_string += gen_md_content(filename, 1) | ||||||
|     return content_string |   return content_string | ||||||
|  |  | ||||||
|  |  | ||||||
| def gen_md_content(path_ex, depth): | def gen_md_content(path_ex, depth): | ||||||
|     """ |   """ | ||||||
|     Convert a markdown file to a html string. |     Convert a markdown file to a html string. | ||||||
|  |  | ||||||
|     Parameters: |     Parameters: | ||||||
| @@ -134,54 +138,52 @@ def gen_md_content(path_ex, depth): | |||||||
|     Returns: |     Returns: | ||||||
|     string: html-formatted string string equivalent to the markdown file |     string: html-formatted string string equivalent to the markdown file | ||||||
|     """ |     """ | ||||||
|     content_string = "" |   content_string = "" | ||||||
|     if path.exists(path_ex): |   if path.exists(path_ex): | ||||||
|         filename = path_ex.split(".", 1) |     filename = path_ex.split(".", 1) | ||||||
|         fileend = filename[len(filename) - 1] |     fileend = filename[len(filename) - 1] | ||||||
|         header = "#" |     header = "#" | ||||||
|         for i in range(depth): |     for i in range(depth): | ||||||
|             header += "#" |       header += "#" | ||||||
|         header += " " |     header += " " | ||||||
|         markdown_lines = open(path_ex, "r").readlines()[1:] |     markdown_lines = open(path_ex, "r").readlines()[1:] | ||||||
|         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 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_rss_string(): | def get_rss_string(): | ||||||
|     """ |   """ | ||||||
|     Create a rss-string of the blog and return it. |     Create a rss-string of the blog and return it. | ||||||
|  |  | ||||||
|     Returns: |     Returns: | ||||||
|     string: rss-string of everything that is in the ENTRY_DIR. |     string: rss-string of everything that is in the ENTRY_DIR. | ||||||
|     """ |     """ | ||||||
|     path_ex = ENTRY_DIR |   path_ex = ENTRY_DIR | ||||||
|     if path.exists(path_ex): |   if path.exists(path_ex): | ||||||
|         name_list = os.listdir(path_ex) |     name_list = os.listdir(path_ex) | ||||||
|         full_list = [os.path.join(path_ex, i) for i in name_list] |     full_list = [os.path.join(path_ex, i) for i in name_list] | ||||||
|         contents = sorted(full_list, key=os.path.getctime) |     contents = sorted(full_list, key=os.path.getctime) | ||||||
|         content_string = "" |     content_string = "" | ||||||
|         for file in reversed(contents): |     for file in reversed(contents): | ||||||
|             filename = pathlib.PurePath(file) |       filename = pathlib.PurePath(file) | ||||||
|             title = open(filename).readline().rstrip("\n") |       title = open(filename).readline().rstrip("\n") | ||||||
|             text = open(filename).readlines()[1:] |       text = open(filename).readlines()[1:] | ||||||
|             filename = filename.name |       filename = filename.name | ||||||
|             if filename[0] != ".": |       if filename[0] != ".": | ||||||
|                 filename = filename.split(".", 1)[0] |         filename = filename.split(".", 1)[0] | ||||||
|             content_string += "<item>\n" |       content_string += "<item>\n" | ||||||
|             content_string += "<title>" + title + "</title>\n" |       content_string += "<title>" + title + "</title>\n" | ||||||
|             content_string += "<guid>" + config.WEBSITE + \ |       content_string += "<guid>" + config.WEBSITE + \ | ||||||
|                 "/index.html#" + filename + "</guid>\n" |           "/index.html#" + filename + "</guid>\n" | ||||||
|             content_string += "<pubDate>" + \ |       content_string += "<pubDate>" + \ | ||||||
|                 datetime.fromtimestamp(os.path.getctime(file)).strftime( |           datetime.fromtimestamp(os.path.getctime(file)).strftime( | ||||||
|                     "%Y-%m-%d") + "</pubDate>\n" |               "%Y-%m-%d") + "</pubDate>\n" | ||||||
|             content_string += "<description>" |       content_string += "<description>" | ||||||
|             for line in text: |       for line in text: | ||||||
|                 content_string += line |         content_string += line | ||||||
|             content_string += "</description>\n" |       content_string += "</description>\n" | ||||||
|             content_string += "</item>\n" |       content_string += "</item>\n" | ||||||
|     return content_string |   return content_string | ||||||
|   | |||||||
| @@ -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 %} | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -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 %} | ||||||
|   | |||||||
| @@ -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" /> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
|         <label for="main-menu-check" class="show-menu">☰</label> |         <label for="main-menu-check" class="show-menu">☰</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> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user