This commit is contained in:
commit
c7377979ad
37 changed files with 5061 additions and 0 deletions
73
.forgejo/workflows/build.yaml
Normal file
73
.forgejo/workflows/build.yaml
Normal file
|
@ -0,0 +1,73 @@
|
|||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: apt-get update && apt-get install -y rsync
|
||||
- name: Create private key
|
||||
run: |
|
||||
echo "${{ secrets.ACT_RUNNER_KEY }}" > /tmp/act_runner_key
|
||||
chmod 600 /tmp/act_runner_key
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- run: pip install "pelican[markdown]"
|
||||
- run: make publish
|
||||
- name: rsync public directory
|
||||
run: |
|
||||
/usr/bin/rsync -avz --delete -e "ssh -i /tmp/act_runner_key -o StrictHostKeyChecking=no" ${{ gitea.workspace }}/output/* root@vps03.hadan-it.com:/data/webspace/blog.hadan-it.com/
|
||||
|
||||
- name: ntfy-success-notifications
|
||||
uses: https://github.com/niniyas/ntfy-action@master
|
||||
if: success()
|
||||
with:
|
||||
title: 'Forgejo Actions'
|
||||
url: '${{ secrets.NTFY_URL }}'
|
||||
topic: '${{ secrets.NTFY_TOPIC }}'
|
||||
priority: 4
|
||||
headers: '${{ secrets.NTFY_HEADERS }}'
|
||||
tags: +1,partying_face,action,successfully,completed
|
||||
details: Workflow has been successfully completed!
|
||||
icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Forgejo_logo.svg/512px-Forgejo_logo.svg.png'
|
||||
image: true
|
||||
|
||||
- name: ntfy-failed-notifications
|
||||
uses: https://github.com/niniyas/ntfy-action@master
|
||||
if: failure()
|
||||
with:
|
||||
title: 'Forgejo Actions'
|
||||
url: '${{ secrets.NTFY_URL }}'
|
||||
topic: '${{ secrets.NTFY_TOPIC }}'
|
||||
priority: 5
|
||||
headers: '${{ secrets.NTFY_HEADERS }}'
|
||||
tags: +1,partying_face,action,failed
|
||||
details: Workflow has failed!
|
||||
actions: 'default'
|
||||
icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Forgejo_logo.svg/512px-Forgejo_logo.svg.png'
|
||||
image: true
|
||||
|
||||
- name: ntfy-cancelled-notifications
|
||||
uses: https://github.com/niniyas/ntfy-action@master
|
||||
if: cancelled()
|
||||
with:
|
||||
title: 'Forgejo Actions'
|
||||
url: '${{ secrets.NTFY_URL }}'
|
||||
topic: '${{ secrets.NTFY_TOPIC }}'
|
||||
priority: 3
|
||||
headers: '${{ secrets.NTFY_HEADERS }}'
|
||||
tags: +1,partying_face,action,cancelled
|
||||
details: Workflow has been cancelled!
|
||||
actions: '[{"action": "view", "label": "Open portal", "url": "https://blog.hadan-it.com/", "clear": true}]'
|
||||
icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Forgejo_logo.svg/512px-Forgejo_logo.svg.png'
|
||||
image: true
|
||||
|
||||
- run: echo "This job's status is ${{ job.status }}."
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
__pycache__/
|
||||
output/
|
||||
tmp/
|
||||
.DS_Store
|
||||
venv/
|
72
Makefile
Normal file
72
Makefile
Normal file
|
@ -0,0 +1,72 @@
|
|||
PY?=
|
||||
PELICAN?=pelican
|
||||
PELICANOPTS=
|
||||
|
||||
BASEDIR=$(CURDIR)
|
||||
INPUTDIR=$(BASEDIR)/content
|
||||
OUTPUTDIR=$(BASEDIR)/output
|
||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||
|
||||
|
||||
DEBUG ?= 0
|
||||
ifeq ($(DEBUG), 1)
|
||||
PELICANOPTS += -D
|
||||
endif
|
||||
|
||||
RELATIVE ?= 0
|
||||
ifeq ($(RELATIVE), 1)
|
||||
PELICANOPTS += --relative-urls
|
||||
endif
|
||||
|
||||
SERVER ?= "0.0.0.0"
|
||||
|
||||
PORT ?= 0
|
||||
ifneq ($(PORT), 0)
|
||||
PELICANOPTS += -p $(PORT)
|
||||
endif
|
||||
|
||||
|
||||
help:
|
||||
@echo 'Makefile for a pelican Web site '
|
||||
@echo ' '
|
||||
@echo 'Usage: '
|
||||
@echo ' make html (re)generate the web site '
|
||||
@echo ' make clean remove the generated files '
|
||||
@echo ' make regenerate regenerate files upon modification '
|
||||
@echo ' make publish generate using production settings '
|
||||
@echo ' make serve [PORT=8000] serve site at http://localhost:8000'
|
||||
@echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 '
|
||||
@echo ' make devserver [PORT=8000] serve and regenerate together '
|
||||
@echo ' make devserver-global regenerate and serve on 0.0.0.0 '
|
||||
@echo ' '
|
||||
@echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html '
|
||||
@echo 'Set the RELATIVE variable to 1 to enable relative urls '
|
||||
@echo ' '
|
||||
|
||||
html:
|
||||
"$(PELICAN)" "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
clean:
|
||||
[ ! -d "$(OUTPUTDIR)" ] || rm -rf "$(OUTPUTDIR)"
|
||||
|
||||
regenerate:
|
||||
"$(PELICAN)" -r "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
serve:
|
||||
"$(PELICAN)" -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
serve-global:
|
||||
"$(PELICAN)" -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS) -b $(SERVER)
|
||||
|
||||
devserver:
|
||||
"$(PELICAN)" -lr "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
|
||||
|
||||
devserver-global:
|
||||
"$(PELICAN)" -lr "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS) -b 0.0.0.0
|
||||
|
||||
publish:
|
||||
"$(PELICAN)" "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(PUBLISHCONF)" $(PELICANOPTS)
|
||||
|
||||
|
||||
.PHONY: html help clean regenerate serve serve-global devserver devserver-global publish
|
45
pelicanconf.py
Normal file
45
pelicanconf.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
AUTHOR = 'Stephan Hadan'
|
||||
DESCRIPTION = ''
|
||||
SITENAME = 'News @ Hadan IT'
|
||||
SITEURL = 'https://blog.hadan-it.com'
|
||||
SITEIMAGE = ''
|
||||
|
||||
PATH = 'content'
|
||||
OUTPUT_PATH = 'output'
|
||||
|
||||
TIMEZONE = 'Europe/Berlin'
|
||||
STARTYEAR = '2025'
|
||||
# comment CURRENTYEAR out if it's the same as STARTYEAR
|
||||
#CURRENTYEAR = date.today().year
|
||||
|
||||
DEFAULT_LANG = 'de'
|
||||
|
||||
# Feed generation is usually not desired when developing
|
||||
FEED_ALL_ATOM = None
|
||||
CATEGORY_FEED_ATOM = None
|
||||
TRANSLATION_FEED_ATOM = None
|
||||
AUTHOR_FEED_ATOM = None
|
||||
AUTHOR_FEED_RSS = None
|
||||
|
||||
DELETE_OUTPUT_DIRECTORY = True
|
||||
|
||||
THEME = 'themes/business'
|
||||
|
||||
# Blogroll
|
||||
LINKS = (
|
||||
("Pelican", "https://getpelican.com/"),
|
||||
("Python.org", "https://www.python.org/"),
|
||||
("Jinja2", "https://palletsprojects.com/p/jinja/"),
|
||||
("You can modify those links in your config file", "#"),
|
||||
)
|
||||
|
||||
# Social widget
|
||||
SOCIAL = (
|
||||
("You can add links in your config file", "#"),
|
||||
("Another social link", "#"),
|
||||
)
|
||||
|
||||
DEFAULT_PAGINATION = 10
|
||||
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
RELATIVE_URLS = True
|
24
publishconf.py
Normal file
24
publishconf.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
# This file is only used if you use `make publish` or
|
||||
# explicitly specify it as your config file.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.curdir)
|
||||
from pelicanconf import *
|
||||
|
||||
# If your site is available via HTTPS, make sure SITEURL begins with https://
|
||||
SITEURL = "https://blog.hadan-it.com"
|
||||
PARENTURL = "https://hadan-it.com"
|
||||
RELATIVE_URLS = False
|
||||
THEME = "themes/business"
|
||||
|
||||
FEED_ALL_ATOM = "feeds/all.atom.xml"
|
||||
CATEGORY_FEED_ATOM = "feeds/{slug}.atom.xml"
|
||||
|
||||
DELETE_OUTPUT_DIRECTORY = True
|
||||
|
||||
# Following items are often useful when publishing
|
||||
|
||||
# DISQUS_SITENAME = ""
|
||||
# GOOGLE_ANALYTICS = ""
|
145
tasks.py
Normal file
145
tasks.py
Normal file
|
@ -0,0 +1,145 @@
|
|||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from invoke import task
|
||||
from invoke.main import program
|
||||
from pelican import main as pelican_main
|
||||
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
|
||||
from pelican.settings import DEFAULT_CONFIG, get_settings_from_file
|
||||
|
||||
OPEN_BROWSER_ON_SERVE = True
|
||||
SETTINGS_FILE_BASE = "pelicanconf.py"
|
||||
SETTINGS = {}
|
||||
SETTINGS.update(DEFAULT_CONFIG)
|
||||
LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
|
||||
SETTINGS.update(LOCAL_SETTINGS)
|
||||
|
||||
CONFIG = {
|
||||
"settings_base": SETTINGS_FILE_BASE,
|
||||
"settings_publish": "publishconf.py",
|
||||
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
|
||||
"deploy_path": SETTINGS["OUTPUT_PATH"],
|
||||
# Host and port for `serve`
|
||||
"host": "localhost",
|
||||
"port": 8000,
|
||||
}
|
||||
|
||||
|
||||
@task
|
||||
def clean(c):
|
||||
"""Remove generated files"""
|
||||
if os.path.isdir(CONFIG["deploy_path"]):
|
||||
shutil.rmtree(CONFIG["deploy_path"])
|
||||
os.makedirs(CONFIG["deploy_path"])
|
||||
|
||||
|
||||
@task
|
||||
def build(c):
|
||||
"""Build local version of site"""
|
||||
pelican_run("-s {settings_base}".format(**CONFIG))
|
||||
|
||||
|
||||
@task
|
||||
def rebuild(c):
|
||||
"""`build` with the delete switch"""
|
||||
pelican_run("-d -s {settings_base}".format(**CONFIG))
|
||||
|
||||
|
||||
@task
|
||||
def regenerate(c):
|
||||
"""Automatically regenerate site upon file modification"""
|
||||
pelican_run("-r -s {settings_base}".format(**CONFIG))
|
||||
|
||||
|
||||
@task
|
||||
def serve(c):
|
||||
"""Serve site at http://$HOST:$PORT/ (default is localhost:8000)"""
|
||||
|
||||
class AddressReuseTCPServer(RootedHTTPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
server = AddressReuseTCPServer(
|
||||
CONFIG["deploy_path"],
|
||||
(CONFIG["host"], CONFIG["port"]),
|
||||
ComplexHTTPRequestHandler,
|
||||
)
|
||||
|
||||
if OPEN_BROWSER_ON_SERVE:
|
||||
# Open site in default browser
|
||||
import webbrowser
|
||||
|
||||
webbrowser.open("http://{host}:{port}".format(**CONFIG))
|
||||
|
||||
sys.stderr.write("Serving at {host}:{port} ...\n".format(**CONFIG))
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
@task
|
||||
def reserve(c):
|
||||
"""`build`, then `serve`"""
|
||||
build(c)
|
||||
serve(c)
|
||||
|
||||
|
||||
@task
|
||||
def preview(c):
|
||||
"""Build production version of site"""
|
||||
pelican_run("-s {settings_publish}".format(**CONFIG))
|
||||
|
||||
@task
|
||||
def livereload(c):
|
||||
"""Automatically reload browser tab upon file modification."""
|
||||
from livereload import Server
|
||||
|
||||
def cached_build():
|
||||
cmd = "-s {settings_base} -e CACHE_CONTENT=true LOAD_CONTENT_CACHE=true"
|
||||
pelican_run(cmd.format(**CONFIG))
|
||||
|
||||
cached_build()
|
||||
server = Server()
|
||||
theme_path = SETTINGS["THEME"]
|
||||
watched_globs = [
|
||||
CONFIG["settings_base"],
|
||||
f"{theme_path}/templates/**/*.html",
|
||||
]
|
||||
|
||||
content_file_extensions = [".md", ".rst"]
|
||||
for extension in content_file_extensions:
|
||||
content_glob = "{}/**/*{}".format(SETTINGS["PATH"], extension)
|
||||
watched_globs.append(content_glob)
|
||||
|
||||
static_file_extensions = [".css", ".js"]
|
||||
for extension in static_file_extensions:
|
||||
static_file_glob = f"{theme_path}/static/**/*{extension}"
|
||||
watched_globs.append(static_file_glob)
|
||||
|
||||
for glob in watched_globs:
|
||||
server.watch(glob, cached_build)
|
||||
|
||||
if OPEN_BROWSER_ON_SERVE:
|
||||
# Open site in default browser
|
||||
import webbrowser
|
||||
|
||||
webbrowser.open("http://{host}:{port}".format(**CONFIG))
|
||||
|
||||
server.serve(host=CONFIG["host"], port=CONFIG["port"], root=CONFIG["deploy_path"])
|
||||
|
||||
|
||||
@task
|
||||
def publish(c):
|
||||
"""Publish to production via rsync"""
|
||||
pelican_run("-s {settings_publish}".format(**CONFIG))
|
||||
c.run(
|
||||
'rsync --delete --exclude ".DS_Store" -pthrvz -c '
|
||||
'-e "ssh -p {ssh_port}" '
|
||||
"{} {ssh_user}@{ssh_host}:{ssh_path}".format(
|
||||
CONFIG["deploy_path"].rstrip("/") + "/", **CONFIG
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def pelican_run(cmd):
|
||||
cmd += " " + program.core.remainder # allows to pass-through args to pelican
|
||||
pelican_main(shlex.split(cmd))
|
15
themes/business/README.md
Normal file
15
themes/business/README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# business
|
||||
|
||||
A custom [pelican][pl] theme for the blog of Stephan Hadan Professional IT-Services. It's based on the
|
||||
[aboutwilson][aw] theme with some minor tweaks, which are listed below.
|
||||
|
||||
* Updated to FontAwesome 5
|
||||
* Reduced number of icons
|
||||
* Different font family for body and headings
|
||||
* Changed colour theme to blue
|
||||
* "Tags: " text is only shown if the post has tags
|
||||
* Site title is aligned with the post titles
|
||||
* New `STARTYEAR` pelican config option
|
||||
|
||||
[pl]: https://getpelican.com
|
||||
[aw]: https://github.com/getpelican/pelican-themes/tree/master/aboutwilson
|
BIN
themes/business/static/css/favicon.ico
Normal file
BIN
themes/business/static/css/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
101
themes/business/static/css/favicon.svg
Normal file
101
themes/business/static/css/favicon.svg
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
viewBox="0 0 2.4898222 2.4794246"
|
||||
id="svg10"
|
||||
width="2.4898221"
|
||||
height="2.4794245"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#">
|
||||
<g
|
||||
transform="translate(2.8898221,0.05769865)"
|
||||
id="g9">
|
||||
<g
|
||||
clip-path="url(#SvgjsClipPath1012)"
|
||||
id="g8">
|
||||
<g
|
||||
clip-path="url(#SvgjsClipPath10062902d424-a408-471b-990d-be55cd49b26d)"
|
||||
id="g3">
|
||||
<path
|
||||
d="m -0.39967561,1.8529838 -0.001946,0.00195 c -0.44607815,0.6134951 -1.30455689,0.75019 -1.91911709,0.3055758 v 0 l -0.00195,-0.00195 C -2.9364565,1.7126872 -3.0733224,0.85404639 -2.628589,0.23944648 v 0 l 0.00162,-0.001946 0.074611,0.0538495 0.07753,0.0532007 v 0.001946 C -2.8610501,0.87676571 -2.7449316,1.6196339 -2.2153126,2.0067468 v 0 h 0.00195 c 0.5303144,0.3860342 1.27303659,0.2699385 1.66025008,-0.2595154 v 0 -0.00227 l 0.0746107,0.054174 z"
|
||||
fill="#bab9b4"
|
||||
fill-rule="evenodd"
|
||||
id="path3" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#SvgjsClipPath10062902d424-a408-471b-990d-be55cd49b26d)"
|
||||
id="g4">
|
||||
<path
|
||||
d="m -1.6901162,0.85968841 c -0.075534,0.0711827 -0.1007471,0.18085869 -0.063882,0.27788069 0.036865,0.097022 0.1285487,0.1622808 0.2322934,0.165343 0.1037447,0.00306 0.1991174,-0.056675 0.2416413,-0.1513539 0.042524,-0.094679 0.023823,-0.20565081 -0.04738,-0.28116477 -0.046634,-0.0495827 -0.1110779,-0.078576 -0.1791158,-0.0805842 -0.068038,-0.002008 -0.1340795,0.0231335 -0.1835569,0.0698792 z"
|
||||
fill="#4e888f"
|
||||
fill-rule="evenodd"
|
||||
id="path4" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#SvgjsClipPath10062902d424-a408-471b-990d-be55cd49b26d)"
|
||||
id="g5">
|
||||
<path
|
||||
d="m -1.4306007,2.150129 c -0.6051712,0.038763 -1.128917,-0.4165181 -1.1747608,-1.0211941 -0.045844,-0.60467602 0.4032753,-1.13371509 1.0073733,-1.18663361 l 0.012327,0.15635806 c -0.5233206,0.03950434 -0.9155312,0.49576413 -0.8760269,1.01908475 0.039504,0.5233206 0.4957642,0.9155312 1.0190848,0.8760268 z"
|
||||
fill="#404040"
|
||||
fill-rule="evenodd"
|
||||
id="path5" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#SvgjsClipPath10062902d424-a408-471b-990d-be55cd49b26d)"
|
||||
id="g6">
|
||||
<path
|
||||
d="M -1.9084336,1.6933818 C -2.1428652,1.5540816 -2.2843723,1.2995639 -2.2789729,1.0269221 c 0.0054,-0.27264189 0.1568728,-0.52135733 0.396636,-0.65126642 0.2397631,-0.1299091 0.5308365,-0.1209755 0.7621815,0.0233928 l -0.066825,0.10899649 C -1.4836967,0.33414422 -1.8650488,0.43035158 -2.0437629,0.72419368 -2.222477,1.0180358 -2.1324984,1.4009054 -1.8416083,1.5843853 Z"
|
||||
fill="#bab9b4"
|
||||
fill-rule="evenodd"
|
||||
id="path6" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#SvgjsClipPath10062902d424-a408-471b-990d-be55cd49b26d)"
|
||||
id="g7">
|
||||
<path
|
||||
d="m -1.8711282,0.87720571 -0.041522,-0.0275735 -0.044118,-0.0217344 C -1.8361852,0.58354994 -1.540448,0.48308353 -1.2959771,0.6034169 h 0.0026 c 0.2429328,0.12124838 0.34201177,0.4161642 0.2215613,0.6594936 v 0.00227 l -0.00195,0.00292 -0.043793,-0.025627 -0.044118,-0.021734 c 0.096279,-0.1954685 0.01599,-0.43197973 -0.17939,-0.52843835 v 0 c -0.1953937,-0.0957958 -0.431459,-0.0154146 -0.5277907,0.17971425 v 0.002595 z"
|
||||
fill="#404040"
|
||||
fill-rule="evenodd"
|
||||
id="path7" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs
|
||||
id="defs10">
|
||||
<clipPath
|
||||
id="SvgjsClipPath1012">
|
||||
<path
|
||||
d="M -2.8900508,-0.05769871 H -0.4 V 2.4219714 h -2.4900508 z"
|
||||
id="path9" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="SvgjsClipPath10062902d424-a408-471b-990d-be55cd49b26d">
|
||||
<path
|
||||
d="M -2.8900508,-0.05769871 H -0.4 V 2.4219714 h -2.4900508 z"
|
||||
id="path10" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-nd/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
</cc:License>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-nd/4.0/" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
1640
themes/business/static/css/ipython.css
Normal file
1640
themes/business/static/css/ipython.css
Normal file
File diff suppressed because one or more lines are too long
133
themes/business/static/css/local.css
Normal file
133
themes/business/static/css/local.css
Normal file
|
@ -0,0 +1,133 @@
|
|||
|
||||
.my-list-style {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.aw-bottom {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.aw-footer {
|
||||
margin-top: 2em;
|
||||
border-top: 2px solid lightgrey;
|
||||
border-bottom: 2px solid lightgrey;
|
||||
/* height: 250px;*/
|
||||
padding-top: 2em;
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
.aw-footer li {
|
||||
line-height: 200%;
|
||||
}
|
||||
|
||||
.summary {
|
||||
margin-bottom: 2em;
|
||||
margin-top: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.summary pre { display: none; }
|
||||
|
||||
.article-body {
|
||||
margin-top: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.article-header {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides of notebook CSS for static HTML export
|
||||
**/
|
||||
div.entry-content {
|
||||
overflow: visible;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.inner_cell {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input_area {
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
a.heading-anchor {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.rendered_html code {
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
pre.ipynb {
|
||||
color: black;
|
||||
background: #f7f7f7;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
margin: 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* remove the prompt div from text cells */
|
||||
.prompt {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* remove horizontal padding from text cells, */
|
||||
/* so it aligns with outer body text */
|
||||
div.text_cell_render {
|
||||
padding: 0.5em 0em;
|
||||
}
|
||||
|
||||
img.anim_icon {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
}
|
||||
|
||||
div.collapseheader {
|
||||
width: 100%;
|
||||
background-color: #d3d3d3;
|
||||
padding: 2px;
|
||||
cursor: pointer;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* codeberg custom */
|
||||
body,
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
font-weight: initial;
|
||||
}
|
||||
|
||||
h1, h2 { font-weight: 300; }
|
||||
|
||||
[class^="cb-"], [class*=" cb-"] {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.page-header img {
|
||||
height: 75px;
|
||||
margin-left: 20%;
|
||||
}
|
||||
|
||||
/* remove left padding, used for site title */
|
||||
.cb-rm-l-padding {
|
||||
padding-left: 0;
|
||||
}
|
62
themes/business/static/css/pygments.css
Normal file
62
themes/business/static/css/pygments.css
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*Syntax highlighting for pygments*/
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #007020 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.highlight .go { color: #808080 } /* Generic.Output */
|
||||
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #902000 } /* Keyword.Type */
|
||||
.highlight .m { color: #40a070 } /* Literal.Number */
|
||||
.highlight .s { color: #4070a0 } /* Literal.String */
|
||||
.highlight .na { color: #4070a0 } /* Name.Attribute */
|
||||
.highlight .nb { color: #007020 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #60add5 } /* Name.Constant */
|
||||
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
|
||||
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #007020 } /* Name.Exception */
|
||||
.highlight .nf { color: #06287e } /* Name.Function */
|
||||
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
|
||||
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #bb60d5 } /* Name.Variable */
|
||||
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #40a070 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
|
||||
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #235388 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
|
BIN
themes/business/static/forkme_right_darkblue_121621.png
Normal file
BIN
themes/business/static/forkme_right_darkblue_121621.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
4
themes/business/static/html5.js
Normal file
4
themes/business/static/html5.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
// iepp v2.1pre @jon_neal & @aFarkas github.com/aFarkas/iepp
|
||||
// html5shiv @rem remysharp.com/html5-enabling-script
|
||||
// Dual licensed under the MIT or GPL Version 2 licenses
|
||||
/*@cc_on(function(a,b){function r(a){var b=-1;while(++b<f)a.createElement(e[b])}if(!window.attachEvent||!b.createStyleSheet||!function(){var a=document.createElement("div");return a.innerHTML="<elem></elem>",a.childNodes.length!==1}())return;a.iepp=a.iepp||{};var c=a.iepp,d=c.html5elements||"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|subline|summary|time|video",e=d.split("|"),f=e.length,g=new RegExp("(^|\\s)("+d+")","gi"),h=new RegExp("<(/*)("+d+")","gi"),i=/^\s*[\{\}]\s*$/,j=new RegExp("(^|[^\\n]*?\\s)("+d+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),k=b.createDocumentFragment(),l=b.documentElement,m=b.getElementsByTagName("script")[0].parentNode,n=b.createElement("body"),o=b.createElement("style"),p=/print|all/,q;c.getCSS=function(a,b){try{if(a+""===undefined)return""}catch(d){return""}var e=-1,f=a.length,g,h=[];while(++e<f){g=a[e];if(g.disabled)continue;b=g.media||b,p.test(b)&&h.push(c.getCSS(g.imports,b),g.cssText),b="all"}return h.join("")},c.parseCSS=function(a){var b=[],c;while((c=j.exec(a))!=null)b.push(((i.exec(c[1])?"\n":c[1])+c[2]+c[3]).replace(g,"$1.iepp-$2")+c[4]);return b.join("\n")},c.writeHTML=function(){var a=-1;q=q||b.body;while(++a<f){var c=b.getElementsByTagName(e[a]),d=c.length,g=-1;while(++g<d)c[g].className.indexOf("iepp-")<0&&(c[g].className+=" iepp-"+e[a])}k.appendChild(q),l.appendChild(n),n.className=q.className,n.id=q.id,n.innerHTML=q.innerHTML.replace(h,"<$1font")},c._beforePrint=function(){if(c.disablePP)return;o.styleSheet.cssText=c.parseCSS(c.getCSS(b.styleSheets,"all")),c.writeHTML()},c.restoreHTML=function(){if(c.disablePP)return;n.swapNode(q)},c._afterPrint=function(){c.restoreHTML(),o.styleSheet.cssText=""},r(b),r(k);if(c.disablePP)return;m.insertBefore(o,m.firstChild),o.media="print",o.className="iepp-printshim",a.attachEvent("onbeforeprint",c._beforePrint),a.attachEvent("onafterprint",c._afterPrint)})(this,document)@*/
|
BIN
themes/business/static/img/glyphicons-halflings-white.png
Normal file
BIN
themes/business/static/img/glyphicons-halflings-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
BIN
themes/business/static/img/glyphicons-halflings.png
Normal file
BIN
themes/business/static/img/glyphicons-halflings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
2280
themes/business/static/js/bootstrap.js
vendored
Normal file
2280
themes/business/static/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
6
themes/business/static/js/bootstrap.min.js
vendored
Normal file
6
themes/business/static/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
11
themes/business/static/js/darkmode.js
Normal file
11
themes/business/static/js/darkmode.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function toggleDarkMode(){
|
||||
halfmoon.toggleDarkMode();
|
||||
|
||||
var fa = document.getElementsByClassName("fa");
|
||||
for (var i = 0; i < fa.length; i++) {
|
||||
if (fa[i].classList.contains('fa-moon') || fa[i].classList.contains('fa-sun')){
|
||||
fa[i].classList.toggle('fa-sun');
|
||||
fa[i].classList.toggle('fa-moon');
|
||||
}
|
||||
}
|
||||
}
|
4
themes/business/static/js/jquery-1.11.0.min.js
vendored
Normal file
4
themes/business/static/js/jquery-1.11.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
themes/business/templates/analytics.html
Normal file
12
themes/business/templates/analytics.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
{% if GOOGLE_ANALYTICS %}
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '{{ GOOGLE_ANALYTICS }}', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
{% endif %}
|
19
themes/business/templates/archives.html
Normal file
19
themes/business/templates/archives.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Archives — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}Find all posts on one page.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Archives</h1>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% for article in dates %}
|
||||
<tr>
|
||||
<td>{{ article.date.strftime("%d %b %Y") }}</td>
|
||||
<td><a href='{{ SITEURL }}/{{ article.url }}'>{{ article.title }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
49
themes/business/templates/article.html
Normal file
49
themes/business/templates/article.html
Normal file
|
@ -0,0 +1,49 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ article.title }} — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}{{ article.summary | striptags | truncate(80, False, '...', 0) }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="article mx-auto" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<div class="text-center article-header">
|
||||
<h1 itemprop="name headline" class="article-title">{{ article.title }}</h1>
|
||||
{% if article.authors %}
|
||||
<h4>{{ article.authors | join(', ') }}</h4>
|
||||
{% elif article.author %}
|
||||
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
|
||||
<h4 itemprop="name">{{ article.author }}</h4>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
<span class="text-muted">
|
||||
<i class="fas fa-clock"></i>
|
||||
<time datetime="{{ article.date.isoformat() }}" itemprop="datePublished">{{ article.locale_date }}</time>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{% if article.category %}
|
||||
<div class="text-muted">
|
||||
<span><i class="fas fa-folder"></i> Category:</span>
|
||||
<span itemprop="articleSection">
|
||||
<a href="{{ SITEURL }}/{{ article.category.url }}" rel="category">{{ article.category }}</a>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if article.tags %}
|
||||
<div class="text-muted">
|
||||
<span><i class="fas fa-tags"></i> Tags:</span>
|
||||
{% for tag in article.tags %}
|
||||
<span itemprop="keywords">
|
||||
<a href="{{ SITEURL }}/{{ tag.url }}" rel="tag">#{{ tag }}</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div itemprop="articleBody" class="article-body">{{ article.content }}</div>
|
||||
{% include "twitter.html" %}
|
||||
{% include "liberapay.html" %}
|
||||
{% include 'disqus.html' %}
|
||||
</div>
|
||||
{% endblock %}
|
18
themes/business/templates/author.html
Normal file
18
themes/business/templates/author.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ author }} — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}All posts written by {{ author }}.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Author <b>{{author}}</b></h1>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% for article in articles %}
|
||||
<tr>
|
||||
<td>{{ article.date.strftime("%d %b %Y") }}</td>
|
||||
<td><a href='{{ SITEURL }}/{{ article.url }}'>{{ article.title }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
13
themes/business/templates/authors.html
Normal file
13
themes/business/templates/authors.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Authors — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}Authors page lists all post authors.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Authors</h1>
|
||||
<ul>
|
||||
{% for author, articles in authors %}
|
||||
<li><a href="{{ SITEURL }}/{{ author.url }}">{{ author }} ({{ articles | count }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
168
themes/business/templates/base.html
Normal file
168
themes/business/templates/base.html
Normal file
|
@ -0,0 +1,168 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ DEFAULT_LANG }}" class="business-design">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% block title %}{{ SITENAME }}{% endblock %}</title>
|
||||
<meta name="description" content="{% block description %}{{ DESCRIPTION }}{% endblock %}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% block meta %}<meta name="author" content="{{ AUTHOR }}">{% endblock %}
|
||||
<link rel="stylesheet" href="{{ SITEURL }}/theme/css/pygments.css">
|
||||
<link rel="stylesheet" href="https://design.hadan-it.com/business/design-kit/v1/css/business.css">
|
||||
<link href="https://fonts.hadan-it.com/dist/inter/web/inter.css" rel="stylesheet">
|
||||
<link href="https://fonts.hadan-it.com/dist/fontawesome5/css/all.min.css" rel="stylesheet">
|
||||
<script defer src="{{ SITEURL }}/theme/js/darkmode.js"></script>
|
||||
<script defer src="https://design.hadan-it.com/business/design-kit/v1/js/business.js"></script>
|
||||
<script defer src="https://design.hadan-it.com/business/design-kit/v1/js/business-components.js"></script>
|
||||
<link rel="icon" href="{{ SITEURL }}/theme/css/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="{{ SITEURL }}/theme/css/favicon.svg" type="image/svg+xml">
|
||||
{% block head %}{% endblock %}
|
||||
{% if FEED_ALL_ATOM %}
|
||||
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}" title="Blog" rel="alternate" type="application/atom+xml">
|
||||
{% endif %}
|
||||
</head>
|
||||
|
||||
<body class="with-custom-webkit-scrollbars with-custom-css-scrollbars" data-dm-shortcut-enabled="true" data-sidebar-shortcut-enabled="true" data-set-preferred-theme-onload="true">
|
||||
<style type="text/css" media="screen">
|
||||
.business-design .content {
|
||||
max-width: 80ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.business-design .content-wrapper {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.business-design img {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-wrapper with-navbar with-sidebar" data-sidebar-type="overlayed-sm-and-down">
|
||||
<nav class="navbar">
|
||||
<div class="navbar-content">
|
||||
<button class="btn btn-primary" type="button" onclick="halfmoon.toggleSidebar()">
|
||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||
<span class="sr-only">Toggle sidebar</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<a href="{{ SITEURL }}" class="navbar-brand" title="Codeberg News">
|
||||
<img src="https://design.hadan-it.com/business/logo-set/plain-transparent/svg/logo-transparent-background.svg" alt="Stephan Hadan Professional IT-Services">
|
||||
News
|
||||
</a>
|
||||
|
||||
<ul class="navbar-nav d-none d-md-flex w-full">
|
||||
{% if LINKS %}
|
||||
{% for name, link in LINKS %}
|
||||
<li class="nav-item">
|
||||
<a href="{{ link }}" class="nav-link">{{ name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<li class="nav-item ml-auto">
|
||||
<a href="javascript:;" onclick="toggleDarkMode()" class="nav-link text-center">
|
||||
<i class="fa fa-moon"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="navbar-content d-md-none ml-auto">
|
||||
<div class="dropdown with-arrow">
|
||||
<button class="btn" data-toggle="dropdown" type="button" id="navbar-dropdown-toggle-btn-1">
|
||||
Menu <i class="fa fa-angle-down" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right w-200" aria-labelledby="navbar-dropdown-toggle-btn-1">
|
||||
<a href="{{ SITEURL }}" class="dropdown-item">Home</a>
|
||||
{% if LINKS %}
|
||||
<div class="dropdown-divider my-5"></div>
|
||||
{% for name, link in LINKS %}
|
||||
<a href="{{ link }}" class="dropdown-item">{{ name }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if SOCIAL %}
|
||||
<div class="dropdown-divider my-5"></div>
|
||||
{% for name, link in SOCIAL %}
|
||||
<a rel="me" href="{{ link }}" class="dropdown-item">
|
||||
<i class="fab fa-{{ name.lower() }} " aria-hidden="true"></i> {{ name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="dropdown-divider my-5"></div>
|
||||
<a href="javascript:;" onclick="toggleDarkMode()" class="dropdown-item">
|
||||
<i class="fa fa-moon"></i> Toggle Dark Mode
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-overlay" onclick="halfmoon.toggleSidebar()"></div>
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-menu">
|
||||
<div class="sidebar-title">Navigation</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<a class="sidebar-link" href="{{ SITEURL }}">Home</a>
|
||||
<a class="sidebar-link" href="{{ SITEURL }}/archives.html">Archives</a>
|
||||
<a class="sidebar-link" href="{{ SITEURL }}/authors.html">Authors</a>
|
||||
{% for title, link in MENUITEMS %}
|
||||
<a href="{{ SITEURL }}/{{ link }}" class="sidebar-link">{{ title }}</a>
|
||||
{% endfor %}
|
||||
{% if DISPLAY_PAGES_ON_MENU %}
|
||||
{% for page in pages %}
|
||||
<a href="{{ SITEURL }}/{{ page.url }}" class="sidebar-link">{{ page.title }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if FEED_ALL_ATOM %}
|
||||
<a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}" type="application/atom+xml" class="sidebar-link">
|
||||
Atom
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if FEED_ALL_RSS %}
|
||||
<a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}" type="application/rss+xml" class="sidebar-link">
|
||||
RSS
|
||||
</a>
|
||||
{% endif %}
|
||||
<br>
|
||||
|
||||
<div class="sidebar-title">Categories</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
{% for cat, art in categories %}
|
||||
<a href="{{ SITEURL }}/category/{{ cat | replace(" ", "-") | lower }}.html" class="sidebar-link">
|
||||
{{ cat }} ({{ art | count }})
|
||||
</a>
|
||||
{% endfor %}
|
||||
<br>
|
||||
|
||||
<div class="sidebar-title">Socials</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
{% if SOCIAL %}
|
||||
{% for name, link in SOCIAL %}
|
||||
<a href="{{ link }}" class="sidebar-link">
|
||||
<i class="fab fa-{{ name.lower() }} pr-5" aria-hidden="true"></i> {{ name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="sidebar-divider"></div>
|
||||
<p class="mt-10 mb-5 mx-20 px-5 text-muted">© {{ AUTHOR }} {{ STARTYEAR }}{% if CURRENTYEAR %}–{{ CURRENTYEAR }}{% endif %}</p>
|
||||
<a href="https://codeberg.org/codeberg/org/src/Imprint.md" class="sidebar-link">Codeberg Imprint</a>
|
||||
<a href="https://blog.getpelican.com" class="sidebar-link">Powered by Pelican</a>
|
||||
</div>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "github.html" %}
|
||||
</body>
|
||||
</html>
|
13
themes/business/templates/categories.html
Normal file
13
themes/business/templates/categories.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Categories — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}Categories page lists all categories used to classify the posts.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Categories</h1>
|
||||
<ul>
|
||||
{% for category, articles in categories %}
|
||||
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }} ({{ articles | count }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
18
themes/business/templates/category.html
Normal file
18
themes/business/templates/category.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ category }} — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}All posts which refer to category {{ category }}.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Category <b>{{category}}</b></h1>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% for article in articles %}
|
||||
<tr>
|
||||
<td>{{ article.date.strftime("%d %b %Y") }}</td>
|
||||
<td><a href='{{ SITEURL }}/{{ article.url }}'>{{ article.title }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
14
themes/business/templates/disqus.html
Normal file
14
themes/business/templates/disqus.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% if DISQUS_SITENAME %}
|
||||
<div id="disqus_thread"></div>
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = '{{ DISQUS_SITENAME }}';
|
||||
var disqus_title = '{{ article.title }}';
|
||||
|
||||
(function() {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||
{% endif %}
|
3
themes/business/templates/github.html
Normal file
3
themes/business/templates/github.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
{% if GITHUB_URL %}
|
||||
<a href="{{ GITHUB_URL }}"><img style="position: absolute; top: 40px; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png" alt="Fork me on GitHub" /></a>
|
||||
{% endif %}
|
38
themes/business/templates/index.html
Normal file
38
themes/business/templates/index.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content_title %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if articles %}
|
||||
{% for article in articles_page.object_list %}
|
||||
<div class="article card mx-auto" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
<a href="{{ SITEURL }}/{{ article.url }}">
|
||||
<h2 class="card-title" itemprop="name headline">{{ article.title }}</h2>
|
||||
</a>
|
||||
<p class="text-muted">
|
||||
<i class="fas fa-clock"></i>
|
||||
<time datetime="{{ article.date.isoformat() }}" itemprop="datePublished">{{ article.locale_date }}</time>
|
||||
</p>
|
||||
<div class="summary">{{ article.summary }}</div>
|
||||
|
||||
{% if article.category %}
|
||||
<span class="text-muted"><i class="fas fa-folder"></i> Category:</span>
|
||||
<span itemprop="articleSection">
|
||||
<a href="{{ SITEURL }}/{{ article.category.url }}" rel="category">{{ article.category }}</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% if article.tags %}
|
||||
<span class="text-muted"><i class="fas fa-tags ml-10"></i> Tags:</span>
|
||||
{% for tag in article.tags %}
|
||||
<span itemprop="keywords">
|
||||
<a href="{{ SITEURL }}/{{ tag.url }}" rel="tag">#{{ tag }}</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% include 'pagination.html' %}
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
4
themes/business/templates/liberapay.html
Normal file
4
themes/business/templates/liberapay.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
{% if LIBERAPAY_USERNAME %}
|
||||
<p>Support us on Liberapay: <script src="https://liberapay.com/{{LIBERAPAY_USERNAME}}/widgets/button.js"></script>
|
||||
<noscript><a href="https://liberapay.com/{{LIBERAPAY_USERNAME}}/donate"><img src="https://liberapay.com/assets/widgets/donate.svg"></a></noscript></p>
|
||||
{% endif %}
|
8
themes/business/templates/page.html
Normal file
8
themes/business/templates/page.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
{% block description %}{{ page.description }}{% endblock %}
|
||||
{% block title %}{{ page.title }} — {{ SITENAME }} {% endblock %}
|
||||
{% block content %}
|
||||
<section id="content" class="body">
|
||||
{{ page.content }}
|
||||
</section>
|
||||
{% endblock %}
|
30
themes/business/templates/pagination.html
Normal file
30
themes/business/templates/pagination.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
<nav>
|
||||
<ul class="pagination text-center">
|
||||
{% if articles_page.has_previous() %}
|
||||
{% set num = articles_page.previous_page_number() %}
|
||||
<li class="page-item prev">
|
||||
<a class="page-link" href="{{ SITEURL }}/{{ page_name }}{{ num if num > 1 else '' }}.html">← Previous</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item prev disabled">
|
||||
<a class="page-link" href="#">← Previous</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for num in range( 1, 1 + articles_paginator.num_pages ) %}
|
||||
<li class="page-item {{ 'active' if num == articles_page.number else '' }}">
|
||||
<a class="page-link" href="{{ SITEURL }}/{{ page_name }}{{ num if num > 1 else '' }}.html">{{ num }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
{% if articles_page.has_next() %}
|
||||
<li class="page-item next">
|
||||
<a class="page-link" href="{{ SITEURL }}/{{ page_name }}{{ articles_page.next_page_number() }}.html">Next →</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item next disabled">
|
||||
<a class="page-link" href="#">→ Next</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
18
themes/business/templates/tag.html
Normal file
18
themes/business/templates/tag.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ tag }} — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}All posts which refer to tag {{ tag }}.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Tag <b>{{tag}}</b></h1>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% for article in articles %}
|
||||
<tr>
|
||||
<td>{{ article.date.strftime("%d %b %Y") }}</td>
|
||||
<td><a href='{{ SITEURL }}/{{ article.url }}'>{{ article.title }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
13
themes/business/templates/tags.html
Normal file
13
themes/business/templates/tags.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Tags — {{ SITENAME }}{% endblock %}
|
||||
{% block description %}The Tags page lists all tags used to classify the posts.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Tags</h1>
|
||||
<ul>
|
||||
{% for tag, posts in tags %}
|
||||
<li><a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }} ({{ posts | count }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
3
themes/business/templates/twitter.html
Normal file
3
themes/business/templates/twitter.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
{% if TWITTER_USERNAME %}
|
||||
<a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-via="{{TWITTER_USERNAME}}">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
|
||||
{% endif %}
|
Loading…
Add table
Reference in a new issue