Reputation: 355
Here is a solution for the same problem:
Open a link in a new window in reStructuredText
However, when the document has a lot of links (especially when the links are in a table), this solution will not work well.
Are there any other solutions? Thanks for any help!
Upvotes: 6
Views: 4584
Reputation: 7150
sphinx-new-tab-link might be a good candidate, with less code to type. To enable it, adapt conf.py
:
extensions = [
# (...)
"sphinx_new_tab_link",
]
Upvotes: 1
Reputation: 852
While the solution below isn't as performant as the one from this answer, it's simpler and less brittle in the case visit_reference()
is patched in the future. Plus it works seamlessly with both the html
and html5
translators:
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.html5 import HTML5Translator
from sphinx.util.docutils import is_html5_writer_available
class PatchedHTMLTranslator(
HTML5Translator if is_html5_writer_available() else HTMLTranslator
):
def starttag(self, node, tagname, *args, **attrs):
if (
tagname == "a"
and "target" not in attrs
and (
"external" in attrs.get("class", "")
or "external" in attrs.get("classes", [])
)
):
attrs["target"] = "_blank"
attrs["ref"] = "noopener noreferrer"
return super().starttag(node, tagname, *args, **attrs)
def setup(app):
app.set_translator("html", PatchedHTMLTranslator)
Upvotes: 1
Reputation: 11905
To add target="_blank"
but also rel="noopener noreferrer"
to external links, it is necessary to copy Sphinx' entire visit_reference()
method to patch this in:
atts['target'] = '_blank'
atts['rel'] = 'noopener noreferrer'
Sphinx' original code does not process a rel
attribute that one might set like node['rel'] = 'noopener noreferrer'
, whereas it does apply a target
attribute (atts['target'] = node['target']
).
Below you find my solution. The base code is from Sphinx 3.0.3 (sphinx/writers/html.py):
from sphinx.writers.html import HTMLTranslator
from docutils import nodes
from docutils.nodes import Element
class PatchedHTMLTranslator(HTMLTranslator):
def visit_reference(self, node: Element) -> None:
atts = {'class': 'reference'}
if node.get('internal') or 'refuri' not in node:
atts['class'] += ' internal'
else:
atts['class'] += ' external'
# ---------------------------------------------------------
# Customize behavior (open in new tab, secure linking site)
atts['target'] = '_blank'
atts['rel'] = 'noopener noreferrer'
# ---------------------------------------------------------
if 'refuri' in node:
atts['href'] = node['refuri'] or '#'
if self.settings.cloak_email_addresses and atts['href'].startswith('mailto:'):
atts['href'] = self.cloak_mailto(atts['href'])
self.in_mailto = True
else:
assert 'refid' in node, \
'References must have "refuri" or "refid" attribute.'
atts['href'] = '#' + node['refid']
if not isinstance(node.parent, nodes.TextElement):
assert len(node) == 1 and isinstance(node[0], nodes.image)
atts['class'] += ' image-reference'
if 'reftitle' in node:
atts['title'] = node['reftitle']
if 'target' in node:
atts['target'] = node['target']
self.body.append(self.starttag(node, 'a', '', **atts))
if node.get('secnumber'):
self.body.append(('%s' + self.secnumber_suffix) %
'.'.join(map(str, node['secnumber'])))
def setup(app):
app.set_translator('html', PatchedHTMLTranslator)
You may paste this directly into your conf.py
at the bottom.
Note that this patches the HTMLTranslator. If you use HTML 5 output then you need a modified HTML5Translator (sphinx/writers/html5.py).
Upvotes: 2
Reputation: 142
If you want external links to open in new tabs, add below code to your conf.py
:
from sphinx.writers.html import HTMLTranslator
class PatchedHTMLTranslator(HTMLTranslator):
def visit_reference(self, node):
if node.get('newtab') or not (node.get('target') or node.get('internal')
or 'refuri' not in node):
node['target'] = '_blank'
super().visit_reference(node)
def setup(app):
app.set_translator('html', PatchedHTMLTranslator)
This also gives you the ability to use the newtab parameter to a reference, have it show as internal, but open in a new tab. I use this for linking to slide PDFs.
source: http://jack.rosenth.al/hacking-docutils.html#external-links-in-new-tabs
Upvotes: 1