Base structure for pelican in the repo.
parent
d527d409a6
commit
4e5f6a2fd8
@ -0,0 +1,4 @@
|
||||
.vscode
|
||||
__paycache__
|
||||
output
|
||||
*.pyc
|
@ -0,0 +1,85 @@
|
||||
PY?=python3
|
||||
PELICAN?=pelican
|
||||
PELICANOPTS=
|
||||
|
||||
BASEDIR=$(CURDIR)
|
||||
INPUTDIR=$(BASEDIR)/content
|
||||
OUTPUTDIR=$(BASEDIR)/output
|
||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||
|
||||
SSH_HOST=localhost
|
||||
SSH_PORT=22
|
||||
SSH_USER=root
|
||||
SSH_TARGET_DIR=/var/www
|
||||
|
||||
|
||||
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 ' make ssh_upload upload the web site via SSH '
|
||||
@echo ' make rsync_upload upload the web site via rsync+ssh '
|
||||
@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)
|
||||
|
||||
ssh_upload: publish
|
||||
scp -P $(SSH_PORT) -r "$(OUTPUTDIR)"/* "$(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)"
|
||||
|
||||
rsync_upload: publish
|
||||
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --include tags --cvs-exclude --delete "$(OUTPUTDIR)"/ "$(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)"
|
||||
|
||||
|
||||
.PHONY: html help clean regenerate serve serve-global devserver publish ssh_upload rsync_upload
|
@ -0,0 +1,12 @@
|
||||
title: About an Algoliterary Publishing House
|
||||
slug: about
|
||||
|
||||
Anaïs Berck is an alias that exists since September 2019. The name stands for a collaboration between humans, algorithms and trees.
|
||||
|
||||
As a collective Anais Berck opens up a space in which human intelligence is explored in the company of plant intelligence and artificial intelligence.
|
||||
|
||||
For this project, Anaïs Berck is represented by the human beings An Mertens, Guillaume Slizewicz, Gijs de Heij and Loren Britton, all members or friends of [Constant](https://constantvzw.org), the association for arts and media in Brussels; and of [Algolit](https://algolit.net), the artistic research group around text and free code.
|
||||
|
||||
This research is initiated in June 2021, with An Mertens, Gijs de Heij and Loren Britton, during a three-week residency at Medialab Prado in Madrid (granted by the Vlaamse Overheid as part of their 'Digital Culture Residencies' program). It will be continued during one year with the support of a grant by [FRArt/Art & Recherche](http://www.art-recherche.be), in partnership with [ESA St-Luc Brussels](http://www.stluc-bruxelles-esa.be/), [ESA La Cambre Brussels](http://www.stluc-bruxelles-esa.be/), [Botanic Garden Meise](https://www.plantentuinmeise.be/en/home/), [Villa Empain](https://www.villaempain.com/), the [Royal Library of Belgium](https://www.kbr.be/en/) and the [Bibliothèque Nationale de France](https://www.bnf.fr/fr).
|
||||
|
||||
Feel free to subscribe for more news: <https://grabuge.domainepublic.net/cgi-bin/mailman/listinfo/announcements>
|
@ -0,0 +1,4 @@
|
||||
title: activities
|
||||
hidden: True
|
||||
|
||||
---
|
@ -0,0 +1,4 @@
|
||||
title: Algoliterary Works
|
||||
hidden: True
|
||||
|
||||
---
|
@ -0,0 +1,4 @@
|
||||
title: Oracle
|
||||
hidden: True
|
||||
|
||||
---
|
@ -0,0 +1,3 @@
|
||||
title: reader
|
||||
|
||||
---
|
@ -0,0 +1,3 @@
|
||||
title: Research questions
|
||||
|
||||
---
|
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*- #
|
||||
|
||||
AUTHOR = 'Anaïs Berck'
|
||||
SITENAME = 'An Algoliterary Publishing House'
|
||||
SITEURL = ''
|
||||
|
||||
PATH = 'content'
|
||||
|
||||
TIMEZONE = 'Europe/Brussels'
|
||||
|
||||
DEFAULT_LANG = 'en'
|
||||
|
||||
# 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
|
||||
|
||||
# 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 = False
|
||||
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
#RELATIVE_URLS = True
|
||||
|
||||
THEME = 'theme'
|
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*- #
|
||||
|
||||
# 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 @@
|
||||
pelican
|
@ -0,0 +1,143 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
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'],
|
||||
# Remote server configuration
|
||||
'ssh_user': 'root',
|
||||
'ssh_host': 'localhost',
|
||||
'ssh_port': '22',
|
||||
'ssh_path': '/var/www',
|
||||
# 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'],
|
||||
'{}/templates/**/*.html'.format(theme_path),
|
||||
]
|
||||
|
||||
content_file_extensions = ['.md', '.rst']
|
||||
for extension in content_file_extensions:
|
||||
content_glob = '{0}/**/*{1}'.format(SETTINGS['PATH'], extension)
|
||||
watched_globs.append(content_glob)
|
||||
|
||||
static_file_extensions = ['.css', '.js']
|
||||
for extension in static_file_extensions:
|
||||
static_file_glob = '{0}/static/**/*{1}'.format(theme_path, 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))
|
@ -0,0 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - Archives{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Archives for {{ SITENAME }}</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,67 @@
|
||||
{% extends "base.html" %}
|
||||
{% block html_lang %}{{ article.lang }}{% endblock %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - {{ article.title|striptags }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
|
||||
{% import 'translations.html' as translations with context %}
|
||||
{% if translations.entry_hreflang(article) %}
|
||||
{{ translations.entry_hreflang(article) }}
|
||||
{% endif %}
|
||||
|
||||
{% if article.description %}
|
||||
<meta name="description" content="{{article.description}}" />
|
||||
{% endif %}
|
||||
|
||||
{% for tag in article.tags %}
|
||||
<meta name="tags" content="{{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">
|
||||
<time class="published" datetime="{{ article.date.isoformat() }}">
|
||||
{{ article.locale_date }}
|
||||
</time>
|
||||
{% if article.modified %}
|
||||
<time class="modified" datetime="{{ article.modified.isoformat() }}">
|
||||
{{ article.locale_modified }}
|
||||
</time>
|
||||
{% 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 %}
|
||||
{% if article.category %}
|
||||
<div class="category">
|
||||
Category: <a href="{{ SITEURL }}/{{ article.category.url }}">{{ article.category }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if article.tags %}
|
||||
<div class="tags">
|
||||
Tags:
|
||||
{% for tag in article.tags %}
|
||||
<a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
{{ article.content }}
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
{% endblock %}
|
@ -0,0 +1,8 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - Articles by {{ author }}{% endblock %}
|
||||
|
||||
{% block content_title %}
|
||||
<h2>Articles by {{ author }}</h2>
|
||||
{% 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,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{% block html_lang %}{{ DEFAULT_LANG }}{% endblock html_lang %}">
|
||||
<head>
|
||||
{% block head %}
|
||||
<title>{% block title %}{{ SITENAME }}{% endblock title %}</title>
|
||||
<meta charset="utf-8" />
|
||||
{% 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 }} Full 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 }} Full RSS Feed" />
|
||||
{% endif %}
|
||||
{% if FEED_ATOM %}
|
||||
<link href="{{ FEED_DOMAIN }}/{%if FEED_ATOM_URL %}{{ FEED_ATOM_URL }}{% else %}{{ FEED_ATOM }}{% endif %}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
|
||||
{% endif %}
|
||||
{% if FEED_RSS %}
|
||||
<link href="{{ FEED_DOMAIN }}/{% if FEED_RSS_URL %}{{ FEED_RSS_URL }}{% else %}{{ FEED_RSS }}{% endif %}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
|
||||
{% endif %}
|
||||
{% if CATEGORY_FEED_ATOM and category %}
|
||||
<link href="{{ FEED_DOMAIN }}/{% if CATEGORY_FEED_ATOM_URL %}{{ CATEGORY_FEED_ATOM_URL.format(slug=category.slug) }}{% else %}{{ CATEGORY_FEED_ATOM.format(slug=category.slug) }}{% endif %}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Categories Atom Feed" />
|
||||
{% endif %}
|
||||
{% if CATEGORY_FEED_RSS and category %}
|
||||
<link href="{{ FEED_DOMAIN }}/{% if CATEGORY_FEED_RSS_URL %}{{ CATEGORY_FEED_RSS_URL.format(slug=category.slug) }}{% else %}{{ CATEGORY_FEED_RSS.format(slug=category.slug) }}{% endif %}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Categories RSS Feed" />
|
||||
{% endif %}
|
||||
{% if TAG_FEED_ATOM and tag %}
|
||||
<link href="{{ FEED_DOMAIN }}/{% if TAG_FEED_ATOM_URL %}{{ TAG_FEED_ATOM_URL.format(slug=tag.slug) }}{% else %}{{ TAG_FEED_ATOM.format(slug=tag.slug) }}{% endif %}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Tags Atom Feed" />
|
||||
{% endif %}
|
||||
{% if TAG_FEED_RSS and tag %}
|
||||
<link href="{{ FEED_DOMAIN }}/{% if TAG_FEED_RSS_URL %}{{ TAG_FEED_RSS_URL.format(slug=tag.slug) }}{% else %}{{ TAG_FEED_RSS.format(slug=tag.slug) }}{% endif %}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Tags RSS Feed" />
|
||||
{% endif %}
|
||||
{% endblock head %}
|
||||
<link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/styles/styles.css" />
|
||||
</head>
|
||||
|
||||
<body class="{% block bodyclass %}{% endblock %}">
|
||||
<main>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</main>
|
||||
<aside>
|
||||
{% block sidebar %}
|
||||
{% endblock %}
|
||||
</aside>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - Categories{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Categories on {{ SITENAME }}</h1>
|
||||
<ul>
|
||||
{% for category, articles in categories|sort %}
|
||||
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a> ({{ articles|count }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
@ -0,0 +1,8 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - {{ category }} category{% endblock %}
|
||||
|
||||
{% block content_title %}
|
||||
<h2>Articles in the {{ category }} category</h2>
|
||||
{% endblock %}
|
||||
|
@ -0,0 +1,14 @@
|
||||
{% if GOSQUARED_SITENAME %}
|
||||
<script type="text/javascript">
|
||||
var GoSquared={};
|
||||
GoSquared.acct = "{{ GOSQUARED_SITENAME }}";
|
||||
(function(w){
|
||||
function gs(){
|
||||
w._gstc_lt=+(new Date); var d=document;
|
||||
var g = d.createElement("script"); g.type = "text/javascript"; g.async = true; g.src = "https://d1l6p2sc9645hc.cloudfront.net/tracker.js";
|
||||
var s = d.getElementsByTagName("script")[0]; s.parentNode.insertBefore(g, s);
|
||||
}
|
||||
w.addEventListener?w.addEventListener("load",gs,false):w.attachEvent("onload",gs);
|
||||
})(window);
|
||||
</script>
|
||||
{% endif %}
|
@ -0,0 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
{% block html_lang %}{{ page.lang }}{% endblock %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - {{ page.title|striptags }}{%endblock%}
|
||||
|
||||
{% block bodyclass %}{{ page.slug }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ page.title }}</h1>
|
||||
|
||||
{{ page.content }}
|
||||
|
||||
<p><a href="{{ SITEURL }}/"><strong>← Back</strong></a></p>
|
||||
{% endblock %}
|
@ -0,0 +1,15 @@
|
||||
{% if DEFAULT_PAGINATION %}
|
||||
{% set first_page = articles_paginator.page(1) %}
|
||||
{% set last_page = articles_paginator.page(articles_paginator.num_pages) %}
|
||||
<p class="paginator">
|
||||
{% if articles_page.has_previous() %}
|
||||
<a href="{{ SITEURL }}/{{ first_page.url }}">⇇</a>
|
||||
<a href="{{ SITEURL }}/{{ articles_previous_page.url }}">«</a>
|
||||
{% endif %}
|
||||
Page {{ articles_page.number }} / {{ articles_paginator.num_pages }}
|
||||
{% if articles_page.has_next() %}
|
||||
<a href="{{ SITEURL }}/{{ articles_next_page.url }}">»</a>
|
||||
<a href="{{ SITEURL }}/{{ last_page.url }}">⇉</a>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% 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,7 @@
|
||||
{% extends "index.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - {{ tag }} tag{% endblock %}
|
||||
|
||||
{% block content_title %}
|
||||
<h2>Articles tagged with {{ tag }}</h2>
|
||||
{% endblock %}
|
@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ SITENAME }} - Tags{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Tags for {{ SITENAME }}</h1>
|
||||
<ul>
|
||||
{% for tag, articles in tags|sort %}
|
||||
<li><a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a> ({{ articles|count }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% 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 %}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,93 @@
|
||||
Copyright (c) 2012-2013, The Mozilla Corporation and Telefonica S.A.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
@ -0,0 +1,48 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
@ -0,0 +1,243 @@
|
||||
@font-face {
|
||||
font-family: "Fira mono";
|
||||
src: url("../fonts/fira-mono/FiraMono-Regular.ttf") format("truetype");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Fira mono";
|
||||
src: url("../fonts/fira-mono/FiraMono-Medium.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Fira mono";
|
||||
src: url("../fonts/fira-mono/FiraMono-Bold.ttf") format("truetype");
|
||||
font-weight: 600;
|
||||
font-style: bold;
|
||||
}
|
||||
|
||||
:root {
|
||||
--line-height: 16pt;
|
||||
--font-size: 11pt;
|
||||
}
|
||||
|
||||
html, body {
|
||||
font-family: "Fira mono";
|
||||
font-size: var(--font-size);
|
||||
line-height: var(--line-height);
|
||||
}
|
||||
|
||||
body {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
display: block;
|
||||
letter-spacing: 0.25em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: var(--line-height);
|
||||
}
|
||||
|
||||
h2 {
|
||||
letter-spacing: .05em;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p {
|
||||
max-width: 80ch;
|
||||
margin-bottom: var(--line-height);
|
||||
}
|
||||
|
||||
main {
|
||||
grid-column: 1;
|
||||
padding: var(--line-height) calc(3 * var(--line-height)) var(--line-height) var(--line-height);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
main {
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
aside {
|
||||
grid-column: 2;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
summary {
|
||||
padding: calc(.5 * var(--line-height)) 0;
|
||||
list-style: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.read-online-link {
|
||||
letter-spacing: .1em;
|
||||
}
|
||||
|
||||
dd.read-online-link {
|
||||
margin-top: calc(var(--line-height) * .425);
|
||||
}
|
||||
|
||||
dd.read-online-link a {
|
||||
text-decoration-style: solid;
|
||||
}
|
||||
|
||||
details > summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
details {
|
||||
border-bottom: 1px solid black;
|
||||
padding: calc(.5 * var(--line-height)) calc(2.5 * var(--line-height)) calc(.5 * var(--line-height)) var(--line-height);
|
||||
}
|
||||
|
||||
details[open] {
|
||||
padding-bottom: calc(2.5 * var(--line-height));
|
||||
}
|
||||
|
||||
details[open] > summary {
|
||||
margin-bottom: calc(var(--line-height) * .5);
|
||||
}
|
||||
|
||||
details + details {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: var(--line-height) 0 0 0;
|
||||
display: grid;
|
||||
grid-template-columns: 15ch 1fr;
|
||||
max-width: 80ch;
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
dl a {
|
||||
text-decoration-style: dotted;
|
||||
}
|
||||
|
||||
summary dl {
|
||||
margin-top: calc(var(--line-height) * .425);
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 601px) {
|
||||
|
||||
summary::after {
|
||||
content: "Show details ↓";
|
||||
font-size: 85%;
|
||||
margin-top: calc(var(--line-height) * .425);
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
margin-left: 15ch;
|
||||
}
|
||||
|
||||
[open] > summary::after {
|
||||
content: "Hide details ↑";
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
body {
|
||||
display: block;
|
||||
padding: var(--line-height) calc(2 * var(--line-height)) var(--line-height) var(--line-height);
|
||||
height: initial;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
main, aside {
|
||||
padding: 0;
|
||||
height: initial;
|
||||
overflow-y: initial;
|
||||
}
|
||||
|
||||
main {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
dt {
|
||||
margin-top: calc(var(--line-height) * .425);
|
||||
}
|
||||
|
||||
dt::after {
|
||||
content: ':';
|
||||
}
|
||||
|
||||
dt:empty::after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
details, details[open] {
|
||||
padding-left: calc(1 * var(--line-height));
|
||||
padding-right: calc(2 * var(--line-height));
|
||||
padding-bottom: var(--line-height);
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid black;
|
||||
margin-left: calc(-1 * var(--line-height));
|
||||
margin-right: calc(-2 * var(--line-height));
|
||||
}
|
||||
|
||||
details {
|
||||
max-height: 50vh;
|
||||
position: relative;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
details[open] {
|
||||
max-height: initial;
|
||||
}
|
||||
|
||||
details:not([open]) summary::after {
|
||||
display: block;
|
||||
content: 'show details ↓';
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: calc(3.5 * var(--line-height));
|
||||
z-index: 1;
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,255,255,1) calc(2 * var(--line-height)));
|
||||
box-sizing: border-box;
|
||||
font-size: 85%;
|
||||
padding: calc(2 * var(--line-height)) 0 0 var(--line-height);
|
||||
/* pointer-events: none; */
|
||||
}
|
||||
|
||||
details[open]::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
[open] > summary::after {
|
||||
content: "Hide details ↑";
|
||||
font-size: 85%;
|
||||
margin-top: calc(var(--line-height) * .85);
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue