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.
@@ -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 @@ lower=True
)[: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 @@ dt = arrow.get(os.path.getmtime(self.fpath))
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 @@
@property def author(self): r = { + "@context": "http://schema.org", + "@type": "Person", 'name': urlparse(self.source).hostname, 'url': self.source }@@ -305,12 +306,7 @@ def jsonld(self):
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 @@ )
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 @@ def is_front(self):
""" 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):@@ -464,17 +465,6 @@ 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 @@
@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 @@ return urls
@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 @@ @cached_property
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 @@ "dateModified": str(arrow.get(self.dt)),
"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 @@
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 @@ })
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 @@ fg = FeedGenerator()
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 @@
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 @@ fe.updated(arrow.get(post.dt).datetime)
fe.rights('%s %s %s' % ( post.licence.upper(), - settings.author.get('name'), + settings.author.name, post.published.format('YYYY') ))
@@ -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", -} - -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" -} + "name": "Peter Molnar" +}) -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 @@ "@type": "DonateAction",
"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 @@ "@type": "DonateAction",
"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 @@ },
'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 @@ 'authorization_endpoint': 'https://indieauth.com/auth',
'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 @@ 'remotequeue': 'queue',
'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 @@ #360 = m
720: '', 1280: '_b', }, -} +}) _parser = argparse.ArgumentParser(description='Parameters for NASG') _booleanparams = {
@@ -33,10 +33,10 @@ {% endif %}
{% 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 @@ {% endfor %}
{% 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 @@ <meta property="og:image:height" content="{{ post.image.height }}" />
{% 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 @@ </header>
{% 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 @@ <footer>
<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> + <dt>Published</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> + <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 @@ For commercial use, please contact me.
{% 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 @@ <section class="comments">
<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 @@ </span>
{% 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 @@ <figure class="photo">
{% 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 @@ <head>
<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 @@ <nav>
<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 @@ <input name="colorscheme" value="light" id="lightscheme" type="radio">
<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 @@ </svg>
</label> <input type="search" placeholder="search..." value="" name="q" id="q" title="Search for:" /> </form> + {% endif %} + {% endfor %} </div> </section> </header>@@ -85,52 +84,60 @@ {% block pagination %}
{% 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 @@ </a>
{% 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 @@ </div>
{% 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 @@ }
.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 @@ margin: 0 0.6em;
} @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 @@ bottom: 0;
right: 0; width: 10em; height: auto; -} +}
@@ -27,7 +27,7 @@ <symbol id="icon-link" viewBox="0 0 16 16">
<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">