Lancelot Shortcode
Introduction
This is a variant of the built-in doc
shortcode (although it seems to go into the plugins folder for some reason, I'll have to look into that). The ReStructured Text doc
documentation says that you can pass in text to display instead of the title of the post it's linking to, but I couldn't get it to work with the non-RST version so I adapted it so I could use it in org-mode posts. I didn't really look too closely at the code, just enough to get it working so it's probably pretty fragile.
The Plugin File
[Core]
name = lancelot
module = lancelot
[Nikola]
PluginCategory = Shortcode
[Documentation]
author = The Cloistered Monkey
version = 0.2
website = https://necromuralist.github.io/Beach-Pig-Thigh
description = Variant of the doc shortcode that allows alternate titles.
The Python Code
# -*- coding: utf-8 -*-
# This file is public domain according to its author, the Cloistered Monkey
"""Shortcode for non-restructured text inter-site links.
Re-write of the ``doc`` plugin to allow alternative titles outside of RST
The documentation seems to indicate that this should work but it uses angle
brackets <> and something is converting them to less than and greater
than HTML symbols.
"""
from nikola.plugin_categories import ShortcodePlugin
from nikola.utils import LOGGER, slugify
class Plugin(ShortcodePlugin):
"""Plugin for non-rst inter-site links."""
name = "lancelot"
def handler(self, title=None, site=None, data=None, lang=None,
date=None, post=None):
"""Create an inter-site link
Note:
if you don't use the keyword "title" in the shortcode, nikola will
pass the string as the first argument to this method (using the *args
trick). So for my future self: put the title first or never
forget the keyword.
Args:
title: optional argument to specify a different title from the post
Returns:
output HTML to replace the shortcode
"""
success, twin_slugs, title, permalink, slug = lancelot_link(
site=site,
slug=data,
title=title)
if success:
if twin_slugs:
LOGGER.warning(
('More than one post with the same slug. '
f'Using "{permalink}" '
'for lancelot shortcode'))
output = f'<a href="{permalink}">{title}</a>'
else:
LOGGER.error(
f'"{slug}" slug doesn\'t exist.')
output = ('<span class="error text-error" style="color: red;">'
f'Invalid link: {data}</span>')
return output, []
def lancelot_link(site, slug, title):
"""process the slug, check if it exists or is duplicated
if `title` is None this will grab the post-title
Args:
site: the Nikola object
slug: the text between the shortcode tags
title: the title passed in by the user (if any)
Returns:
tuple (success, has duplicate slugs, title, permalink, slug)
"""
if '#' in slug:
slug, fragment = slug.split('#', 1)
else:
fragment = None
slug = slugify(slug)
twin_slugs = False
post = None
for p in site.timeline:
if p.meta('slug') == slug:
if post is None:
post = p
else:
twin_slugs = True
break
try:
if post is None:
raise ValueError("No post with matching slug found.")
except ValueError:
return False, False, title, None, slug
if title is None:
title = post.title()
permalink = post.permalink()
if fragment:
permalink += '#' + fragment
return True, twin_slugs, title, permalink, slug