From 392839509761d58c82f78a0df8fd5e85df849fc0 Mon Sep 17 00:00:00 2001 From: Jean Abou Samra Date: Mon, 13 Feb 2023 23:20:04 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=E2=80=9CEdit=20this=20page=E2=80=9D=20?= =?UTF-8?q?=E2=86=92=20=E2=80=9CEdit=20on=20GitHub/GitLab/Bitbucket?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1172 --- docs/user_guide/source-buttons.rst | 35 +++++++++++++++++-- src/pydata_sphinx_theme/__init__.py | 21 ++++++----- .../components/edit-this-page.html | 12 +++++-- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/docs/user_guide/source-buttons.rst b/docs/user_guide/source-buttons.rst index 16bfe2ace..a4db469ad 100644 --- a/docs/user_guide/source-buttons.rst +++ b/docs/user_guide/source-buttons.rst @@ -4,8 +4,8 @@ Source Buttons Source buttons are links to the source of your page's content (either on your site, or on hosting sites like GitHub). -Add an Edit this Page button -============================ +Add an edit button +================== You can add a button to each page that will allow users to edit the page text directly and submit a pull request to update the documentation. To include this @@ -80,6 +80,37 @@ any other context values. "some_other_arg": "?some-other-arg" } +With the predefined providers, the link text reads "Edit on GitHub/GitLab/Bitbucket". +By default, a simple "Edit" is used if you use a custom URL. However, you can set +a provider name like this: + +.. code:: python + + html_context = { + "edit_page_url_template": "...", + "edit_page_provider_name": "Provider", + } + +This will turn the link into "Edit on Provider". + + +Custom link text +---------------- + +You can change the default text by extending the ``edit-this-page.html`` +template. For example, if you have ``templates_path = ["_templates"]`` +in your Sphinx configuration, you could put this code in +`_templates/edit-this-page.html`: + +.. code:: html+jinja + + {% extends "!components/edit-this-page.html" %} + + {% block edit_this_page_text %} + Edit this page + {% endblock %} + + View Source link ================ diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 315507bae..a258e5692 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -779,8 +779,8 @@ def extract_level_recursive(ul, navs_list): def setup_edit_url(app, pagename, templatename, context, doctree): """Add a function that jinja can access for returning the edit URL of a page.""" - def get_edit_url(): - """Return a URL for an "edit this page" link.""" + def get_edit_provider_and_url(): + """Return a provider name and a URL for an "edit this page" link.""" file_name = f"{pagename}{context['page_source_suffix']}" # Make sure that doc_path has a path separator only if it exists (to avoid //) @@ -794,7 +794,7 @@ def get_edit_url(): "gitlab_url": "https://gitlab.com", } - edit_url_attrs = {} + edit_attrs = {} # ensure custom URL is checked first, if given url_template = context.get("edit_page_url_template") @@ -806,21 +806,24 @@ def get_edit_url(): "Ensure `file_name` appears in `edit_page_url_template`: " f"{url_template}" ) + provider_name = context.get("edit_page_provider_name") + edit_attrs[("edit_page_url_template",)] = (provider_name, url_template) - edit_url_attrs[("edit_page_url_template",)] = url_template - - edit_url_attrs.update( + edit_attrs.update( { ("bitbucket_user", "bitbucket_repo", "bitbucket_version"): ( + "Bitbucket", "{{ bitbucket_url }}/{{ bitbucket_user }}/{{ bitbucket_repo }}" "/src/{{ bitbucket_version }}" "/{{ doc_path }}{{ file_name }}?mode=edit" ), ("github_user", "github_repo", "github_version"): ( + "GitHub", "{{ github_url }}/{{ github_user }}/{{ github_repo }}" "/edit/{{ github_version }}/{{ doc_path }}{{ file_name }}" ), ("gitlab_user", "gitlab_repo", "gitlab_version"): ( + "GitLab", "{{ gitlab_url }}/{{ gitlab_user }}/{{ gitlab_repo }}" "/-/edit/{{ gitlab_version }}/{{ doc_path }}{{ file_name }}" ), @@ -831,9 +834,9 @@ def get_edit_url(): doc_context.update(context) doc_context.update(doc_path=doc_path, file_name=file_name) - for attrs, url_template in edit_url_attrs.items(): + for attrs, (provider, url_template) in edit_attrs.items(): if all(doc_context.get(attr) not in [None, "None"] for attr in attrs): - return jinja2.Template(url_template).render(**doc_context) + return provider, jinja2.Template(url_template).render(**doc_context) raise ExtensionError( "Missing required value for `use_edit_page_button`. " @@ -841,7 +844,7 @@ def get_edit_url(): f"configuration: {sorted(edit_url_attrs.keys())}" ) - context["get_edit_url"] = get_edit_url + context["get_edit_provider_and_url"] = get_edit_provider_and_url # Ensure that the max TOC level is an integer context["theme_show_toc_level"] = int(context.get("theme_show_toc_level", 1)) diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/edit-this-page.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/edit-this-page.html index 2d1e8819c..5bc0f1fca 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/edit-this-page.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/edit-this-page.html @@ -1,8 +1,16 @@ {% if sourcename is defined and theme_use_edit_page_button==true and page_source_suffix %} {% set src = sourcename.split('.') %}
- - {{ _("Edit this page") }} + + + {% set provider = get_edit_provider_and_url()[0] %} + {% block edit_this_page_text %} + {% if provider %} + {% trans provider=provider %}Edit on {{ provider }}{% endtrans %} + {% else %} + {% trans %}Edit{% endtrans %} + {% endif %} + {% endblock %}
{% endif %} From 138bf523c508464ef4210c2a0dc22bde369ae40d Mon Sep 17 00:00:00 2001 From: Jean Abou Samra Date: Tue, 14 Feb 2023 12:56:49 +0100 Subject: [PATCH 2/3] Add tests --- tests/test_build.py | 57 +++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 0132cd57c..736dcbf0a 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -495,7 +495,7 @@ def test_included_toc(sphinx_build_factory): "github_version": "HEAD", "doc_path": "docs", }, - "https://github.com/foo/bar/edit/HEAD/docs/index.rst", + ("Edit on GitHub", "https://github.com/foo/bar/edit/HEAD/docs/index.rst"), ], [ { @@ -504,7 +504,7 @@ def test_included_toc(sphinx_build_factory): "gitlab_version": "HEAD", "doc_path": "docs", }, - "https://gitlab.com/foo/bar/-/edit/HEAD/docs/index.rst", + ("Edit on GitLab", "https://gitlab.com/foo/bar/-/edit/HEAD/docs/index.rst"), ], [ { @@ -513,7 +513,10 @@ def test_included_toc(sphinx_build_factory): "bitbucket_version": "HEAD", "doc_path": "docs", }, - "https://bitbucket.org/foo/bar/src/HEAD/docs/index.rst?mode=edit", + ( + "Edit on Bitbucket", + "https://bitbucket.org/foo/bar/src/HEAD/docs/index.rst?mode=edit", + ), ], ] @@ -526,10 +529,10 @@ def test_included_toc(sphinx_build_factory): key: f"{value}/" if key == "doc_path" else value for key, value in html_context.items() }, - # the URL does not change - url, + # the text and URL do not change + text_and_url, ] - for html_context, url in good_edits + for html_context, text_and_url in good_edits ] # copy the "good" ones, provide a `_url` based off the default @@ -541,11 +544,14 @@ def test_included_toc(sphinx_build_factory): # add a provider url **{f"{provider}_url": f"https://{provider}.example.com"}, ), - f"""https://{provider}.example.com/foo/{url.split("/foo/")[1]}""", + ( + text, + f"""https://{provider}.example.com/foo/{url.split("/foo/")[1]}""", + ), ] - for html_context, url in good_edits - for provider in ["gitlab", "bitbucket", "github"] - if provider in url + for html_context, (text, url) in good_edits + for provider in ["github", "gitlab", "bitbucket"] + if provider in text.lower() ] # missing any of the values should fail @@ -560,7 +566,7 @@ def test_included_toc(sphinx_build_factory): }, None, ] - for html_context, url in good_edits + for html_context, _ in good_edits ] # a good custom URL template @@ -571,7 +577,20 @@ def test_included_toc(sphinx_build_factory): "https://dvcs.example.com/foo/bar/edit/HEAD/{{ file_name }}" ) }, - "https://dvcs.example.com/foo/bar/edit/HEAD/index.rst", + ("Edit", "https://dvcs.example.com/foo/bar/edit/HEAD/index.rst"), + ] +] + +# a good custom URL template with an additional provider name +good_custom_with_provider = [ + [ + { + "edit_page_url_template": ( + "https://dvcs.example.com/foo/bar/edit/HEAD/{{ file_name }}" + ), + "edit_page_provider_name": "FooProvider", + }, + ("Edit on FooProvider", "https://dvcs.example.com/foo/bar/edit/HEAD/index.rst"), ] ] @@ -594,24 +613,29 @@ def test_included_toc(sphinx_build_factory): ] -@pytest.mark.parametrize("html_context,edit_url", all_edits) -def test_edit_page_url(sphinx_build_factory, html_context, edit_url): +@pytest.mark.parametrize("html_context,edit_text_and_url", all_edits) +def test_edit_page_url(sphinx_build_factory, html_context, edit_text_and_url): confoverrides = { "html_theme_options.use_edit_page_button": True, "html_context": html_context, } sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides) - if edit_url is None: + if edit_text_and_url is None: with pytest.raises(sphinx.errors.ExtensionError): sphinx_build.build() return + edit_text, edit_url = edit_text_and_url sphinx_build.build() index_html = sphinx_build.html_tree("index.html") edit_link = index_html.select(".editthispage a") assert edit_link, "no edit link found" assert edit_link[0].attrs["href"] == edit_url, f"edit link didn't match {edit_link}" + # First child is the icon + assert ( + list(edit_link[0].strings)[1].strip() == edit_text + ), f"edit text didn't match {edit_text}" @pytest.mark.parametrize( @@ -636,7 +660,6 @@ def test_edit_page_url(sphinx_build_factory, html_context, edit_url): ], ) def test_analytics(sphinx_build_factory, provider, tags): - confoverrides = provider sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides) sphinx_build.build() @@ -895,7 +918,7 @@ def test_translations(sphinx_build_factory): # TODO: Add translations where there are english phrases below sidebar_secondary = index.select(".bd-sidebar-secondary")[0] assert "Montrer le code source" in str(sidebar_secondary) - assert "Edit this page" in str(sidebar_secondary) + assert "Edit on GitHub" in str(sidebar_secondary) # TODO: Add translations where there are english phrases below header = index.select(".bd-header")[0] From 7d3e4bcdca8f5060dcdc66fdd5be844968dbdec8 Mon Sep 17 00:00:00 2001 From: Jean Abou Samra Date: Tue, 14 Feb 2023 18:47:48 +0100 Subject: [PATCH 3/3] Fix typo --- src/pydata_sphinx_theme/__init__.py | 8 ++++---- tests/test_build.py | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index a258e5692..48641d8be 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -815,17 +815,17 @@ def get_edit_provider_and_url(): "Bitbucket", "{{ bitbucket_url }}/{{ bitbucket_user }}/{{ bitbucket_repo }}" "/src/{{ bitbucket_version }}" - "/{{ doc_path }}{{ file_name }}?mode=edit" + "/{{ doc_path }}{{ file_name }}?mode=edit", ), ("github_user", "github_repo", "github_version"): ( "GitHub", "{{ github_url }}/{{ github_user }}/{{ github_repo }}" - "/edit/{{ github_version }}/{{ doc_path }}{{ file_name }}" + "/edit/{{ github_version }}/{{ doc_path }}{{ file_name }}", ), ("gitlab_user", "gitlab_repo", "gitlab_version"): ( "GitLab", "{{ gitlab_url }}/{{ gitlab_user }}/{{ gitlab_repo }}" - "/-/edit/{{ gitlab_version }}/{{ doc_path }}{{ file_name }}" + "/-/edit/{{ gitlab_version }}/{{ doc_path }}{{ file_name }}", ), } ) @@ -841,7 +841,7 @@ def get_edit_provider_and_url(): raise ExtensionError( "Missing required value for `use_edit_page_button`. " "Ensure one set of the following in your `html_context` " - f"configuration: {sorted(edit_url_attrs.keys())}" + f"configuration: {sorted(edit_attrs.keys())}" ) context["get_edit_provider_and_url"] = get_edit_provider_and_url diff --git a/tests/test_build.py b/tests/test_build.py index 736dcbf0a..d104cd175 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -622,7 +622,9 @@ def test_edit_page_url(sphinx_build_factory, html_context, edit_text_and_url): sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides) if edit_text_and_url is None: - with pytest.raises(sphinx.errors.ExtensionError): + with pytest.raises( + sphinx.errors.ExtensionError, match="Missing required value" + ): sphinx_build.build() return