Open TormodLandet opened 5 years ago
About OGP, we are waiting for the next release of docutils (see #2645).
Note: As a workaround, you can add meta tags as you like with custom template.
# in _template/layout.html
{% extends "alabaster/layout.html" %}
{% block extrahead %}
<meta property="og:title" content="ogp title">
{% endblock %}
Yeah, I use meta tags directly in the template, but it is rather ugly to be able to override this from the meta directive.
First I need to provide a function in conf.py
to check if the rst file overrides the description using a meta directive:
def get_meta_tag_content(name, html_string):
"""
Parse pre-rendered meta tags to find name->content mappings
Given input arguments
name='myname',
html_string='<... name="myname" ... content="a" ...>',
Return the string 'a'.
If the requested name is not found, return the empty string
"""
if not html_string or '<' not in html_string:
return ''
for tag in html_string.split('<')[1:]:
# Check that we can expect to be able to parse this tag
if 'name="' not in tag:
print('ERROR: metatag without name found: %r' % tag)
print('ERROR: html_string=%r' % html_string)
continue
if 'content="' not in tag:
print('ERROR: metatag without content found: %r' % tag)
print('ERROR: html_string=%r' % html_string)
continue
# Parse the generated HTML and check for the correct tag name
tag_name = tag.split('name="')[1].split('"')[0]
tag_content = tag.split('content="')[1].split('"')[0]
if tag_name == name:
return tag_content
return ''
html_context = {
'default_description': 'This is the default description',
'get_meta_tag_content': get_meta_tag_content,
}
And then the template uses this to either show the default description, or the meta directive description:
{# Make sure the metatags variable is present, also if the meta directive has not been used #}
{% if metatags is not defined %}
{% set metatags = '' %}
{% endif %}
{# Use the meta RST directive description if defined, otherwise use the default description #}
{% set page_description = get_meta_tag_content('description', metatags) %}
{% if not page_description %}
{% set page_description = default_description %}
{% set metatags = metatags + '<meta name="description" content="%s">' % page_description %}
{% endif %}
...
<meta property="og:title" content="{{ title|striptags|e }}">
<meta property="og:description" content="{{ page_description }}">
This would be much easier if the meta directive could be configured with default values.
PS: The whole thing can be seen in context here https://bitbucket.org/ocellarisproject/ocellaris/src/master/documentation/_templates/layout.html which is rendered here: https://www.ocellaris.org/
As a workaround, you can use following extension. It adds og_title
and og_description
config variables. And they can be overridden via bibliographic fields (refs)
import html
def on_html_page_context(app, pagename, templatename, ctx, doctree):
if doctree:
metadata = app.env.metadata.get(pagename, {})
title = metadata.get('og:title', app.config.og_title)
if not title:
title = ctx['title']
if title:
ctx['metatags'] += ('\n <meta property="og:title" content="%s">' % html.escape(title))
description = metadata.get('og:description', app.config.og_description)
if description:
ctx['metatags'] += ('\n <meta property="og:description" content="%s">' % html.escape(description))
def setup(app):
app.add_config_value('og_title', None, 'html')
app.add_config_value('og_description', None, 'html')
app.connect('html-page-context', on_html_page_context)
This is a scribbling code. So I can't promise you that this will be merged into Sphinx core in future. (At least, I know this will conflicts with meta
directive.) But this will help you at this moment.
Thanks,
Sphinx and docutils provide the meta directive where arbitrary HMTL metadata can be set, such as
description
,og:image
,og:title
etc. This can be used to set per-document metadata, but there is no facility (that I have been able to find) to provide default values for these fields.Best solution: Provide a dictionary in the conf file that gives default values for the html meta data that can be overridden by the meta directive for specific documents
Alternative solution: make the
metatags
template variable available as a dictionary, it is a pre-rendered string. Right now I parse this string to figure out if there have been any meta overrides defined in the local document. This is of course an ugly hack. The best would be to provide this only as a dictionary, but that is probably not very backwards compatible with any existing theme ... It could be that makingmetatags
a special dict that implements__str__
could maybe work? Anyway, providing overridable default values would be preferable.For context: Providing proper html metadata is good for search engines, and providing OpenGraph
og:*
metadata lets web pages make links to the documentation that looks nice and attractive for sharing on Twitter, Facebook, LinkedIn and other pages that provide OpenGraph support.