mirror of https://github.com/tiyn/amphora-wiki
parent
1c57f74541
commit
51682d00f0
@ -0,0 +1,68 @@
|
|||||||
|
# Python Flask Wiki
|
||||||
|
|
||||||
|
This is a simple wiki based on Pythons Flask framework.
|
||||||
|
There is much great wiki software.
|
||||||
|
Most of them are using some kind of database.
|
||||||
|
I however just want to put my markdown files in a directory and get a working wiki.
|
||||||
|
|
||||||
|
## Features/To-Dos
|
||||||
|
|
||||||
|
- [ ] Plain text support for blog entries
|
||||||
|
- [ ] Markdown Files (.md)
|
||||||
|
- [ ] Entry page
|
||||||
|
- [ ] Navigation
|
||||||
|
- [ ] Header
|
||||||
|
- [ ] Footer
|
||||||
|
- [ ] Switchable CSS
|
||||||
|
- [ ] CSS dark-theme
|
||||||
|
- [ ] CSS light-theme
|
||||||
|
- [ ] Config file
|
||||||
|
- [ ] Docker installation
|
||||||
|
- [ ] Enable variables/environment variables
|
||||||
|
- [ ] Logo
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Create entries
|
||||||
|
|
||||||
|
Wiki entries are managed by plain markdown files in the `templates/entry/` directory.
|
||||||
|
The first line of each document is reserved as the title of the document.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### PIP/Python
|
||||||
|
|
||||||
|
- `git clone https://github.com/tiyn/tiyny-blog`
|
||||||
|
- `cd flaskblog/src`
|
||||||
|
- edit the `config.py` file according to your needs
|
||||||
|
- `pip3install -r requirements.txt` - install depenencies
|
||||||
|
- run `python app.py`
|
||||||
|
- blog is available on port 5000
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Make sure you copy an example `config.py` and edit it before running the container.
|
||||||
|
The `config.py` can be found in the `src` folder.
|
||||||
|
|
||||||
|
#### Volumes
|
||||||
|
|
||||||
|
Set the following volumes with the -v tag.
|
||||||
|
|
||||||
|
| Volume-Name | Container mount | Description |
|
||||||
|
|-------------|---------------------------|--------------------------------------------------------------|
|
||||||
|
| config-file | /blog/src/config.py | Config file |
|
||||||
|
| entries | /blog/src/templates/entry | Directory for blog entries |
|
||||||
|
| css | /blog/src/static/css | (optional) Directory for css files |
|
||||||
|
| html | /blog/src/templates | (optional) Directory for templates (entry-volume not needed) |
|
||||||
|
|
||||||
|
#### Ports
|
||||||
|
|
||||||
|
Set the following ports with the -p tag.
|
||||||
|
|
||||||
|
| Container-Port | Recommended outside port | Protocol | Description |
|
||||||
|
|----------------|--------------------------|----------|-------------|
|
||||||
|
| 5000 | 80 | TCP | HTTP port |
|
||||||
|
|
||||||
|
#### Example run-command
|
||||||
|
|
||||||
|
`docker run --name wiki --restart unless-stopped -v ./config.py:/wiki/src/config.py -v entries:/wiki/src/templates/entry -p 80:5000 -d tiynger/tiyny-wiki`
|
@ -0,0 +1,21 @@
|
|||||||
|
FROM ubuntu
|
||||||
|
|
||||||
|
MAINTAINER Tiyn tiyn@martenkante.eu
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
RUN apt-get install python3 python3-pip git -y
|
||||||
|
|
||||||
|
RUN git clone https://github.com/tiyn/tiyny-wiki /wiki
|
||||||
|
|
||||||
|
WORKDIR /wiki/src
|
||||||
|
|
||||||
|
RUN pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
VOLUME /wiki/src/templates/entry
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
ENTRYPOINT [ "python3" ]
|
||||||
|
|
||||||
|
CMD [ "app.py" ]
|
@ -0,0 +1,22 @@
|
|||||||
|
from flask import Flask, flash, make_response, render_template, request, redirect, abort
|
||||||
|
|
||||||
|
import content as con_gen
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def page_not_found(e):
|
||||||
|
return render_template('error.html', title=config.TITLE, errorcode='404', style=config.STYLE), 404
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
@app.route('/index.html')
|
||||||
|
def index():
|
||||||
|
return 'ok'
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0')
|
@ -0,0 +1,8 @@
|
|||||||
|
# Name/title of your blog
|
||||||
|
TITLE = 'Tiyny-Wiki'
|
||||||
|
|
||||||
|
# URL for your website: e.g. https://domain.tld
|
||||||
|
WEBSITE = 'localhost:5000'
|
||||||
|
|
||||||
|
# Theme for the blog: dark, light
|
||||||
|
STYLE = 'dark'
|
@ -0,0 +1,10 @@
|
|||||||
|
import datetime
|
||||||
|
from datetime import datetime
|
||||||
|
import markdown
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
ENTRY_DIR = 'templates/entry'
|
@ -0,0 +1,2 @@
|
|||||||
|
Flask==1.1.2
|
||||||
|
Markdown==3.1.1
|
@ -0,0 +1,72 @@
|
|||||||
|
@import 'style.css';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg0: rgb(29,32,33);
|
||||||
|
--color0: rgb(220,120,0);
|
||||||
|
--error: rgb(255,0,0);
|
||||||
|
--footerbg0: rgb(29,32,33);
|
||||||
|
--link0: rgb(220, 120, 0);
|
||||||
|
--link1: rgb(255,255,255);
|
||||||
|
--menulink0: rgb(220, 120, 0);
|
||||||
|
--menulink1: rgb(255,255,255);
|
||||||
|
--menubg0: rgb(29,32,33);
|
||||||
|
--text0: rgb(235,219,178);
|
||||||
|
--text1: rgb(220, 120, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--link0);
|
||||||
|
transition: var(--transtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--link1);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--bg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background: var(--footerbg0);
|
||||||
|
color: var(--text0);
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--text1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
color: var(--text0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container h1,
|
||||||
|
.container h2 {
|
||||||
|
color: var(--text1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .flash {
|
||||||
|
background-color: var(--error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-menu:hover,
|
||||||
|
.main-menu a:hover,
|
||||||
|
.show-menu:hover {
|
||||||
|
color: var(--menulink1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu a {
|
||||||
|
color: var(--menulink0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu-dropdown {
|
||||||
|
background: var(--menubg0);
|
||||||
|
color: var(--menulink0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width:800px) {
|
||||||
|
|
||||||
|
.main-menu {
|
||||||
|
background: var(--menubg0);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
@import 'style.css';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg0: rgb(255,255,255);
|
||||||
|
--color0: rgb(0,0,120);
|
||||||
|
--error: rgb(255,0,0);
|
||||||
|
--footerbg0: rgb(192,192,192);
|
||||||
|
--link0: rgb(0,0,120);
|
||||||
|
--link1: rgb(255,255,255);
|
||||||
|
--menulink0: rgb(0,0,120);
|
||||||
|
--menulink1: rgb(255,255,255);
|
||||||
|
--menubg0: rgb(192,192,192);
|
||||||
|
--text0: rgb(0,0,0);
|
||||||
|
--text1: rgb(0,0,120);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--link0);
|
||||||
|
transition: var(--transtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--link1);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--bg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background: var(--footerbg0);
|
||||||
|
color: var(--text0);
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--text1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
color: var(--text0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container h1,
|
||||||
|
.container h2 {
|
||||||
|
color: var(--text1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .flash {
|
||||||
|
background-color: var(--error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-menu:hover,
|
||||||
|
.main-menu a:hover,
|
||||||
|
.show-menu:hover {
|
||||||
|
color: var(--menulink1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu a {
|
||||||
|
color: var(--menulink0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu-dropdown {
|
||||||
|
background: var(--menubg0);
|
||||||
|
color: var(--menulink0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width:800px) {
|
||||||
|
|
||||||
|
.main-menu {
|
||||||
|
background: var(--menubg0);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,153 @@
|
|||||||
|
:root {
|
||||||
|
--error: rgb(255,0,0);
|
||||||
|
--transtime: 0.7s;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
transition: var(--transtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
html {
|
||||||
|
font-family: sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
height: 100px;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer .center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
min-height: 100%;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
padding-left: 10%;
|
||||||
|
padding-right: 10%;
|
||||||
|
padding-top: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .flash {
|
||||||
|
padding: 10px;
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-menu,
|
||||||
|
.show-menu {
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
font-size: 30px;
|
||||||
|
transition: var(--transtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
.important {
|
||||||
|
font-size: xx-large;
|
||||||
|
padding-left: 25vw;
|
||||||
|
padding-right: 25vw;
|
||||||
|
padding-top: 30vh;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.important span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 80px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu-dropdown span {
|
||||||
|
float: left;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 100px;
|
||||||
|
padding: 0 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: 0.7s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu {
|
||||||
|
float: right;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu a {
|
||||||
|
padding: 0 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: 0.7s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu-dropdown {
|
||||||
|
height: 100px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-menu {
|
||||||
|
float: right;
|
||||||
|
line-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-menu-check {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: -1111;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width:800px) {
|
||||||
|
.hide-menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 40px;
|
||||||
|
top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-menu,
|
||||||
|
.show-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu {
|
||||||
|
height: 100vh;
|
||||||
|
line-height: normal;
|
||||||
|
padding: 80px 0;
|
||||||
|
position: fixed;
|
||||||
|
right: -100%;
|
||||||
|
text-align: center;
|
||||||
|
top: 0;
|
||||||
|
transition: var(--transtime);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.main-menu a {
|
||||||
|
display: block;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-menu-check:checked ~ .main-menu {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
Test Entry Title 3
|
||||||
|
This is a markdown file
|
||||||
|
|
||||||
|
- list entry
|
||||||
|
- list entry
|
||||||
|
- list entry
|
||||||
|
|
||||||
|
# md-header
|
||||||
|
|
||||||
|
more content
|
@ -0,0 +1,10 @@
|
|||||||
|
Test Entry Title 3
|
||||||
|
This is a markdown file
|
||||||
|
|
||||||
|
- list entry
|
||||||
|
- list entry
|
||||||
|
- list entry
|
||||||
|
|
||||||
|
# md-header
|
||||||
|
|
||||||
|
more content
|
@ -0,0 +1,10 @@
|
|||||||
|
Test Entry Title 3
|
||||||
|
This is a markdown file
|
||||||
|
|
||||||
|
- list entry
|
||||||
|
- list entry
|
||||||
|
- list entry
|
||||||
|
|
||||||
|
# md-header
|
||||||
|
|
||||||
|
more content
|
@ -0,0 +1,9 @@
|
|||||||
|
{% extends "template.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="important">
|
||||||
|
Error<br>
|
||||||
|
<span>{{ errorcode }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,32 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width", initial-scale=1.0>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Menu -->
|
||||||
|
<div class="main-menu-dropdown">
|
||||||
|
<!-- <img class="logo" src="/static/images/logo.png"> -->
|
||||||
|
<span>{{ title }}</span>
|
||||||
|
<input type="checkbox" id="main-menu-check">
|
||||||
|
<label for="main-menu-check" class="show-menu">☰</label>
|
||||||
|
<div class="main-menu">
|
||||||
|
<a href="/">Startpage</a>
|
||||||
|
<label for="main-menu-check" class="hide-menu">X</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Menu -->
|
||||||
|
<!-- Content -->
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
<!-- Content -->
|
||||||
|
<footer>
|
||||||
|
<div class="center">
|
||||||
|
Dieser Blog enthält kein Javascript oder PHP.<br>
|
||||||
|
Dies ist eine Instanz vom <a href="https://github.com/tiyn/tiyny-wiki">Tiyny-Wiki</a>.
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in new issue