diff --git a/api/funkwhale_api/common/middleware.py b/api/funkwhale_api/common/middleware.py index 1143255e3d45bc8103ea7a11ec9a2d503798f0e4..de06fd1d442e097fc7c6060df2a669a113c176a9 100644 --- a/api/funkwhale_api/common/middleware.py +++ b/api/funkwhale_api/common/middleware.py @@ -39,6 +39,9 @@ def serve_spa(request): settings.FUNKWHALE_SPA_REWRITE_MANIFEST_URL or federation_utils.full_url(urls.reverse("api:v1:instance:spa-manifest")) ) + title = preferences.get("instance__name") + if title: + head = replace_title(head, title) head = replace_manifest_url(head, new_url) if not preferences.get("common__api_authentication_required"): @@ -82,6 +85,7 @@ def serve_spa(request): MANIFEST_LINK_REGEX = re.compile(r"<link [^>]*rel=(?:'|\")?manifest(?:'|\")?[^>]*>") +TITLE_REGEX = re.compile(r"<title>.*</title>") def replace_manifest_url(head, new_url): @@ -90,6 +94,12 @@ def replace_manifest_url(head, new_url): return head +def replace_title(head, new_title): + replacement = "<title>{}</title>".format(html.escape(new_title)) + head = TITLE_REGEX.sub(replacement, head) + return head + + def get_spa_html(spa_url): return get_spa_file(spa_url, "index.html") diff --git a/api/tests/common/test_middleware.py b/api/tests/common/test_middleware.py index 40ff279cbf1b6b38761c114c503ef8053043d797..8f04ba3184f9cee1bf79b3f0def2f1ae1197eb82 100644 --- a/api/tests/common/test_middleware.py +++ b/api/tests/common/test_middleware.py @@ -1,6 +1,6 @@ +import html import time import pytest - from django.http import HttpResponse from django.urls import reverse @@ -55,10 +55,12 @@ def test_should_fallback(path, expected, mocker): def test_serve_spa_from_cache(mocker, settings, preferences, no_api_auth): - + preferences["instance__name"] = 'Best Funkwhale "pod"' request = mocker.Mock(path="/") get_spa_html = mocker.patch.object( - middleware, "get_spa_html", return_value="<html><head></head></html>" + middleware, + "get_spa_html", + return_value="<html><head><title>Funkwhale</title></head></html>", ) mocker.patch.object( middleware, @@ -84,7 +86,8 @@ def test_serve_spa_from_cache(mocker, settings, preferences, no_api_auth): assert response.status_code == 200 expected = [ - "<html><head>", + "<html><head>" + "<title>{}</title>".format(html.escape(preferences["instance__name"])), '<meta content="custom title" property="og:title" />', '<meta content="custom description" property="og:description" />', '<meta content="default site name" property="og:site_name" />', diff --git a/changes/changelog.d/1107.enhancement b/changes/changelog.d/1107.enhancement new file mode 100644 index 0000000000000000000000000000000000000000..2b4ff88639e44fbacb9e5cda8c89f1feef8d45f9 --- /dev/null +++ b/changes/changelog.d/1107.enhancement @@ -0,0 +1 @@ +Fix HTML <title> not including instance name in some situations (#1107) diff --git a/front/src/App.vue b/front/src/App.vue index f85d8e920ae4316c57019cf95d3cda0c537165ae..0cfbb5bdccda410057088687fd7c4af3c6263471 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -66,6 +66,7 @@ export default { instanceUrl: null, showShortcutsModal: false, showSetInstanceModal: false, + initialTitle: document.title, } }, async created () { @@ -147,7 +148,6 @@ export default { }, mounted () { let self = this - // slight hack to allow use to have internal links in <translate> tags // while preserving router behaviour document.documentElement.addEventListener('click', function (event) { @@ -281,7 +281,7 @@ export default { if (this.$store.state.ui.pageTitle) { parts.push(this.$store.state.ui.pageTitle) } - parts.push(this.$store.state.instance.settings.instance.name.value || 'Funkwhale') + parts.push(this.initialTitle || 'Funkwhale') document.title = parts.join(' – ') }, diff --git a/front/src/components/Footer.vue b/front/src/components/Footer.vue index 3b2442831c335dae014cbece1ce4e6ab0af9966d..6e9f76167caefcf2cc5d2ea36f7cc2c5bef1c29f 100644 --- a/front/src/components/Footer.vue +++ b/front/src/components/Footer.vue @@ -4,10 +4,10 @@ <div class="ui stackable equal height stackable grid"> <section class="four wide column"> <h4 v-if="podName" class="ui header ellipsis"> - <translate translate-context="Footer/About/Title" :translate-params="{instanceName: podName}" >About %{instanceName}</translate> + <span v-translate="{instanceName: podName}" translate-context="Footer/About/Title">About %{instanceName}</span> </h4> <h4 v-else class="ui header ellipsis"> - <translate translate-context="Footer/About/Title" :translate-params="{instanceUrl: instanceHostname}" >About %{instanceUrl}</translate> + <span v-translate="{instanceUrl: instanceHostname}" translate-context="Footer/About/Title">About %{instanceUrl}</span> </h4> <div class="ui link list"> <router-link class="item" to="/about">