summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2021-01-24 14:40:56 +0900
committerGitHub <noreply@github.com>2021-01-24 14:40:56 +0900
commit0e6a2a9ebd04e43d1d6ce6f8c4ba774989c9078c (patch)
tree0a1dd82ab734d82c9482dd27f54432f0fae52a76
parent502c4ee5fbef6bf51fe60cc820b1484471dd1b32 (diff)
parentc50ce99c9d8a68eac9db9ec1501efe3f9d79b95e (diff)
downloadsphinx-git-0e6a2a9ebd04e43d1d6ce6f8c4ba774989c9078c.tar.gz
Merge pull request #8737 from tk0miya/8510_html_logo_url
Allow user to use url to reference html logo & favicon
-rw-r--r--CHANGES3
-rw-r--r--doc/extdev/deprecated.rst10
-rw-r--r--doc/templating.rst28
-rw-r--r--doc/usage/configuration.rst20
-rw-r--r--sphinx/builders/html/__init__.py35
-rw-r--r--sphinx/themes/agogo/layout.html4
-rw-r--r--sphinx/themes/basic/layout.html8
-rw-r--r--sphinx/themes/basic/opensearch.xml4
-rw-r--r--sphinx/themes/haiku/layout.html4
-rw-r--r--sphinx/themes/pyramid/layout.html2
-rw-r--r--sphinx/util/__init__.py8
11 files changed, 101 insertions, 25 deletions
diff --git a/CHANGES b/CHANGES
index 8788b39b5..79226b310 100644
--- a/CHANGES
+++ b/CHANGES
@@ -38,6 +38,7 @@ Incompatible changes
Deprecated
----------
+* ``favicon`` and ``logo`` variable in HTML templates
* ``sphinx.directives.patches.CSVTable``
* ``sphinx.directives.patches.ListTable``
* ``sphinx.directives.patches.RSTTable``
@@ -53,6 +54,8 @@ Features added
the location where the object is defined
* #7784: i18n: The alt text for image is translated by default (without
:confval:`gettext_additional_targets` setting)
+* #2018: html: :confval:`html_favicon` and :confval:`html_logo` now accept URL
+ for the image
* #8070: html search: Support searching for 2characters word
* #7830: Add debug logs for change detection of sources and templates
* #8201: Emit a warning if toctree contains duplicated entries
diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst
index 893356df9..be085b357 100644
--- a/doc/extdev/deprecated.rst
+++ b/doc/extdev/deprecated.rst
@@ -26,6 +26,16 @@ The following is a list of deprecated interfaces.
- (will be) Removed
- Alternatives
+ * - ``favicon`` variable in HTML templates
+ - 4.0
+ - TBD
+ - ``favicon_url``
+
+ * - ``logo`` variable in HTML templates
+ - 4.0
+ - TBD
+ - ``logo_url``
+
* - ``sphinx.directives.patches.CSVTable``
- 4.0
- 6.0
diff --git a/doc/templating.rst b/doc/templating.rst
index 548f8b8d9..97596e6a9 100644
--- a/doc/templating.rst
+++ b/doc/templating.rst
@@ -274,7 +274,19 @@ in the future.
.. data:: favicon
- The path to the HTML favicon in the static path, or ``''``.
+ The path to the HTML favicon in the static path, or URL to the favicon, or
+ ``''``.
+
+ .. deprecated:: 4.0
+
+ Recommend to use ``favicon_url`` instead.
+
+.. data:: favicon_url
+
+ The relative path to the HTML favicon image from the current document, or
+ URL to the favicon, or ``''``.
+
+ .. versionadded:: 4.0
.. data:: file_suffix
@@ -297,7 +309,19 @@ in the future.
.. data:: logo
- The path to the HTML logo image in the static path, or ``''``.
+ The path to the HTML logo image in the static path, or URL to the logo, or
+ ``''``.
+
+ .. deprecated:: 4.0
+
+ Recommend to use ``logo_url`` instead.
+
+.. data:: logo_url
+
+ The relative path to the HTML logo image from the current document, or URL
+ to the logo, or ``''``.
+
+ .. versionadded:: 4.0
.. data:: master_doc
diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst
index ed2a3711a..3bb993f25 100644
--- a/doc/usage/configuration.rst
+++ b/doc/usage/configuration.rst
@@ -987,26 +987,32 @@ that use Sphinx's HTMLWriter class.
.. confval:: html_logo
If given, this must be the name of an image file (path relative to the
- :term:`configuration directory`) that is the logo of the docs. It is placed
- at the top of the sidebar; its width should therefore not exceed 200 pixels.
- Default: ``None``.
+ :term:`configuration directory`) that is the logo of the docs, or URL that
+ points an image file for the logo. It is placed at the top of the sidebar;
+ its width should therefore not exceed 200 pixels. Default: ``None``.
.. versionadded:: 0.4.1
The image file will be copied to the ``_static`` directory of the output
HTML, but only if the file does not already exist there.
+ .. versionchanged:: 4.0
+ Also accepts the URL for the logo file.
+
.. confval:: html_favicon
If given, this must be the name of an image file (path relative to the
- :term:`configuration directory`) that is the favicon of the docs. Modern
- browsers use this as the icon for tabs, windows and bookmarks. It should
- be a Windows-style icon file (``.ico``), which is 16x16 or 32x32
- pixels large. Default: ``None``.
+ :term:`configuration directory`) that is the favicon of the docs, or URL that
+ points an image file for the favicon. Modern browsers use this as the icon
+ for tabs, windows and bookmarks. It should be a Windows-style icon file
+ (``.ico``), which is 16x16 or 32x32 pixels large. Default: ``None``.
.. versionadded:: 0.4
The image file will be copied to the ``_static`` directory of the output
HTML, but only if the file does not already exist there.
+ .. versionchanged:: 4.0
+ Also accepts the URL for the favicon.
+
.. confval:: html_css_files
A list of CSS files. The entry must be a *filename* string or a tuple
diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py
index 332c7c989..6d5f24638 100644
--- a/sphinx/builders/html/__init__.py
+++ b/sphinx/builders/html/__init__.py
@@ -38,7 +38,7 @@ from sphinx.highlighting import PygmentsBridge
from sphinx.locale import _, __
from sphinx.search import js_index
from sphinx.theming import HTMLThemeFactory
-from sphinx.util import logging, md5, progress_message, status_iterator
+from sphinx.util import isurl, logging, md5, progress_message, status_iterator
from sphinx.util.docutils import is_html5_writer_available, new_document
from sphinx.util.fileutil import copy_asset
from sphinx.util.i18n import format_date
@@ -792,12 +792,12 @@ class StandaloneHTMLBuilder(Builder):
excluded, context=context, renderer=self.templates, onerror=onerror)
def copy_html_logo(self) -> None:
- if self.config.html_logo:
+ if self.config.html_logo and not isurl(self.config.html_logo):
copy_asset(path.join(self.confdir, self.config.html_logo),
path.join(self.outdir, '_static'))
def copy_html_favicon(self) -> None:
- if self.config.html_favicon:
+ if self.config.html_favicon and not isurl(self.config.html_favicon):
copy_asset(path.join(self.confdir, self.config.html_favicon),
path.join(self.outdir, '_static'))
@@ -1155,6 +1155,26 @@ def setup_js_tag_helper(app: Sphinx, pagename: str, templatexname: str,
context['js_tag'] = js_tag
+def setup_resource_paths(app: Sphinx, pagename: str, templatename: str,
+ context: Dict, doctree: Node) -> None:
+ """Set up relative resource paths."""
+ pathto = context.get('pathto')
+
+ # favicon_url
+ favicon = context.get('favicon')
+ if not isurl(favicon):
+ context['favicon_url'] = pathto('_static/' + favicon, resource=True)
+ else:
+ context['favicon_url'] = favicon
+
+ # logo_url
+ logo = context.get('logo')
+ if not isurl(logo):
+ context['logo_url'] = pathto('_static/' + logo, resource=True)
+ else:
+ context['logo_url'] = logo
+
+
def validate_math_renderer(app: Sphinx) -> None:
if app.builder.format != 'html':
return
@@ -1195,14 +1215,18 @@ def validate_html_static_path(app: Sphinx, config: Config) -> None:
def validate_html_logo(app: Sphinx, config: Config) -> None:
"""Check html_logo setting."""
- if config.html_logo and not path.isfile(path.join(app.confdir, config.html_logo)):
+ if (config.html_logo and
+ not path.isfile(path.join(app.confdir, config.html_logo)) and
+ not isurl(config.html_logo)):
logger.warning(__('logo file %r does not exist'), config.html_logo)
config.html_logo = None # type: ignore
def validate_html_favicon(app: Sphinx, config: Config) -> None:
"""Check html_favicon setting."""
- if config.html_favicon and not path.isfile(path.join(app.confdir, config.html_favicon)):
+ if (config.html_favicon and
+ not path.isfile(path.join(app.confdir, config.html_favicon)) and
+ not isurl(config.html_favicon)):
logger.warning(__('favicon file %r does not exist'), config.html_favicon)
config.html_favicon = None # type: ignore
@@ -1288,6 +1312,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('config-inited', validate_html_favicon, priority=800)
app.connect('builder-inited', validate_math_renderer)
app.connect('html-page-context', setup_js_tag_helper)
+ app.connect('html-page-context', setup_resource_paths)
# load default math renderer
app.setup_extension('sphinx.ext.mathjax')
diff --git a/sphinx/themes/agogo/layout.html b/sphinx/themes/agogo/layout.html
index 1d9df693b..a8ae6304d 100644
--- a/sphinx/themes/agogo/layout.html
+++ b/sphinx/themes/agogo/layout.html
@@ -13,9 +13,9 @@
{% block header %}
<div class="header-wrapper" role="banner">
<div class="header">
- {%- if logo %}
+ {%- if logo_url %}
<p class="logo"><a href="{{ pathto(master_doc)|e }}">
- <img class="logo" src="{{ pathto('_static/' + logo, 1)|e }}" alt="Logo"/>
+ <img class="logo" src="{{ logo_url|e }}" alt="Logo"/>
</a></p>
{%- endif %}
{%- block headertitle %}
diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html
index 8d1e4f608..e35d4e5fe 100644
--- a/sphinx/themes/basic/layout.html
+++ b/sphinx/themes/basic/layout.html
@@ -51,9 +51,9 @@
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
- {%- if logo %}
+ {%- if logo_url %}
<p class="logo"><a href="{{ pathto(master_doc)|e }}">
- <img class="logo" src="{{ pathto('_static/' + logo, 1)|e }}" alt="Logo"/>
+ <img class="logo" src="{{ logo_url|e }}" alt="Logo"/>
</a></p>
{%- endif %}
{%- endblock %}
@@ -135,8 +135,8 @@
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
- {%- if favicon %}
- <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1)|e }}"/>
+ {%- if favicon_url %}
+ <link rel="shortcut icon" href="{{ favicon_url|e }}"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
diff --git a/sphinx/themes/basic/opensearch.xml b/sphinx/themes/basic/opensearch.xml
index 0cad2967c..ca7bb5966 100644
--- a/sphinx/themes/basic/opensearch.xml
+++ b/sphinx/themes/basic/opensearch.xml
@@ -6,8 +6,8 @@
<Url type="text/html" method="get"
template="{{ use_opensearch }}/{{ pathto('search') }}?q={searchTerms}"/>
<LongName>{{ docstitle|e }}</LongName>
-{%- if favicon %}
- <Image height="16" width="16" type="image/x-icon">{{ use_opensearch }}/{{ pathto('_static/' + favicon, 1)|e }}</Image>
+{%- if favicon_url %}
+ <Image height="16" width="16" type="image/x-icon">{{ use_opensearch }}/{{ favicon_url|e }}</Image>
{%- endif %}
{% block extra %} {# Put e.g. an <Image> element here. #} {% endblock %}
</OpenSearchDescription>
diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html
index 2c2469722..bf76204b1 100644
--- a/sphinx/themes/haiku/layout.html
+++ b/sphinx/themes/haiku/layout.html
@@ -36,11 +36,11 @@
{%- block haikuheader %}
{%- if theme_full_logo != "false" %}
<a href="{{ pathto('index') }}">
- <img class="logo" src="{{ pathto('_static/' + logo, 1)|e }}" alt="Logo"/>
+ <img class="logo" src="{{ logo_url|e }}" alt="Logo"/>
</a>
{%- else %}
{%- if logo -%}
- <img class="rightlogo" src="{{ pathto('_static/' + logo, 1)|e }}" alt="Logo"/>
+ <img class="rightlogo" src="{{ logo_url|e }}" alt="Logo"/>
{%- endif -%}
<h1 class="heading"><a href="{{ pathto('index') }}">
<span>{{ shorttitle|e }}</span></a></h1>
diff --git a/sphinx/themes/pyramid/layout.html b/sphinx/themes/pyramid/layout.html
index 02eec1cfb..097e97407 100644
--- a/sphinx/themes/pyramid/layout.html
+++ b/sphinx/themes/pyramid/layout.html
@@ -13,7 +13,7 @@
<div class="header" role="banner">
<div class="logo">
<a href="{{ pathto(master_doc)|e }}">
- <img class="logo" src="{{ pathto('_static/' + logo, 1)|e }}" alt="Logo"/>
+ <img class="logo" src="{{ pathto(logo, 1)|e }}" alt="Logo"/>
</a>
</div>
</div>
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 3f1f2a95d..6ae5e6162 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -447,6 +447,14 @@ def encode_uri(uri: str) -> str:
return urlunsplit(split)
+def isurl(url: str) -> bool:
+ """Check *url* is URL or not."""
+ if url and '://' in url:
+ return True
+ else:
+ return False
+
+
def display_chunk(chunk: Any) -> str:
if isinstance(chunk, (list, tuple)):
if len(chunk) == 1: