How does one add custom attributes to generated HTML?

22 views
Skip to first unread message

Vinay Sajip

unread,
Nov 6, 2022, 2:33:43 PM11/6/22
to sphinx-dev
Sphinx seems to use docutils.writers._base_html.HTMLTranslator.starttag to start off a tag, which has this signature:

def starttag(self, node, tagname, suffix='\n', empty=False, **attributes):

Apart from CSS classes, it doesn't seem to have any logic for picking up attributes from the node itself - you have to pass them in attributes. It seems like every place that calls starttag calls it with some custom classes where needed, and these are merged with any classes set in the node. Here's an example for literals from sphinx.writers.html.HTMLTranslator:

self.starttag(node, 'code', '', CLASS='docutils literal notranslate')

If you had previously done node['classes'].append('foo'), then the resulting HTML element would have class="foo docutils literal notranslate" - but

Vinay Sajip

unread,
Nov 6, 2022, 2:35:47 PM11/6/22
to sphinx-dev
Whoops, pressed the wrong key and posted prematurely. I was about to ask - how can I arrange for an element to have e.g. data-foo="bar" data-bar="baz" in the HTML output? I don't want to have to duplicate all the existing logic.

Guenter Milde

unread,
Nov 18, 2022, 5:27:16 AM11/18/22
to sphin...@googlegroups.com
On 2022-11-06, 'Vinay Sajip' via sphinx-dev wrote:

> [-- Type: text/plain, Encoding: --]

> Whoops, pressed the wrong key and posted prematurely. I was about to ask -
> how can I arrange for an element to have e.g. data-foo="bar" data-bar="baz"
> in the HTML output? I don't want to have to duplicate all the existing
> logic.

Custom attributes in generated HTML are not supported. This is a generic
limitation due to the overal design and the stated aims of Docutils.
There are currently no plans to add such a support (which would be
non-trivial to get right given that Docutils supports also output to
LaTeX, OpenDocument, and troff).

As a HTML-only workaround, you can use "raw" HTML that is passed
unchanged from the source (or a custom directive) to the output.
https://docutils.sourceforge.io/docs/ref/rst/directives.html#raw-data-pass-through

A (silly) test example:
https://docutils.sourceforge.io/test/functional/expected/standalone_rst_html5.html#raw-text
generated from rST source text at the end of
https://docutils.sourceforge.io/test/functional/input/data/standard.txt


Günter

Guenter Milde

unread,
Nov 18, 2022, 5:41:34 AM11/18/22
to sphin...@googlegroups.com
On 2022-11-06, 'Vinay Sajip' via sphinx-dev wrote:

> Sphinx seems to use docutils.writers._base_html.HTMLTranslator.starttag to
> start off a tag, which has this signature:

> def starttag(self, node, tagname, suffix='\n', empty=False, **attributes):

> Apart from CSS classes, it doesn't seem to have any logic for picking up
> attributes from the node itself - you have to pass them in attributes. It
> seems like every place that calls starttag calls it with some custom
> classes where needed, and these are merged with any classes set in the node.
> Here's an example for literals from sphinx.writers.html.HTMLTranslator:

HTMLTranslator.starttag() is an auxiliary function for translating
`standard Docutils nodes`__ which have a `fixed set of supported
attributes`__.

__ https://docutils.sourceforge.io/docs/ref/doctree.html
__ https://docutils.sourceforge.io/docs/ref/doctree.html#attribute-reference

In simple cases as well as in case of extra requirements, the
`HTMLTranslator.visit_…()` functions create the start tag string
without calling `startag()` or modifying its return value.


Günter


Reply all
Reply to author
Forward
0 new messages