pydata-sphinx-theme icon indicating copy to clipboard operation
pydata-sphinx-theme copied to clipboard

Suggested way to customize "Edit this page" link based on document

Open djhoese opened this issue 2 years ago • 7 comments

The vispy library uses the sphinxcontrib.apidoc extension to automatically generate our API documents at build time. These generated files just use apidoc/autodoc tools to pull the information from the python package's source code. The issue with this is that the default "Edit this page" link in the pydata-sphinx-theme points to where the API doc file would be if it was committed to the repository. Since they aren't you get a 404.

I've hacked something together that seems to work, but wondering if anyone here had suggestions to make it better using either smarter jinja2 tips or features in the theme that I'm not aware of. You can find all the details here: https://github.com/vispy/vispy/pull/2220

But the main context changes make it pretty obvious what I'm doing:

html_context = {
    "github_user": "vispy",
    "github_repo": "vispy",
    "github_version": "main",
    "doc_path": "doc",
    "edit_page_url_template": "{{ vispy_custom_edit_url(github_user, github_repo, github_version, doc_path, file_name, default_edit_page_url_template) }}",
    "default_edit_page_url_template": "https://github.com/{github_user}/{github_repo}/edit/{github_version}/{doc_path}{file_name}",
    "vispy_custom_edit_url": _custom_edit_url,
}

djhoese avatar Sep 24 '21 19:09 djhoese

Hmm just a quick thought, if the main thing you want to do is prevent the button on some pages, could you just a very short JavaScript snipped that checks the current url and removed the button if it's a part of some pages?

choldgraf avatar Sep 24 '21 20:09 choldgraf

I could, but in the best case I don't want to hide/remove it but rather update the URL to point to a different location (python source file instead of .rst doc file).

djhoese avatar Sep 24 '21 20:09 djhoese

I have a slightly different approach:

I am making a documentation for a platform that use many modules coming from different repositories. the doc page thus lives in these repositories and I simply add it from github with a urlretreive in my conf.py.

as you @djhoese I end up with "edit this page" btn that doesn't point to the correct location and that would be super nice if I was able to customize it.

12rambau avatar Sep 30 '21 09:09 12rambau

@12rambau one "workaround" for your situation is that you could create git submodules for those other repositories in your "main" repository. That way those files still "live" in your main repository even though they are controlled/versioned in the sub-repositories.

djhoese avatar Sep 30 '21 13:09 djhoese

I'll have a look, I'm not really using the sub-module git fonctionnality, but I'll stay tuned in htis thread for the customization

12rambau avatar Sep 30 '21 14:09 12rambau

Git submodules are 50% good and 50% bad. In your case it may make things easier. In the vispy project I got annoyed by the single git submodule we had for our docs (one code repos with one doc repos) so I just moved the doc repository content into the main repository.

If you want to see one way of working around the issue I had see the PR I referenced for vispy linked above. It has been merged and seems to be working fine.

djhoese avatar Sep 30 '21 14:09 djhoese

@djhoese I didn't managed to use Git submodules and lost myself in the documentation. At least now I know it exists. Instead I decided to build a custom directive to overwrite the link via JS. here is my code if your are interested:

# -*- coding: utf-8 -*-

"""
ReST directive for dynamically change the value of the "edit this page btn". only compatblie with the current theme.
The directive require the complete raw file path (from github).
Example::
    .. custom-edit:: https://raw.githubusercontent.com/openforis/sepal-doc/custom_edit/README.rst
"""

from docutils import nodes
from docutils.parsers.rst import Directive, directives

class CustomEdit(Directive):
    has_content = False
    required_arguments = 1
    optional_arguments = 0
    final_argument_whitespace = False
    option_spec = {}
    html = """
    <script>
        var div = document.getElementsByClassName("tocsection editthispage")[0];
        var link = div.getElementsByTagName("a")[0];
        link.href = "{}";
    </script>
    """
    
    def run(self):
        
        # get the raw link 
        raw_link = directives.uri(self.arguments[0])
        
        # transform it into an edit link 
        raw = "raw.githubusercontent.com"
        github = "github.com"
        edit = "edit"
        list_ = raw_link.replace(raw, github).split("/")
        list_.insert(5, edit)
        link = "/".join(list_)
        
        return [nodes.raw('', self.html.format(link), format='html')]
    
def setup(builder):
    directives.register_directive('custom-edit', CustomEdit)

sorry for the noise, I assume you were expecting something more systematic but I least if anyone needs it, it's here...

12rambau avatar Oct 11 '21 17:10 12rambau