Initial commit

This commit is contained in:
randogoth 2023-07-01 11:01:17 +03:00
commit 50f1eba33a
204 changed files with 4749 additions and 0 deletions

14
web/mc-pelican/LICENSE Normal file
View file

@ -0,0 +1,14 @@
Copyright (c) 2015 Michael Cardell Widerkrantz <mc@hack.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

16
web/mc-pelican/Makefile Normal file
View file

@ -0,0 +1,16 @@
VERSION=20150208
DIST=mc-pelican-$(VERSION)
DISTFILES=README.txt LICENSE Makefile static templates
$(DIST).tar.bz2:
mkdir $(DIST)
cp -r $(DISTFILES) $(DIST)/
tar cf $(DIST).tar --exclude .git $(DIST)
bzip2 -9 $(DIST).tar
$(RM) -rf $(DIST)
dist: $(DIST).tar.bz2
clean:
$(RM) -f $(DIST).tar.bz2

28
web/mc-pelican/README.txt Normal file
View file

@ -0,0 +1,28 @@
A minimalist theme for the Pelican static blog generator:
http://blog.getpelican.com/
It's based on the built-in simple theme with some small changes to the
templates and some very minimalist CSS.
Install like this:
# pelican-themes -i mc-pelican
Then, in your pelicanconf.py:
THEME = 'mc-pelican'
You add menu items with MENUITEMS like this:
MENUITEMS = (
('Homepage', '/mc/'),
('About MC', '/mc/bio.html'),
('Contact', '/mc/contact.html'),
('Archives', '{0}/archives.html'.format(SITEURL)), )
If you want a blog description in the footer of all pages, define
DESCRIPTION.
Happy blogging,
MC.

Binary file not shown.

View file

@ -0,0 +1,284 @@
@font-face {
font-family: 'Classic Console Neue';
src: local('Classic Console Neue'), local('ClassicConsoleNeue'),
url('clacon2.woff2') format('woff2')
}
/* CSS Reset */
html {
margin: 0;
padding: 0;
text-align: left;
text-rendering: optimizeLegibility;
}
/* HTML5 tag defaults. */
header, footer, aside, nav, article
{
display: block;
}
h1, h2, h3, h4, h5 {
font-weight: normal;
text-align: left;
font-size: 1em;
text-transform: uppercase;
}
body {
font-family: 'Classic Console Neue';
padding: 1em;
font-size: 1.4em;
line-height: 1.2em;
text-align: left;
background: #090A0E;
color: #bbb;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 2px;
margin: auto;
max-width: 40em;
}
ul, ul li {
margin:0;
padding:0;
list-style:none
}
ul li::before {
content: '*\00a0';
}
/* Use a thin border around all images. */
img
{
border: 1px solid;
max-width: 40em;
width: 100%;
}
/* Navigation bar. */
nav
{
padding-bottom: 1ex;
margin-bottom: 4em;
}
nav::after {
clear:left;
}
nav ul
{
padding: 0;
margin-left: 0;
list-style: none;
}
nav ul li
{
display: inline;
float: left;
margin-right: .4em; /* How far between items. */
margin-top: .3em;
}
nav li::before {
content: none;
}
nav ul li a
{
display: inline;
margin: 0;
}
/*
* Use a border around tables, but don't draw lines around individual
* cells.
*/
table
{
border-style: solid;
border-collapse: collapse;
border-width: thin;
font-size: 100%;
}
th, td
{
border-style: solid;
border-width: thin;
}
a {
background-color: #bbb;
color:#090A0E;
padding: 0.2em 0.3em 0em 0.3em;
}
a.translation {
background-color: #333;
}
/* for unvisited links: blue */
a:link
{
text-decoration: none;
}
/* for visited links: purple */
a:visited
{
text-decoration: none;
}
/* when mouse is over link or the link is active*/
a:hover, a:active
{
text-decoration: none;
}
/* Very clean ruler with no shadows. */
hr
{
border: none;
}
@media screen and (min-width: 941px) {
hr::after {
content: '--------------------------------------------------------------------------------';
}
}
@media screen and (max-width: 940px) {
hr {
border-top: 2px dashed #bbb;
}
}
.hentry::after {
content: '\00a0'
}
abbr {
float: left;
display: inline;
text-decoration: none;
padding: 0;
}
.hentry .published::before {
content: '*';
}
.hentry .published::after {
content: '>\00a0';
}
.hentry .entry-summary p {
margin: 0;
margin-left: 7.5em;
}
.hentry h2 {
margin: 0;
}
header h2 a {
background: none;
color: #bbb;
text-transform: uppercase;
padding: 0;
}
.post-info abbr {
float: none;
}
.author {
font-style: normal;
padding: 0;
}
.post-info {
color: #555;
}
.author a {
padding: 0;
background: none;
color: #555;
}
@keyframes cursor-blink {
0% {
opacity: 0;
}
}
#root {
display: block;
margin-top: 2em;
}
[contenteditable="true"]:active,
[contenteditable="true"]:focus{
border:none;
outline:none;
caret-color: transparent;
}
[contenteditable="true"]:active:after,
[contenteditable="true"]:focus:after {
content: "\02588";
animation: cursor-blink 1.5s steps(2) infinite;
}
.para {
border: 1px solid;
max-width: 40em;
display: block;
background-attachment: fixed;
background-position: center;
background-size: contain;
}
iframe {
border: 1px solid;
aspect-ratio: 16 / 9;
width: 100%;
}
blockquote {
border: 1px solid;
margin: 0;
padding-left: 1em;
background: #222;
}
em, strong {
font-style: normal;
color: white;
}
.overlay {
height: 100%;
width: 100%;
position: fixed;
z-index: 1;
left: 0;
overflow-x: hidden;
pointer-events: none;
}
.vignette {
background-image: radial-gradient(ellipse at center, rgba(0,0,0,0) 50%, rgba(0,0,0,0.25) 100%);
}
.scanline {
background-image: linear-gradient(0deg, rgba(0,0,0,0) 25%, rgba(0,0,0,0.33) 25%, rgba(0,0,0,0.33) 50%, rgba(0,0,0,0) 50%, rgba(0,0,0,0) 75%, rgba(0,0,0,0.33) 75%, rgba(0,0,0,0.33) 100%);
background-size: 4px 4px;
}

