diff --git a/public/js/table-sort.js b/public/js/table-sort.js new file mode 100644 index 0000000..7957992 --- /dev/null +++ b/public/js/table-sort.js @@ -0,0 +1,91 @@ +/** + * Simple table sorting script + * Enables sorting for all tables with the class 'sortable' + */ +document.addEventListener('DOMContentLoaded', function() { + // Get all tables with the class 'table' + const tables = document.querySelectorAll('table.table'); + + // Add sortable class to all tables + tables.forEach(table => { + table.classList.add('sortable'); + }); + + // Get all sortable tables + const sortableTables = document.querySelectorAll('table.sortable'); + + sortableTables.forEach(table => { + const thead = table.querySelector('thead'); + const tbody = table.querySelector('tbody'); + const thList = thead ? thead.querySelectorAll('th') : []; + + // Add click event to each header cell + thList.forEach((th, columnIndex) => { + // Skip if the header spans multiple rows or columns + if (th.hasAttribute('rowspan') || th.hasAttribute('colspan')) { + return; + } + + // Add sort indicator and cursor style + th.style.cursor = 'pointer'; + th.innerHTML = `${th.innerHTML} `; + + // Add click event + th.addEventListener('click', () => { + const isAscending = th.classList.contains('sort-asc'); + + // Remove sort classes from all headers + thList.forEach(header => { + header.classList.remove('sort-asc', 'sort-desc'); + const indicator = header.querySelector('.sort-indicator'); + if (indicator) { + indicator.textContent = ''; + } + }); + + // Set sort direction + if (isAscending) { + th.classList.add('sort-desc'); + th.querySelector('.sort-indicator').textContent = ' ▼'; + } else { + th.classList.add('sort-asc'); + th.querySelector('.sort-indicator').textContent = ' ▲'; + } + + // Get all rows from tbody + const rows = Array.from(tbody.querySelectorAll('tr')); + + // Sort rows + rows.sort((rowA, rowB) => { + const cellA = rowA.querySelectorAll('td')[columnIndex]; + const cellB = rowB.querySelectorAll('td')[columnIndex]; + + if (!cellA || !cellB) { + return 0; + } + + const valueA = cellA.textContent.trim(); + const valueB = cellB.textContent.trim(); + + // Check if values are numbers + const numA = parseFloat(valueA); + const numB = parseFloat(valueB); + + if (!isNaN(numA) && !isNaN(numB)) { + return isAscending ? numB - numA : numA - numB; + } + + // Sort as strings + return isAscending + ? valueB.localeCompare(valueA, undefined, {sensitivity: 'base'}) + : valueA.localeCompare(valueB, undefined, {sensitivity: 'base'}); + }); + + // Reorder rows in the table + rows.forEach(row => { + tbody.appendChild(row); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/src/Controller/WikiController.php b/src/Controller/WikiController.php index f9166f2..6f7f501 100644 --- a/src/Controller/WikiController.php +++ b/src/Controller/WikiController.php @@ -8,6 +8,44 @@ use Symfony\Component\Routing\Annotation\Route; class WikiController extends AbstractController { + /** + * Displays the evolution of decrepitude scores from JSON history data + */ + #[Route('/wiki/decrepitude', name: 'app_admin_wiki_decrepitude')] + public function decrepitudeScores(): Response + { + $outdatedPagesFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/outdated_pages.json'; + $histogramFile = $this->getParameter('kernel.project_dir') . '/wiki_compare/staleness_histogram.png'; + + $regularPages = []; + $specificPages = []; + $lastUpdated = null; + $histogramExists = file_exists($histogramFile); + + if (file_exists($outdatedPagesFile)) { + $outdatedPagesData = json_decode(file_get_contents($outdatedPagesFile), true); + + if (isset($outdatedPagesData['regular_pages']) && is_array($outdatedPagesData['regular_pages'])) { + $regularPages = $outdatedPagesData['regular_pages']; + } + + if (isset($outdatedPagesData['specific_pages']) && is_array($outdatedPagesData['specific_pages'])) { + $specificPages = $outdatedPagesData['specific_pages']; + } + + if (isset($outdatedPagesData['last_updated'])) { + $lastUpdated = $outdatedPagesData['last_updated']; + } + } + + return $this->render('admin/wiki_decrepitude.html.twig', [ + 'regular_pages' => $regularPages, + 'specific_pages' => $specificPages, + 'last_updated' => $lastUpdated, + 'histogram_exists' => $histogramExists, + 'json_exists' => file_exists($outdatedPagesFile) + ]); + } /** * Detects incorrect heading hierarchies in a list of sections * For example, h4 directly under h2 without h3 in between @@ -283,9 +321,25 @@ class WikiController extends AbstractController $this->addFlash('error', 'Impossible de générer le fichier des pages sans traduction.'); } } + + // Remove duplicates based on page title + $uniquePages = []; + $seenTitles = []; + + foreach ($untranslatedPages as $page) { + if (!isset($seenTitles[$page['title']])) { + $seenTitles[$page['title']] = true; + $uniquePages[] = $page; + } + } + + // Sort pages by title + usort($uniquePages, function($a, $b) { + return strcasecmp($a['title'], $b['title']); + }); return $this->render('admin/wiki_missing_translations.html.twig', [ - 'untranslated_pages' => $untranslatedPages, + 'untranslated_pages' => $uniquePages, 'last_updated' => $lastUpdated ]); } @@ -717,7 +771,7 @@ class WikiController extends AbstractController public function createFrench(string $key): Response { // Construct the URLs for the English page and the French page creation form - $englishUrl = "https://wiki.openstreetmap.org/wiki/Key:{$key}"; + $englishUrl = "https://wiki.openstreetmap.org/wiki/{$key}"; $frenchEditUrl = "https://wiki.openstreetmap.org/w/index.php?title=FR:{$key}&action=edit"; // Fetch the HTML content of the English page using wiki_compare.py @@ -910,7 +964,7 @@ EOT; $pageDifferences = []; $pagesUnavailableInEnglish = []; - // First pass: collect all staleness scores to find min and max + // Collect all staleness scores for statistics $stalenessScores = []; foreach ($csvData as $row) { $page = array_combine($headers, $row); @@ -919,27 +973,40 @@ EOT; } } - // Find min and max scores for normalization - $minScore = !empty($stalenessScores) ? min($stalenessScores) : 0; - $maxScore = !empty($stalenessScores) ? max($stalenessScores) : 100; + // Calculate statistics + $stalenessStats = [ + 'count' => count($stalenessScores), + 'min' => !empty($stalenessScores) ? min($stalenessScores) : 0, + 'max' => !empty($stalenessScores) ? max($stalenessScores) : 0, + 'mean' => 0, + 'std_dev' => 0 + ]; + + // Calculate mean + if (!empty($stalenessScores)) { + $stalenessStats['mean'] = array_sum($stalenessScores) / count($stalenessScores); + + // Calculate standard deviation + $variance = 0; + foreach ($stalenessScores as $score) { + $variance += pow($score - $stalenessStats['mean'], 2); + } + $stalenessStats['std_dev'] = sqrt($variance / count($stalenessScores)); + } + + // Round statistics to 2 decimal places + $stalenessStats['mean'] = round($stalenessStats['mean'], 2); + $stalenessStats['std_dev'] = round($stalenessStats['std_dev'], 2); - // Second pass: process pages and normalize scores + // Process pages - use absolute values without normalization foreach ($csvData as $row) { $page = array_combine($headers, $row); - // Normalize staleness score to 0-100 range (0 = best, 100 = worst) + // Use absolute values of staleness score without normalization if (isset($page['staleness_score']) && is_numeric($page['staleness_score'])) { - $originalScore = (float)$page['staleness_score']; - - // Avoid division by zero - if ($maxScore > $minScore) { - $normalizedScore = ($originalScore - $minScore) / ($maxScore - $minScore) * 100; - } else { - $normalizedScore = 50; // Default to middle value if all scores are the same - } - + $page['staleness_score'] = abs((float)$page['staleness_score']); // Round to 2 decimal places - $page['staleness_score'] = round($normalizedScore, 2); + $page['staleness_score'] = round($page['staleness_score'], 2); } $wikiPages[$page['key']][$page['language']] = $page; @@ -953,6 +1020,18 @@ EOT; } + // Prepare arrays for statistics + $stats = [ + 'en_sections' => [], + 'fr_sections' => [], + 'en_words' => [], + 'fr_words' => [], + 'en_links' => [], + 'fr_links' => [], + 'en_media' => [], + 'fr_media' => [] + ]; + // Calculate differences between English and French versions foreach ($wikiPages as $key => $languages) { if (isset($languages['en']) && isset($languages['fr'])) { @@ -977,6 +1056,39 @@ EOT; 'media_diff' => $mediaDiff, 'media_diff_formatted' => ($mediaDiff >= 0 ? '+' : '') . $mediaDiff, ]; + + // Collect data for statistics + $stats['en_sections'][] = (int)$en['sections']; + $stats['fr_sections'][] = (int)$fr['sections']; + $stats['en_words'][] = (int)$en['word_count']; + $stats['fr_words'][] = (int)$fr['word_count']; + $stats['en_links'][] = (int)$en['link_count']; + $stats['fr_links'][] = (int)$fr['link_count']; + $stats['en_media'][] = isset($en['media_count']) ? (int)$en['media_count'] : 0; + $stats['fr_media'][] = isset($fr['media_count']) ? (int)$fr['media_count'] : 0; + } + } + + // Calculate statistics + $wikiPagesStats = []; + foreach ($stats as $key => $values) { + if (!empty($values)) { + $mean = array_sum($values) / count($values); + + // Calculate standard deviation + $variance = 0; + foreach ($values as $value) { + $variance += pow($value - $mean, 2); + } + $stdDev = sqrt($variance / count($values)); + + $wikiPagesStats[$key] = [ + 'count' => count($values), + 'min' => min($values), + 'max' => max($values), + 'mean' => round($mean, 2), + 'std_dev' => round($stdDev, 2) + ]; } } @@ -1022,7 +1134,9 @@ EOT; 'page_differences' => $pageDifferences, 'pages_unavailable_in_english' => $pagesUnavailableInEnglish, 'specific_pages' => $specificPages, - 'newly_created_pages' => $newlyCreatedPages + 'newly_created_pages' => $newlyCreatedPages, + 'staleness_stats' => $stalenessStats, + 'wiki_pages_stats' => $wikiPagesStats ]); } @@ -1380,7 +1494,7 @@ EOT; // Create URL for new French page if it doesn't exist $createFrUrl = null; if (!$frPage) { - $createFrUrl = 'https://wiki.openstreetmap.org/wiki/FR:Key:' . $key; + $createFrUrl = 'https://wiki.openstreetmap.org/wiki/FR:' . $key; } // Format section titles for copy functionality diff --git a/templates/admin/_wiki_navigation.html.twig b/templates/admin/_wiki_navigation.html.twig index d1e3ab4..faa497c 100644 --- a/templates/admin/_wiki_navigation.html.twig +++ b/templates/admin/_wiki_navigation.html.twig @@ -51,6 +51,11 @@ Changements récents + diff --git a/templates/admin/wiki.html.twig b/templates/admin/wiki.html.twig index 6a1b31c..89c11e9 100644 --- a/templates/admin/wiki.html.twig +++ b/templates/admin/wiki.html.twig @@ -20,6 +20,31 @@
+ {% if wiki_pages_stats is defined %} +
+

Statistiques des pages wiki

+
+
+
Pages en anglais
+
    +
  • Sections : Moyenne: {{ wiki_pages_stats.en_sections.mean }}, Écart type: {{ wiki_pages_stats.en_sections.std_dev }}
  • +
  • Mots : Moyenne: {{ wiki_pages_stats.en_words.mean }}, Écart type: {{ wiki_pages_stats.en_words.std_dev }}
  • +
  • Liens : Moyenne: {{ wiki_pages_stats.en_links.mean }}, Écart type: {{ wiki_pages_stats.en_links.std_dev }}
  • +
  • Images : Moyenne: {{ wiki_pages_stats.en_media.mean }}, Écart type: {{ wiki_pages_stats.en_media.std_dev }}
  • +
+
+
+
Pages en français
+
    +
  • Sections : Moyenne: {{ wiki_pages_stats.fr_sections.mean }}, Écart type: {{ wiki_pages_stats.fr_sections.std_dev }}
  • +
  • Mots : Moyenne: {{ wiki_pages_stats.fr_words.mean }}, Écart type: {{ wiki_pages_stats.fr_words.std_dev }}
  • +
  • Liens : Moyenne: {{ wiki_pages_stats.fr_links.mean }}, Écart type: {{ wiki_pages_stats.fr_links.std_dev }}
  • +
  • Images : Moyenne: {{ wiki_pages_stats.fr_media.mean }}, Écart type: {{ wiki_pages_stats.fr_media.std_dev }}
  • +
+
+
+
+ {% endif %}
@@ -283,12 +308,13 @@ - +{# #} {% for page in pages_unavailable_in_english %} + {% if "FR:Réunions" not in page.title %} - +{# #} + {% endif %} {% endfor %}
TitreScore de décrépitudeScore de décrépitudeActions
@@ -303,22 +329,22 @@
- {% if page.outdatedness_score is defined %} -
- {% set score_class = page.outdatedness_score > 70 ? 'bg-danger' : (page.outdatedness_score > 40 ? 'bg-warning' : 'bg-success') %} -
- {{ page.outdatedness_score }} -
-
- {% else %} - Non disponible - {% endif %} -
#} +{# {% if page.outdatedness_score is defined %}#} +{#
#} +{# {% set score_class = page.outdatedness_score > 70 ? 'bg-danger' : (page.outdatedness_score > 40 ? 'bg-warning' : 'bg-success') %}#} +{#
#} +{# {{ page.outdatedness_score }}#} +{#
#} +{#
#} +{# {% else %}#} +{# Non disponible#} +{# {% endif %}#} +{#
@@ -413,6 +440,16 @@

Graphe de décrépitude

+ {% if staleness_stats is defined %} +
+ Statistiques : + Moyenne : {{ staleness_stats.mean }} | + Écart type : {{ staleness_stats.std_dev }} | + Min : {{ staleness_stats.min }} | + Max : {{ staleness_stats.max }} | + Nombre de pages : {{ staleness_stats.count }} +
+ {% endif %}
@@ -436,13 +473,19 @@ {% set score = languages['en'].staleness_score|default(0) %} scores.push({{ score }}); - // Set color based on score - {% if score > 50 %} - colors.push('rgba(220, 53, 69, 0.7)'); // danger + // Set color based on score with more nuanced intermediate colors + {% if score > 80 %} + colors.push('rgba(220, 53, 69, 0.7)'); // danger (red) + {% elseif score > 60 %} + colors.push('rgba(232, 113, 55, 0.7)'); // dark orange + {% elseif score > 40 %} + colors.push('rgba(255, 153, 0, 0.7)'); // orange {% elseif score > 20 %} - colors.push('rgba(255, 193, 7, 0.7)'); // warning + colors.push('rgba(255, 193, 7, 0.7)'); // warning (yellow) + {% elseif score > 10 %} + colors.push('rgba(140, 195, 38, 0.7)'); // light green {% else %} - colors.push('rgba(25, 135, 84, 0.7)'); // success + colors.push('rgba(25, 135, 84, 0.7)'); // success (green) {% endif %} {% endif %} {% endfor %} diff --git a/templates/admin/wiki_compare.html.twig b/templates/admin/wiki_compare.html.twig index 88be230..43f2bfb 100644 --- a/templates/admin/wiki_compare.html.twig +++ b/templates/admin/wiki_compare.html.twig @@ -112,8 +112,8 @@ fr en {% else %} - fr - en + fr + en {% endif %} @@ -738,164 +738,164 @@ {# {% endif %} #} - {#
#} - {#
#} - {#

Score de décrépitude

#} - {#
#} - {#
#} - {#

Le score de décrépitude est calculé en prenant en compte plusieurs facteurs, avec une pondération #} - {# plus importante pour la différence de nombre de mots :

#} +
+
+

Score de décrépitude

+
+
+

Le score de décrépitude est calculé en prenant en compte plusieurs facteurs, avec une pondération + plus importante pour la différence de nombre de mots :

- {#
#} - {# #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# {% for key, component in score_components %} #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# #} - {# {% endfor %} #} - {# #} - {# #} - {# #} - {# #} - {# #} - {#
FacteurValeurPoidsContribution
{{ component.description }}{{ component.value }}{{ component.weight * 100 }}%{{ component.component|round(2) }}
Score total #} - {# {% set total_score = 0 %} #} - {# {% for key, component in score_components %} #} - {# {% set total_score = total_score + component.component %} #} - {# {% endfor %} #} - {# {{ total_score|round(2) }} #} - {#
#} - {#
#} +
+ + + + + + + + + + + {% for key, component in score_components %} + + + + + + + {% endfor %} + + + + + +
FacteurValeurPoidsContribution
{{ component.description }}{{ component.value }}{{ component.weight * 100 }}%{{ component.component|round(2) }}
Score total + {% set total_score = 0 %} + {% for key, component in score_components %} + {% set total_score = total_score + component.component %} + {% endfor %} + {{ total_score|round(2) }} +
+
- {#
#} - {#

Comment interpréter ce score :

#} - {#
    #} - {#
  • Plus le score est élevé, plus la page française est considérée comme "décrépite" par rapport #} - {# à la version anglaise. #} - {#
  • #} - {#
  • La différence de nombre de mots compte pour 50% du score, car c'est l'indicateur le plus #} - {# important de la complétude de la traduction. #} - {#
  • #} - {#
  • Les différences de sections (15%), de liens (15%) et de date de modification (20%) #} - {# complètent le score. #} - {#
  • #} - {#
#} - {#
#} - {#
#} - {#
#} +
+

Comment interpréter ce score :

+
    +
  • Plus le score est élevé, plus la page française est considérée comme "décrépite" par rapport + à la version anglaise. +
  • +
  • La différence de nombre de mots compte pour 50% du score, car c'est l'indicateur le plus + important de la complétude de la traduction. +
  • +
  • Les différences de sections (15%), de liens (15%) et de date de modification (20%) + complètent le score. +
  • +
+
+
+
- {#
#} - {# #} - {# Retour à la liste des pages wiki #} - {# #} - {#
#} - {#
#} - {#
#} - {#

Comparaison des versions

#} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#

Version anglaise

#} - {#

#} - {# Dernière modification: {{ en_page.last_modified }} #} - {#

#} - {#
#} - {#
#} - {#
    #} - {#
  • #} - {# Sections #} - {# #} - {# {% if detailed_comparison.adjusted_en_section_count is defined %} #} - {# {{ detailed_comparison.adjusted_en_section_count }} #} - {# {% else %} #} - {# {{ en_page.sections }} #} - {# {% endif %} #} - {# #} - {#
  • #} - {#
  • #} - {# Mots #} - {# {{ en_page.word_count }} #} - {#
  • #} - {#
  • #} - {# Liens #} - {# {{ en_page.link_count }} #} - {#
  • #} - {#
#} - {#
#} - {# #} - {# Voir la page #} - {# #} - {# #} - {# #} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#

Version française

#} - {#

#} - {# Dernière modification: {{ fr_page.last_modified }} #} - {#

#} - {#
#} - {#
#} - {#
    #} - {#
  • #} - {# Sections #} - {# #} - {# {% if detailed_comparison.adjusted_fr_section_count is defined %} #} - {# {{ detailed_comparison.adjusted_fr_section_count }} #} - {# {% else %} #} - {# {{ fr_page.sections }} #} - {# {% endif %} #} - {# #} - {#
  • #} - {#
  • #} - {# Mots #} - {# {{ fr_page.word_count }} #} - {#
  • #} - {#
  • #} - {# Liens #} - {# {{ fr_page.link_count }} #} - {#
  • #} - {#
#} - {#
#} - {# #} - {# Voir la page #} - {# #} - {# #} - {# #} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} - {#
#} +
+ + Retour à la liste des pages wiki + +
+
+
+

Comparaison des versions

+
+
+
+
+
+
+

Version anglaise

+

+ Dernière modification: {{ en_page.last_modified }} +

+
+
+
    +
  • + Sections + + {% if detailed_comparison.adjusted_en_section_count is defined %} + {{ detailed_comparison.adjusted_en_section_count }} + {% else %} + {{ en_page.sections }} + {% endif %} + +
  • +
  • + Mots + {{ en_page.word_count }} +
  • +
  • + Liens + {{ en_page.link_count }} +
  • +
+
+ + Voir la page + + + +
+
+
+
+
+
+
+

Version française

+

+ Dernière modification: {{ fr_page.last_modified }} +

+
+
+
    +
  • + Sections + + {% if detailed_comparison.adjusted_fr_section_count is defined %} + {{ detailed_comparison.adjusted_fr_section_count }} + {% else %} + {{ fr_page.sections }} + {% endif %} + +
  • +
  • + Mots + {{ fr_page.word_count }} +
  • +
  • + Liens + {{ fr_page.link_count }} +
  • +
+
+ + Voir la page + + + +
+
+
+
+
+
+
diff --git a/templates/admin/wiki_decrepitude.html.twig b/templates/admin/wiki_decrepitude.html.twig new file mode 100644 index 0000000..5472289 --- /dev/null +++ b/templates/admin/wiki_decrepitude.html.twig @@ -0,0 +1,325 @@ +{% extends 'base.html.twig' %} + +{% block title %}Évolution des scores de décrépitude - Wiki OSM{% endblock %} + +{% block body %} +
+ {% include 'admin/_wiki_navigation.html.twig' %} + +

Évolution des scores de décrépitude

+

+ Cette page montre l'évolution des scores de décrépitude des pages wiki OpenStreetMap en français par rapport aux versions anglaises. + + Venez discuter QualiWiki sur le forum + +

+ + {% if not json_exists %} +
+

Données manquantes

+

Le fichier JSON contenant les données de décrépitude n'existe pas. Vous pouvez le générer en exécutant le script Python suivant :

+
cd {{ app.request.server.get('DOCUMENT_ROOT')|replace({'/public': ''}) }}/wiki_compare
+python3 wiki_compare.py
+

Ce script va analyser les pages wiki et générer les fichiers nécessaires, y compris le fichier outdated_pages.json et l'histogramme.

+
+ {% else %} + {% if last_updated %} +
+

Dernière mise à jour des données : {{ last_updated|date('d/m/Y H:i:s') }}

+
+ {% endif %} + + {% if histogram_exists %} +
+
+

Histogramme des scores de décrépitude

+
+
+ Histogramme des scores de décrépitude +
+
+ {% endif %} + +
+
+

Évolution des scores de décrépitude

+
+
+

Le score de décrépitude est calculé en prenant en compte plusieurs facteurs :

+
    +
  • La différence de date entre les versions anglaise et française (20%)
  • +
  • La différence de nombre de mots entre les versions (50%)
  • +
  • La différence de nombre de sections entre les versions (15%)
  • +
  • La différence de nombre de liens entre les versions (15%)
  • +
+

Plus le score est élevé, plus la page française est considérée comme "décrépite" par rapport à sa version anglaise.

+ + +
+
+ +
+
+

Pages régulières avec les scores de décrépitude les plus élevés

+
+
+
+ + + + + + + + + + + + + + {% for page in regular_pages|slice(0, 20) %} + + + + + + + + + + {% endfor %} + +
CléRaisonDifférence de motsDifférence de sectionsDifférence de liensScore de décrépitudeActions
{{ page.key }}{{ page.reason }} + {% if page.word_diff > 0 %} + {{ page.word_diff }} + {% elseif page.word_diff < 0 %} + {{ page.word_diff }} + {% else %} + 0 + {% endif %} + + {% if page.section_diff > 0 %} + {{ page.section_diff }} + {% elseif page.section_diff < 0 %} + {{ page.section_diff }} + {% else %} + 0 + {% endif %} + + {% if page.link_diff > 0 %} + {{ page.link_diff }} + {% elseif page.link_diff < 0 %} + {{ page.link_diff }} + {% else %} + 0 + {% endif %} + +
+ {% set score_class = page.staleness_score > 70 ? 'bg-danger' : (page.staleness_score > 40 ? 'bg-warning' : 'bg-success') %} +
+ {{ page.staleness_score }} +
+
+
+
+ + EN + + {% if page.fr_page %} + + FR + + + Comparer + + {% else %} + + Traduire + + {% endif %} +
+
+
+
+
+ + {% if specific_pages|length > 0 %} +
+
+

Pages spécifiques avec scores de décrépitude ({{ specific_pages|length }})

+
+
+

Ces pages wiki sont des pages spécifiques qui ont été sélectionnées pour une comparaison particulière.

+
+ + + + + + + + + + + {% for page in specific_pages %} + + + + + + + {% endfor %} + +
TitreRaisonScore de décrépitudeActions
+
+ {% if page.en_page.description_img_url is defined and page.en_page.description_img_url %} +
+ {{ page.key }} +
+ {% endif %} +
+ {{ page.key }} +
+
+
+ {{ page.reason }} + +
+ {% set score_class = page.staleness_score > 70 ? 'bg-danger' : (page.staleness_score > 40 ? 'bg-warning' : 'bg-success') %} +
+ {{ page.staleness_score }} +
+
+
+
+ + EN + + {% if page.fr_page %} + + FR + + + Comparer + + {% else %} + + Traduire + + {% endif %} +
+
+
+
+
+ {% endif %} + {% endif %} +
+{% endblock %} + +{% block javascripts %} + {{ parent() }} + {% if json_exists %} + + + {% endif %} +{% endblock %} \ No newline at end of file diff --git a/templates/admin/wiki_missing_translations.html.twig b/templates/admin/wiki_missing_translations.html.twig index 5b96a8d..5698544 100644 --- a/templates/admin/wiki_missing_translations.html.twig +++ b/templates/admin/wiki_missing_translations.html.twig @@ -40,7 +40,7 @@ FR - + Créer EN diff --git a/templates/admin/wiki_random_suggestion.html.twig b/templates/admin/wiki_random_suggestion.html.twig index d079448..c92b2ba 100644 --- a/templates/admin/wiki_random_suggestion.html.twig +++ b/templates/admin/wiki_random_suggestion.html.twig @@ -93,7 +93,7 @@

Vous pouvez contribuer en créant cette page sur le wiki OpenStreetMap.

- Créer la page française diff --git a/templates/base.html.twig b/templates/base.html.twig index 2e99b96..8dfdb04 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -119,7 +119,7 @@ - {# #} +