initial commit
This commit is contained in:
parent
459ff5989c
commit
3f954e525f
|
@ -0,0 +1,5 @@
|
|||
*.pyc
|
||||
__pycache__
|
||||
*.swp
|
||||
*.swo
|
||||
output
|
|
@ -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
|
|
@ -0,0 +1,12 @@
|
|||
Hello World
|
||||
###########
|
||||
|
||||
:date: 2010-10-03 10:20
|
||||
:modified: 2010-10-04 18:40
|
||||
:tags: helloworld, test
|
||||
:category: none
|
||||
:slug: hello-world
|
||||
:authors: toto
|
||||
:summary: les shorts
|
||||
|
||||
cucu hello wrlod
|
|
@ -0,0 +1,22 @@
|
|||
# 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 = ""
|
||||
RELATIVE_URLS = False
|
||||
|
||||
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 = ""
|
|
@ -0,0 +1,147 @@
|
|||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
from invoke import task
|
||||
from invoke.main import program
|
||||
from invoke.util import cd
|
||||
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))
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,38 @@
|
|||
@import url(https://files.stork-search.net/basic.css);
|
||||
|
||||
body:not(.stork-multitheme),
|
||||
.stork-wrapper-dark {
|
||||
--stork-border-color: hsl(0, 0%, 36%);
|
||||
--stork-background-color: hsl(0, 0%, 22%);
|
||||
--stork-accent-color: hsl(194, 90%, 53%);
|
||||
|
||||
--stork-input-text-color: white;
|
||||
|
||||
--stork-results-hover-color: hsl(210, 83%, 16%);
|
||||
--stork-results-title-color: white;
|
||||
--stork-results-excerpt-color: hsla(0, 0%, 80%, 1);
|
||||
--stork-results-highlight-color: rgb(94, 201, 186);
|
||||
--stork-results-border-color: hsl(0, 0%, 30%);
|
||||
}
|
||||
|
||||
body:not(.stork-multitheme) .stork-close-button,
|
||||
.stork-wrapper-dark .stork-close-button {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
hsl(0, 0%, 60%) 0%,
|
||||
hsl(0, 0%, 50%) 100%
|
||||
);
|
||||
border: 1px solid hsla(0, 0%, 50%, 0.8);
|
||||
color: hsl(0, 0%, 25%);
|
||||
}
|
||||
|
||||
body:not(.stork-multitheme) .stork-close-button:hover,
|
||||
.stork-wrapper-dark .stork-close-button:hover {
|
||||
background: hsla(0, 0%, 45%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
body:not(.stork-multitheme) .stork-close-button:active,
|
||||
.stork-wrapper-dark .stork-close-button:active {
|
||||
background: hsla(0, 0%, 40%);
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
:root {
|
||||
--stork-border-color: hsl(0, 0%, 65%);
|
||||
--stork-background-color: hsla(0, 0%, 97%, 1);
|
||||
--stork-font-family: inherit;
|
||||
--stork-size-multiplier: 1;
|
||||
--stork-accent-color: hsl(210, 72%, 45%);
|
||||
|
||||
--stork-input-width: 100%;
|
||||
--stork-input-border-radius: 8px;
|
||||
--stork-input-text-color: black;
|
||||
--stork-input-shadow: 1;
|
||||
|
||||
--stork-results-width: 100%;
|
||||
--stork-results-border-radius: 4px;
|
||||
--stork-results-shadow: 1;
|
||||
--stork-results-hover-color: hsl(210, 65%, 75%);
|
||||
--stork-results-title-color: black;
|
||||
--stork-results-excerpt-color: black;
|
||||
--stork-results-highlight-color: rgb(245, 230, 26);
|
||||
--stork-results-border-color: var(--stork-border-color);
|
||||
}
|
||||
|
||||
.stork-wrapper {
|
||||
position: relative;
|
||||
font-family: var(--stork-font-family);
|
||||
box-sizing: border-box;
|
||||
font-size: 1em * var(--stork-size-multiplier);
|
||||
}
|
||||
|
||||
.stork-wrapper *,
|
||||
.stork-wrapper *:before,
|
||||
.stork-wrapper *:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.stork-input {
|
||||
width: var(--stork-input-width);
|
||||
height: 2.4em;
|
||||
font-size: 1em;
|
||||
padding: 0.4em 0.8em;
|
||||
position: relative;
|
||||
box-shadow: inset 0 0.1em 0.3em
|
||||
hsla(0, 0%, 0%, calc(var(--stork-input-shadow) * 0.25));
|
||||
border: 1px solid var(--stork-border-color);
|
||||
border-radius: var(--stork-input-border-radius);
|
||||
background-color: var(--stork-background-color);
|
||||
color: var(--stork-input-text-color);
|
||||
font-family: var(--stork-font-family);
|
||||
}
|
||||
|
||||
.stork-input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.stork-progress {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: "";
|
||||
bottom: 1px;
|
||||
background-color: var(--stork-accent-color);
|
||||
box-shadow: 0 0 8px var(--stork-accent-color);
|
||||
height: 1px;
|
||||
transition: width 0.25s ease, opacity 0.4s ease 0.4s;
|
||||
}
|
||||
|
||||
.stork-output {
|
||||
position: absolute;
|
||||
width: var(--stork-results-width);
|
||||
margin-top: 0.5em;
|
||||
border-radius: var(--stork-results-border-radius);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 100;
|
||||
color: var(--stork-results-title-color);
|
||||
font-weight: 400;
|
||||
font-family: var(--stork-font-family);
|
||||
}
|
||||
|
||||
.stork-attribution a:link,
|
||||
.stork-attribution a:visited {
|
||||
color: var(--stork-accent-color);
|
||||
}
|
||||
|
||||
.stork-output-visible {
|
||||
border: 1px solid var(--stork-border-color);
|
||||
box-shadow: 0px 0px 2.2px
|
||||
rgba(0, 0, 0, calc(var(--stork-results-shadow) * 0.02)),
|
||||
0px 0px 5.3px rgba(0, 0, 0, calc(var(--stork-results-shadow) * 0.028)),
|
||||
0px 0px 10px rgba(0, 0, 0, calc(var(--stork-results-shadow) * 0.035)),
|
||||
0px 0px 17.9px rgba(0, 0, 0, calc(var(--stork-results-shadow) * 0.042)),
|
||||
0px 0px 33.4px rgba(0, 0, 0, calc(var(--stork-results-shadow) * 0.05)),
|
||||
0px 0px 80px rgba(0, 0, 0, calc(var(--stork-results-shadow) * 0.07));
|
||||
background: var(--stork-background-color);
|
||||
}
|
||||
|
||||
.stork-message {
|
||||
width: 100%;
|
||||
padding: 0.5em 1em;
|
||||
color: var(--stork-results-title-color);
|
||||
}
|
||||
|
||||
.stork-attribution {
|
||||
width: 100%;
|
||||
padding: 0.5em 1em;
|
||||
font-size: 0.8em;
|
||||
color: var(--stork-results-title-color);
|
||||
}
|
||||
|
||||
.stork-results {
|
||||
margin: 0;
|
||||
padding: 0.25em 0;
|
||||
width: 100%;
|
||||
list-style-type: none;
|
||||
max-height: 25em;
|
||||
overflow-y: scroll;
|
||||
border-top: 1px solid var(--stork-border-color);
|
||||
border-bottom: 1px solid var(--stork-border-color);
|
||||
box-shadow: inset 0em 0.7em 0.7em -0.7em hsla(0, 0%, 0%, calc(var(
|
||||
--stork-results-shadow
|
||||
) * 0.34)),
|
||||
inset 0em -0.7em 0.7em -0.7em
|
||||
hsl(0, 0%, 0%, calc(var(--stork-results-shadow) * 0.34));
|
||||
}
|
||||
|
||||
.stork-result:not(:last-child) {
|
||||
border-bottom: 1px solid var(--stork-results-border-color);
|
||||
}
|
||||
|
||||
.stork-result.selected {
|
||||
background: var(--stork-results-hover-color);
|
||||
}
|
||||
|
||||
.stork-result a:link {
|
||||
padding: 1em;
|
||||
display: block;
|
||||
color: currentcolor;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.stork-result p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.stork-title {
|
||||
font-weight: bold;
|
||||
font-size: 0.95em;
|
||||
margin: 0 0 0.75em 0;
|
||||
color: var(--stork-results-title-color);
|
||||
|
||||
/* Flexbox container for the title and the score, when debugging */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.stork-excerpt {
|
||||
font-size: 0.8em;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
color: var(--stork-results-excerpt-color);
|
||||
|
||||
/* Flexbox container for the title and the score, when debugging */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.stork-excerpt:not(:last-of-type) {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
.stork-highlight {
|
||||
background-color: var(--stork-results-highlight-color);
|
||||
padding: 0 0.1em;
|
||||
}
|
||||
|
||||
.stork-error {
|
||||
outline: 2px solid hsl(0, 89%, 46%);
|
||||
}
|
||||
|
||||
.stork-close-button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: 0.3em 0.4em;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
padding: 0px;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
hsl(0, 0%, 85%) 0%,
|
||||
hsl(0, 0%, 75%) 100%
|
||||
);
|
||||
border: 1px solid hsla(0, 0%, 50%, 0.8);
|
||||
font-size: 1.1em;
|
||||
color: hsl(0, 0%, 45%);
|
||||
border-radius: 15%;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stork-close-button svg {
|
||||
width: 0.8em;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.stork-close-button:hover {
|
||||
background: hsla(0, 0%, 70%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.stork-close-button:active {
|
||||
background: hsla(0, 0%, 65%);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{% if GOOGLE_ANALYTICS %}
|
||||
<script type="text/javascript">
|
||||
(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', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||
|
||||
ga('create', '{{GOOGLE_ANALYTICS}}', '{{GA_COOKIE_DOMAIN if GA_COOKIE_DOMAIN else "auto"}}');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if GAUGES %}
|
||||
<script type="text/javascript">
|
||||
var _gauges = _gauges || [];
|
||||
(function () {
|
||||
var t = document.createElement('script');
|
||||
t.type = 'text/javascript';
|
||||
t.async = true;
|
||||
t.id = 'gauges-tracker';
|
||||
t.setAttribute('data-site-id', '{{GAUGES}}');
|
||||
t.src = '//secure.gaug.es/track.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(t, s);
|
||||
})();
|
||||
</script>
|
||||
{% endif %}
|
|
@ -0,0 +1,120 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Archive | {{ SITENAME }}{% endblock %}
|
||||
{% set current = "archive" %}
|
||||
|
||||
{% macro countyear(year) %}
|
||||
{% set name = namespace(y=0) %}
|
||||
{% for article in dates %}
|
||||
{% if article.date | strftime('%Y') == year %}
|
||||
{% set name.y = name.y + 1 %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{name.y}}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro countmonth(month, year) %}
|
||||
{% set name = namespace(m=0) %}
|
||||
{% for article in dates %}
|
||||
{% if article.date | strftime('%B') == month and article.date | strftime('%Y') == year %}
|
||||
{% set name.m = name.m + 1 %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{name.m}}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="md:mt-14 text-zinc-800 dark:text-zinc-300 pb-6">
|
||||
<h1 class="font-bold text-4xl my-10">Archive</h1>
|
||||
<ul class=" flex-col">
|
||||
{% for year, year_group in dates_page.object_list|groupby('date.year')|reverse %}
|
||||
{% for month, month_group in year_group|groupby('date.month')|reverse %}
|
||||
{% for article in month_group %}
|
||||
{% if article == month_group[0] and article == year_group[0] %}
|
||||
<h3 class="text-2xl font-semibold my-8">{{(month_group|first).date|strftime('%Y')}}
|
||||
<sup class="text-sm text-zinc-800 dark:text-zinc-400">
|
||||
{{ countyear(article.date | strftime('%Y')) }}
|
||||
</sup>
|
||||
</h3>
|
||||
<div class="md:flex my-1">
|
||||
<time class="text-xl font-semibold flex mt-6 md:mt-2 md:w-40">{{ (month_group|first).date|strftime('%B') }}
|
||||
<sup class="text-sm m-1 text-zinc-800 dark:text-zinc-400">
|
||||
{{ countmonth(article.date | strftime('%B'), article.date | strftime('%Y')) }}
|
||||
</sup>
|
||||
</time>
|
||||
<a href="{{ SITEURL }}/{{ article.url }}">
|
||||
<li class="flex-1 md:mt-2"><span class="text-lg">{{ article.title}}</span><br>
|
||||
<div class="flex text-xs text-zinc-800 dark:text-zinc-400">
|
||||
<time>{{ article.date|strftime('%B %d, %Y') }}</time>
|
||||
<div>
|
||||
{% if article.readtime %}
|
||||
<span> · {{ article.readtime }} min read</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if article.author != '' %}
|
||||
<span> · {{ article.author }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
</div>
|
||||
{% elif article == month_group[0] %}
|
||||
<div class="md:flex mt-3">
|
||||
<time class="text-xl font-semibold flex mt-6 md:mt-2 md:w-40">{{ (month_group|first).date|strftime('%B') }}
|
||||
<sup class="text-sm m-1 text-zinc-800 dark:text-zinc-400">
|
||||
{{ countmonth(article.date | strftime('%B'), article.date | strftime('%Y')) }}
|
||||
</sup>
|
||||
</time>
|
||||
<a href="{{ SITEURL }}/{{ article.url }}">
|
||||
<li class="flex-1 md:mt-2"><span class="text-lg">{{ article.title}}</span><br>
|
||||
<div class="flex text-xs text-zinc-800 dark:text-zinc-400">
|
||||
<time>{{ article.date|strftime('%B %d, %Y') }}</time>
|
||||
<div>
|
||||
{% if article.readtime %}
|
||||
<span> · {{ article.readtime }} min read</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if article.author != '' %}
|
||||
<span> · {{ article.author }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="md:flex">
|
||||
<time class="flex md:w-40"></time>
|
||||
<a href="{{ SITEURL }}/{{ article.url }}">
|
||||
<li class="flex-1 md:mt-2 mt-1"><span class="text-lg">{{ article.title}}</span><br>
|
||||
<div class="flex text-xs text-zinc-800 dark:text-zinc-400">
|
||||
<time>{{ article.date|strftime('%B %d, %Y') }}</time>
|
||||
<div>
|
||||
{% if article.readtime %}
|
||||
<span> · {{ article.readtime }} min read</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if article.author != '' %}
|
||||
<span> · {{ article.author }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% if dates_page.has_other_pages() %}
|
||||
{% include 'pagination.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,123 @@
|
|||
{% extends "base.html" %}
|
||||
{% block html_lang %}{{ article.lang }}{% endblock %}
|
||||
{% block head -%}
|
||||
{{ super() -}}
|
||||
{% if article.summary %}
|
||||
<meta name="description" content="{{ article.summary | striptags | safe | truncate(150) }}" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block title %}{{ article.title|striptags }}{% endblock %}
|
||||
{% block extra_head %}
|
||||
{% import 'translations.html' as translations with context %}
|
||||
{% if translations.entry_hreflang(article) %}
|
||||
{{ translations.entry_hreflang(article) }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<main>
|
||||
<header>
|
||||
<h1 class="font-semibold text-3xl my-2">{{article.title}}</h1>
|
||||
<footer class="flex text-sm text-zinc-800 dark:text-zinc-400">
|
||||
<div class="flex text-xs text-zinc-800 dark:text-zinc-400">
|
||||
<time>{{ article.date|strftime('%B %d, %Y') }}</time>
|
||||
<div>
|
||||
{% if article.readtime %}
|
||||
<span> · {{ article.readtime }} min read</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if article.author != '' %}
|
||||
<span> · {{ article.author }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{% if article.modified %}
|
||||
<div class="flex text-xs text-zinc-800 dark:text-zinc-400">
|
||||
<span>Last updated: {{ article.modified|strftime('%B %d, %Y') }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
{% if article.toc %}
|
||||
<details class="flex flex-col my-6 p-4 bg-zinc-200 dark:bg-zinc-800 rounded-lg">
|
||||
<summary class="text-lg font-bold">Table of contents</summary>
|
||||
<div class="mx-4 px-4 underline">
|
||||
{{ article.toc }}
|
||||
</div>
|
||||
</details>
|
||||
{% endif %}
|
||||
<div class="max-w-7xl container mx-auto my-8 text-zinc-800 dark:text-zinc-300
|
||||
prose lg:max-w-none prose-headings:text-zinc-800 prose-headings:dark:text-zinc-300
|
||||
prose-h1:text-3xl lg:prose-h1:text-3xl prose-headings:font-semibold
|
||||
prose-pre:bg-zinc-200 prose-pre:text-zinc-800
|
||||
dark:prose-pre:bg-zinc-800 dark:prose-pre:text-zinc-200
|
||||
prose-blockquote:text-zinc-800
|
||||
dark:prose-blockquote:text-zinc-200
|
||||
prose-a:text-gray-500
|
||||
dark:prose-a:text-gray-400
|
||||
dark:prose-strong:text-zinc-200
|
||||
dark:prose-code:text-zinc-200
|
||||
dark:prose-code:bg-zinc-800
|
||||
prose-code:bg-zinc-200
|
||||
prose-code:font-light
|
||||
prose-img:rounded-md
|
||||
">
|
||||
{{ article.content }}
|
||||
<!-- <div class="aspect-w-16 aspect-h-9 mx-auto"></div> CSS placeholder -->
|
||||
</div>
|
||||
<footer class="flex flex-col mt-10 ">
|
||||
<ul class="flex flex-wrap">
|
||||
{% for tag in article.tags|sort %}
|
||||
<a href="{{ SITEURL }}/{{ tag.url }}">
|
||||
<li
|
||||
class="bg-zinc-200 hover:bg-zinc-300 dark:hover:bg-zinc-800 dark:bg-zinc-700 text-zinc-500 dark:text-neutral-400 mb-2 mr-2 px-3 py-1.5 rounded-md transition ease-in active:-translate-y-1 active:scale-110 duration-75">
|
||||
{{ tag }}
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="flex w-full my-2 bg-zinc-200 dark:bg-zinc-700 rounded-lg">
|
||||
{% if article.next_article %}
|
||||
<div class="w-1/2 hover:bg-zinc-300 dark:hover:bg-zinc-800 rounded-l-lg">
|
||||
<a class="flex flex-col pr-2" href="{{ SITEURL }}/{{ article.next_article.url }}">
|
||||
<div class="mx-4 py-2 text-left">
|
||||
<p class="text-zinc-500 dark:text-neutral-400 text-sm">« PREV PAGE</p>
|
||||
<p class="text-left py-1 hover:underline">{{ article.next_article.title }}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="w-1/2 rounded-l-lg"></div>
|
||||
{% endif %}
|
||||
{% if article.prev_article %}
|
||||
<div class="w-1/2 hover:bg-zinc-300 dark:hover:bg-zinc-800 rounded-r-lg ">
|
||||
<a class="flex flex-col" href="{{ SITEURL }}/{{ article.prev_article.url }}">
|
||||
<div class="text-right mx-4 py-2">
|
||||
<p class="text-zinc-500 dark:text-neutral-400 text-sm">NEXT PAGE »</p>
|
||||
<p class="text-right py-1 hover:underline">{{ article.prev_article.title }}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="flex bg-zinc-200 dark:bg-zinc-700 py-2 rounded-lg justify-center space-x-2 text-xs">
|
||||
{% for name, link in SHARE %}
|
||||
<ul>
|
||||
<a target="_blank" rel="noopener noreferrer" title="{{ name }}" aria-label="share Features on {{ name }}"
|
||||
href="{{ link }}{{ SITEURL }}/{{ article.url }}">
|
||||
<li class="bg-gray-900 p-1 text-white rounded-md">
|
||||
<i class="fab fa-{{ name }} fa-2x" aria-hidden="true"></i>
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</footer>
|
||||
<div>
|
||||
{% include 'disqus_script.html' %}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,2 @@
|
|||
{% extends "index.html" %}
|
||||
{% block title %}{{ SITENAME }} - {{ author }}{% endblock %}
|
|
@ -0,0 +1,12 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - Authors{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Authors on {{ SITENAME }}</h1>
|
||||
<ul>
|
||||
{% for author, articles in authors|sort %}
|
||||
<li><a href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a> ({{ articles|count }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
|
@ -0,0 +1,252 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{% block html_lang %}{{ DEFAULT_LANG }}{% endblock html_lang %}">
|
||||
|
||||
<head>
|
||||
{% block head %}
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="generator" content="Pelican" />
|
||||
<title>{% block title %} {{ SITENAME }} {% endblock %}</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Slab|Ruda" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/main.css" />
|
||||
<link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/stork.css">
|
||||
<link rel="stylesheet" media="screen and (prefers-color-scheme: dark)"
|
||||
href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/stork-dark.css">
|
||||
{% if FEED_ALL_ATOM %}
|
||||
<link
|
||||
href="{{ FEED_DOMAIN }}/{% if FEED_ALL_ATOM_URL %}{{ FEED_ALL_ATOM_URL }}{% else %}{{ FEED_ALL_ATOM }}{% endif %}"
|
||||
type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
|
||||
{% endif %}
|
||||
{% if FEED_ALL_RSS %}
|
||||
<link
|
||||
href="{{ FEED_DOMAIN }}/{% if FEED_ALL_RSS_URL %}{{ FEED_ALL_RSS_URL }}{% else %}{{ FEED_ALL_RSS }}{% endif %}"
|
||||
type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
|
||||
{% endif %}
|
||||
{% block extra_head %}{% endblock extra_head %}
|
||||
{% endblock head %}
|
||||
<script>
|
||||
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia(
|
||||
'(prefers-color-scheme: dark)').matches)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="min-h-screen flex flex-col max-w-7xl lg:max-w-none text-zinc-800 bg-neutral-100
|
||||
dark:bg-neutral-900 dark:text-zinc-300 container mx-auto justify-center md:px-3 ">
|
||||
<nav class="sm:flex sm:justify-between xl:ml-32 pl-4 items-center">
|
||||
<div class="flex pt-4">
|
||||
<h1 class="font-semibold text-2xl"><a href="{{ SITEURL }}/">{{ SITENAME }}</a></h1>
|
||||
<button id="theme-toggle" type="button"
|
||||
class="text-zinc-700 dark:text-zinc-400 rounded-full focus:outline-none text-sm ml-2 p-1">
|
||||
<svg id="theme-toggle-dark-icon" class="w-5 h-5 hidden" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
|
||||
</svg>
|
||||
<svg id="theme-toggle-light-icon" class="w-5 h-5 hidden" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
|
||||
fill-rule="evenodd" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="flex flex-wrap lg:mr-24 md:pt-0">
|
||||
{% if DISPLAY_PAGES_ON_MENU %}
|
||||
{% for p in pages %}
|
||||
<li class="mr-4 pt-6"><a {% if p==page %} class="border-b-2 border-zinc-800 dark:border-zinc-300"
|
||||
{% endif %} href="{{ SITEURL }}/{{ p.url }}">{{ p.title }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<li class="mr-4 pt-6"><a {% if current=="archive" %} class="border-b-2 border-zinc-800 dark:border-zinc-300"
|
||||
{% endif %} href="{{ SITEURL }}/archives.html">Archive</a></li>
|
||||
<li class="mr-4 pt-6"><a {% if current=="categories" %}
|
||||
class="border-b-2 border-zinc-800 dark:border-zinc-300" {% endif %}
|
||||
href="{{ SITEURL }}/categories.html">Categories</a></li>
|
||||
<li class="mr-4 pt-6"><a {% if current=="tags" %} class="border-b-2 border-zinc-800 dark:border-zinc-300"
|
||||
{% endif %} href="{{ SITEURL }}/tags.html">Tags</a></li>
|
||||
<li class="mr-4 pt-6"><a {% if current=="search" %} class="border-b-2 border-zinc-800 dark:border-zinc-300"
|
||||
{% endif %} href="{{ SITEURL }}/search.html">Search</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="flex-grow md:max-w-screen-md md:mx-auto md:w-3/4 px-4">
|
||||
{% if article %}
|
||||
<nav class="text-zinc-800 dark:text-zinc-300 mt-12 pb-2 md:mt-16" aria-label="Breadcrumb">
|
||||
<ul class="p-0 inline-flex items-center">
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/" class="text-zinc-800 dark:text-zinc-300 inline-flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z">
|
||||
</path>
|
||||
</svg>
|
||||
Home
|
||||
</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/categories.html">Categories</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/{{category.url}}">{{ category }}</a>
|
||||
</li>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</ul>
|
||||
</nav>
|
||||
{% elif tag %}
|
||||
<nav class="text-zinc-800 dark:text-zinc-300 mt-12 pb-3 md:mt-16" aria-label="Breadcrumb">
|
||||
<ul class="p-0 inline-flex">
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/" class="text-zinc-800 dark:text-zinc-300 inline-flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z">
|
||||
</path>
|
||||
</svg>
|
||||
Home
|
||||
</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/tags.html">Tags</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="border-b-2 border-zinc-800 dark:border-zinc-300">
|
||||
{{ tag }}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% elif page %}
|
||||
<nav class="text-zinc-800 dark:text-zinc-300 mt-12 pb-3 md:mt-16" aria-label="Breadcrumb">
|
||||
<ul class="p-0 inline-flex">
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/" class="text-zinc-800 dark:text-zinc-300 inline-flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z">
|
||||
</path>
|
||||
</svg>
|
||||
Home
|
||||
</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="border-b-2 border-zinc-800 dark:border-zinc-300">
|
||||
{{page.title}}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% elif category %}
|
||||
<nav class="text-zinc-800 dark:text-zinc-300 mt-12 pb-3 md:mt-16" aria-label="Breadcrumb">
|
||||
<ul class="p-0 inline-flex">
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/" class="text-zinc-800 dark:text-zinc-300 inline-flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z">
|
||||
</path>
|
||||
</svg>
|
||||
Home
|
||||
</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<a href="{{ SITEURL }}/categories.html">Categories</a>
|
||||
<svg class="fill-current w-3 h-3 mr-2 ml-1" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="border-b-2 border-zinc-800 dark:border-zinc-300">
|
||||
{{ category }}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% block content %} {% endblock %}
|
||||
</div>
|
||||
<footer class="flex w-full text-xs justify-center mt-10 mb-6 text-zinc-500 dark:text-zinc-400">
|
||||
<div class="px-4">
|
||||
<span>{% if COPYRIGHT %}{{ COPYRIGHT }} • {% endif %}</span>Powered by
|
||||
<a class="underline" href="https://getpelican.com/">Pelican</a> &
|
||||
<a class="underline" href="https://github.com/aleylara/Papyrus"> Papyrus</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
{% include 'analytics.html' %}
|
||||
{% include 'disqus_script.html' %}
|
||||
|
||||
<script>
|
||||
let themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
|
||||
let themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
|
||||
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia(
|
||||
'(prefers-color-scheme: dark)').matches)) {
|
||||
themeToggleLightIcon.classList.remove('hidden');
|
||||
} else {
|
||||
themeToggleDarkIcon.classList.remove('hidden');
|
||||
}
|
||||
let themeToggleBtn = document.getElementById('theme-toggle');
|
||||
themeToggleBtn.addEventListener('click', function () {
|
||||
themeToggleDarkIcon.classList.toggle('hidden');
|
||||
themeToggleLightIcon.classList.toggle('hidden');
|
||||
if (localStorage.getItem('color-theme')) {
|
||||
if (localStorage.getItem('color-theme') === 'light') {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.setItem('color-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.setItem('color-theme', 'light');
|
||||
}
|
||||
} else {
|
||||
if (document.documentElement.classList.contains('dark')) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.setItem('color-theme', 'light');
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.setItem('color-theme', 'dark');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="https://files.stork-search.net/releases/v1.4.0/stork.js"></script>
|
||||
<script>
|
||||
stork.register("sitesearch", "{{ SITEURL }}/search-index.st")
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} | Categories{% endblock %}
|
||||
{% set current = "categories" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="mb-12 md:mt-14 text-zinc-800 dark:text-zinc-300">
|
||||
<h1 class="font-bold text-4xl my-10">Categories</h1>
|
||||
<ul class="flex flex-wrap font-medium">
|
||||
{% for category, articles in categories|sort %}
|
||||
<a href="{{ SITEURL }}/{{ category.url }}">
|
||||
<li
|
||||
class="bg-zinc-300 dark:bg-neutral-700 text-zinc-800 dark:text-zinc-300 hover:bg-zinc-400 dark:hover:bg-zinc-800 m-2 py-2 px-2 md:px-4 rounded-md transition ease-in active:-translate-y-1 active:scale-110 duration-75">
|
||||
{{ category }}<sup class="p-1">{{ articles|count }}</sup></li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ category }} | {{SITENAME}}{% endblock %}
|
||||
|
||||
{% block content_title %}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,5 @@
|
|||
{% if DISQUS_SITENAME %}
|
||||
<p>
|
||||
There are <a href="{{ SITEURL }}/{{ article.url }}#disqus_thread">comments</a>.
|
||||
</p>
|
||||
{% endif %}
|
|
@ -0,0 +1,12 @@
|
|||
{% if DISQUS_SITENAME %}
|
||||
<script type="text/javascript">
|
||||
var disqus_shortname = '{{ DISQUS_SITENAME }}';
|
||||
(function () {
|
||||
var s = document.createElement('script');
|
||||
s.async = true;
|
||||
s.type = 'text/javascript';
|
||||
s.src = 'https://' + disqus_shortname + '.disqus.com/count.js';
|
||||
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
|
||||
}());
|
||||
</script>
|
||||
{% endif %}
|
|
@ -0,0 +1,89 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% block content_title %}
|
||||
{% if not category and not tag %}
|
||||
<div class="my-12 md:my-24 text-zinc-800 dark:text-zinc-300">
|
||||
{% if SUBTITLE %}
|
||||
<h1 class="mb-6 text-3xl font-bold">{{ SUBTITLE }}</h1>
|
||||
{%endif%}
|
||||
{%if SUBTEXT %}
|
||||
<p class="mb-8 text-zinc-500 dark:text-zinc-400"> {{ SUBTEXT }}</p>
|
||||
{% endif %}
|
||||
{% if SOCIAL or FEED_ALL_ATOM or FEED_ALL_RSS %}
|
||||
<ul class="flex px-2 space-x-4 text-lg">
|
||||
{% for name, link in SOCIAL %}
|
||||
<li><a href="{{ link }}"><i class="fab fa-{{ name }} fa-lg" aria-hidden="true" target="_blank"
|
||||
rel="noopener noreferrer" title="{{ name }}"></i></a></li>
|
||||
{% endfor %}
|
||||
{% if FEED_ALL_ATOM %}
|
||||
<li><a href="{{ FEED_DOMAIN }}/
|
||||
{% if FEED_ALL_ATOM_URL %}{{ FEED_ALL_ATOM_URL }}{% else %}{{ FEED_ALL_ATOM }}{% endif %}"
|
||||
type="application/atom+xml" title="{{ FEED_ALL_ATOM }}" rel="alternate"><i class="fa fa-rss fa-lg"
|
||||
aria-hidden="true"></i></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if FEED_ALL_RSS %}
|
||||
<li><a href="{{ FEED_DOMAIN }}/
|
||||
{% if FEED_ALL_RSS_URL %}{{ FEED_ALL_RSS_URL }}{% else %}{{ FEED_ALL_RSS }}{% endif %}"
|
||||
type="application/rss+xml" title="{{ FEED_ALL_RSS }}" rel="alternate"><i class="fa fa-rss fa-lg"
|
||||
aria-hidden="true"></i></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
<div class="py-1">
|
||||
<ul>
|
||||
{% for article in articles_page.object_list %}
|
||||
<a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">
|
||||
<li class="transition ease-in active:-translate-y-1 active:scale-110 duration-75">
|
||||
<div class="bg-white dark:bg-zinc-800 p-4 md:p-6 mb-4 rounded-lg">
|
||||
<header class="font-semibold text-2xl mb-2">
|
||||
<h1>{{ article.title }}</h1>
|
||||
</header>
|
||||
<div class="max-w-7xl container mx-auto my-4 justify-center overflow-hidden mb-2 text-sm text-zinc-800 dark:text-zinc-400
|
||||
prose lg:max-w-none prose-headings:text-zinc-800 prose-headings:dark:text-zinc-300
|
||||
prose-h1:text-3xl prose-headings:font-semibold
|
||||
prose-pre:bg-zinc-200 prose-pre:text-zinc-800
|
||||
dark:prose-pre:bg-zinc-800 dark:prose-pre:text-zinc-200
|
||||
prose-blockquote:text-zinc-800
|
||||
dark:prose-blockquote:text-zinc-200
|
||||
prose-a:text-gray-500
|
||||
dark:prose-a:text-gray-400
|
||||
dark:prose-strong:text-zinc-200
|
||||
dark:prose-code:text-zinc-200
|
||||
dark:prose-code:bg-zinc-800
|
||||
prose-code:bg-zinc-200
|
||||
prose-code:font-light
|
||||
prose-img:rounded-md
|
||||
">
|
||||
{{ article.summary }}
|
||||
</div>
|
||||
<div class="flex text-xs text-zinc-800 dark:text-zinc-400">
|
||||
<time>{{ article.date|strftime('%B %d, %Y') }}</time>
|
||||
<div>
|
||||
{% if article.readtime %}
|
||||
<span> · {{ article.readtime }} min read</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if article.author != '' %}
|
||||
<span> · {{ article.author }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% if articles_page.has_other_pages() %}
|
||||
{% include 'pagination.html' %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock content %}
|
|
@ -0,0 +1,47 @@
|
|||
{% extends "base.html" %}
|
||||
{% block html_lang %}{{ page.lang }}{% endblock %}
|
||||
|
||||
{% block title %}{{ SITENAME }} | {{ page.title }}{%endblock%}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<main class="text-zinc-800 dark:text-zinc-300">
|
||||
<div class="max-w-7xl container mx-auto my-2 text-zinc-800 dark:text-zinc-300
|
||||
prose lg:max-w-none prose-headings:text-zinc-800 prose-headings:dark:text-zinc-300
|
||||
prose-h1:text-3xl lg:prose-h1:text-3xl prose-headings:font-semibold
|
||||
prose-pre:bg-zinc-200 prose-pre:text-zinc-800
|
||||
dark:prose-pre:bg-zinc-800 dark:prose-pre:text-zinc-200
|
||||
prose-blockquote:text-zinc-800
|
||||
dark:prose-blockquote:text-zinc-200
|
||||
prose-a:text-gray-500
|
||||
dark:prose-a:text-gray-400
|
||||
dark:prose-strong:text-zinc-200
|
||||
dark:prose-code:text-zinc-200
|
||||
dark:prose-code:bg-zinc-800
|
||||
prose-code:bg-zinc-200
|
||||
prose-code:font-light
|
||||
prose-img:rounded-md
|
||||
">
|
||||
{% import 'translations.html' as translations with context %}
|
||||
{{ translations.translations_for(page) }}
|
||||
{{ page.content }}
|
||||
<!-- <div class="aspect-w-16 aspect-h-9 mx-auto"></div> CSS placeholder -->
|
||||
</div>
|
||||
<footer class="flex bg-zinc-200 dark:bg-zinc-700 mt-10 py-2 rounded-lg justify-center space-x-2 text-xs">
|
||||
{% for name, link in SHARE %}
|
||||
<ul>
|
||||
<a target="_blank" rel="noopener noreferrer" title="{{ name }}" aria-label="share Features on {{ name }}"
|
||||
href="{{ link }}{{ SITEURL }}/{{ page.url }}">
|
||||
<li class="bg-gray-900 p-1 text-white rounded-md">
|
||||
<i class="fab fa-{{ name }} fa-2x" aria-hidden="true"></i>
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</footer>
|
||||
<div>
|
||||
{% include 'disqus_script.html' %}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,20 @@
|
|||
{% if DEFAULT_PAGINATION %}
|
||||
{% set first_page = articles_paginator.page(1) %}
|
||||
{% set last_page = articles_paginator.page(articles_paginator.num_pages) %}
|
||||
<div class="relative h-12 mt-3">
|
||||
{% if articles_page.has_previous() %}
|
||||
<a href="{{ SITEURL }}/{{ articles_previous_page.url }}">
|
||||
<button
|
||||
class="bg-zinc-800 dark:bg-zinc-300 rounded-full py-2.5 px-4 text-zinc-100 dark:text-zinc-800 font-medium text-xs absolute left-0">
|
||||
« Prev Page
|
||||
</button></a>
|
||||
{% endif %}
|
||||
{% if articles_page.has_next() %}
|
||||
<a href="{{ SITEURL }}/{{ articles_next_page.url }}">
|
||||
<button
|
||||
class="bg-zinc-800 dark:bg-zinc-300 rounded-full py-2.5 px-4 text-zinc-100 dark:text-zinc-800 font-medium text-xs absolute right-0">
|
||||
Next Page »
|
||||
</button></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
|
@ -0,0 +1,14 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} | {{ period | reverse | join(' ') }} archives{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Archives for {{ period | reverse | join(' ') }}</h1>
|
||||
|
||||
<dl>
|
||||
{% for article in dates %}
|
||||
<dt>{{ article.locale_date }}</dt>
|
||||
<dd><a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a></dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
{% endblock %}
|
|
@ -0,0 +1,24 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Search | {{ SITENAME }}{% endblock %}
|
||||
{% set current = "search" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="relative mb-12 md:mt-14 text-zinc-800 dark:text-zinc-300">
|
||||
<h1 class="flex font-bold my-10 text-4xl mb-12 md:my-12 text-zinc-800 dark:text-zinc-300">Search
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentcolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
</svg>
|
||||
</h1>
|
||||
<div class="stork-wrapper">
|
||||
<input
|
||||
class="font-semibold h-10 w-full border-2 border-zinc-500 bg-zinc-100 dark:bg-zinc-800 placeholder-zinc-400 dark:placeholder-zinc-300 focus:border-zinc-500 focus:outline-none rounded-lg pl-4"
|
||||
data-stork="sitesearch" autofocus="" placeholder=" Search ↵" aria-label="search" type="search">
|
||||
<div data-stork="sitesearch-output" class=""></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "index.html" %}
|
||||
|
||||
{% block title %} {{ tag }} | {{ SITENAME }}{% endblock %}
|
||||
|
||||
{% block content_title %}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,22 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} | Tags{% endblock %}
|
||||
{% set current = "tags" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="mb-12 md:mt-14 text-gray-800 dark:text-gray-300">
|
||||
<h1 class="font-bold text-4xl my-10">Tags</h1>
|
||||
<ul class="flex flex-wrap font-medium">
|
||||
{% for tag, articles in tags|sort %}
|
||||
<a href="{{ SITEURL }}/{{ tag.url }}">
|
||||
<li
|
||||
class="bg-zinc-300 dark:bg-neutral-700 text-zinc-800 dark:text-zinc-300 hover:bg-zinc-400 dark:hover:bg-zinc-800 m-2 py-2 px-2 md:px-4 rounded-md transition ease-in active:-translate-y-1 active:scale-110 duration-75">
|
||||
{{ tag }}<sup class="p-1">{{ articles|count }}</sup>
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,16 @@
|
|||
{% macro translations_for(article) %}
|
||||
{% if article.translations %}
|
||||
Translations:
|
||||
{% for translation in article.translations %}
|
||||
<a href="{{ SITEURL }}/{{ translation.url }}" hreflang="{{ translation.lang }}">{{ translation.lang }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro entry_hreflang(entry) %}
|
||||
{% if entry.translations %}
|
||||
{% for translation in entry.translations %}
|
||||
<link rel="alternate" hreflang="{{ translation.lang }}" href="{{ SITEURL }}/{{ translation.url }}">
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
Loading…
Reference in New Issue