Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for "scope" option #284

Merged
merged 14 commits into from
Oct 27, 2023
7 changes: 7 additions & 0 deletions docs/customization.rst
2bndy5 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,13 @@ Configuration Options

A list of dictionaries used to populate the :ref:`version_dropdown` selector.

.. themeconf:: scope

Scope of site preferences (i.e. cookie consent, content tabs, color palette).
If you have multi-site project, you can set this to "/"
to share preferences between all sub-sites. See the :ref:`version_dropdown` section
on how to setup a multi-site project.

.. themeconf:: languages

A list of dictionaries to populate the language selector drop-down menu (in the navigation
Expand Down
1 change: 1 addition & 0 deletions requirements/dev-mypy.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mypy==1.5.1
types-PyYAML
docutils-stubs
types-beautifulsoup4
types-jsonschema
types-appdirs
types-requests
Expand Down
21 changes: 13 additions & 8 deletions sphinx_immaterial/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,18 @@ def html_page_context(
if theme_options.get("analytics"):
analytics = theme_options.get("analytics")

extra = {
"version": version_config,
"social": theme_options.get("social"),
"disqus": theme_options.get("disqus"),
"manifest": theme_options.get("pwa_manifest"),
"analytics": analytics,
"alternate": theme_options.get("languages"),
}
scope = theme_options.get("scope")
if scope is not None:
extra["scope"] = scope

context.update(
config=dict_merge(
context.get("config", {}),
Expand All @@ -235,14 +247,7 @@ def html_page_context(
"site_name": context["docstitle"],
"repo_url": theme_options.get("repo_url"),
"repo_name": theme_options.get("repo_name", None),
"extra": {
"version": version_config,
"social": theme_options.get("social"),
"disqus": theme_options.get("disqus"),
"manifest": theme_options.get("pwa_manifest"),
"analytics": analytics,
"alternate": theme_options.get("languages"),
},
"extra": extra,
"plugins": theme_options.get("plugins"),
},
),
Expand Down
5 changes: 5 additions & 0 deletions sphinx_immaterial/theme.conf
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,10 @@ version_info =
# "_static/old_versions.json"
version_json = "versions.json"

# Scope of site preferences (i.e. cookie consent, content tabs, color palette).
# If you have multi-site project, you can set this to "/"
# to share preferences between all sub-sites.
scope =

# extra configuration (namely for `alternative` languages)
languages =
68 changes: 68 additions & 0 deletions tests/extra_scope_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from __future__ import annotations

import re
import textwrap
from pathlib import Path
from typing import TYPE_CHECKING

import pytest
from bs4 import BeautifulSoup

if TYPE_CHECKING:
from sphinx.testing.util import SphinxTestApp


@pytest.mark.parametrize(
"scope_url,expected_scope_url",
[
(None, "."),
("", ""),
("/", "/"),
("/subsite", "/subsite"),
],
ids=[
"base_url",
"empty",
"root",
"subsite",
],
)
def test_extra_scope(
immaterial_make_app,
scope_url: str | None,
expected_scope_url: str,
):
if scope_url is not None:
scope_url = f'"{scope_url}"'

app: SphinxTestApp = immaterial_make_app(
extra_conf=textwrap.dedent(
f"""
html_theme_options = {{
"scope": {scope_url}
}}
"""
),
files={
"index.rst": "Sample text",
},
)
app.build()

assert not app._warning.getvalue()

with open(Path(app.outdir) / "index.html", mode="r") as file:
soup = BeautifulSoup(file.read(), "html.parser")

head = soup.head
assert head is not None

scope_pattern = re.compile(r"__md_scope=new URL\(\"(?P<url>[^\"]+)\"")
matched_scope_url = ""
for script in head.find_all("script"):
scope_match = scope_pattern.search(script.text)
if scope_match:
matched_scope_url = scope_match.group("url")
break

assert matched_scope_url == expected_scope_url
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
coverage[toml] >= 7.0
pytest
pytest-snapshot
beautifulsoup4
tests/issue_134/sphinx-immaterial-pybind11-issue-134

-r ../requirements.txt
Expand Down