2025-09-01 18:28:23 +02:00
{% extends 'base.html.twig' %}
{% block title %} Pages Wiki OSM {% endblock %}
{% block body %}
<div class="container mt-4">
{% include 'admin/_wiki_navigation.html.twig' %}
<h1>Pages Wiki OpenStreetMap</h1>
<p class="lead">Outil de qualité des des pages wiki OpenStreetMap en français et en anglais pour les clés OSM
les plus utilisées.
<a href="https://forum.openstreetmap.fr/t/fabriquer-un-outil-de-qualite-pour-le-wiki-osm/36814">
Venez discuter QualiWiki sur le forum
</a>
</p>
<div class="card mb-4">
<div class="card-header">
<h2>Liste des pages wiki</h2>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th rowspan="2">Image</th>
<th rowspan="2">Clé</th>
<th colspan="4" class="text-center">Différences FR vs EN</th>
<th rowspan="2" class="text-center">Score de<br>décrépitude</th>
<th rowspan="2" class="text-center">Liens</th>
</tr>
<tr>
<th class="text-center">Sections</th>
<th class="text-center">Mots</th>
<th class="text-center">Liens</th>
<th class="text-center">Images</th>
</tr>
</thead>
<tbody>
{% for key , languages in wiki_pages %}
{% if languages [ 'en' ] is defined and languages [ 'fr' ] is defined %}
<tr>
<td>
<img src=" {{ languages [ 'en' ] .description_img_url }} " alt="image"
style="height: 2rem;">
</td>
<td>
<strong> {{ key }} </strong>
</td>
{% set diff = page_differences [ key ] %}
<td class="text-center">
{% if diff .section_diff > 0 %}
<span class="badge bg-success"> {{ diff .section_diff_formatted }} </span>
{% elseif diff .section_diff < 0 %}
<span class="badge bg-danger"> {{ diff .section_diff_formatted }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
</td>
<td class="text-center">
{% if diff .word_diff > 0 %}
<span class="badge bg-success"> {{ diff .word_diff_formatted }} </span>
{% elseif diff .word_diff < 0 %}
<span class="badge bg-danger"> {{ diff .word_diff_formatted }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
</td>
<td class="text-center">
{% if diff .link_diff > 0 %}
<span class="badge bg-success"> {{ diff .link_diff_formatted }} </span>
{% elseif diff .link_diff < 0 %}
<span class="badge bg-danger"> {{ diff .link_diff_formatted }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
</td>
<td class="text-center">
{% if diff .media_diff > 0 %}
<span class="badge bg-success"> {{ diff .media_diff_formatted }} </span>
{% elseif diff .media_diff < 0 %}
<span class="badge bg-danger"> {{ diff .media_diff_formatted }} </span>
{% else %}
<span class="badge bg-secondary">0</span>
{% endif %}
</td>
<td class="text-center">
{% set score = languages [ 'en' ] .staleness_score | default ( 0 ) %}
{% if score > 5 0 %}
<span class="badge bg-danger"> {{ score }} </span>
{% elseif score > 2 0 %}
<span class="badge bg-warning text-dark"> {{ score }} </span>
{% else %}
<span class="badge bg-success"> {{ score }} </span>
{% endif %}
</td>
<td class="text-center">
<div class="btn-group" role="group">
<a href=" {{ languages [ 'en' ] .url }} " target="_blank"
class="btn btn-sm btn-outline-primary" title="Version anglaise">
<i class="bi bi-translate"></i> EN
</a>
<a href=" {{ languages [ 'fr' ] .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version française">
<i class="bi bi-translate"></i> FR
</a>
<a href=" {{ path ( 'app_admin_wiki_compare' , { 'key' : key } ) }} "
class="btn btn-sm btn-outline-secondary" title="Comparer les versions">
<i class="bi bi-arrows-angle-expand"></i> Comparer
</a>
</div>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% if missing_translations | length > 0 %}
<div class="card mb-4">
<div class="card-header bg-warning text-dark">
<h2>Pages manquantes en français ( {{ missing_translations | length }} )</h2>
</div>
<div class="card-body">
<p>Ces pages wiki ont une version anglaise mais pas de traduction française.</p>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Clé</th>
<th>Sections</th>
<th>Mots</th>
<th>Liens</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for key , page in missing_translations %}
<tr>
<td><strong> {{ key }} </strong></td>
<td> {{ page .sections }} </td>
<td> {{ page .word_count }} </td>
<td> {{ page .link_count }} </td>
<td class="text-center">
<div class="btn-group" role="group">
<a href=" {{ page .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version anglaise">
<i class="bi bi-flag-fill"></i> EN
</a>
<a href=" {{ path ( 'app_admin_wiki_create_french' , { 'key' : key } ) }} "
class="btn btn-sm btn-success"
title="Créer une traduction française">
<i class="bi bi-plus-circle"></i> Traduire
</a>
{# <a href="{{ path('app_admin_wiki_compare', {'key': key}) }}" #}
{# class="btn btn-sm btn-outline-secondary" #}
{# title="Voir les détails et comparer"> #}
{# <i class="bi bi-arrows-angle-expand"></i> Comparer #}
{# </a> #}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
{% if specific_pages is defined and specific_pages | length > 0 %}
<div class="card mb-4">
<div class="card-header bg-primary text-white">
<h2>Pages spécifiques ( {{ specific_pages | length }} )</h2>
</div>
<div class="card-body">
<p>Ces pages wiki sont des pages spécifiques qui ont été sélectionnées pour une comparaison
particulière.</p>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Titre</th>
<th>Raison</th>
<th>Score de décrépitude</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for page in specific_pages %}
<tr>
<td>
<div class="d-flex align-items-center">
{% if page .en_page .description_img_url is defined and page .en_page .description_img_url %}
<div class="me-3">
<img src=" {{ page .en_page .description_img_url }} "
alt=" {{ page .key }} "
style="max-width: 80px; max-height: 60px; object-fit: contain;">
</div>
{% endif %}
<div>
<strong> {{ page .key }} </strong>
<span class="badge bg-primary">Spécifique</span>
</div>
</div>
</td>
<td>
{{ page .reason }}
</td>
<td>
{% if page .staleness_score is defined %}
<div class="progress" style="height: 20px;">
{% set score_class = page .staleness_score > 7 0 ? 'bg-danger' : ( page .staleness_score > 4 0 ? 'bg-warning' : 'bg-success' ) %}
<div class="progress-bar {{ score_class }} " role="progressbar"
style="width: {{ page .staleness_score }} %;"
aria-valuenow=" {{ page .staleness_score }} "
aria-valuemin="0"
aria-valuemax="100">
{{ page .staleness_score }}
</div>
</div>
{% else %}
<span class="text-muted">Non disponible</span>
{% endif %}
</td>
<td class="text-center">
<div class="btn-group" role="group">
<a href=" {{ page .en_page .url }} " target="_blank"
class="btn btn-sm btn-outline-primary" title="Version anglaise">
<i class="bi bi-translate"></i> EN
</a>
{% if page .fr_page %}
<a href=" {{ page .fr_page .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version française">
<i class="bi bi-translate"></i> FR
</a>
<a href=" {{ path ( 'app_admin_wiki_compare' , { 'key' : page .key } ) }} "
class="btn btn-sm btn-outline-secondary"
title="Comparer les versions">
<i class="bi bi-arrows-angle-expand"></i> Comparer
</a>
{% else %}
<a href=" {{ path ( 'app_admin_wiki_create_french' , { 'key' : page .key } ) }} "
class="btn btn-sm btn-success"
title="Créer une traduction française">
<i class="bi bi-plus-circle"></i> Traduire
</a>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
{% if pages_unavailable_in_english | length > 0 %}
<div class="card mb-4">
<div class="card-header bg-info text-dark">
<h2>Pages françaises non disponibles en Anglais ( {{ pages_unavailable_in_english | length }} )</h2>
</div>
<div class="card-body">
<p>Ces pages wiki ont une version française mais pas de traduction anglaise.</p>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Titre</th>
2025-09-03 17:18:21 +02:00
{# <th>Score de décrépitude</th>#}
2025-09-01 18:28:23 +02:00
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for page in pages_unavailable_in_english %}
<tr>
<td>
<div class="d-flex align-items-center">
{% if page .description_img_url is defined and page .description_img_url %}
<div class="me-3">
<img src=" {{ page .description_img_url }} " alt=" {{ page .title }} "
style="max-width: 80px; max-height: 60px; object-fit: contain;">
</div>
{% endif %}
<div>
<strong> {{ page .title }} </strong>
</div>
</div>
</td>
2025-09-03 17:18:21 +02:00
{# <td>#}
{# {% if page.outdatedness_score is defined %}#}
{# <div class="progress" style="height: 20px;">#}
{# {% set score_class = page.outdatedness_score > 70 ? 'bg-danger' : (page.outdatedness_score > 40 ? 'bg-warning' : 'bg-success') %}#}
{# <div class="progress-bar {{ score_class }}" role="progressbar"#}
{# style="width: {{ page.outdatedness_score }}%;"#}
{# aria-valuenow="{{ page.outdatedness_score }}"#}
{# aria-valuemin="0"#}
{# aria-valuemax="100">#}
{# {{ page.outdatedness_score }}#}
{# </div>#}
{# </div>#}
{# {% else %}#}
{# <span class="text-muted">Non disponible</span>#}
{# {% endif %}#}
{# </td>#}
2025-09-01 18:28:23 +02:00
<td class="text-center">
<div class="btn-group" role="group">
<a href=" {{ page .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version française">
<i class="bi bi-flag-fill"></i> FR
</a>
{% set en_url = page .url | replace ( { 'FR:' : '' } ) %}
2025-09-03 17:18:21 +02:00
<a href="https://wiki.openstreetmap.org/w/index.php?title= {{ page .key }} &action=edit" target="_blank" class="btn btn-sm btn-outline-primary" title="Créer la version anglaise">
2025-09-01 18:28:23 +02:00
title="Créer une traduction anglaise">
<i class="bi bi-translate"></i> créer EN
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
{% if newly_created_pages is defined and newly_created_pages | length > 0 %}
<div class="card mb-4">
<div class="card-header bg-success text-white">
<h2>Pages françaises récemment créées ( {{ newly_created_pages | length }} )</h2>
</div>
<div class="card-body">
<p>Ces pages wiki françaises ont été récemment créées et étaient auparavant dans la liste des pages
non disponibles en français.</p>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Titre</th>
<th>Version anglaise</th>
<th>Date de création</th>
<th>Créée par</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for page in newly_created_pages %}
<tr>
<td>
<div class="d-flex align-items-center">
<div>
<strong> {{ page .title }} </strong>
<span class="badge bg-success">Nouvelle</span>
</div>
</div>
</td>
<td>
{{ page .en_title }}
</td>
<td>
{{ page .created_at }}
</td>
<td>
{{ page .created_by }}
</td>
<td class="text-center">
<div class="btn-group" role="group">
<a href=" {{ page .url }} " target="_blank"
class="btn btn-sm btn-outline-info" title="Version française">
<i class="bi bi-flag-fill"></i> FR
</a>
<a href=" {{ page .en_url }} " target="_blank"
class="btn btn-sm btn-outline-primary" title="Version anglaise">
<i class="bi bi-flag-fill"></i> EN
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<p>
le score de fraîcheur prend en compte d'avantage la différence entre le nombre de mots que l'ancienneté de
modification.
On compte aussi le nombre de sections et de liens.
</p>
<div class="mt-3">
<div class="card mb-4">
<div class="card-header">
<h2>Graphe de décrépitude</h2>
</div>
<div class="card-body">
<canvas id="decrepitudeChart" height="300"></canvas>
</div>
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
{{ parent ( ) }}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Collect data from the table
const labels = [];
const scores = [];
const colors = [];
{% for key , languages in wiki_pages %}
{% if languages [ 'en' ] is defined and languages [ 'fr' ] is defined %}
labels.push(" {{ key }} ");
{% set score = languages [ 'en' ] .staleness_score | default ( 0 ) %}
scores.push( {{ score }} );
// Set color based on score
{% if score > 5 0 %}
colors.push('rgba(220, 53, 69, 0.7)'); // danger
{% elseif score > 2 0 %}
colors.push('rgba(255, 193, 7, 0.7)'); // warning
{% else %}
colors.push('rgba(25, 135, 84, 0.7)'); // success
{% endif %}
{% endif %}
{% endfor %}
// Sort data by score (descending)
const indices = Array.from(Array(scores.length).keys())
.sort((a, b) => scores[b] - scores[a]);
const sortedLabels = indices.map(i => labels[i]);
const sortedScores = indices.map(i => scores[i]);
const sortedColors = indices.map(i => colors[i]);
// Limit to top 20 pages for readability
const displayLimit = 20;
const displayLabels = sortedLabels.slice(0, displayLimit);
const displayScores = sortedScores.slice(0, displayLimit);
const displayColors = sortedColors.slice(0, displayLimit);
// Create the chart
const ctx = document.getElementById('decrepitudeChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: displayLabels,
datasets: [ {
label: 'Score de décrépitude',
data: displayScores,
backgroundColor: displayColors,
borderColor: displayColors.map(c => c.replace('0.7', '1')),
borderWidth: 1
}]
},
options: {
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: function (context) {
return `Score: $ { context.raw}`;
}
}
}
},
scales: {
x: {
beginAtZero: true,
2025-09-03 17:18:21 +02:00
// max: 100,
2025-09-01 18:28:23 +02:00
title: {
display: true,
2025-09-03 17:18:21 +02:00
text: 'Score de décrépitude'
2025-09-01 18:28:23 +02:00
}
}
}
}
});
});
</script>
{% endblock %}