Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,11 @@ repos:
- id: deptry
args: [".", "--per-rule-ignores", "DEP002=python-docs-theme", "--package-module-name-map", "gitpython=git,sphinx-lint=sphinxlint"]

- repo: https://github.com/djlint/djLint
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a dead project, no releases since 2024, are there no alternatives? It seems to work alright currently.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My quick research implied it is mature and stable, and there's no better alternative. It looks stagnant on PyPI, but the repo still receives commits. The GitHub project had updates as recently as Nov 2025, and the docs were updated in 2026, which indicates some ongoing maintenance.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact they have Renovate set up to do updates multiple times a day, and automerge them without human review, is a bit odd:

https://github.com/djlint/djLint/commits/master/

Also no cooldown, so a very good way to be among the very first to be exposed to a new vulnerability...

https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns

We're on a pinned tag not on master, which helps, but tags are immutable and a vuln could rewrite the tags.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've opened an issue with a suggestion to add the cooldown: djlint/djLint#1783.

It's only library like that that offers an autoformatter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing as the whole litellm thing happened the day after Hugo’s message, I think we should wait with this PR till they make such changes.

rev: v1.36.4
hooks:
- id: djlint-reformat-jinja
- id: djlint-jinja

ci:
autoupdate_schedule: quarterly
2 changes: 2 additions & 0 deletions djlint.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignore="J018"
indent=2
9 changes: 9 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ body {
outline-offset: 8px;
}

.navbar-brand a span {
font-size: 1.25rem;
font-weight: 700;
color: #4a4a4a;
}