View file

@ -0,0 +1,62 @@
/* Syntax highlighting. */
.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 */

View file

@ -0,0 +1,137 @@
const randomColor = Math.floor(Math.random()*16777215).toString(16);
document.querySelector('#blog-title').firstElementChild.style.backgroundColor = '#' + randomColor;
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
let paras = document.getElementsByClassName("para");
for (let i = 0; i < paras.length; i++) {
var imageSrc = paras[i].style.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2').split(',')[0];
var image = new Image();
image.src = imageSrc;
paras[i].setAttribute("offset", paras[i].getBoundingClientRect().bottom - image.height * 0.5);
}
window.addEventListener('scroll', () => {
let { scrollY } = window;
if ( screen.width > screen.height ) {
for (let i = 0; i < paras.length; i++) {
paras[i].style.backgroundPositionY = paras[i].getAttribute("offset") * 0.1 + -0.1 * scrollY + 'px';
}
}
});
//components
//console component
class Console{
comps=[];
input_received=false;
blocking_interval=null;
text_color="#bbb";
constructor(root){
this.elem=document.createElement("span");
this.elem.className="console";
root.appendChild(this.elem);
this.resetTextColor();
}
appendComponent(comp){
this.comps.push(comp);
this.elem.appendChild(comp.elem);
}
writeLine(txt){
let text=new Text(txt,this.text_color);
this.appendComponent(text);
}
async readLine(txt){
let text=new Text(txt,this.text_color);
this.appendComponent(text);
let input=new Input(this.text_color);
this.appendComponent(input);
input.elem.focus({ preventScroll: true});
return new Promise(resolve=>{
this.blocking_interval=setInterval(()=>{
if(this.input_received){
this.input_received=false;
clearInterval(this.blocking_interval);
resolve(input.elem.innerText);
}
},500);
})
}
setTextColor(color){
this.text_color=color;
}
resetTextColor(){
this.text_color="#bbb";
}
//helpers
get lastComp(){return this.comps[this.comps.length-1]};
}
//text component
class Text{
constructor(txt,color){
this.elem=document.createElement("span");
this.elem.className="text";
this.elem.style.color=color;
this.elem.innerText=txt;
}
}
//input component
class Input{
constructor(color){
this.elem=document.createElement("span");
this.elem.style.color=color;
this.elem.contentEditable=true;
this.elem.addEventListener('keydown',function(e){
let key=e.key;
if(key=="Enter"){
e.preventDefault();
cmd.input_received=true;
cmd.lastComp.elem.contentEditable=false;
cmd.lastComp.elem.style.borderWidth="0px";
}
});
}
}
/************************************/
let root=document.getElementById("root");
let cmd=new Console(root);
let prompt = "C:\\>"
async function execute(){
let command= await cmd.readLine(prompt);
if ( command == "projects" ) window.location = "/current.html";
else if ( command == "blog" ) window.location = "/blog";
else if ( command == "archive" ) window.location = "/archive";
else if ( command == "dir" ) window.location = "/archive";
else if ( command == "home" ) window.location = "/";
else if ( command == "connect" ) window.location = "/connect.html";
else if ( command == "reboot" ) location.reload();
else if ( command == "a:" ) {
prompt = "A:\\>";
cmd.writeLine("\n");
cmd=new Console(root);
execute();
}
else if ( command == "b:" ) {
prompt = "B:\\>";
cmd.writeLine("\n");
cmd=new Console(root);
execute();
}
else if ( command == "c:" ) {
prompt = "C:\\>";
cmd.writeLine("\n");
cmd=new Console(root);
execute();
}
else {
cmd.writeLine("\nSyntax error\n");
cmd=new Console(root);
execute();
}
}
execute();

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="english">
<head>
<title>404</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/theme/local.css" rel="stylesheet">
<style>
body {
color: white;
background-color: blue;
display: table;
height: 100vh;
max-width: 100%;
overflow: hidden;
margin: 0;
}
a {
color: blue
}
div {
display: table-cell;
height: 100%;
vertical-align: middle;
}
</style>
</head>
<body id="index">
<div id="404">
<center><a>Windows</a></center>
<p>An exception 404 has occurred. The page could not be found. It may be possible to continue normally.</p>
<ul>
<li>Press the backspace key to attempt to continue.</li>
<li>Press CTRL+ALT+DEL to restart your computer. You will<br />
lose any unsaved information in all applications.</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block content %}
<section id="content">
{% block content_title %}
{% endblock %}
{% for article in dates if article.category != 'blog' %}
<article class="hentry">
<abbr class="published" title="{{ article.date.isoformat() }}"> {{ article.locale_date }} </abbr>
<header>
<h2 class="entry-title">
<a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a>
</h2>
<span class="entry-summary">{{ article.summary }}</span>
</header>
</article>
{% endfor %}
{% include 'pagination.html' %}
</section><!-- /#content -->
{% endblock content %}

