Skip to content

Commit

Permalink
Merge pull request #41 from ru-fu/DOCPR519-contributors
Browse files Browse the repository at this point in the history
Add contributor listing
  • Loading branch information
ru-fu authored Jul 16, 2024
2 parents 294b52b + 26921eb commit 86ddc05
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 6 deletions.
74 changes: 69 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Add `related-links` to your extensions list in `conf.py` to enable the extension

extensions = [
(...),
 "related-links"
 "canonical.related-links"
]

If you want to add Discourse links, you must also configure the prefix for your Discourse instance in the `html_context` variable:
Expand Down Expand Up @@ -135,7 +135,7 @@ Add `youtube-links` to your extensions list in `conf.py` to enable the extension

extensions = [
(...),
 "youtube-links"
 "canonical.youtube-links"
]

#### Style the output
Expand Down Expand Up @@ -185,7 +185,7 @@ Add `config-options` to your extensions list in `conf.py` to enable the extensio

extensions = [
(...),
"config-options"
"canonical.config-options"
]

#### Style the output
Expand Down Expand Up @@ -259,7 +259,7 @@ Add `terminal-output` to your extensions list in `conf.py` to enable the extensi

extensions = [
(...),
 "terminal-output"
 "canonical.terminal-output"
]

#### Style the output
Expand Down Expand Up @@ -316,7 +316,7 @@ Add `filtered-toc` to your extensions list in `conf.py` to enable the extension:

extensions = [
(...),
 "filtered-toc"
 "canonical.filtered-toc"
]

#### Configure the filters
Expand Down Expand Up @@ -357,3 +357,67 @@ Get support <:external:/support>

In this case, all three topics would be included by default.
When setting `toc_filter_exclude = ['draft','internal']`, only `Get support` would be included.

### Contributor listing

This extension allows adding a link that displays all contributors for a page.
The contributors are retrieved from the Git history of each file.
The link can be displayed at any place in the output by adapting the Sphinx template.

#### Enable the extension

Add `canonical.contributor-listing` to your extensions list in `conf.py` to enable the extension:

extensions = [
(...),
 "canonical.contributor-listing"
]

You can then control whether contributors are displayed by setting the `display_contributors` field in the `html_context` variable:

html_context = {
(...),
"display_contributors": True,
}

You can configure a time frame for retrieving contributors by specifying a value for `display_contributors_since`:

html_context = {
(...),
"display_contributors_since": "3 months",
}

#### Add contributor link to the template

The extension provides a `get_contributors_for_file` function that can be used in your template.
This function returns an alphabetical list of tuples that contain the name of the contributor and the link to their latest commit to the file.

For example, to include the contributor link in your template based on the Furo theme, place code similar to the following at an appropriate location in your `_templates/footer.html` file:

```
{% if display_contributors and pagename and page_source_suffix %}
{% set contributors = get_contributors_for_file(pagename, page_source_suffix) %}
{% if contributors %}
{% if contributors | length > 1 %}
<a class="display-contributors">Thanks to the {{ contributors |length }} contributors!</a>
{% else %}
<a class="display-contributors">Thanks to our contributor!</a>
{% endif %}
<div id="overlay"></div>
<ul class="all-contributors">
{% for contributor in contributors %}
<li>
<a href="{{ contributor[1] }}" class="contributor">{{ contributor[0] }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
```

See the [Sphinx documentation](https://www.sphinx-doc.org/en/master/templating.html#jinja-sphinx-templating-primer) for information on how templating works in Sphinx.

#### Style the output

The extension comes with a CSS file that is suitable for the template example as given above.
You can override these styles or define your own, depending on the theme and template that you use.
81 changes: 81 additions & 0 deletions canonical-sphinx-extensions/contributor-listing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from git import Repo, InvalidGitRepositoryError
from sphinx.util import logging
import os
from . import common

logger = logging.getLogger(__name__)


def setup(app):
app.connect("html-page-context", setup_func)

common.add_css(app, "contributors.css")
common.add_js(app, "contributors.js")

return {"version": "1.0.0",
"parallel_read_safe": True,
"parallel_write_safe": True}


def setup_func(app, pagename, templatename, context, doctree):
def get_contributors_for_file(pagename, page_source_suffix):

if (
"display_contributors" not in context
or "github_folder" not in context
or "github_url" not in context
):
return []

if context["display_contributors"]:
filename = f"{pagename}{page_source_suffix}"
paths = context["github_folder"][1:] + filename

try:
repo = Repo(".")
except InvalidGitRepositoryError:
cwd = os.getcwd()
ghfolder = context["github_folder"][:-1]
if ghfolder and cwd.endswith(ghfolder):
repo = Repo(cwd.rpartition(ghfolder)[0])
else:
logger.warning(
"The local Git repository could not be found."
)
return

since = None

if (
"display_contributors_since" in context
and context["display_contributors_since"]
and context["display_contributors_since"].strip()
):
since = context["display_contributors_since"]

commits = repo.iter_commits(paths=paths, since=since)

contributors_dict = {}
for commit in commits:
contributor = commit.author.name
if (
contributor not in contributors_dict
or commit.committed_date >
contributors_dict[contributor]["date"]
):
contributors_dict[contributor] = {
"date": commit.committed_date,
"sha": commit.hexsha,
}
# github_page contains the link to the contributor's latest commit
contributors_list = [
(name, f"{context['github_url']}/commit/{data['sha']}")
for name, data in contributors_dict.items()
]

return sorted(contributors_list)

else:
return []

context["get_contributors_for_file"] = get_contributors_for_file
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.display-contributors {
color: var(--color-sidebar-link-text);
cursor: pointer;
}
.all-contributors {
display: none;
z-index: 55;
list-style: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 200px;
height: 200px;
overflow-y: scroll;
margin: auto;
padding: 0;
background: var(--color-background-primary);
scrollbar-color: var(--color-foreground-border) transparent;
scrollbar-width: thin;
}

.all-contributors li:hover {
background: var(--color-sidebar-item-background--hover);
width: 100%;
}

.all-contributors li a{
color: var(--color-sidebar-link-text);
padding: 1rem;
display: inline-block;
}

#overlay {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 2;
cursor: pointer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
$(document).ready(function() {
$(document).on("click", function () {
$(".all-contributors").hide();
$("#overlay").hide();
});

$('.display-contributors').click(function(event) {
$('.all-contributors').toggle();
$("#overlay").toggle();
event.stopPropagation();
});
})
1 change: 1 addition & 0 deletions canonical-sphinx-extensions/contributor-listing/common.py
4 changes: 3 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = canonical-sphinx-extensions
version = 0.0.22
version = 0.0.23
author = Ruth Fuchss
author_email = [email protected]
description = A collection of Sphinx extensions used by Canonical documentation
Expand All @@ -22,6 +22,7 @@ packages =
canonical.terminal-output
filtered-toc
canonical.filtered-toc
canonical.contributor-listing
package_dir =
canonical = canonical-sphinx-extensions
= canonical-sphinx-extensions
Expand All @@ -31,6 +32,7 @@ install_requires =
requests
beautifulsoup4
docutils
gitpython

[options.package_data]
* = _static/*

0 comments on commit 86ddc05

Please sign in to comment.