.nav-link svg {
vertical-align: middle;
margin-top: -4.5px;
Expand Down Expand Up @@ -102,6 +108,9 @@ ul.links-row li:not(:first-child)::before {
content: '•';
margin-right: 0.5ch;
}
ul.links-row a {
color: #1178cc;
}

/* ------------------------------ Index ------------------------------------- */

Expand Down
175 changes: 94 additions & 81 deletions templates/base.html.jinja
Original file line number Diff line number Diff line change
@@ -1,70 +1,87 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Python Documentation Translation Dashboard">

<title>Python Docs Translation Dashboard</title>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin="anonymous">
<link href="style.css?version=1" rel="stylesheet">
</head>

<body>
<header>
<nav class="navbar navbar-expand-md fixed-top">
<div class="container-fluid">
<div class="navbar-brand">
<a href="./">
<img src="logo.png" style="height: 2rem;" alt="Python logo">
<span style="font-size: 1.25rem; font-weight: 700; color: #4a4a4a">Translation Dashboard</span>
</a>
</div>

<div class="navbar-light bg-light">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>

<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="build-details.html">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-card-text" viewBox="0 0 16 16">
<path d="M14.5 3a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2z"></path>
<path d="M3 5.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M3 8a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9A.5.5 0 0 1 3 8m0 2.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5"></path>
</svg>
Build details
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description"
content="Python Documentation Translation Dashboard">
<meta name="keywords" content="python,docs,translations,progress,status">
<title>Python Docs Translation Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin="anonymous">
<link href="style.css?version=2" rel="stylesheet">
</head>
<body>
<header>
<nav class="navbar navbar-expand-md fixed-top">
<div class="container-fluid">
<div class="navbar-brand">
<a href="./">
<img src="logo.png" alt="Python logo" width="31.07" height="32">
<span>Translation Dashboard</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://devguide.python.org/documentation/translations/translating/" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"></path>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"></path>
</svg>
Translating
</a>
</li>
</ul>
</div>
</div>
</nav>
</header>

<main role="main">
{% block main %}
{% endblock %}
</main>

</body>

<script>
</div>
<div class="navbar-light bg-light">
<button class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="build-details.html">
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-card-text"
viewBox="0 0 16 16">
<path d="M14.5 3a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2z">
</path>
<path d="M3 5.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M3 8a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9A.5.5 0 0 1 3 8m0 2.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5">
</path>
</svg>
Build details
</a>
</li>
<li class="nav-item">
<a class="nav-link"
href="https://devguide.python.org/documentation/translations/translating/"
target="_blank">
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-box-arrow-up-right"
viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5">
</path>
<path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z">
</path>
</svg>
Translating
</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<main role="main">
{% block main %}
{% endblock main %}
</main>
</body>
<script>
function padnavbar() {
const navbar = document.querySelector('.navbar.fixed-top');
if (navbar) {
Expand All @@ -73,20 +90,16 @@
}
window.addEventListener('load', padnavbar);
window.addEventListener('resize', padnavbar);
</script>

<script src="https://code.jquery.com/jquery-4.0.0.slim.min.js"
integrity="sha256-8DGpv13HIm+5iDNWw1XqxgFB4mj+yOKFNb+tHBZOowc="
crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
crossorigin="anonymous">
</script>

{# Plausible analytics #}
<script defer data-domain="translations.python.org" src="https://analytics.python.org/js/script.outbound-links.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
{% block extrascript %}
{% endblock %}
</script>
<script src="https://code.jquery.com/jquery-4.0.0.slim.min.js" integrity="sha256-8DGpv13HIm+5iDNWw1XqxgFB4mj+yOKFNb+tHBZOowc=" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous">
</script>
{# Plausible analytics #}
<script defer
data-domain="translations.python.org"
src="https://analytics.python.org/js/script.outbound-links.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
{% block extrascript %}
{% endblock extrascript %}
</html>
82 changes: 41 additions & 41 deletions templates/build-details.html.jinja
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
{% extends "base.html.jinja" %}

{% block main %}
<table>
<thead>
<tr>
<th>language</th>
<th>branch</th>
<th>last updated</th>
<th>build warnings*</th>
<th>lint failures</th>
</tr>
</thead>
<tbody>
{% for project, metadata in build_details | sort(attribute='0.completion') | reverse %}
{% if project.repository %}
<tr>
<td data-label="language">{{ project.language.name }} ({{ project.language.code }})</td>
<td data-label="branch">{{ project.branch }}</td>
<td data-label="updated">{{ metadata[2].strftime('%Y/%m/%d %T') if metadata[2] else '' }}</td>
<td data-label="warnings">
{% if project.completion %}
<a href="warnings-{{ project.language.code }}.txt">{{ metadata[0] }}</a>
{% else %}
{{ metadata[0] }}
{% endif %}
</td>
<td data-label="lint">
{% if project.completion %}
<a href="warnings-lint-{{ project.language.code }}.txt">{{ metadata[1] }}</a>
{% else %}
{{ metadata[1] }}
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>

<p>* number of Sphinx build process warnings</p>
<p>Last updated at {{ generation_time.strftime('%A, %-d %B %Y, %-H:%M:%S %Z') }} (in {{ duration // 60 }}:{{ "{:02}".format(duration % 60) }} minutes).</p>
{% endblock %}
<table>
<thead>
<tr>
<th>language</th>
<th>branch</th>
<th>last updated</th>
<th>build warnings*</th>
<th>lint failures</th>
</tr>
</thead>
<tbody>
{% for project, metadata in build_details | sort(attribute='0.completion') | reverse %}
{% if project.repository %}
<tr>
<td data-label="language">{{ project.language.name }} ({{ project.language.code }})</td>
<td data-label="branch">{{ project.branch }}</td>
<td data-label="updated">{{ metadata[2].strftime("%Y/%m/%d %T") if metadata[2] else '' }}</td>
<td data-label="warnings">
{% if project.completion %}
<a href="warnings-{{ project.language.code }}.txt">{{ metadata[0] }}</a>
{% else %}
{{ metadata[0] }}
{% endif %}
</td>
<td data-label="lint">
{% if project.completion %}
<a href="warnings-lint-{{ project.language.code }}.txt">{{ metadata[1] }}</a>
{% else %}
{{ metadata[1] }}
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<p>* number of Sphinx build process warnings</p>
<p>
Last updated at {{ generation_time.strftime("%A, %-d %B %Y, %-H:%M:%S %Z") }} (in {{ duration // 60 }}:{{ "{:02}".format(duration % 60) }} minutes).
</p>
{% endblock main %}
Loading
Loading