View file

@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="{{ DEFAULT_LANG }}">
<head>
<base target="_top">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ SITENAME }}</title>
<link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />
<link rel="stylesheet" href="{{ SITEURL }}/theme/local.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin=""/>
<style>
html, body { height: 100%; margin: 0; padding: 0; }
#map {
height: 100%;
width: 100vw;
}
#map img {
border: none
}
.info {
padding: 6px 8px;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
font-size: 1.6em;
margin: 0 0 5px;
color: #777;
}
.info span {
line-height: 18px;
vertical-align: top;
}
</style>
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
</head>
<body>
<script>
var mapArticles = {
"type": "FeatureCollection",
"title": "{{ SITENAME }}",
"features": [
{% for article in dates %}
{% if article.metadata['lat'] and article.metadata['lon'] %}
{
"type": "Feature",
"id": "{{ article.slug }}",
"geometry": {
"type": "Point",
"coordinates": [{{ article.metadata['lon'] }}, {{ article.metadata['lat'] }}]
},
"properties": {
"title": "{{ article.title }}",
"url": "{{ SITEURL }}/{{ article.url }}"
},
},
{% endif %}
{% endfor %}
]
};
</script>
<div id='map'></div>
<script>
const showArticles = L.geoJSON(mapArticles, {
pointToLayer(feature, latlng) { return L.marker(latlng);},
onEachFeature
});
const map = L.map('map').fitBounds(showArticles.getBounds());
const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
showArticles.addTo(map);
function onEachFeature(feature, layer) {
let popupContent = ``;
if (feature.properties && feature.properties.title) {
popupContent += '<a href="'+feature.properties.url+'">' + feature.properties.title + '</a>';
}
layer.bindPopup(popupContent);
}
var info = L.control({position: 'topright'});
var download = L.control({position: 'bottomleft'});
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
this._div.innerHTML = '<h4>' + mapArticles["title"] + '</h4>';
return this._div;
};
download.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
this._div.innerHTML = 'Download <a href="{{ SITEURL }}/articles.gpx">GPX</a> <a href="{{ SITEURL }}/articles.kml">KML</a>';
return this._div;
};
info.addTo(map);
download.addTo(map);
</script>
</body>
</html>

