once more with feeling: on-the-fly representation is schema.org json-ld for everything,
becase it's easy to write, forces me to use some sort of structure, and it might come handy. However, the end HTML is microformats v1 and v2 - v1 for google, search engines, etc, v2 for anything indieweb.
This commit is contained in:
parent
c6755e6125
commit
f47ed93fa0
11 changed files with 236 additions and 271 deletions
71
nasg.py
71
nasg.py
|
@ -15,7 +15,6 @@ import asyncio
|
|||
import sqlite3
|
||||
import json
|
||||
import queue
|
||||
from copy import deepcopy
|
||||
from shutil import copy2 as cp
|
||||
from math import ceil
|
||||
from urllib.parse import urlparse
|
||||
|
@ -33,7 +32,7 @@ from emoji import UNICODE_EMOJI
|
|||
from slugify import slugify
|
||||
import requests
|
||||
from pandoc import PandocMarkdown
|
||||
from meta import Exif, GoogleVision, GoogleClassifyText
|
||||
from meta import Exif
|
||||
import settings
|
||||
import keys
|
||||
|
||||
|
@ -85,8 +84,8 @@ def url2slug(url, limit=200):
|
|||
)[:limit]
|
||||
|
||||
def rfc3339todt(rfc3339):
|
||||
t = arrow.get(rfc3339).to('utc').format('YYYY-MM-DD HH:mm')
|
||||
return "%s UTC" % (t)
|
||||
t = arrow.get(rfc3339).format('YYYY-MM-DD HH:mm ZZZ')
|
||||
return "%s" % (t)
|
||||
|
||||
J2.filters['printdate'] = rfc3339todt
|
||||
J2.filters['url2slug'] = url2slug
|
||||
|
@ -265,7 +264,7 @@ class Comment(MarkdownDoc):
|
|||
return dt
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
def targetname(self):
|
||||
t = urlparse(self.meta.get('target'))
|
||||
return t.path.rstrip('/').strip('/').split('/')[-1]
|
||||
|
||||
|
@ -276,6 +275,8 @@ class Comment(MarkdownDoc):
|
|||
@property
|
||||
def author(self):
|
||||
r = {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
'name': urlparse(self.source).hostname,
|
||||
'url': self.source
|
||||
}
|
||||
|
@ -305,12 +306,7 @@ class Comment(MarkdownDoc):
|
|||
r = {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Comment",
|
||||
"author": {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
"url": self.author.get('url'),
|
||||
"name": self.author.get('name'),
|
||||
},
|
||||
"author": self.author,
|
||||
"url": self.source,
|
||||
"discussionUrl": self.meta.get('target'),
|
||||
"datePublished": str(self.dt),
|
||||
|
@ -425,6 +421,11 @@ class Singular(MarkdownDoc):
|
|||
if imgpath in self.files:
|
||||
if imghdr.what(imgpath):
|
||||
images.update({match: WebImage(imgpath, mdimg, self)})
|
||||
else:
|
||||
logger.error("Missing image: %s, referenced in %s",
|
||||
imgpath,
|
||||
self.fpath
|
||||
)
|
||||
return images
|
||||
|
||||
@property
|
||||
|
@ -438,9 +439,9 @@ class Singular(MarkdownDoc):
|
|||
"""
|
||||
Returns if the post should be displayed on the front
|
||||
"""
|
||||
if self.category not in settings.notinfeed:
|
||||
return True
|
||||
return False
|
||||
if self.category in settings.notinfeed:
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_photo(self):
|
||||
|
@ -463,17 +464,6 @@ class Singular(MarkdownDoc):
|
|||
return None
|
||||
return next(iter(self.images.values()))
|
||||
|
||||
@property
|
||||
def enclosure(self):
|
||||
if not self.is_photo:
|
||||
return None
|
||||
else:
|
||||
return {
|
||||
'mime': self.photo.mime_type,
|
||||
'size': self.photo.mime_size,
|
||||
'url': self.photo.href
|
||||
}
|
||||
|
||||
@property
|
||||
def summary(self):
|
||||
return self.meta.get('summary', '')
|
||||
|
@ -501,9 +491,9 @@ class Singular(MarkdownDoc):
|
|||
@property
|
||||
def syndicate(self):
|
||||
urls = self.meta.get('syndicate', [])
|
||||
urls.append("https://fed.brid.gy/")
|
||||
if self.is_photo:
|
||||
urls.append("https://brid.gy/publish/flickr")
|
||||
urls.append("https://fed.brid.gy/")
|
||||
return urls
|
||||
|
||||
def baseN(self, num, b=36,
|
||||
|
@ -568,9 +558,10 @@ class Singular(MarkdownDoc):
|
|||
|
||||
@property
|
||||
def licence(self):
|
||||
k = '_default'
|
||||
if self.category in settings.licence:
|
||||
return settings.licence[self.category]
|
||||
return settings.licence['_default']
|
||||
k = self.category
|
||||
return settings.licence[k]
|
||||
|
||||
@property
|
||||
def lang(self):
|
||||
|
@ -625,7 +616,6 @@ class Singular(MarkdownDoc):
|
|||
def event(self):
|
||||
if 'event' not in self.meta:
|
||||
return False
|
||||
|
||||
event = self.meta.get('event', {})
|
||||
r = {
|
||||
"@context": "http://schema.org",
|
||||
|
@ -658,10 +648,10 @@ class Singular(MarkdownDoc):
|
|||
"datePublished": str(self.published),
|
||||
"copyrightYear": str(self.published.format('YYYY')),
|
||||
"license": "https://spdx.org/licenses/%s.html" % (self.licence),
|
||||
"image": settings.author.get('image'),
|
||||
"image": settings.site.image,
|
||||
"author": settings.author,
|
||||
"sameAs": self.sameas,
|
||||
"publisher": settings.publisher,
|
||||
"publisher": settings.site.publisher,
|
||||
"name": self.name,
|
||||
"text": self.html_content,
|
||||
"description": self.html_summary,
|
||||
|
@ -708,11 +698,7 @@ class Singular(MarkdownDoc):
|
|||
for donation in settings.donateActions:
|
||||
r["potentialAction"].append(donation)
|
||||
|
||||
syndicate = self.meta.get('syndicate', [])
|
||||
syndicate.append("https://fed.brid.gy/")
|
||||
if self.is_photo:
|
||||
syndicate.append("https://brid.gy/publish/flickr/")
|
||||
for url in list(set(syndicate)):
|
||||
for url in list(set(self.syndicate)):
|
||||
r["potentialAction"].append({
|
||||
"@context": "http://schema.org",
|
||||
"@type": "InteractAction",
|
||||
|
@ -911,7 +897,8 @@ class WebImage(object):
|
|||
if self.is_photo:
|
||||
r.update({
|
||||
"creator": settings.author,
|
||||
"copyrightHolder": settings.author
|
||||
"copyrightHolder": settings.author,
|
||||
"license": settings.licence['_default']
|
||||
})
|
||||
if self.is_mainimg:
|
||||
r.update({"representativeOfPage": True})
|
||||
|
@ -1614,8 +1601,8 @@ class Category(dict):
|
|||
fg.id(self.feedurl)
|
||||
fg.title(self.title)
|
||||
fg.author({
|
||||
'name': settings.author.get('name'),
|
||||
'email': settings.author.get('email')
|
||||
'name': settings.author.name,
|
||||
'email': settings.author.email
|
||||
})
|
||||
fg.logo('%s/favicon.png' % settings.site.get('url'))
|
||||
fg.updated(arrow.get(self.mtime).to('utc').datetime)
|
||||
|
@ -1628,8 +1615,8 @@ class Category(dict):
|
|||
fe.id(post.url)
|
||||
fe.title(post.title)
|
||||
fe.author({
|
||||
'name': settings.author.get('name'),
|
||||
'email': settings.author.get('email')
|
||||
'name': settings.author.name,
|
||||
'email': settings.author.email
|
||||
})
|
||||
fe.category({
|
||||
'term': post.category,
|
||||
|
@ -1645,7 +1632,7 @@ class Category(dict):
|
|||
|
||||
fe.rights('%s %s %s' % (
|
||||
post.licence.upper(),
|
||||
settings.author.get('name'),
|
||||
settings.author.name,
|
||||
post.published.format('YYYY')
|
||||
))
|
||||
|
||||
|
|
116
settings.py
116
settings.py
|
@ -17,50 +17,72 @@ notinfeed = ['note']
|
|||
flat = ['article', 'journal']
|
||||
displaydate = 'YYYY-MM-DD HH:mm'
|
||||
|
||||
author = {
|
||||
class struct(dict):
|
||||
__getattr__ = dict.get
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__
|
||||
|
||||
# full author, only for h-card generation
|
||||
author = struct({
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
"image": "https://petermolnar.net/molnar_peter_avatar.jpg",
|
||||
"image": "https://petermolnar.net/favicon.jpg",
|
||||
"email": "mail@petermolnar.net",
|
||||
"url": "https://petermolnar.net/",
|
||||
"name": "Peter Molnar",
|
||||
"sameAs": [
|
||||
"https://github.com/petermolnar",
|
||||
"https://petermolnar.net/cv.html",
|
||||
],
|
||||
"follows": "https://petermolnar.net/following.opml",
|
||||
#"@id": "https://petermolnar.net/#me",
|
||||
}
|
||||
"name": "Peter Molnar"
|
||||
})
|
||||
|
||||
publisher = {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Organization",
|
||||
"logo": {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "ImageObject",
|
||||
"url": "https://petermolnar.net/molnar_peter_avatar.jpg"
|
||||
},
|
||||
"url": "https://petermolnar.net/",
|
||||
"name": "petermolnar.net",
|
||||
"email": "webmaster@petermolnar.net"
|
||||
}
|
||||
|
||||
site = {
|
||||
site = struct({
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebSite",
|
||||
"headline": "Peter Molnar",
|
||||
"url": "https://petermolnar.net",
|
||||
"name": "petermolnar.net",
|
||||
"image": "https://petermolnar.net/favicon.ico",
|
||||
"author": author,
|
||||
"publisher": publisher,
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "https://petermolnar.net/search.php?q={q}",
|
||||
"query-input": "required name=q",
|
||||
"url": "https://petermolnar.net/search.php"
|
||||
}
|
||||
}
|
||||
"author": {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
"image": "https://petermolnar.net/favicon.jpg",
|
||||
"email": "mail@petermolnar.net",
|
||||
"url": "https://petermolnar.net/",
|
||||
"name": "Peter Molnar",
|
||||
"sameAs": [
|
||||
"https://github.com/petermolnar",
|
||||
"https://petermolnar.net/cv.html",
|
||||
"xmpp:mail@petermolnar.net",
|
||||
"https://wa.me/447592011721",
|
||||
"https://t.me/petermolnar",
|
||||
],
|
||||
"follows": "https://petermolnar.net/following.opml"
|
||||
},
|
||||
"publisher": {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Organization",
|
||||
"logo": {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "ImageObject",
|
||||
"url": "https://petermolnar.net/favicon.jpg"
|
||||
},
|
||||
"url": "https://petermolnar.net/",
|
||||
"name": "petermolnar.net",
|
||||
"email": "webmaster@petermolnar.net"
|
||||
},
|
||||
"potentialAction": [
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "SearchAction",
|
||||
"target": "https://petermolnar.net/search.php?q={q}",
|
||||
"query-input": "required name=q",
|
||||
"url": "https://petermolnar.net/search.php"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "FollowAction",
|
||||
"url": "https://petermolnar.net/follow/",
|
||||
"name": "follow"
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
donateActions = [
|
||||
{
|
||||
|
@ -69,8 +91,8 @@ donateActions = [
|
|||
"description": "Monzo (only in the UK or via Google Pay)",
|
||||
"name": "monzo",
|
||||
"price": "3GBP",
|
||||
"recipient": author,
|
||||
"url": "https://monzo.me/petermolnar/3"
|
||||
"url": "https://monzo.me/petermolnar/3",
|
||||
"recipient": author
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
|
@ -78,8 +100,8 @@ donateActions = [
|
|||
"description": "Paypal",
|
||||
"name": "paypal",
|
||||
"price": "3GBP",
|
||||
"recipient": author,
|
||||
"url": "https://paypal.me/petermolnar/3GBP"
|
||||
"url": "https://paypal.me/petermolnar/3GBP",
|
||||
"recipient": author
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -103,20 +125,16 @@ menu = {
|
|||
'note': {
|
||||
'url': '%s/category/note/' % site['url'],
|
||||
'text': 'notes'
|
||||
},
|
||||
'follow': {
|
||||
'url': '%s/follow/' % site['url'],
|
||||
'text': 'follow'
|
||||
}
|
||||
}
|
||||
|
||||
licence = {
|
||||
licence = struct({
|
||||
'article': 'CC-BY-4.0',
|
||||
'journal': 'CC-BY-NC-4.0',
|
||||
'_default': 'CC-BY-NC-ND-4.0'
|
||||
}
|
||||
})
|
||||
|
||||
meta = {
|
||||
meta = struct({
|
||||
'webmention': 'https://webmention.io/petermolnar.net/webmention',
|
||||
'pingback': 'https://webmention.io/petermolnar.net/xmlrpc',
|
||||
'hub': 'https://petermolnar.superfeedr.com/',
|
||||
|
@ -124,9 +142,9 @@ meta = {
|
|||
'token_endpoint': 'https://tokens.indieauth.com/token',
|
||||
'micropub': 'https://petermolnar.net/micropub.php',
|
||||
#'microsub': 'https://aperture.p3k.io/microsub/83'
|
||||
}
|
||||
})
|
||||
|
||||
paths = {
|
||||
paths = struct({
|
||||
'content': os.path.join(base, 'content'),
|
||||
'tmpl': os.path.join(base, 'nasg', 'templates'),
|
||||
'watermark': os.path.join(base, 'nasg', 'templates', 'watermark.png'),
|
||||
|
@ -137,9 +155,9 @@ paths = {
|
|||
'micropub': os.path.join(base, 'content', 'note'),
|
||||
'tmp': os.path.join(base, 'tmp'),
|
||||
'home': os.path.join(base, 'content', 'home', 'index.md'),
|
||||
}
|
||||
})
|
||||
|
||||
photo = {
|
||||
photo = struct({
|
||||
're_author': re.compile(r'(?:P[eé]ter Moln[aá]r)|(?:Moln[aá]r P[eé]ter)|(?:petermolnar\.(?:eu|net))'),
|
||||
'default': 720,
|
||||
'sizes': {
|
||||
|
@ -148,7 +166,7 @@ photo = {
|
|||
720: '',
|
||||
1280: '_b',
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
_parser = argparse.ArgumentParser(description='Parameters for NASG')
|
||||
_booleanparams = {
|
||||
|
|
|
@ -33,10 +33,10 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main class="h-feed hfeed">
|
||||
<main class="h-feed hatom">
|
||||
<header>
|
||||
<p>
|
||||
<svg width="128" height="128"><use xlink:href="#icon-{{ category.name }}" /></svg>
|
||||
<svg width="128" height="128"><use xlink:href="#icon-{{ category.name }}" /></svg>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% block meta %}
|
||||
<meta name="author" content="{{ site.author.name }} <{{ site.author.email }}>" />
|
||||
<meta name="description" content="{{ post.description|e }}" />
|
||||
<link rel="canonical" href="{{ post.url }}" />
|
||||
<link rel="canonical" href="{{ site.url }}" />
|
||||
{% for category, latest in elements %}
|
||||
<link rel="alternate" type="application/rss+xml" title="{{ category.title }} RSS feed" href="{{ category.feed }}" />
|
||||
<link rel="alternate" type="application/atom+xml" title="{{ category.title }} ATOM feed" href="{{ category.feed }}atom.xml" />
|
||||
|
@ -14,7 +14,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main class="h-feed hfeed">
|
||||
<main class="h-feed hatom">
|
||||
<aside>
|
||||
<div>
|
||||
{{ post.text }}
|
||||
|
|
|
@ -1,26 +1,12 @@
|
|||
{% extends "base.j2.html" %}
|
||||
|
||||
{% macro includefile(fname) %}
|
||||
{% include fname %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block lang %} lang="{{ post.inLanguage }}" {% endblock %}
|
||||
|
||||
{% block title %}{{ post.headline }} - {{ site.name }}{% endblock %}
|
||||
|
||||
{% block meta %}
|
||||
<meta name="author" content="{{ post.author.name }} ({{ post.author.email }})" />
|
||||
<meta name="description" content="{{ post.description|striptags|e }}" />
|
||||
<link rel="canonical" href="{{ post.url }}" />
|
||||
<script type="application/ld+json">
|
||||
{{ post|tojson(indent=4) }}
|
||||
</script>
|
||||
{% if post['@type'] == 'TechArticle' %}
|
||||
<style media="all">
|
||||
{{ includefile('prism.css')|indent(8) }}
|
||||
</style>
|
||||
{% endif %}
|
||||
|
||||
<meta property="og:title" content="{{ post.headline }}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{ post.url }}" />
|
||||
|
@ -36,26 +22,27 @@
|
|||
{% else %}
|
||||
<meta property="og:image" content="{{ post.image }}" />
|
||||
{% endif %}
|
||||
|
||||
{% if post['@type'] == 'TechArticle' %}
|
||||
<style media="all">
|
||||
{% include('prism.css') %}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block prism %}
|
||||
{% if post['@type'] == 'TechArticle' %}
|
||||
<script>
|
||||
{{ includefile('prism.js')|indent(8) }}
|
||||
{% include('prism.js') %}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if post.event %}
|
||||
{% set mftype = 'h-entry hentry h-event hevent' %}
|
||||
{% else %}
|
||||
{% set mftype = 'h-entry hentry' %}
|
||||
{% endif %}
|
||||
<main>
|
||||
<article class="{{ mftype }}" lang="{{ post.inLanguage }}" id="article">
|
||||
<article class="h-entry hentry" lang="{{ post.inLanguage }}" id="article">
|
||||
<header>
|
||||
<h1 class="entry-title p-name">
|
||||
<h1 class="p-name entry-title">
|
||||
{% if post.mentions %}
|
||||
<span>
|
||||
<svg width="16" height="16">
|
||||
|
@ -78,17 +65,17 @@
|
|||
|
||||
{% if post.review %}
|
||||
<div class="h-review hreview">
|
||||
<strong>Review summary of: <a href="{{ post.review.url }}" class="item fn p-name u-url p-item h-product">{{ post.review.name }}</a></strong>
|
||||
<strong>Review summary of: <a href="{{ post.review.url }}" class="p-name u-url p-item h-product item fn">{{ post.review.name }}</a></strong>
|
||||
<p>
|
||||
By
|
||||
<span class="p-author h-card vcard reviewer">
|
||||
<a class="fn p-name url u-url u-uid" href="{{ post.author.url }}">
|
||||
<span class="p-author h-card reviewer vcard">
|
||||
<a class="p-name u-url fn" href="{{ post.author.url }}">
|
||||
<span>{{ post.author.name }}</span>
|
||||
</a></span> in <time class="dt-published dtreviewed" datetime="{{ post.datePublished }}">{{ post.copyrightYear }}</time>
|
||||
</a></span> in <time class="dt-published dtreviewed" datetime="{{ post.datePublished }}" title="{{ post.datePublished }}">{{ post.datePublished|printdate }}</time>
|
||||
</p>
|
||||
<p>
|
||||
<span class="rating">
|
||||
<span class="value">{{ post.review.reviewRating.ratingValue }}</span>
|
||||
<span class="value p-rating">{{ post.review.reviewRating.ratingValue }}</span>
|
||||
out of
|
||||
<span class="best">{{ post.review.reviewRating.bestRating }}</span>
|
||||
</span>
|
||||
|
@ -111,39 +98,28 @@
|
|||
<dl>
|
||||
{% if post.subjectOf %}
|
||||
<dt>Trip details</dt>
|
||||
<dd>
|
||||
From
|
||||
<time class="dt-start dtstart" datetime="{{ post.subjectOf.startDate }}">
|
||||
{{ post.subjectOf.startDate }}
|
||||
</time>
|
||||
to
|
||||
<time class="dt-end dtend" datetime="{{ post.subjectOf.endDate }}">
|
||||
{{ post.subjectOf.endDate }}
|
||||
</time>, in
|
||||
<span class="p-location location">
|
||||
{{ post.subjectOf.location.name }}
|
||||
<dd class="h-event vevent">
|
||||
<span class="summary">
|
||||
From
|
||||
<time class="dt-start dtstart" datetime="{{ post.subjectOf.startDate }}">
|
||||
{{ post.subjectOf.startDate|printdate }}
|
||||
</time>
|
||||
to
|
||||
<time class="dt-end dtend" datetime="{{ post.subjectOf.endDate }}">
|
||||
{{ post.subjectOf.endDate|printdate }}
|
||||
</time>, in
|
||||
<span class="p-location location">
|
||||
{{ post.subjectOf.location.name }}
|
||||
</span>
|
||||
</span>
|
||||
<a class="u-url url" href="{{ post.url }}"></a>
|
||||
</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt>Author</dt>
|
||||
<dd>
|
||||
<span class="p-author h-card vcard">
|
||||
<img class="photo avatar u-photo u-avatar"
|
||||
src="{{ post.author.image }}"
|
||||
alt="Photo of {{ post.author.name }}" />
|
||||
<a class="fn p-name url u-url u-uid org" href="{{ post.author.url }}">
|
||||
{{ post.author.name }}
|
||||
</a>
|
||||
<a class="u-email email" href="mailto:{{ post.author.email }}">
|
||||
{{ post.author.email }}
|
||||
</a>
|
||||
</span>
|
||||
</dd>
|
||||
|
||||
<dt>Published</dt>
|
||||
<dd class="published updated">
|
||||
<time class="dt-published dt-updated" datetime="{{ post.datePublished }}">{{ post.datePublished|printdate }}</time>
|
||||
<dd>
|
||||
<time datetime="{{ post.datePublished }}" class="dt-published published">{{ post.datePublished|printdate }}</time>
|
||||
<time datetime="{{ post.dateModified }}" class="dt-updated updated"></time>
|
||||
</dd>
|
||||
|
||||
<dt>License</dt>
|
||||
|
@ -186,9 +162,16 @@
|
|||
{% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>Author</dt>
|
||||
<dd class="p-author h-card vcard">
|
||||
<img class="u-photo photo" src="{{ post.author.image }}" alt="" />
|
||||
<a class="p-name u-url fn url" href="{{ post.author.url }}">{{ post.author.name }}</a>
|
||||
<a class="u-email email" href="mailto:{{ post.author.email }}">{{ post.author.email }}</a>
|
||||
</dd>
|
||||
|
||||
<dt>Entry URL</dt>
|
||||
<dd>
|
||||
<a class="u-url u-uuid" href="{{ post.url }}">
|
||||
<a class="u-url u-uuid bookmark" href="{{ post.url }}">
|
||||
{{ post.url }}
|
||||
</a>
|
||||
</dd>
|
||||
|
@ -243,19 +226,15 @@
|
|||
<h2><a id="comments"></a>Responses</h2>
|
||||
<ol>
|
||||
{% for comment in post.comment %}
|
||||
<li class="h-entry p-comment">
|
||||
<span class="reaction">
|
||||
<a class="u-url" href="{{ comment.url }}">
|
||||
{{ comment.disambiguatingDescription }}
|
||||
</a>
|
||||
</span>
|
||||
<li class="h-entry p-comment hentry">
|
||||
<a href="{{ comment.url }}">
|
||||
{{ comment.disambiguatingDescription }}
|
||||
</a>
|
||||
from
|
||||
<span class="p-author h-card">
|
||||
<span class="p-author h-card vcard">
|
||||
{% if comment.author.url %}
|
||||
<a class="url u-url" href="{{ comment.author.url }}">
|
||||
<span class="p-name fn">
|
||||
{{ comment.author.name }}
|
||||
</span>
|
||||
<a class="u-url p-name fn" href="{{ comment.author.url }}">
|
||||
{{ comment.author.name }}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="p-name fn">
|
||||
|
@ -264,18 +243,17 @@
|
|||
{% endif %}
|
||||
</span>
|
||||
at
|
||||
<time class="dt-published" datetime="{{ comment.datePublished }}">
|
||||
<time class="dt-published published" datetime="{{ comment.datePublished }}">
|
||||
{{ comment.datePublished|printdate }}
|
||||
</time>
|
||||
<br />
|
||||
<span class="source">
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-link"></use>
|
||||
</svg>
|
||||
<a class="u-url" href="{{ comment.url }}">
|
||||
{{ comment.url }}
|
||||
</a>
|
||||
</span>
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-link"></use>
|
||||
</svg>
|
||||
<a class="u-url" href="{{ comment.url }}">
|
||||
{{ comment.url }}
|
||||
</a>
|
||||
<a href="{{ post.url }}" class="u-in-reply-to"></a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{% if url != thumbnail.url %}
|
||||
<a href="{{ url }}"{% if representativeOfPage %} class="u-featured"{% endif %}>
|
||||
{% endif %}
|
||||
<img src="{{ thumbnail.url }}" title="{{ headline }}" alt="" width="{{ thumbnail.width }}" height="{{ thumbnail.height }}" />
|
||||
<img src="{{ thumbnail.url }}" title="{{ headline }}" alt="{{ headline }}" width="{{ thumbnail.width }}" height="{{ thumbnail.height }}" />
|
||||
{% if url != thumbnail.url %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -4,26 +4,21 @@
|
|||
<title>{% block title %}{% endblock %}</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1" />
|
||||
<meta name="author" content="{{ site.author.name }} ({{ site.author.email }})" />
|
||||
<link rel="icon" href="{{ site.image }}" />
|
||||
{% for key, value in meta.items() %}
|
||||
<link rel="{{ key }}" href="{{ value }}" />
|
||||
{% endfor %}
|
||||
{% macro cssinclude(fname) %}
|
||||
{% include fname %}
|
||||
{% endmacro %}
|
||||
{% block meta %}{% endblock %}
|
||||
<style media="all">
|
||||
{{ cssinclude('style.css')|indent(8)}}
|
||||
{% include('style.css') %}
|
||||
</style>
|
||||
<style id="css_alt" media="speech">
|
||||
{{ cssinclude('style-alt.css')|indent(8)}}
|
||||
{% include('style-alt.css') %}
|
||||
</style>
|
||||
<style media="print">
|
||||
{{ cssinclude('style-print.css')|indent(8)}}
|
||||
{% include('style-print.css') %}
|
||||
</style>
|
||||
<script type="application/ld+json">
|
||||
{{ site|tojson(indent=4) }}
|
||||
</script>
|
||||
{% block meta %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -31,7 +26,7 @@
|
|||
{% macro activemenu(name) %}
|
||||
{% if (post is defined and post.name == name )
|
||||
or (post is defined and post.genre == name )
|
||||
or ( category is defined and category.name == name )%}active{% endif %}
|
||||
or ( category is defined and category.name == name )%}class="active"{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
<header>
|
||||
|
@ -40,7 +35,7 @@
|
|||
<ul>
|
||||
{% for key, data in menu.items() %}
|
||||
<li>
|
||||
<a title="{{ data.text }}" href="{{ data.url }}" class="{{ activemenu(key) }}">
|
||||
<a title="{{ data.text }}" href="{{ data.url }}" {{ activemenu(key) }} >
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-{{ key }}" />
|
||||
</svg>
|
||||
|
@ -65,7 +60,9 @@
|
|||
<label for="lightscheme">light</label>
|
||||
</span>
|
||||
</form>
|
||||
<form role="search" method="get" action="{{ site.potentialAction.url }}">
|
||||
{% for action in site.potentialAction %}
|
||||
{% if 'SearchAction' == action['@type'] %}
|
||||
<form role="search" method="get" action="{{ action.url }}">
|
||||
<label for="qsub">
|
||||
<input type="submit" value="search" id="qsub" name="qsub" />
|
||||
<svg width="16" height="16">
|
||||
|
@ -74,6 +71,8 @@
|
|||
</label>
|
||||
<input type="search" placeholder="search..." value="" name="q" id="q" title="Search for:" />
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
</header>
|
||||
|
@ -85,52 +84,60 @@
|
|||
{% endblock %}
|
||||
|
||||
<footer class="p-author h-card vcard">
|
||||
<p>
|
||||
<a href="https://creativecommons.org/">CC</a>,
|
||||
1999-2019,
|
||||
<img class="photo avatar u-photo u-avatar"
|
||||
src="{{ site.author.image }}"
|
||||
alt="Photo of {{ site.author.name }}" />
|
||||
<a class="fn p-name url u-url u-uid org" rel="me" href="{{ site.author.url }}">
|
||||
{{ site.author.name }}
|
||||
</a>
|
||||
<a class="u-email email" rel="me" href="mailto:{{ site.author.email }}">
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-mail"></use>
|
||||
</svg>
|
||||
{{ site.author.email }}
|
||||
</a>
|
||||
</p>
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<a title="following" href="{{ site.author.follows }}">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-following" /></svg>
|
||||
followings
|
||||
</a>
|
||||
</li>
|
||||
{% for url in site.author.sameAs %}
|
||||
<li>
|
||||
{% if 'cv.html' in url %}
|
||||
<a title="CV" href="{{ url }}">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-resume" /></svg>
|
||||
resume
|
||||
</a>
|
||||
{% elif 'github' in url %}
|
||||
<a title="github" rel="me" href="{{ url }}">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-github" /></svg>
|
||||
github
|
||||
</a>
|
||||
<section>
|
||||
<p>
|
||||
<a href="https://creativecommons.org/">CC</a>,
|
||||
1999-2019,
|
||||
<img class="u-photo photo" src="{{ site.author.image }}" alt="Photo of {{ site.author.name }}" />
|
||||
<a class="p-name u-url fn url" href="{{ site.author.url }}" rel="me"> {{ site.author.name }}</a>
|
||||
<a class="u-email email" rel="me" href="mailto:{{ site.author.email }}">
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-mail"></use>
|
||||
</svg>
|
||||
{{ site.author.email }}
|
||||
</a>
|
||||
</p>
|
||||
<nav>
|
||||
<ul>
|
||||
{% for action in site.potentialAction %}
|
||||
{% if 'FollowAction' == action['@type'] %}
|
||||
<li>
|
||||
<a href="{{ action.url }}">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-{{ action['@type'] }}" /></svg>
|
||||
{{ action.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
<p>
|
||||
<a href="https://xn--sr8hvo.ws/🇻🇮📢/previous">←</a>
|
||||
Member of <a href="https://xn--sr8hvo.ws">IndieWeb Webring</a>
|
||||
<a href="https://xn--sr8hvo.ws/🇻🇮📢/next">→</a>
|
||||
</p>
|
||||
{% endfor %}
|
||||
<li>
|
||||
<a href="{{ site.author.follows }}">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-following" /></svg>
|
||||
followings
|
||||
</a>
|
||||
</li>
|
||||
{% for url in site.author.sameAs %}
|
||||
<li>
|
||||
{% if 'cv.html' in url %}
|
||||
<a href="{{ url }}" class="u-url">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-resume" /></svg>
|
||||
resume
|
||||
</a>
|
||||
{% elif 'github' in url %}
|
||||
<a rel="me" href="{{ url }}">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-github" /></svg>
|
||||
github
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
<nav>
|
||||
<a href="https://xn--sr8hvo.ws/🇻🇮📢/previous">←</a>
|
||||
Member of <a href="https://xn--sr8hvo.ws">IndieWeb Webring</a>
|
||||
<a href="https://xn--sr8hvo.ws/🇻🇮📢/next">→</a>
|
||||
</nav>
|
||||
</section>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
{% endif %}
|
||||
|
||||
</h3>
|
||||
<a href="{{ post.url }}" class="u-url"></a>
|
||||
<a href="{{ post.url }}" class="u-url bookmark"></a>
|
||||
</header>
|
||||
|
||||
{% if post.description|length %}
|
||||
|
@ -39,41 +39,14 @@
|
|||
{% endif %}
|
||||
|
||||
<footer aria-hidden="true" hidden="hidden">
|
||||
<time datetime="{{ post.datePublished }}" class="published dt-published"></time>
|
||||
<time datetime="{{ post.dateModified }}" class="updated dt-updated"></time>
|
||||
Published at
|
||||
<time datetime="{{ post.datePublished }}" class="dt-published published">{{ post.datePublished|printdate }}</time>
|
||||
<time datetime="{{ post.dateModified }}" class="dt-updated updated"></time>
|
||||
by
|
||||
<span class="p-author h-card vcard">
|
||||
<img class="photo avatar u-photo u-avatar"
|
||||
src="{{ post.author.image }}"
|
||||
alt="Photo of {{ post.author.name }}" />
|
||||
<a class="fn p-name url u-url u-uid org" href="{{ post.author.url }}">
|
||||
{{ post.author.name }}
|
||||
</a>
|
||||
<a class="u-email email" href="mailto:{{ post.author.email }}">
|
||||
{{ post.author.email }}
|
||||
</a>
|
||||
<img class="u-photo photo" src="{{ post.author.image }}" alt="" />
|
||||
<a class="p-name u-url fn url" href="{{ post.author.url }}">{{ post.author.name }}</a>
|
||||
<a class="u-email email" href="mailto:{{ post.author.email }}">{{ post.author.email }}</a>
|
||||
</span>
|
||||
</footer>
|
||||
<script type="application/ld+json">
|
||||
{%
|
||||
set basedata = {
|
||||
"@context": post['@context'],
|
||||
"@type": post['@type'],
|
||||
"inLanguage": post.inLanguage,
|
||||
"headline": post.headline,
|
||||
"url": post.url,
|
||||
"mainEntityOfPage": post.mainEntityOfPage,
|
||||
"dateModified": post.dateModified,
|
||||
"datePublished": post.datePublished,
|
||||
"copyrightYear": post.copyrightYear,
|
||||
"license": post.license,
|
||||
"image": post.image,
|
||||
"author": post.author,
|
||||
"sameAs": post.sameAs,
|
||||
"publisher": post.publisher,
|
||||
"name": post.name,
|
||||
"description": post.description
|
||||
}
|
||||
%}
|
||||
{{ basedata|tojson(indent=4) }}
|
||||
</script>
|
||||
</article>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
* {
|
||||
background-color: #fff !important;
|
||||
color: #222;
|
||||
|
@ -86,4 +87,4 @@ pre {
|
|||
|
||||
.h-feed .h-entry {
|
||||
page-break-after: always;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
|
@ -171,7 +173,7 @@ body > footer {
|
|||
margin-top: 2em;
|
||||
}
|
||||
|
||||
body > footer > * {
|
||||
body > footer > section > * {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
|
@ -335,8 +337,7 @@ body > nav > ul > li {
|
|||
}
|
||||
|
||||
@media all and (min-width: 58em) {
|
||||
body > header > section,
|
||||
body > footer > section {
|
||||
body > header > section {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
justify-content:space-between;
|
||||
|
@ -357,4 +358,4 @@ body > img {
|
|||
right: 0;
|
||||
width: 10em;
|
||||
height: auto;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@
|
|||
<path d="M6.879 9.934c-0.208 0-0.416-0.079-0.575-0.238-1.486-1.486-1.486-3.905 0-5.392l3-3c0.72-0.72 1.678-1.117 2.696-1.117s1.976 0.397 2.696 1.117c1.486 1.487 1.486 3.905 0 5.392l-1.371 1.371c-0.317 0.317-0.832 0.317-1.149 0s-0.317-0.832 0-1.149l1.371-1.371c0.853-0.853 0.853-2.241 0-3.094-0.413-0.413-0.963-0.641-1.547-0.641s-1.134 0.228-1.547 0.641l-3 3c-0.853 0.853-0.853 2.241 0 3.094 0.317 0.317 0.317 0.832 0 1.149-0.159 0.159-0.367 0.238-0.575 0.238z"></path>
|
||||
<path d="M4 15.813c-1.018 0-1.976-0.397-2.696-1.117-1.486-1.486-1.486-3.905 0-5.392l1.371-1.371c0.317-0.317 0.832-0.317 1.149 0s0.317 0.832 0 1.149l-1.371 1.371c-0.853 0.853-0.853 2.241 0 3.094 0.413 0.413 0.962 0.641 1.547 0.641s1.134-0.228 1.547-0.641l3-3c0.853-0.853 0.853-2.241 0-3.094-0.317-0.317-0.317-0.832 0-1.149s0.832-0.317 1.149 0c1.486 1.486 1.486 3.905 0 5.392l-3 3c-0.72 0.72-1.678 1.117-2.696 1.117z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-follow" viewBox="0 0 16 16">
|
||||
<symbol id="icon-FollowAction" viewBox="0 0 16 16">
|
||||
<path d="M14.5 0h-13c-0.825 0-1.5 0.675-1.5 1.5v13c0 0.825 0.675 1.5 1.5 1.5h13c0.825 0 1.5-0.675 1.5-1.5v-13c0-0.825-0.675-1.5-1.5-1.5zM4.359 12.988c-0.75 0-1.359-0.603-1.359-1.353 0-0.744 0.609-1.356 1.359-1.356 0.753 0 1.359 0.613 1.359 1.356 0 0.75-0.609 1.353-1.359 1.353zM7.772 13c0-1.278-0.497-2.481-1.397-3.381-0.903-0.903-2.1-1.4-3.375-1.4v-1.956c3.713 0 6.738 3.022 6.738 6.737h-1.966zM11.244 13c0-4.547-3.697-8.25-8.241-8.25v-1.956c5.625 0 10.203 4.581 10.203 10.206h-1.963z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-home" viewBox="0 0 16 16">
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Loading…
Reference in a new issue