View file

@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block head %}
{{ super() }}
{% for keyword in article.keywords %}
<meta name="keywords" contents="{{keyword}}" />
{% endfor %}
{% for description in article.description %}
<meta name="description" contents="{{description}}" />
{% endfor %}
{% for tag in article.tags %}
<meta name="tags" contents="{{tag}}" />
{% endfor %}
{% endblock %}
{% block content %}
<section id="content" class="body">
<header>
<h2 class="entry-title">
<a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark"
title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a></h2>
{% import 'translations.html' as translations with context %}
{{ translations.translations_for(article) }}
</header>
<footer class="post-info">
<abbr class="published" title="{{ article.date.isoformat() }}">
{{ article.locale_date }}
</abbr>
{% if article.modified %}
<abbr class="modified" title="{{ article.modified.isoformat() }}">
{{ article.locale_modified }}
</abbr>
{% endif %}
{% if article.authors %}
<address class="vcard author">
by {% for author in article.authors %}
<a class="url fn" href="{{ SITEURL }}/{{ author.url }}">{{ author }}</a>
{% endfor %}
</address>
{% endif %}
</footer><!-- /.post-info -->
<div class="entry-content">
{{ article.content }}
</div><!-- /.entry-content -->
</section>
{% endblock %}

View file

@ -0,0 +1,7 @@
{% extends "index.html" %}
{% block title %}{{ SITENAME }} - Articles by {{ author }}{% endblock %}
{% block content_title %}
<h2>Articles by {{ author }}</h2>
{% endblock %}

View file

@ -0,0 +1,13 @@
{% 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 %}

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html lang="{{ DEFAULT_LANG }}">
<head>
{% block head %}
<title>{% block title %}{{ SITENAME }}{% endblock title %}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% if FEED_ALL_ATOM %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Full Atom Feed" />
{% endif %}
{% if FEED_ALL_RSS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Full RSS Feed" />
{% endif %}
{% if FEED_ATOM %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ATOM }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
{% endif %}
{% if FEED_RSS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_RSS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
{% endif %}
{% if CATEGORY_FEED_ATOM and category %}
<link href="{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_ATOM|format(category.slug) }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Categories Atom Feed" />
{% endif %}
{% if CATEGORY_FEED_RSS and category %}
<link href="{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_RSS|format(category.slug) }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Categories RSS Feed" />
{% endif %}
{% if TAG_FEED_ATOM and tag %}
<link href="{{ FEED_DOMAIN }}/{{ TAG_FEED_ATOM|format(tag.slug) }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Tags Atom Feed" />
{% endif %}
{% if TAG_FEED_RSS and tag %}
<link href="{{ FEED_DOMAIN }}/{{ TAG_FEED_RSS|format(tag.slug) }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Tags RSS Feed" />
{% endif %}
<link href="{{ SITEURL }}/theme/local.css" rel="stylesheet">
<link href="{{ SITEURL }}/theme/pygments.css" rel="stylesheet">
{% endblock head %}
</head>
<body id="index" class="home">
<nav id="menu"><ul>
<li id="blog-title"><a href="{{ SITEURL }}/">{{ SITENAME }}</a></li>
{% for title, link in MENUITEMS %}
<li><a href="{{ link }}">{{ title }}</a></li>
{% endfor %}
{% if FEED_ALL_RSS %}
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}">RSS</a></li>
{% endif %}
{% if FEED_ALL_ATOM %}
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}">Atom</a></li>
{% endif %}
{% if DISPLAY_PAGES_ON_MENU %}
{% for p in PAGES %}
<li{% if p == page %} class="active"{% endif %}><a href="{{ SITEURL }}/{{ p.url }}">{{ p.title }}</a></li>
{% endfor %}
{% else %}
{% if DISPLAY_CATEGORIES_ON_MENU %}
{% for cat, null in categories %}
<li{% if cat == category %} class="active"{% endif %}><a href="{{ SITEURL }}/{{ cat.url }}">{{ cat }}</a></li>
{% endfor %}
{% endif %}
{% endif %}
</ul></nav><!-- /#menu -->
{% block content %}
{% endblock %}
{% if DESCRIPTION %}
<footer id="contentinfo" class="body">
<hr>
{{ DESCRIPTION }}
</footer><!-- /#contentinfo -->
{% endif %}
<span id="root"></span>
{% if JS_OVERRIDE %}
<!-- Script specified by the user -->
{% for js in JS_OVERRIDE %}
<script type="text/javascript" src="{{ SITEURL }}/{{ js }}"></script>
{% endfor %}
{% endif %}
</body>
</html>

View file

@ -0,0 +1,8 @@
{% extends "base.html" %}
{% block content %}
<ul>
{% for category, articles in categories %}
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -0,0 +1,5 @@
{% extends "index.html" %}
{% block content_title %}
<h2>{{ category }}</h2>
{% endblock %}

View file

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block content %}
<section id="content">
{% block content_title %}
{% endblock %}
{% for article in articles_page.object_list %}
<article class="hentry">
<abbr class="published" title="{{ article.date.isoformat() }}"> {{ article.locale_date }} </abbr>
<header>
<h2 class="entry-title">
<a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a>
</h2>
<span class="entry-summary">{{ article.summary }}</span>
</header>
</article>
{% endfor %}
{% include 'pagination.html' %}
</section><!-- /#content -->
{% endblock content %}

View file

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block title %}{{ page.title }}{%endblock%}
{% block content %}
<h1>{{ page.title }}</h1>
{% import 'translations.html' as translations with context %}
{{ translations.translations_for(page) }}
{{ page.content }}
{% if page.modified %}
<p>
Last updated: {{ page.locale_modified }}
</p>
{% endif %}
{% endblock %}

View file

@ -0,0 +1,11 @@
{% if DEFAULT_PAGINATION %}
<p class="paginator">
{% if articles_page.has_previous() %}
<a href="{{ SITEURL }}/{{ articles_previous_page.url }}">&laquo;</a>
{% endif %}
Page {{ articles_page.number }} / {{ articles_paginator.num_pages }}
{% if articles_page.has_next() %}
<a href="{{ SITEURL }}/{{ articles_next_page.url }}">&raquo;</a>
{% endif %}
</p>
{% endif %}

View file

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% 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 %}

View file

View file

@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block title %}{{ SITENAME }} - Tags{% endblock %}
{% block content %}
<h1>Tags for {{ SITENAME }}</h1>
{%- for tag, articles in tags|sort %}
<li><a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a> ({{ articles|count }})</li>
{% endfor %}
{% endblock %}

View file

@ -0,0 +1,8 @@
{% macro translations_for(article) %}
{% if article.translations %}
{% for translation in article.translations %}
<a class="translation" href="{{ SITEURL }}/{{ translation.url }}">{{ translation.lang }}</a>
{% endfor %}
{% endif %}
{% endmacro %}