Преглед изворни кода

Change i18n process (#4131)

Before, the ignore info were stored in a different file which was a bit cumbersome
for new comers. Now, this info is stored directly in the translation file as a
comment.

Before, there was no way of telling translators that a previously translated string
was in need of a new translation. Now, the dirty information is there to convey that
info.
Alexis Degrugillier пре 4 година
родитељ
комит
127b7f0a3a
100 измењених фајлова са 3191 додато и 2191 уклоњено
  1. 37 27
      app/i18n/cz/admin.php
  2. 69 59
      app/i18n/cz/conf.php
  3. 29 19
      app/i18n/cz/feedback.php
  4. 75 65
      app/i18n/cz/gen.php
  5. 15 5
      app/i18n/cz/index.php
  6. 17 7
      app/i18n/cz/install.php
  7. 64 54
      app/i18n/cz/sub.php
  8. 30 20
      app/i18n/cz/user.php
  9. 15 5
      app/i18n/de/admin.php
  10. 19 9
      app/i18n/de/conf.php
  11. 10 0
      app/i18n/de/feedback.php
  12. 56 46
      app/i18n/de/gen.php
  13. 12 2
      app/i18n/de/index.php
  14. 12 2
      app/i18n/de/install.php
  15. 15 5
      app/i18n/de/sub.php
  16. 10 0
      app/i18n/de/user.php
  17. 139 129
      app/i18n/en-us/admin.php
  18. 182 172
      app/i18n/en-us/conf.php
  19. 92 82
      app/i18n/en-us/feedback.php
  20. 191 181
      app/i18n/en-us/gen.php
  21. 55 45
      app/i18n/en-us/index.php
  22. 79 69
      app/i18n/en-us/install.php
  23. 107 97
      app/i18n/en-us/sub.php
  24. 30 20
      app/i18n/en-us/user.php
  25. 10 0
      app/i18n/en/admin.php
  26. 10 0
      app/i18n/en/conf.php
  27. 10 0
      app/i18n/en/feedback.php
  28. 10 0
      app/i18n/en/gen.php
  29. 10 0
      app/i18n/en/index.php
  30. 10 0
      app/i18n/en/install.php
  31. 10 0
      app/i18n/en/sub.php
  32. 10 0
      app/i18n/en/user.php
  33. 12 2
      app/i18n/es/admin.php
  34. 18 8
      app/i18n/es/conf.php
  35. 10 0
      app/i18n/es/feedback.php
  36. 50 40
      app/i18n/es/gen.php
  37. 11 1
      app/i18n/es/index.php
  38. 10 0
      app/i18n/es/install.php
  39. 12 2
      app/i18n/es/sub.php
  40. 10 0
      app/i18n/es/user.php
  41. 15 5
      app/i18n/fr/admin.php
  42. 25 15
      app/i18n/fr/conf.php
  43. 10 0
      app/i18n/fr/feedback.php
  44. 52 42
      app/i18n/fr/gen.php
  45. 14 4
      app/i18n/fr/index.php
  46. 12 2
      app/i18n/fr/install.php
  47. 15 5
      app/i18n/fr/sub.php
  48. 10 0
      app/i18n/fr/user.php
  49. 72 62
      app/i18n/he/admin.php
  50. 79 69
      app/i18n/he/conf.php
  51. 54 44
      app/i18n/he/feedback.php
  52. 108 98
      app/i18n/he/gen.php
  53. 15 5
      app/i18n/he/index.php
  54. 32 22
      app/i18n/he/install.php
  55. 63 53
      app/i18n/he/sub.php
  56. 30 20
      app/i18n/he/user.php
  57. 21 11
      app/i18n/it/admin.php
  58. 69 59
      app/i18n/it/conf.php
  59. 29 19
      app/i18n/it/feedback.php
  60. 77 67
      app/i18n/it/gen.php
  61. 18 8
      app/i18n/it/index.php
  62. 20 10
      app/i18n/it/install.php
  63. 63 53
      app/i18n/it/sub.php
  64. 30 20
      app/i18n/it/user.php
  65. 10 0
      app/i18n/ja/admin.php
  66. 18 8
      app/i18n/ja/conf.php
  67. 10 0
      app/i18n/ja/feedback.php
  68. 46 36
      app/i18n/ja/gen.php
  69. 11 1
      app/i18n/ja/index.php
  70. 10 0
      app/i18n/ja/install.php
  71. 11 1
      app/i18n/ja/sub.php
  72. 10 0
      app/i18n/ja/user.php
  73. 10 0
      app/i18n/ko/admin.php
  74. 17 7
      app/i18n/ko/conf.php
  75. 10 0
      app/i18n/ko/feedback.php
  76. 59 49
      app/i18n/ko/gen.php
  77. 11 1
      app/i18n/ko/index.php
  78. 10 0
      app/i18n/ko/install.php
  79. 11 1
      app/i18n/ko/sub.php
  80. 10 0
      app/i18n/ko/user.php
  81. 12 2
      app/i18n/nl/admin.php
  82. 21 11
      app/i18n/nl/conf.php
  83. 10 0
      app/i18n/nl/feedback.php
  84. 56 46
      app/i18n/nl/gen.php
  85. 12 2
      app/i18n/nl/index.php
  86. 12 2
      app/i18n/nl/install.php
  87. 12 2
      app/i18n/nl/sub.php
  88. 10 0
      app/i18n/nl/user.php
  89. 16 6
      app/i18n/oc/admin.php
  90. 21 11
      app/i18n/oc/conf.php
  91. 10 0
      app/i18n/oc/feedback.php
  92. 50 40
      app/i18n/oc/gen.php
  93. 14 4
      app/i18n/oc/index.php
  94. 10 0
      app/i18n/oc/install.php
  95. 14 4
      app/i18n/oc/sub.php
  96. 10 0
      app/i18n/oc/user.php
  97. 55 45
      app/i18n/pl/admin.php
  98. 17 7
      app/i18n/pl/conf.php
  99. 10 0
      app/i18n/pl/feedback.php
  100. 49 39
      app/i18n/pl/gen.php

+ 37 - 27
app/i18n/cz/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Umožnit anonymně číst články výchozího uživatele (%s)',
 		'allow_anonymous' => 'Umožnit anonymně číst články výchozího uživatele (%s)',
@@ -66,8 +76,8 @@ return array(
 			'ok' => 'Máte rozšíření JSON.',
 			'ok' => 'Máte rozšíření JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// TODO - Translation
-			'ok' => 'You have the recommended mbstring library for Unicode.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// TODO
+			'ok' => 'You have the recommended mbstring library for Unicode.',	// TODO
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
 			'nok' => 'Nemáte požadovanou knihovnu pro regulární výrazy (php-pcre).',
 			'nok' => 'Nemáte požadovanou knihovnu pro regulární výrazy (php-pcre).',
@@ -101,23 +111,23 @@ return array(
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
-		'author' => 'Author',	// TODO - Translation
-		'community' => 'Available community extensions',	// TODO - Translation
-		'description' => 'Description',	// TODO - Translation
+		'author' => 'Author',	// TODO
+		'community' => 'Available community extensions',	// TODO
+		'description' => 'Description',	// TODO
 		'disabled' => 'Vypnuto',
 		'disabled' => 'Vypnuto',
 		'empty_list' => 'Není naistalováno žádné rozšíření',
 		'empty_list' => 'Není naistalováno žádné rozšíření',
 		'enabled' => 'Zapnuto',
 		'enabled' => 'Zapnuto',
-		'latest' => 'Installed',	// TODO - Translation
-		'name' => 'Name',	// TODO - Translation
+		'latest' => 'Installed',	// TODO
+		'name' => 'Name',	// TODO
 		'no_configure_view' => 'Toto rozšíření nemá žádné možnosti nastavení.',
 		'no_configure_view' => 'Toto rozšíření nemá žádné možnosti nastavení.',
 		'system' => array(
 		'system' => array(
 			'_' => 'Systémová rozšíření',
 			'_' => 'Systémová rozšíření',
 			'no_rights' => 'Systémová rozšíření (na ně nemáte oprávnění)',
 			'no_rights' => 'Systémová rozšíření (na ně nemáte oprávnění)',
 		),
 		),
 		'title' => 'Rozšíření',
 		'title' => 'Rozšíření',
-		'update' => 'Update available',	// TODO - Translation
+		'update' => 'Update available',	// TODO
 		'user' => 'Uživatelská rozšíření',
 		'user' => 'Uživatelská rozšíření',
-		'version' => 'Version',	// TODO - Translation
+		'version' => 'Version',	// TODO
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistika',
 		'_' => 'Statistika',
@@ -147,16 +157,16 @@ return array(
 		'top_feed' => 'Top ten kanálů',
 		'top_feed' => 'Top ten kanálů',
 	),
 	),
 	'system' => array(
 	'system' => array(
-		'_' => 'System configuration',	// TODO - Translation
-		'auto-update-url' => 'Auto-update server URL',	// TODO - Translation
+		'_' => 'System configuration',	// TODO
+		'auto-update-url' => 'Auto-update server URL',	// TODO
 		'cookie-duration' => array(
 		'cookie-duration' => array(
-			'help' => 'in seconds',	// TODO - Translation
-			'number' => 'Duration to keep logged in',	// TODO - Translation
+			'help' => 'in seconds',	// TODO
+			'number' => 'Duration to keep logged in',	// TODO
 		),
 		),
-		'force_email_validation' => 'Force email address validation',	// TODO - Translation
-		'instance-name' => 'Instance name',	// TODO - Translation
-		'max-categories' => 'Max number of categories per user',	// TODO - Translation
-		'max-feeds' => 'Max number of feeds per user',	// TODO - Translation
+		'force_email_validation' => 'Force email address validation',	// TODO
+		'instance-name' => 'Instance name',	// TODO
+		'max-categories' => 'Max number of categories per user',	// TODO
+		'max-feeds' => 'Max number of feeds per user',	// TODO
 		'registration' => array(
 		'registration' => array(
 			'help' => '0 znamená žádná omezení účtu',
 			'help' => '0 znamená žádná omezení účtu',
 			'number' => 'Maximální počet účtů',
 			'number' => 'Maximální počet účtů',
@@ -172,18 +182,18 @@ return array(
 		'title' => 'Aktualizovat systém',
 		'title' => 'Aktualizovat systém',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'admin' => 'Administrator',	// TODO - Translation
-		'article_count' => 'Articles',	// TODO - Translation
-		'back_to_manage' => '← Return to user list',	// TODO - Translation
+		'admin' => 'Administrator',	// TODO
+		'article_count' => 'Articles',	// TODO
+		'back_to_manage' => '← Return to user list',	// TODO
 		'create' => 'Vytvořit nového uživatele',
 		'create' => 'Vytvořit nového uživatele',
-		'database_size' => 'Database size',	// TODO - Translation
-		'email' => 'Email address',	// TODO - Translation
-		'enabled' => 'Enabled',	// TODO - Translation
-		'feed_count' => 'Feeds',	// TODO - Translation
-		'is_admin' => 'Is admin',	// TODO - Translation
+		'database_size' => 'Database size',	// TODO
+		'email' => 'Email address',	// TODO
+		'enabled' => 'Enabled',	// TODO
+		'feed_count' => 'Feeds',	// TODO
+		'is_admin' => 'Is admin',	// TODO
 		'language' => 'Jazyk',
 		'language' => 'Jazyk',
-		'last_user_activity' => 'Last user activity',	// TODO - Translation
-		'list' => 'User list',	// TODO - Translation
+		'last_user_activity' => 'Last user activity',	// TODO
+		'list' => 'User list',	// TODO
 		'number' => 'Zatím je vytvořen %d účet',
 		'number' => 'Zatím je vytvořen %d účet',
 		'numbers' => 'Zatím je vytvořeno %d účtů',
 		'numbers' => 'Zatím je vytvořeno %d účtů',
 		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
 		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',

+ 69 - 59
app/i18n/cz/conf.php

@@ -1,21 +1,31 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archivace',
 		'_' => 'Archivace',
-		'exception' => 'Purge exception',	// TODO - Translation
+		'exception' => 'Purge exception',	// TODO
 		'help' => 'Více možností je dostupných v nastavení jednotlivých kanálů',
 		'help' => 'Více možností je dostupných v nastavení jednotlivých kanálů',
-		'keep_favourites' => 'Never delete favourites',	// TODO - Translation
-		'keep_labels' => 'Never delete labels',	// TODO - Translation
-		'keep_max' => 'Maximum number of articles to keep',	// TODO - Translation
+		'keep_favourites' => 'Never delete favourites',	// TODO
+		'keep_labels' => 'Never delete labels',	// TODO
+		'keep_max' => 'Maximum number of articles to keep',	// TODO
 		'keep_min_by_feed' => 'Zachovat tento minimální počet článků v každém kanálu',
 		'keep_min_by_feed' => 'Zachovat tento minimální počet článků v každém kanálu',
-		'keep_period' => 'Maximum age of articles to keep',	// TODO - Translation
-		'keep_unreads' => 'Never delete unread articles',	// TODO - Translation
-		'maintenance' => 'Maintenance',	// TODO - Translation
+		'keep_period' => 'Maximum age of articles to keep',	// TODO
+		'keep_unreads' => 'Never delete unread articles',	// TODO
+		'maintenance' => 'Maintenance',	// TODO
 		'optimize' => 'Optimalizovat databázi',
 		'optimize' => 'Optimalizovat databázi',
 		'optimize_help' => 'Občasná údržba zmenší velikost databáze',
 		'optimize_help' => 'Občasná údržba zmenší velikost databáze',
-		'policy' => 'Purge policy',	// TODO - Translation
-		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// TODO - Translation
+		'policy' => 'Purge policy',	// TODO
+		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// TODO
 		'purge_now' => 'Vyčistit nyní',
 		'purge_now' => 'Vyčistit nyní',
 		'title' => 'Archivace',
 		'title' => 'Archivace',
 		'ttl' => 'Neaktualizovat častěji než',
 		'ttl' => 'Neaktualizovat častěji než',
@@ -24,12 +34,12 @@ return array(
 		'_' => 'Zobrazení',
 		'_' => 'Zobrazení',
 		'icon' => array(
 		'icon' => array(
 			'bottom_line' => 'Spodní řádek',
 			'bottom_line' => 'Spodní řádek',
-			'display_authors' => 'Authors',	// TODO - Translation
+			'display_authors' => 'Authors',	// TODO
 			'entry' => 'Ikony článků',
 			'entry' => 'Ikony článků',
 			'publication_date' => 'Datum vydání',
 			'publication_date' => 'Datum vydání',
 			'related_tags' => 'Související tagy',
 			'related_tags' => 'Související tagy',
 			'sharing' => 'Sdílení',
 			'sharing' => 'Sdílení',
-			'summary' => 'Summary',	// TODO - Translation
+			'summary' => 'Summary',	// TODO
 			'top_line' => 'Horní řádek',
 			'top_line' => 'Horní řádek',
 		),
 		),
 		'language' => 'Jazyk',
 		'language' => 'Jazyk',
@@ -37,15 +47,15 @@ return array(
 			'seconds' => 'sekund (0 znamená žádný timeout)',
 			'seconds' => 'sekund (0 znamená žádný timeout)',
 			'timeout' => 'Timeout HTML5 notifikací',
 			'timeout' => 'Timeout HTML5 notifikací',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	// TODO - Translation
+		'show_nav_buttons' => 'Show the navigation buttons',	// TODO
 		'theme' => 'Vzhled',
 		'theme' => 'Vzhled',
-		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// TODO - Translation
+		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// TODO
 		'thumbnail' => array(
 		'thumbnail' => array(
-			'label' => 'Thumbnail',	// TODO - Translation
-			'landscape' => 'Landscape',	// TODO - Translation
-			'none' => 'None',	// TODO - Translation
-			'portrait' => 'Portrait',	// TODO - Translation
-			'square' => 'Square',	// TODO - Translation
+			'label' => 'Thumbnail',	// TODO
+			'landscape' => 'Landscape',	// TODO
+			'none' => 'None',	// TODO
+			'portrait' => 'Portrait',	// TODO
+			'square' => 'Square',	// TODO
 		),
 		),
 		'title' => 'Zobrazení',
 		'title' => 'Zobrazení',
 		'width' => array(
 		'width' => array(
@@ -58,7 +68,7 @@ return array(
 	),
 	),
 	'profile' => array(
 	'profile' => array(
 		'_' => 'Správa profilu',
 		'_' => 'Správa profilu',
-		'api' => 'API management',	// TODO - Translation
+		'api' => 'API management',	// TODO
 		'delete' => array(
 		'delete' => array(
 			'_' => 'Smazání účtu',
 			'_' => 'Smazání účtu',
 			'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty',
 			'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty',
@@ -74,19 +84,19 @@ return array(
 		'deprecated' => 'Tento dotaz již není platný. Odkazovaná kategorie nebo kanál byly smazány.',
 		'deprecated' => 'Tento dotaz již není platný. Odkazovaná kategorie nebo kanál byly smazány.',
 		'filter' => array(
 		'filter' => array(
 			'_' => 'Filtr aplikován:',
 			'_' => 'Filtr aplikován:',
-			'categories' => 'Display by category',	// TODO - Translation
-			'feeds' => 'Display by feed',	// TODO - Translation
-			'order' => 'Sort by date',	// TODO - Translation
-			'search' => 'Expression',	// TODO - Translation
-			'state' => 'State',	// TODO - Translation
-			'tags' => 'Display by tag',	// TODO - Translation
-			'type' => 'Type',	// TODO - Translation
+			'categories' => 'Display by category',	// TODO
+			'feeds' => 'Display by feed',	// TODO
+			'order' => 'Sort by date',	// TODO
+			'search' => 'Expression',	// TODO
+			'state' => 'State',	// TODO
+			'tags' => 'Display by tag',	// TODO
+			'type' => 'Type',	// TODO
 		),
 		),
 		'get_all' => 'Zobrazit všechny články',
 		'get_all' => 'Zobrazit všechny články',
 		'get_category' => 'Zobrazit "%s" kategorii',
 		'get_category' => 'Zobrazit "%s" kategorii',
 		'get_favorite' => 'Zobrazit oblíbené články',
 		'get_favorite' => 'Zobrazit oblíbené články',
 		'get_feed' => 'Zobrazit "%s" článkek',
 		'get_feed' => 'Zobrazit "%s" článkek',
-		'name' => 'Name',	// TODO - Translation
+		'name' => 'Name',	// TODO
 		'no_filter' => 'Zrušit filtr',
 		'no_filter' => 'Zrušit filtr',
 		'number' => 'Dotaz n°%d',
 		'number' => 'Dotaz n°%d',
 		'order_asc' => 'Zobrazit nejdříve nejstarší články',
 		'order_asc' => 'Zobrazit nejdříve nejstarší články',
@@ -113,13 +123,13 @@ return array(
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Čtení',
 		'_' => 'Čtení',
 		'after_onread' => 'Po “označit vše jako přečtené”,',
 		'after_onread' => 'Po “označit vše jako přečtené”,',
-		'always_show_favorites' => 'Show all articles in favourites by default',	// TODO - Translation
+		'always_show_favorites' => 'Show all articles in favourites by default',	// TODO
 		'articles_per_page' => 'Počet článků na stranu',
 		'articles_per_page' => 'Počet článků na stranu',
 		'auto_load_more' => 'Načítat další články dole na stránce',
 		'auto_load_more' => 'Načítat další články dole na stránce',
 		'auto_remove_article' => 'Po přečtení články schovat',
 		'auto_remove_article' => 'Po přečtení články schovat',
 		'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”',
 		'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”',
 		'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené',
 		'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené',
-		'display_categories_unfolded' => 'Categories to unfold',	// TODO - Translation
+		'display_categories_unfolded' => 'Categories to unfold',	// TODO
 		'hide_read_feeds' => 'Schovat kategorie a kanály s nulovým počtem nepřečtených článků (nefunguje s nastavením “Zobrazit všechny články”)',
 		'hide_read_feeds' => 'Schovat kategorie a kanály s nulovým počtem nepřečtených článků (nefunguje s nastavením “Zobrazit všechny články”)',
 		'img_with_lazyload' => 'Použít "lazy load" mód pro načítaní obrázků',
 		'img_with_lazyload' => 'Použít "lazy load" mód pro načítaní obrázků',
 		'jump_next' => 'skočit na další nepřečtený (kanál nebo kategorii)',
 		'jump_next' => 'skočit na další nepřečtený (kanál nebo kategorii)',
@@ -128,24 +138,24 @@ return array(
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'když je otevřen původní web s článkem',
 			'article_open_on_website' => 'když je otevřen původní web s článkem',
 			'article_viewed' => 'během čtení článku',
 			'article_viewed' => 'během čtení článku',
-			'keep_max_n_unread' => 'Max number of articles to keep unread',	// TODO - Translation
+			'keep_max_n_unread' => 'Max number of articles to keep unread',	// TODO
 			'scroll' => 'během skrolování',
 			'scroll' => 'během skrolování',
 			'upon_reception' => 'po načtení článku',
 			'upon_reception' => 'po načtení článku',
 			'when' => 'Označit článek jako přečtený…',
 			'when' => 'Označit článek jako přečtený…',
-			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// TODO - Translation
+			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// TODO
 		),
 		),
 		'show' => array(
 		'show' => array(
 			'_' => 'Počet zobrazených článků',
 			'_' => 'Počet zobrazených článků',
-			'active_category' => 'Active category',	// TODO - Translation
+			'active_category' => 'Active category',	// TODO
 			'adaptive' => 'Vyberte zobrazení',
 			'adaptive' => 'Vyberte zobrazení',
 			'all_articles' => 'Zobrazit všechny články',
 			'all_articles' => 'Zobrazit všechny články',
-			'all_categories' => 'All categories',	// TODO - Translation
-			'no_category' => 'No category',	// TODO - Translation
-			'remember_categories' => 'Remember open categories',	// TODO - Translation
+			'all_categories' => 'All categories',	// TODO
+			'no_category' => 'No category',	// TODO
+			'remember_categories' => 'Remember open categories',	// TODO
 			'unread' => 'Zobrazit jen nepřečtené',
 			'unread' => 'Zobrazit jen nepřečtené',
 		),
 		),
-		'show_fav_unread_help' => 'Applies also on labels',	// TODO - Translation
-		'sides_close_article' => 'Clicking outside of article text area closes the article',	// TODO - Translation
+		'show_fav_unread_help' => 'Applies also on labels',	// TODO
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	// TODO
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Řazení',
 			'_' => 'Řazení',
 			'newer_first' => 'Nejdříve nejnovější',
 			'newer_first' => 'Nejdříve nejnovější',
@@ -162,21 +172,21 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Sdílení',
 		'_' => 'Sdílení',
-		'add' => 'Add a sharing method',	// TODO - Translation
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',	// TODO - Translation
-		'facebook' => 'Facebook',
+		'add' => 'Add a sharing method',	// TODO
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// TODO
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Více informací',
 		'more_information' => 'Více informací',
 		'print' => 'Tisk',
 		'print' => 'Tisk',
-		'raindrop' => 'Raindrop.io',
-		'remove' => 'Remove sharing method',	// TODO - Translation
-		'shaarli' => 'Shaarli',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'remove' => 'Remove sharing method',	// TODO
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Jméno pro zobrazení',
 		'share_name' => 'Jméno pro zobrazení',
 		'share_url' => 'Jakou URL použít pro sdílení',
 		'share_url' => 'Jakou URL použít pro sdílení',
 		'title' => 'Sdílení',
 		'title' => 'Sdílení',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Zkratky',
 		'_' => 'Zkratky',
@@ -187,7 +197,7 @@ return array(
 		'collapse_article' => 'Srolovat',
 		'collapse_article' => 'Srolovat',
 		'first_article' => 'Skočit na první článek',
 		'first_article' => 'Skočit na první článek',
 		'focus_search' => 'Hledání',
 		'focus_search' => 'Hledání',
-		'global_view' => 'Switch to global view',	// TODO - Translation
+		'global_view' => 'Switch to global view',	// TODO
 		'help' => 'Zobrazit documentaci',
 		'help' => 'Zobrazit documentaci',
 		'javascript' => 'Pro použití zkratek musí být povolen JavaScript',
 		'javascript' => 'Pro použití zkratek musí být povolen JavaScript',
 		'last_article' => 'Skočit na poslední článek',
 		'last_article' => 'Skočit na poslední článek',
@@ -196,24 +206,24 @@ return array(
 		'mark_read' => 'Označit jako přečtené',
 		'mark_read' => 'Označit jako přečtené',
 		'navigation' => 'Navigace',
 		'navigation' => 'Navigace',
 		'navigation_help' => 'Pomocí přepínače <kbd>⇧ Shift</kbd> fungují navigační zkratky v rámci kanálů.<br/>Pomocí přepínače <kbd>Alt ⎇</kbd> fungují v rámci kategorií.',
 		'navigation_help' => 'Pomocí přepínače <kbd>⇧ Shift</kbd> fungují navigační zkratky v rámci kanálů.<br/>Pomocí přepínače <kbd>Alt ⎇</kbd> fungují v rámci kategorií.',
-		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// TODO - Translation
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// TODO
 		'next_article' => 'Skočit na další článek',
 		'next_article' => 'Skočit na další článek',
-		'next_unread_article' => 'Open the next unread article',	// TODO - Translation
-		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// TODO - Translation
-		'normal_view' => 'Switch to normal view',	// TODO - Translation
+		'next_unread_article' => 'Open the next unread article',	// TODO
+		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// TODO
+		'normal_view' => 'Switch to normal view',	// TODO
 		'other_action' => 'Ostatní akce',
 		'other_action' => 'Ostatní akce',
 		'previous_article' => 'Skočit na předchozí článek',
 		'previous_article' => 'Skočit na předchozí článek',
-		'reading_view' => 'Switch to reading view',	// TODO - Translation
-		'rss_view' => 'Open as RSS feed',	// TODO - Translation
+		'reading_view' => 'Switch to reading view',	// TODO
+		'rss_view' => 'Open as RSS feed',	// TODO
 		'see_on_website' => 'Navštívit původní webovou stránku',
 		'see_on_website' => 'Navštívit původní webovou stránku',
-		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// TODO - Translation
-		'skip_next_article' => 'Focus next without opening',	// TODO - Translation
-		'skip_previous_article' => 'Focus previous without opening',	// TODO - Translation
+		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// TODO
+		'skip_next_article' => 'Focus next without opening',	// TODO
+		'skip_previous_article' => 'Focus previous without opening',	// TODO
 		'title' => 'Zkratky',
 		'title' => 'Zkratky',
-		'toggle_media' => 'Play/pause media',	// TODO - Translation
+		'toggle_media' => 'Play/pause media',	// TODO
 		'user_filter' => 'Aplikovat uživatelské filtry',
 		'user_filter' => 'Aplikovat uživatelské filtry',
 		'user_filter_help' => 'Je-li nastaven pouze jeden filtr, bude použit. Další filtry jsou dostupné pomocí jejich čísla.',
 		'user_filter_help' => 'Je-li nastaven pouze jeden filtr, bude použit. Další filtry jsou dostupné pomocí jejich čísla.',
-		'views' => 'Views',	// TODO - Translation
+		'views' => 'Views',	// TODO
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s článků (%s)',
 		'articles_and_size' => '%s článků (%s)',

+ 29 - 19
app/i18n/cz/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'Nemáte oprávnění přistupovat na tuto stránku',
 		'denied' => 'Nemáte oprávnění přistupovat na tuto stránku',
@@ -10,8 +20,8 @@ return array(
 	),
 	),
 	'api' => array(
 	'api' => array(
 		'password' => array(
 		'password' => array(
-			'failed' => 'Your password cannot be modified',	// TODO - Translation
-			'updated' => 'Your password has been modified',	// TODO - Translation
+			'failed' => 'Your password cannot be modified',	// TODO
+			'updated' => 'Your password has been modified',	// TODO
 		),
 		),
 	),
 	),
 	'auth' => array(
 	'auth' => array(
@@ -31,7 +41,7 @@ return array(
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
 		'already_enabled' => '%s je již zapnut',
 		'already_enabled' => '%s je již zapnut',
-		'cannot_remove' => '%s cannot be removed',	// TODO - Translation
+		'cannot_remove' => '%s cannot be removed',	// TODO
 		'disable' => array(
 		'disable' => array(
 			'ko' => '%s nelze vypnout. Pro více detailů <a href="%s">zkontrolujte logy FreshRSS</a>.',
 			'ko' => '%s nelze vypnout. Pro více detailů <a href="%s">zkontrolujte logy FreshRSS</a>.',
 			'ok' => '%s je nyní vypnut',
 			'ok' => '%s je nyní vypnut',
@@ -43,7 +53,7 @@ return array(
 		'no_access' => 'Nemáte přístup k %s',
 		'no_access' => 'Nemáte přístup k %s',
 		'not_enabled' => '%s není ještě zapnut',
 		'not_enabled' => '%s není ještě zapnut',
 		'not_found' => '%s neexistuje',
 		'not_found' => '%s neexistuje',
-		'removed' => '%s removed',	// TODO - Translation
+		'removed' => '%s removed',	// TODO
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export_no_zip_extension' => 'Na serveru není naistalována podpora ZIP. Zkuste prosím exportovat soubory jeden po druhém.',
 		'export_no_zip_extension' => 'Na serveru není naistalována podpora ZIP. Zkuste prosím exportovat soubory jeden po druhém.',
@@ -60,8 +70,8 @@ return array(
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Aktualizovat',
 		'actualize' => 'Aktualizovat',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	// TODO - Translation
-			'marked_unread' => 'The articles have been marked as unread.',	// TODO - Translation
+			'marked_read' => 'The selected articles have been marked as read.',	// TODO
+			'marked_unread' => 'The articles have been marked as unread.',	// TODO
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => 'Kategorie %s byla vytvořena.',
 			'created' => 'Kategorie %s byla vytvořena.',
@@ -81,7 +91,7 @@ return array(
 			'actualizeds' => 'RSS kanály byly aktualizovány',
 			'actualizeds' => 'RSS kanály byly aktualizovány',
 			'added' => 'RSS kanál <em>%s</em> byl přidán',
 			'added' => 'RSS kanál <em>%s</em> byl přidán',
 			'already_subscribed' => 'Již jste přihlášen k odběru <em>%s</em>',
 			'already_subscribed' => 'Již jste přihlášen k odběru <em>%s</em>',
-			'cache_cleared' => '<em>%s</em> cache has been cleared',	// TODO - Translation
+			'cache_cleared' => '<em>%s</em> cache has been cleared',	// TODO
 			'deleted' => 'Kanál byl smazán',
 			'deleted' => 'Kanál byl smazán',
 			'error' => 'Kanál nelze aktualizovat',
 			'error' => 'Kanál nelze aktualizovat',
 			'internal_problem' => 'RSS kanál nelze přidat. Pro detaily <a href="%s">zkontrolujte logy FreshRSS</a>.',
 			'internal_problem' => 'RSS kanál nelze přidat. Pro detaily <a href="%s">zkontrolujte logy FreshRSS</a>.',
@@ -90,24 +100,24 @@ return array(
 			'n_entries_deleted' => '%d článků bylo smazáno',
 			'n_entries_deleted' => '%d článků bylo smazáno',
 			'no_refresh' => 'Nelze obnovit žádné kanály…',
 			'no_refresh' => 'Nelze obnovit žádné kanály…',
 			'not_added' => '<em>%s</em> nemůže být přidán',
 			'not_added' => '<em>%s</em> nemůže být přidán',
-			'not_found' => 'Feed cannot be found',	// TODO - Translation
+			'not_found' => 'Feed cannot be found',	// TODO
 			'over_max' => 'Dosáhl jste maximálního počtu kanálů (%d)',
 			'over_max' => 'Dosáhl jste maximálního počtu kanálů (%d)',
-			'reloaded' => '<em>%s</em> has been reloaded',	// TODO - Translation
+			'reloaded' => '<em>%s</em> has been reloaded',	// TODO
 			'selector_preview' => array(
 			'selector_preview' => array(
-				'http_error' => 'Failed to load website content.',	// TODO - Translation
-				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// TODO - Translation
-				'no_feed' => 'Internal error (feed cannot be found).',	// TODO - Translation
-				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// TODO - Translation
-				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// TODO - Translation
+				'http_error' => 'Failed to load website content.',	// TODO
+				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// TODO
+				'no_feed' => 'Internal error (feed cannot be found).',	// TODO
+				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// TODO
+				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// TODO
 			),
 			),
 			'updated' => 'Kanál byl aktualizován',
 			'updated' => 'Kanál byl aktualizován',
 		),
 		),
 		'purge_completed' => 'Vyprázdněno (smazáno %d článků)',
 		'purge_completed' => 'Vyprázdněno (smazáno %d článků)',
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'created' => 'Tag "%s" has been created.',	// TODO - Translation
-		'name_exists' => 'Tag name already exists.',	// TODO - Translation
-		'renamed' => 'Tag "%s" has been renamed to "%s".',	// TODO - Translation
+		'created' => 'Tag "%s" has been created.',	// TODO
+		'name_exists' => 'Tag name already exists.',	// TODO
+		'renamed' => 'Tag "%s" has been renamed to "%s".',	// TODO
 	),
 	),
 	'update' => array(
 	'update' => array(
 		'can_apply' => 'FreshRSS bude nyní upgradováno na <strong>verzi %s</strong>.',
 		'can_apply' => 'FreshRSS bude nyní upgradováno na <strong>verzi %s</strong>.',
@@ -127,8 +137,8 @@ return array(
 			'error' => 'Uživatele %s nelze smazat',
 			'error' => 'Uživatele %s nelze smazat',
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated',	// TODO - Translation
-			'error' => 'User %s has not been updated',	// TODO - Translation
+			'_' => 'User %s has been updated',	// TODO
+			'error' => 'User %s has not been updated',	// TODO
 		),
 		),
 	),
 	),
 );
 );

+ 75 - 65
app/i18n/cz/gen.php

@@ -1,37 +1,47 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Aktualizovat',
 		'actualize' => 'Aktualizovat',
-		'add' => 'Add',	// TODO - Translation
-		'back' => '← Go back',	// TODO - Translation
+		'add' => 'Add',	// TODO
+		'back' => '← Go back',	// TODO
 		'back_to_rss_feeds' => '← Zpět na seznam RSS kanálů',
 		'back_to_rss_feeds' => '← Zpět na seznam RSS kanálů',
 		'cancel' => 'Zrušit',
 		'cancel' => 'Zrušit',
 		'create' => 'Vytvořit',
 		'create' => 'Vytvořit',
-		'demote' => 'Demote',	// TODO - Translation
+		'demote' => 'Demote',	// TODO
 		'disable' => 'Zakázat',
 		'disable' => 'Zakázat',
 		'empty' => 'Vyprázdnit',
 		'empty' => 'Vyprázdnit',
 		'enable' => 'Povolit',
 		'enable' => 'Povolit',
-		'export' => 'Export',	// TODO - Translation
+		'export' => 'Export',	// TODO
 		'filter' => 'Filtrovat',
 		'filter' => 'Filtrovat',
-		'import' => 'Import',	// TODO - Translation
-		'load_default_shortcuts' => 'Load default shortcuts',	// TODO - Translation
+		'import' => 'Import',	// TODO
+		'load_default_shortcuts' => 'Load default shortcuts',	// TODO
 		'manage' => 'Spravovat',
 		'manage' => 'Spravovat',
 		'mark_read' => 'Označit jako přečtené',
 		'mark_read' => 'Označit jako přečtené',
-		'promote' => 'Promote',	// TODO - Translation
-		'purge' => 'Purge',	// TODO - Translation
+		'promote' => 'Promote',	// TODO
+		'purge' => 'Purge',	// TODO
 		'remove' => 'Odstranit',
 		'remove' => 'Odstranit',
-		'rename' => 'Rename',	// TODO - Translation
+		'rename' => 'Rename',	// TODO
 		'see_website' => 'Navštívit WWW stránku',
 		'see_website' => 'Navštívit WWW stránku',
 		'submit' => 'Odeslat',
 		'submit' => 'Odeslat',
 		'truncate' => 'Smazat všechny články',
 		'truncate' => 'Smazat všechny články',
-		'update' => 'Update',	// TODO - Translation
+		'update' => 'Update',	// TODO
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// TODO - Translation
+		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// TODO
 		'email' => 'Email',
 		'email' => 'Email',
 		'keep_logged_in' => 'Zapamatovat přihlášení <small>(%s dny)</small>',
 		'keep_logged_in' => 'Zapamatovat přihlášení <small>(%s dny)</small>',
-		'login' => 'Login',	// TODO - Translation
+		'login' => 'Login',	// TODO
 		'logout' => 'Odhlášení',
 		'logout' => 'Odhlášení',
 		'password' => array(
 		'password' => array(
 			'_' => 'Heslo',
 			'_' => 'Heslo',
@@ -69,8 +79,8 @@ return array(
 		'december' => 'Pro',
 		'december' => 'Pro',
 		'feb' => 'úno',
 		'feb' => 'úno',
 		'february' => 'Úno',
 		'february' => 'Úno',
-		'format_date' => 'j\\. %s Y',
-		'format_date_hour' => 'j\\. %s Y \\v H\\:i',
+		'format_date' => 'j\\. %s Y',	// IGNORE
+		'format_date_hour' => 'j\\. %s Y \\v H\\:i',	// IGNORE
 		'fri' => 'Pá',
 		'fri' => 'Pá',
 		'jan' => 'led',
 		'jan' => 'led',
 		'january' => 'Led',
 		'january' => 'Led',
@@ -78,10 +88,10 @@ return array(
 		'july' => 'Čvn',
 		'july' => 'Čvn',
 		'jun' => 'čer',
 		'jun' => 'čer',
 		'june' => 'Čer',
 		'june' => 'Čer',
-		'last_2_year' => 'Last two years',	// TODO - Translation
+		'last_2_year' => 'Last two years',	// TODO
 		'last_3_month' => 'Minulé tři měsíce',
 		'last_3_month' => 'Minulé tři měsíce',
-		'last_3_year' => 'Last three years',	// TODO - Translation
-		'last_5_year' => 'Last five years',	// TODO - Translation
+		'last_3_year' => 'Last three years',	// TODO
+		'last_5_year' => 'Last five years',	// TODO
 		'last_6_month' => 'Minulých šest měsíců',
 		'last_6_month' => 'Minulých šest měsíců',
 		'last_month' => 'Minulý měsíc',
 		'last_month' => 'Minulý měsíc',
 		'last_week' => 'Minulý týden',
 		'last_week' => 'Minulý týden',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'St',
 		'wed' => 'St',
 		'yesterday' => 'Včera',
 		'yesterday' => 'Včera',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',	// TODO - Translation
+		'_' => 'FreshRSS',	// TODO
 		'about' => 'O FreshRSS',
 		'about' => 'O FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,28 +134,28 @@ return array(
 		'should_be_activated' => 'JavaScript musí být povolen',
 		'should_be_activated' => 'JavaScript musí být povolen',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'O aplikaci',
 		'about' => 'O aplikaci',
-		'account' => 'Account',	// TODO - Translation
+		'account' => 'Account',	// TODO
 		'admin' => 'Administrace',
 		'admin' => 'Administrace',
 		'archiving' => 'Archivace',
 		'archiving' => 'Archivace',
 		'authentication' => 'Přihlášení',
 		'authentication' => 'Přihlášení',
@@ -160,7 +170,7 @@ return array(
 		'sharing' => 'Sdílení',
 		'sharing' => 'Sdílení',
 		'shortcuts' => 'Zkratky',
 		'shortcuts' => 'Zkratky',
 		'stats' => 'Statistika',
 		'stats' => 'Statistika',
-		'system' => 'System configuration',	// TODO - Translation
+		'system' => 'System configuration',	// TODO
 		'update' => 'Aktualizace',
 		'update' => 'Aktualizace',
 		'user_management' => 'Správa uživatelů',
 		'user_management' => 'Správa uživatelů',
 		'user_profile' => 'Profil',
 		'user_profile' => 'Profil',
@@ -175,33 +185,33 @@ return array(
 		'previous' => 'Předchozí',
 		'previous' => 'Předchozí',
 	),
 	),
 	'period' => array(
 	'period' => array(
-		'days' => 'days',	// TODO - Translation
-		'hours' => 'hours',	// TODO - Translation
-		'months' => 'months',	// TODO - Translation
-		'weeks' => 'weeks',	// TODO - Translation
-		'years' => 'years',	// TODO - Translation
+		'days' => 'days',	// TODO
+		'hours' => 'hours',	// TODO
+		'months' => 'months',	// TODO
+		'weeks' => 'weeks',	// TODO
+		'years' => 'years',	// TODO
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',	// TODO - Translation
-		'blogotext' => 'Blogotext',
-		'clipboard' => 'Clipboard',	// TODO - Translation
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',	// TODO - Translation
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'Known' => 'Known based sites',	// TODO
+		'blogotext' => 'Blogotext',	// IGNORE
+		'clipboard' => 'Clipboard',	// TODO
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// TODO
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Tisk',
 		'print' => 'Tisk',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Upozornění!',
 		'attention' => 'Upozornění!',
@@ -211,8 +221,8 @@ return array(
 		'damn' => 'Sakra!',
 		'damn' => 'Sakra!',
 		'default_category' => 'Nezařazeno',
 		'default_category' => 'Nezařazeno',
 		'no' => 'Ne',
 		'no' => 'Ne',
-		'not_applicable' => 'Not available',	// TODO - Translation
-		'ok' => 'Okay!',	// TODO - Translation
+		'not_applicable' => 'Not available',	// TODO
+		'ok' => 'Okay!',	// TODO
 		'or' => 'nebo',
 		'or' => 'nebo',
 		'yes' => 'Ano',
 		'yes' => 'Ano',
 	),
 	),

+ 15 - 5
app/i18n/cz/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'O FreshRSS',
 		'_' => 'O FreshRSS',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Hlášení chyb',
 		'bugs_reports' => 'Hlášení chyb',
 		'credits' => 'Poděkování',
 		'credits' => 'Poděkování',
 		'credits_content' => 'Některé designové prvky pocházejí z <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>, FreshRSS ale tuto platformu nevyužívá. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Ikony</a> pocházejí z <a href="https://www.gnome.org/">GNOME projektu</a>. Font <em>Open Sans</em> vytvořil <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS je založen na PHP framework <a href="https://github.com/marienfressinaud/MINZ">Minz</a>.',
 		'credits_content' => 'Některé designové prvky pocházejí z <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>, FreshRSS ale tuto platformu nevyužívá. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Ikony</a> pocházejí z <a href="https://www.gnome.org/">GNOME projektu</a>. Font <em>Open Sans</em> vytvořil <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS je založen na PHP framework <a href="https://github.com/marienfressinaud/MINZ">Minz</a>.',
@@ -32,14 +42,14 @@ return array(
 		'about' => 'O FreshRSS',
 		'about' => 'O FreshRSS',
 		'before_one_day' => 'Den nazpět',
 		'before_one_day' => 'Den nazpět',
 		'before_one_week' => 'Před týdnem',
 		'before_one_week' => 'Před týdnem',
-		'bookmark_query' => 'Bookmark current query',	// TODO - Translation
+		'bookmark_query' => 'Bookmark current query',	// TODO
 		'favorites' => 'Oblíbené (%s)',
 		'favorites' => 'Oblíbené (%s)',
 		'global_view' => 'Přehled',
 		'global_view' => 'Přehled',
 		'main_stream' => 'Všechny kanály',
 		'main_stream' => 'Všechny kanály',
 		'mark_all_read' => 'Označit vše jako přečtené',
 		'mark_all_read' => 'Označit vše jako přečtené',
 		'mark_cat_read' => 'Označit kategorii jako přečtenou',
 		'mark_cat_read' => 'Označit kategorii jako přečtenou',
 		'mark_feed_read' => 'Označit kanál jako přečtený',
 		'mark_feed_read' => 'Označit kanál jako přečtený',
-		'mark_selection_unread' => 'Mark selection as unread',	// TODO - Translation
+		'mark_selection_unread' => 'Mark selection as unread',	// TODO
 		'newer_first' => 'Nové nejdříve',
 		'newer_first' => 'Nové nejdříve',
 		'non-starred' => 'Zobrazit vše vyjma oblíbených',
 		'non-starred' => 'Zobrazit vše vyjma oblíbených',
 		'normal_view' => 'Normální',
 		'normal_view' => 'Normální',
@@ -52,7 +62,7 @@ return array(
 		'starred' => 'Zobrazit oblíbené',
 		'starred' => 'Zobrazit oblíbené',
 		'stats' => 'Statistika',
 		'stats' => 'Statistika',
 		'subscription' => 'Správa subskripcí',
 		'subscription' => 'Správa subskripcí',
-		'tags' => 'My labels',	// TODO - Translation
+		'tags' => 'My labels',	// TODO
 		'unread' => 'Zobrazovat nepřečtené',
 		'unread' => 'Zobrazovat nepřečtené',
 	),
 	),
 	'share' => 'Sdílet',
 	'share' => 'Sdílet',
@@ -60,6 +70,6 @@ return array(
 		'related' => 'Související tagy',
 		'related' => 'Související tagy',
 	),
 	),
 	'tos' => array(
 	'tos' => array(
-		'title' => 'Terms of Service',	// TODO - Translation
+		'title' => 'Terms of Service',	// TODO
 	),
 	),
 );
 );

+ 17 - 7
app/i18n/cz/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Dokončit instalaci',
 		'finish' => 'Dokončit instalaci',
@@ -65,8 +75,8 @@ return array(
 			'ok' => 'Máte doporučenou knihovnu pro parsování JSON.',
 			'ok' => 'Máte doporučenou knihovnu pro parsování JSON.',
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// TODO - Translation
-			'ok' => 'You have the recommended library mbstring for Unicode.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// TODO
+			'ok' => 'You have the recommended library mbstring for Unicode.',	// TODO
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
 			'nok' => 'Nemáte požadovanou knihovnu pro regulární výrazy (php-pcre).',
 			'nok' => 'Nemáte požadovanou knihovnu pro regulární výrazy (php-pcre).',
@@ -80,12 +90,12 @@ return array(
 			'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.',
 			'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.',
 			'ok' => 'Vaše verze PHP je %s a je kompatibilní s FreshRSS.',
 			'ok' => 'Vaše verze PHP je %s a je kompatibilní s FreshRSS.',
 		),
 		),
-		'reload' => 'Check again',	// TODO - Translation
+		'reload' => 'Check again',	// TODO
 		'tmp' => array(
 		'tmp' => array(
 			'nok' => 'Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu.',
 			'nok' => 'Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu.',
-			'ok' => 'Permissions on the temp directory are good.',	// TODO - Translation
+			'ok' => 'Permissions on the temp directory are good.',	// TODO
 		),
 		),
-		'unknown_process_username' => 'unknown',	// TODO - Translation
+		'unknown_process_username' => 'unknown',	// TODO
 		'users' => array(
 		'users' => array(
 			'nok' => 'Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu.',
 			'nok' => 'Zkontrolujte oprávnění adresáře <em>%s</em>. HTTP server musí mít do tohoto adresáře práva zápisu.',
 			'ok' => 'Oprávnění adresáře users jsou v pořádku.',
 			'ok' => 'Oprávnění adresáře users jsou v pořádku.',
@@ -111,10 +121,10 @@ return array(
 		'choose' => 'Vyberte jazyk FreshRSS',
 		'choose' => 'Vyberte jazyk FreshRSS',
 		'defined' => 'Jazyk byl nastaven.',
 		'defined' => 'Jazyk byl nastaven.',
 	),
 	),
-	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// TODO - Translation
+	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// TODO
 	'ok' => 'Instalace byla úspěšná.',
 	'ok' => 'Instalace byla úspěšná.',
 	'session' => array(
 	'session' => array(
-		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// TODO - Translation
+		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// TODO
 	),
 	),
 	'step' => 'krok %d',
 	'step' => 'krok %d',
 	'steps' => 'Kroky',
 	'steps' => 'Kroky',

+ 64 - 54
app/i18n/cz/sub.php

@@ -1,14 +1,24 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',	// TODO - Translation
-		'title' => 'API',	// TODO - Translation
+		'documentation' => 'Copy the following URL to use it within an external tool.',	// TODO
+		'title' => 'API',	// TODO
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// TODO - Translation
-		'label' => 'Subscribe',	// TODO - Translation
-		'title' => 'Bookmarklet',	// TODO - Translation
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// TODO
+		'label' => 'Subscribe',	// TODO
+		'title' => 'Bookmarklet',	// TODO
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Kategorie',
 		'_' => 'Kategorie',
@@ -16,8 +26,8 @@ return array(
 		'archiving' => 'Archivace',
 		'archiving' => 'Archivace',
 		'empty' => 'Vyprázdit kategorii',
 		'empty' => 'Vyprázdit kategorii',
 		'information' => 'Informace',
 		'information' => 'Informace',
-		'position' => 'Display position',	// TODO - Translation
-		'position_help' => 'To control category sort order',	// TODO - Translation
+		'position' => 'Display position',	// TODO
+		'position_help' => 'To control category sort order',	// TODO
 		'title' => 'Název',
 		'title' => 'Název',
 	),
 	),
 	'feed' => array(
 	'feed' => array(
@@ -31,108 +41,108 @@ return array(
 			'password' => 'Heslo',
 			'password' => 'Heslo',
 			'username' => 'Přihlašovací jméno',
 			'username' => 'Přihlašovací jméno',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	// TODO - Translation
+		'clear_cache' => 'Always clear cache',	// TODO
 		'content_action' => array(
 		'content_action' => array(
-			'_' => 'Content action when fetching the article content',	// TODO - Translation
-			'append' => 'Add after existing content',	// TODO - Translation
-			'prepend' => 'Add before existing content',	// TODO - Translation
-			'replace' => 'Replace existing content',	// TODO - Translation
+			'_' => 'Content action when fetching the article content',	// TODO
+			'append' => 'Add after existing content',	// TODO
+			'prepend' => 'Add before existing content',	// TODO
+			'replace' => 'Replace existing content',	// TODO
 		),
 		),
-		'css_cookie' => 'Use Cookies when fetching the article content',	// TODO - Translation
-		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// TODO - Translation
+		'css_cookie' => 'Use Cookies when fetching the article content',	// TODO
+		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// TODO
 		'css_help' => 'Stáhne zkrácenou verzi RSS kanálů (pozor, náročnější na čas!)',
 		'css_help' => 'Stáhne zkrácenou verzi RSS kanálů (pozor, náročnější na čas!)',
 		'css_path' => 'Původní CSS soubor článku z webových stránek',
 		'css_path' => 'Původní CSS soubor článku z webových stránek',
 		'description' => 'Popis',
 		'description' => 'Popis',
 		'empty' => 'Kanál je prázdný. Ověřte prosím zda je ještě autorem udržován.',
 		'empty' => 'Kanál je prázdný. Ověřte prosím zda je ještě autorem udržován.',
 		'error' => 'Vyskytl se problém s kanálem. Ověřte že je vždy dostupný, prosím, a poté jej aktualizujte.',
 		'error' => 'Vyskytl se problém s kanálem. Ověřte že je vždy dostupný, prosím, a poté jej aktualizujte.',
 		'filteractions' => array(
 		'filteractions' => array(
-			'_' => 'Filter actions',	// TODO - Translation
-			'help' => 'Write one search filter per line.',	// TODO - Translation
+			'_' => 'Filter actions',	// TODO
+			'help' => 'Write one search filter per line.',	// TODO
 		),
 		),
 		'information' => 'Informace',
 		'information' => 'Informace',
 		'keep_min' => 'Zachovat tento minimální počet článků',
 		'keep_min' => 'Zachovat tento minimální počet článků',
 		'maintenance' => array(
 		'maintenance' => array(
-			'clear_cache' => 'Clear cache',	// TODO - Translation
-			'clear_cache_help' => 'Clear the cache for this feed.',	// TODO - Translation
-			'reload_articles' => 'Reload articles',	// TODO - Translation
-			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// TODO - Translation
-			'title' => 'Maintenance',	// TODO - Translation
+			'clear_cache' => 'Clear cache',	// TODO
+			'clear_cache_help' => 'Clear the cache for this feed.',	// TODO
+			'reload_articles' => 'Reload articles',	// TODO
+			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// TODO
+			'title' => 'Maintenance',	// TODO
 		),
 		),
 		'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.',
 		'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.',
-		'mute' => 'mute',	// TODO - Translation
+		'mute' => 'mute',	// TODO
 		'no_selected' => 'Nejsou označeny žádné kanály.',
 		'no_selected' => 'Nejsou označeny žádné kanály.',
 		'number_entries' => '%d článků',
 		'number_entries' => '%d článků',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility',	// TODO - Translation
-			'archived' => 'Do not show (archived)',	// TODO - Translation
+			'_' => 'Visibility',	// TODO
+			'archived' => 'Do not show (archived)',	// TODO
 			'main_stream' => 'Zobrazit ve “Všechny kanály”',
 			'main_stream' => 'Zobrazit ve “Všechny kanály”',
-			'normal' => 'Show in its category',	// TODO - Translation
+			'normal' => 'Show in its category',	// TODO
 		),
 		),
-		'proxy' => 'Set a proxy for fetching this feed',	// TODO - Translation
-		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// TODO - Translation
+		'proxy' => 'Set a proxy for fetching this feed',	// TODO
+		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// TODO
 		'selector_preview' => array(
 		'selector_preview' => array(
-			'show_raw' => 'Show source code',	// TODO - Translation
-			'show_rendered' => 'Show content',	// TODO - Translation
+			'show_raw' => 'Show source code',	// TODO
+			'show_rendered' => 'Show content',	// TODO
 		),
 		),
 		'show' => array(
 		'show' => array(
-			'all' => 'Show all feeds',	// TODO - Translation
-			'error' => 'Show only feeds with errors',	// TODO - Translation
+			'all' => 'Show all feeds',	// TODO
+			'error' => 'Show only feeds with errors',	// TODO
 		),
 		),
 		'showing' => array(
 		'showing' => array(
-			'error' => 'Showing only feeds with errors',	// TODO - Translation
+			'error' => 'Showing only feeds with errors',	// TODO
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	// TODO - Translation
+		'ssl_verify' => 'Verify SSL security',	// TODO
 		'stats' => 'Statistika',
 		'stats' => 'Statistika',
 		'think_to_add' => 'Můžete přidat kanály.',
 		'think_to_add' => 'Můžete přidat kanály.',
-		'timeout' => 'Timeout in seconds',	// TODO - Translation
+		'timeout' => 'Timeout in seconds',	// TODO
 		'title' => 'Název',
 		'title' => 'Název',
 		'title_add' => 'Přidat RSS kanál',
 		'title_add' => 'Přidat RSS kanál',
 		'ttl' => 'Neobnovovat častěji než',
 		'ttl' => 'Neobnovovat častěji než',
 		'url' => 'URL kanálu',
 		'url' => 'URL kanálu',
-		'useragent' => 'Set the user agent for fetching this feed',	// TODO - Translation
-		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// TODO - Translation
+		'useragent' => 'Set the user agent for fetching this feed',	// TODO
+		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// TODO
 		'validator' => 'Zkontrolovat platnost kanálu',
 		'validator' => 'Zkontrolovat platnost kanálu',
 		'website' => 'URL webové stránky',
 		'website' => 'URL webové stránky',
 		'websub' => 'Okamžité oznámení s WebSub',
 		'websub' => 'Okamžité oznámení s WebSub',
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
-		'export' => 'Export',	// TODO - Translation
-		'export_labelled' => 'Export your labelled articles',	// TODO - Translation
+		'export' => 'Export',	// TODO
+		'export_labelled' => 'Export your labelled articles',	// TODO
 		'export_opml' => 'Exportovat seznam kanálů (OPML)',
 		'export_opml' => 'Exportovat seznam kanálů (OPML)',
 		'export_starred' => 'Exportovat oblíbené',
 		'export_starred' => 'Exportovat oblíbené',
 		'feed_list' => 'Seznam %s článků',
 		'feed_list' => 'Seznam %s článků',
 		'file_to_import' => 'Soubor k importu<br />(OPML, JSON nebo ZIP)',
 		'file_to_import' => 'Soubor k importu<br />(OPML, JSON nebo ZIP)',
 		'file_to_import_no_zip' => 'Soubor k importu<br />(OPML nebo JSON)',
 		'file_to_import_no_zip' => 'Soubor k importu<br />(OPML nebo JSON)',
-		'import' => 'Import',	// TODO - Translation
+		'import' => 'Import',	// TODO
 		'starred_list' => 'Seznam oblíbených článků',
 		'starred_list' => 'Seznam oblíbených článků',
-		'title' => 'Import / export',	// TODO - Translation
+		'title' => 'Import / export',	// TODO
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'add' => 'Add a feed or category',	// TODO - Translation
-		'import_export' => 'Import / export',	// TODO - Translation
-		'label_management' => 'Label management',	// TODO - Translation
+		'add' => 'Add a feed or category',	// TODO
+		'import_export' => 'Import / export',	// TODO
+		'label_management' => 'Label management',	// TODO
 		'stats' => array(
 		'stats' => array(
 			'idle' => 'Neaktivní kanály',
 			'idle' => 'Neaktivní kanály',
 			'main' => 'Přehled',
 			'main' => 'Přehled',
 			'repartition' => 'Rozdělení článků',
 			'repartition' => 'Rozdělení článků',
 		),
 		),
 		'subscription_management' => 'Správa subskripcí',
 		'subscription_management' => 'Správa subskripcí',
-		'subscription_tools' => 'Subscription tools',	// TODO - Translation
+		'subscription_tools' => 'Subscription tools',	// TODO
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'name' => 'Name',	// TODO - Translation
-		'new_name' => 'New name',	// TODO - Translation
-		'old_name' => 'Old name',	// TODO - Translation
+		'name' => 'Name',	// TODO
+		'new_name' => 'New name',	// TODO
+		'old_name' => 'Old name',	// TODO
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'Správa subskripcí',
 		'_' => 'Správa subskripcí',
-		'add' => 'Add a feed or category',	// TODO - Translation
-		'add_category' => 'Add a category',	// TODO - Translation
-		'add_feed' => 'Add a feed',	// TODO - Translation
-		'add_label' => 'Add a label',	// TODO - Translation
-		'delete_label' => 'Delete a label',	// TODO - Translation
+		'add' => 'Add a feed or category',	// TODO
+		'add_category' => 'Add a category',	// TODO
+		'add_feed' => 'Add a feed',	// TODO
+		'add_label' => 'Add a label',	// TODO
+		'delete_label' => 'Delete a label',	// TODO
 		'feed_management' => 'Správa RSS kanálů',
 		'feed_management' => 'Správa RSS kanálů',
-		'rename_label' => 'Rename a label',	// TODO - Translation
-		'subscription_tools' => 'Subscription tools',	// TODO - Translation
+		'rename_label' => 'Rename a label',	// TODO
+		'subscription_tools' => 'Subscription tools',	// TODO
 	),
 	),
 );
 );

+ 30 - 20
app/i18n/cz/user.php

@@ -1,44 +1,54 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'This email address is invalid.',	// TODO - Translation
-			'required' => 'An email address is required.',	// TODO - Translation
+			'invalid' => 'This email address is invalid.',	// TODO
+			'required' => 'An email address is required.',	// TODO
 		),
 		),
 		'validation' => array(
 		'validation' => array(
-			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// TODO - Translation
-			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// TODO - Translation
+			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// TODO
+			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// TODO
 			'feedback' => array(
 			'feedback' => array(
-				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// TODO - Translation
-				'email_sent' => 'An email has been sent to your address.',	// TODO - Translation
-				'error' => 'Email address validation failed.',	// TODO - Translation
-				'ok' => 'This email address has been validated.',	// TODO - Translation
-				'unnecessary' => 'This email address was already validated.',	// TODO - Translation
-				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// TODO - Translation
+				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// TODO
+				'email_sent' => 'An email has been sent to your address.',	// TODO
+				'error' => 'Email address validation failed.',	// TODO
+				'ok' => 'This email address has been validated.',	// TODO
+				'unnecessary' => 'This email address was already validated.',	// TODO
+				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// TODO
 			),
 			),
-			'need_to' => 'You need to validate your email address before being able to use %s.',	// TODO - Translation
-			'resend_email' => 'Resend the email',	// TODO - Translation
-			'title' => 'Email address validation',	// TODO - Translation
+			'need_to' => 'You need to validate your email address before being able to use %s.',	// TODO
+			'resend_email' => 'Resend the email',	// TODO
+			'title' => 'Email address validation',	// TODO
 		),
 		),
 	),
 	),
 	'mailer' => array(
 	'mailer' => array(
 		'email_need_validation' => array(
 		'email_need_validation' => array(
-			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// TODO - Translation
-			'title' => 'You need to validate your account',	// TODO - Translation
-			'welcome' => 'Welcome %s,',	// TODO - Translation
+			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// TODO
+			'title' => 'You need to validate your account',	// TODO
+			'welcome' => 'Welcome %s,',	// TODO
 		),
 		),
 	),
 	),
 	'password' => array(
 	'password' => array(
-		'invalid' => 'The password is invalid.',	// TODO - Translation
+		'invalid' => 'The password is invalid.',	// TODO
 	),
 	),
 	'tos' => array(
 	'tos' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'You must accept the Terms of Service to be able to register.',	// TODO - Translation
+			'invalid' => 'You must accept the Terms of Service to be able to register.',	// TODO
 		),
 		),
 	),
 	),
 	'username' => array(
 	'username' => array(
-		'invalid' => 'This username is invalid.',	// TODO - Translation
-		'taken' => 'This username, %s, is taken.',	// TODO - Translation
+		'invalid' => 'This username is invalid.',	// TODO
+		'taken' => 'This username, %s, is taken.',	// TODO
 	),
 	),
 );
 );

+ 15 - 5
app/i18n/de/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Anonymes Lesen der Artikel des Standardbenutzers (%s) erlauben',
 		'allow_anonymous' => 'Anonymes Lesen der Artikel des Standardbenutzers (%s) erlauben',
@@ -108,7 +118,7 @@ return array(
 		'empty_list' => 'Es gibt keine installierte Erweiterung.',
 		'empty_list' => 'Es gibt keine installierte Erweiterung.',
 		'enabled' => 'Aktiviert',
 		'enabled' => 'Aktiviert',
 		'latest' => 'Installiert',
 		'latest' => 'Installiert',
-		'name' => 'Name',
+		'name' => 'Name',	// IGNORE
 		'no_configure_view' => 'Diese Erweiterung kann nicht konfiguriert werden.',
 		'no_configure_view' => 'Diese Erweiterung kann nicht konfiguriert werden.',
 		'system' => array(
 		'system' => array(
 			'_' => 'System-Erweiterungen',
 			'_' => 'System-Erweiterungen',
@@ -117,7 +127,7 @@ return array(
 		'title' => 'Erweiterungen',
 		'title' => 'Erweiterungen',
 		'update' => 'Update verfügbar',
 		'update' => 'Update verfügbar',
 		'user' => 'Benutzer-Erweiterungen',
 		'user' => 'Benutzer-Erweiterungen',
-		'version' => 'Version',
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistiken',
 		'_' => 'Statistiken',
@@ -130,7 +140,7 @@ return array(
 		'entry_per_hour' => 'Pro Stunde (Durchschnitt: %.2f Nachrichten)',
 		'entry_per_hour' => 'Pro Stunde (Durchschnitt: %.2f Nachrichten)',
 		'entry_per_month' => 'Pro Monat (Durchschnitt: %.2f Nachrichten)',
 		'entry_per_month' => 'Pro Monat (Durchschnitt: %.2f Nachrichten)',
 		'entry_repartition' => 'Einträge-Verteilung',
 		'entry_repartition' => 'Einträge-Verteilung',
-		'feed' => 'Feed',
+		'feed' => 'Feed',	// IGNORE
 		'feed_per_category' => 'Feeds pro Kategorie',
 		'feed_per_category' => 'Feeds pro Kategorie',
 		'idle' => 'Inaktive Feeds',
 		'idle' => 'Inaktive Feeds',
 		'main' => 'Haupt-Statistiken',
 		'main' => 'Haupt-Statistiken',
@@ -172,14 +182,14 @@ return array(
 		'title' => 'System aktualisieren',
 		'title' => 'System aktualisieren',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'admin' => 'Administrator',
+		'admin' => 'Administrator',	// IGNORE
 		'article_count' => 'Artikel',
 		'article_count' => 'Artikel',
 		'back_to_manage' => '← Zurück zur Benutzerliste',
 		'back_to_manage' => '← Zurück zur Benutzerliste',
 		'create' => 'Neuen Benutzer erstellen',
 		'create' => 'Neuen Benutzer erstellen',
 		'database_size' => 'Datenbankgröße',
 		'database_size' => 'Datenbankgröße',
 		'email' => 'E-Mail-Adresse',
 		'email' => 'E-Mail-Adresse',
 		'enabled' => 'Aktiviert',
 		'enabled' => 'Aktiviert',
-		'feed_count' => 'Feeds',
+		'feed_count' => 'Feeds',	// IGNORE
 		'is_admin' => 'Ist Administrator',
 		'is_admin' => 'Ist Administrator',
 		'language' => 'Sprache',
 		'language' => 'Sprache',
 		'last_user_activity' => 'Letzte Benutzeraktivität',
 		'last_user_activity' => 'Letzte Benutzeraktivität',

+ 19 - 9
app/i18n/de/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archivierung',
 		'_' => 'Archivierung',
@@ -86,7 +96,7 @@ return array(
 		'get_category' => 'Kategorie "%s" anzeigen',
 		'get_category' => 'Kategorie "%s" anzeigen',
 		'get_favorite' => 'Lieblingsartikel anzeigen',
 		'get_favorite' => 'Lieblingsartikel anzeigen',
 		'get_feed' => 'Feed "%s" anzeigen',
 		'get_feed' => 'Feed "%s" anzeigen',
-		'name' => 'Name',
+		'name' => 'Name',	// IGNORE
 		'no_filter' => 'Kein Filter',
 		'no_filter' => 'Kein Filter',
 		'number' => 'Abfrage Nr. %d',
 		'number' => 'Abfrage Nr. %d',
 		'order_asc' => 'Älteste Artikel zuerst anzeigen',
 		'order_asc' => 'Älteste Artikel zuerst anzeigen',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Teilen',
 		'_' => 'Teilen',
 		'add' => 'Füge eine Teilen-Dienst hinzu',
 		'add' => 'Füge eine Teilen-Dienst hinzu',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'E-Mail',
 		'email' => 'E-Mail',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Weitere Informationen',
 		'more_information' => 'Weitere Informationen',
 		'print' => 'Drucken',
 		'print' => 'Drucken',
-		'raindrop' => 'Raindrop.io',
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => 'Entferne Teilen-Dienst',
 		'remove' => 'Entferne Teilen-Dienst',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Anzuzeigender Teilen-Name',
 		'share_name' => 'Anzuzeigender Teilen-Name',
 		'share_url' => 'Zu verwendende Teilen-URL',
 		'share_url' => 'Zu verwendende Teilen-URL',
 		'title' => 'Teilen',
 		'title' => 'Teilen',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Tastenkombination',
 		'_' => 'Tastenkombination',
@@ -194,7 +204,7 @@ return array(
 		'load_more' => 'Weitere Artikel laden',
 		'load_more' => 'Weitere Artikel laden',
 		'mark_favorite' => 'Als Favorit auswählen/entfernen',
 		'mark_favorite' => 'Als Favorit auswählen/entfernen',
 		'mark_read' => 'Als (un-)gelesen markieren',
 		'mark_read' => 'Als (un-)gelesen markieren',
-		'navigation' => 'Navigation',
+		'navigation' => 'Navigation',	// IGNORE
 		'navigation_help' => 'Mit der <kbd>⇧ Umschalttaste</kbd> finden die Tastenkombination auf Feeds Anwendung.<br/>Mit der <kbd>Alt ⎇</kbd>-Taste finden die Tastenkombination auf Kategorien Anwendung.',
 		'navigation_help' => 'Mit der <kbd>⇧ Umschalttaste</kbd> finden die Tastenkombination auf Feeds Anwendung.<br/>Mit der <kbd>Alt ⎇</kbd>-Taste finden die Tastenkombination auf Kategorien Anwendung.',
 		'navigation_no_mod_help' => 'Die folgenden Navigationsverknüpfungen unterstützen keine Modifikatoren.',
 		'navigation_no_mod_help' => 'Die folgenden Navigationsverknüpfungen unterstützen keine Modifikatoren.',
 		'next_article' => 'Zum nächsten Artikel springen',
 		'next_article' => 'Zum nächsten Artikel springen',

+ 10 - 0
app/i18n/de/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'Sie haben nicht die Berechtigung, diese Seite aufzurufen',
 		'denied' => 'Sie haben nicht die Berechtigung, diese Seite aufzurufen',

+ 56 - 46
app/i18n/de/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Feeds aktualisieren',
 		'actualize' => 'Feeds aktualisieren',
@@ -48,8 +58,8 @@ return array(
 		),
 		),
 	),
 	),
 	'date' => array(
 	'date' => array(
-		'Apr' => '\\A\\p\\r\\i\\l',
-		'Aug' => '\\A\\u\\g\\u\\s\\t',
+		'Apr' => '\\A\\p\\r\\i\\l',	// IGNORE
+		'Aug' => '\\A\\u\\g\\u\\s\\t',	// IGNORE
 		'Dec' => '\\D\\e\\z\\e\\m\\b\\e\\r',
 		'Dec' => '\\D\\e\\z\\e\\m\\b\\e\\r',
 		'Feb' => '\\F\\e\\b\\r\\u\\a\\r',
 		'Feb' => '\\F\\e\\b\\r\\u\\a\\r',
 		'Jan' => '\\J\\a\\n\\u\\a\\r',
 		'Jan' => '\\J\\a\\n\\u\\a\\r',
@@ -57,13 +67,13 @@ return array(
 		'Jun' => '\\J\\u\\n\\i',
 		'Jun' => '\\J\\u\\n\\i',
 		'Mar' => '\\M\\ä\\r\\z',
 		'Mar' => '\\M\\ä\\r\\z',
 		'May' => '\\M\\a\\i',
 		'May' => '\\M\\a\\i',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',	// IGNORE
 		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
 		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
-		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',	// IGNORE
 		'apr' => 'Apr',
 		'apr' => 'Apr',
-		'april' => 'April',
+		'april' => 'April',	// IGNORE
 		'aug' => 'Aug',
 		'aug' => 'Aug',
-		'august' => 'August',
+		'august' => 'August',	// IGNORE
 		'before_yesterday' => 'Ältere Beiträge',
 		'before_yesterday' => 'Ältere Beiträge',
 		'dec' => 'Dez',
 		'dec' => 'Dez',
 		'december' => 'Dezember',
 		'december' => 'Dezember',
@@ -93,12 +103,12 @@ return array(
 		'mon' => 'Mo',
 		'mon' => 'Mo',
 		'month' => 'Monat(en)',
 		'month' => 'Monat(en)',
 		'nov' => 'Nov',
 		'nov' => 'Nov',
-		'november' => 'November',
+		'november' => 'November',	// IGNORE
 		'oct' => 'Okt',
 		'oct' => 'Okt',
 		'october' => 'Oktober',
 		'october' => 'Oktober',
 		'sat' => 'Sa',
 		'sat' => 'Sa',
 		'sep' => 'Sep',
 		'sep' => 'Sep',
-		'september' => 'September',
+		'september' => 'September',	// IGNORE
 		'sun' => 'So',
 		'sun' => 'So',
 		'thu' => 'Do',
 		'thu' => 'Do',
 		'today' => 'Heute',
 		'today' => 'Heute',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'Mi',
 		'wed' => 'Mi',
 		'yesterday' => 'Gestern',
 		'yesterday' => 'Gestern',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'Über FreshRSS',
 		'about' => 'Über FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,29 +134,29 @@ return array(
 		'should_be_activated' => 'JavaScript muss aktiviert sein',
 		'should_be_activated' => 'JavaScript muss aktiviert sein',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'Über',
 		'about' => 'Über',
-		'account' => 'Account',
-		'admin' => 'Administration',
+		'account' => 'Account',	// IGNORE
+		'admin' => 'Administration',	// IGNORE
 		'archiving' => 'Archivierung',
 		'archiving' => 'Archivierung',
 		'authentication' => 'Authentifizierung',
 		'authentication' => 'Authentifizierung',
 		'check_install' => 'Installationsüberprüfung',
 		'check_install' => 'Installationsüberprüfung',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Known-Seite (https://withknown.com)',
 		'Known' => 'Known-Seite (https://withknown.com)',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'Zwischenablage',
 		'clipboard' => 'Zwischenablage',
-		'diaspora' => 'Diaspora*',
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'E-Mail',
 		'email' => 'E-Mail',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Drucken',
 		'print' => 'Drucken',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Achtung!',
 		'attention' => 'Achtung!',

+ 12 - 2
app/i18n/de/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'Über',
 		'_' => 'Über',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Fehlerberichte',
 		'bugs_reports' => 'Fehlerberichte',
 		'credits' => 'Mitwirkende',
 		'credits' => 'Mitwirkende',
 		'credits_content' => 'Einige Designelemente stammen von <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>, obwohl FreshRSS dieses Framework nicht nutzt. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> stammen vom <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> Font wurde von <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a> erstellt. FreshRSS basiert auf <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, einem PHP-Framework.',
 		'credits_content' => 'Einige Designelemente stammen von <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>, obwohl FreshRSS dieses Framework nicht nutzt. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> stammen vom <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> Font wurde von <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a> erstellt. FreshRSS basiert auf <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, einem PHP-Framework.',
@@ -12,7 +22,7 @@ return array(
 		'license' => 'Lizenz',
 		'license' => 'Lizenz',
 		'project_website' => 'Projekt-Website',
 		'project_website' => 'Projekt-Website',
 		'title' => 'Über',
 		'title' => 'Über',
-		'version' => 'Version',
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'feed' => array(
 	'feed' => array(
 		'add' => 'Sie können Feeds hinzufügen.',
 		'add' => 'Sie können Feeds hinzufügen.',

+ 12 - 2
app/i18n/de/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Installation fertigstellen',
 		'finish' => 'Installation fertigstellen',
@@ -23,7 +33,7 @@ return array(
 			'ko' => 'Überprüfen Sie Ihre Datenbank-Information.',
 			'ko' => 'Überprüfen Sie Ihre Datenbank-Information.',
 			'ok' => 'Datenbank-Konfiguration ist gespeichert worden.',
 			'ok' => 'Datenbank-Konfiguration ist gespeichert worden.',
 		),
 		),
-		'host' => 'Host',
+		'host' => 'Host',	// IGNORE
 		'password' => 'Datenbank-Password',
 		'password' => 'Datenbank-Password',
 		'prefix' => 'Tabellen-Präfix',
 		'prefix' => 'Tabellen-Präfix',
 		'type' => 'Datenbank-Typ',
 		'type' => 'Datenbank-Typ',
@@ -119,5 +129,5 @@ return array(
 	'step' => 'Schritt %d',
 	'step' => 'Schritt %d',
 	'steps' => 'Schritte',
 	'steps' => 'Schritte',
 	'this_is_the_end' => 'Das ist das Ende',
 	'this_is_the_end' => 'Das ist das Ende',
-	'title' => 'Installation · FreshRSS',
+	'title' => 'Installation · FreshRSS',	// IGNORE
 );
 );

+ 15 - 5
app/i18n/de/sub.php

@@ -1,21 +1,31 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => 'Kopieren Sie die folgende URL, um sie in einem externen Tool zu verwenden.',
 		'documentation' => 'Kopieren Sie die folgende URL, um sie in einem externen Tool zu verwenden.',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'Ziehen Sie diese Schaltfläche auf Ihre Lesezeichen-Symbolleiste oder klicken Sie mit der rechten Maustaste darauf und wählen Sie "Als Lesezeichen hinzufügen". Klicken Sie dann auf einer beliebigen Seite, die Sie abonnieren möchten, auf die Schaltfläche "Abonnieren".',
 		'documentation' => 'Ziehen Sie diese Schaltfläche auf Ihre Lesezeichen-Symbolleiste oder klicken Sie mit der rechten Maustaste darauf und wählen Sie "Als Lesezeichen hinzufügen". Klicken Sie dann auf einer beliebigen Seite, die Sie abonnieren möchten, auf die Schaltfläche "Abonnieren".',
 		'label' => 'Abonnieren',
 		'label' => 'Abonnieren',
-		'title' => 'Bookmarklet',
+		'title' => 'Bookmarklet',	// IGNORE
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Kategorie',
 		'_' => 'Kategorie',
 		'add' => 'Kategorie hinzufügen',
 		'add' => 'Kategorie hinzufügen',
 		'archiving' => 'Archivierung',
 		'archiving' => 'Archivierung',
 		'empty' => 'Leere Kategorie',
 		'empty' => 'Leere Kategorie',
-		'information' => 'Information',
+		'information' => 'Information',	// IGNORE
 		'position' => 'Reihenfolge',
 		'position' => 'Reihenfolge',
 		'position_help' => 'Steuert die Kategoriesortierung',
 		'position_help' => 'Steuert die Kategoriesortierung',
 		'title' => 'Titel',
 		'title' => 'Titel',
@@ -49,7 +59,7 @@ return array(
 			'_' => 'Filteraktionen',
 			'_' => 'Filteraktionen',
 			'help' => 'Ein Suchfilter pro Zeile',
 			'help' => 'Ein Suchfilter pro Zeile',
 		),
 		),
-		'information' => 'Information',
+		'information' => 'Information',	// IGNORE
 		'keep_min' => 'Minimale Anzahl an Artikeln, die behalten wird',
 		'keep_min' => 'Minimale Anzahl an Artikeln, die behalten wird',
 		'maintenance' => array(
 		'maintenance' => array(
 			'clear_cache' => 'Zwischenspeicher leeren',
 			'clear_cache' => 'Zwischenspeicher leeren',
@@ -120,7 +130,7 @@ return array(
 		'subscription_tools' => 'Abonnement-Tools',
 		'subscription_tools' => 'Abonnement-Tools',
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'name' => 'Name',
+		'name' => 'Name',	// IGNORE
 		'new_name' => 'Neuer Name',
 		'new_name' => 'Neuer Name',
 		'old_name' => 'Alter Name',
 		'old_name' => 'Alter Name',
 	),
 	),

+ 10 - 0
app/i18n/de/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 139 - 129
app/i18n/en-us/admin.php

@@ -1,194 +1,204 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
-		'allow_anonymous' => 'Allow anonymous reading of the default user\'s articles (%s)',
-		'allow_anonymous_refresh' => 'Allow anonymous refresh of the articles',
-		'api_enabled' => 'Allow <abbr>API</abbr> access <small>(required for mobile apps)</small>',
-		'form' => 'Web form (traditional, requires JavaScript)',
-		'http' => 'HTTP (for advanced users with HTTPS)',
-		'none' => 'None (dangerous)',
-		'title' => 'Authentication',
-		'token' => 'Authentication token',
-		'token_help' => 'Allows access to RSS output of the default user without authentication:',
-		'type' => 'Authentication method',
-		'unsafe_autologin' => 'Allow unsafe automatic login using the format: ',
+		'allow_anonymous' => 'Allow anonymous reading of the default user\'s articles (%s)',	// IGNORE
+		'allow_anonymous_refresh' => 'Allow anonymous refresh of the articles',	// IGNORE
+		'api_enabled' => 'Allow <abbr>API</abbr> access <small>(required for mobile apps)</small>',	// IGNORE
+		'form' => 'Web form (traditional, requires JavaScript)',	// IGNORE
+		'http' => 'HTTP (for advanced users with HTTPS)',	// IGNORE
+		'none' => 'None (dangerous)',	// IGNORE
+		'title' => 'Authentication',	// IGNORE
+		'token' => 'Authentication token',	// IGNORE
+		'token_help' => 'Allows access to RSS output of the default user without authentication:',	// IGNORE
+		'type' => 'Authentication method',	// IGNORE
+		'unsafe_autologin' => 'Allow unsafe automatic login using the format: ',	// IGNORE
 	),
 	),
 	'check_install' => array(
 	'check_install' => array(
 		'cache' => array(
 		'cache' => array(
-			'nok' => 'Check permissions on <em>./data/cache</em> directory. HTTP server must have write permission.',
-			'ok' => 'Permissions on the cache directory are good.',
+			'nok' => 'Check permissions on <em>./data/cache</em> directory. HTTP server must have write permission.',	// IGNORE
+			'ok' => 'Permissions on the cache directory are good.',	// IGNORE
 		),
 		),
 		'categories' => array(
 		'categories' => array(
-			'nok' => 'Category table is improperly configured.',
-			'ok' => 'Category table is okay.',
+			'nok' => 'Category table is improperly configured.',	// IGNORE
+			'ok' => 'Category table is okay.',	// IGNORE
 		),
 		),
 		'connection' => array(
 		'connection' => array(
-			'nok' => 'Connection to the database cannot be established.',
-			'ok' => 'Connection to the database is okay.',
+			'nok' => 'Connection to the database cannot be established.',	// IGNORE
+			'ok' => 'Connection to the database is okay.',	// IGNORE
 		),
 		),
 		'ctype' => array(
 		'ctype' => array(
-			'nok' => 'Cannot find a required library for character type checking (php-ctype).',
-			'ok' => 'You have the required library for character type checking (ctype).',
+			'nok' => 'Cannot find a required library for character type checking (php-ctype).',	// IGNORE
+			'ok' => 'You have the required library for character type checking (ctype).',	// IGNORE
 		),
 		),
 		'curl' => array(
 		'curl' => array(
-			'nok' => 'Cannot find the cURL library (php-curl package).',
-			'ok' => 'You have the cURL library.',
+			'nok' => 'Cannot find the cURL library (php-curl package).',	// IGNORE
+			'ok' => 'You have the cURL library.',	// IGNORE
 		),
 		),
 		'data' => array(
 		'data' => array(
-			'nok' => 'Check permissions on <em>./data</em> directory. HTTP server must have write permission.',
-			'ok' => 'Permissions on the data directory are good.',
+			'nok' => 'Check permissions on <em>./data</em> directory. HTTP server must have write permission.',	// IGNORE
+			'ok' => 'Permissions on the data directory are good.',	// IGNORE
 		),
 		),
-		'database' => 'Database installation',
+		'database' => 'Database installation',	// IGNORE
 		'dom' => array(
 		'dom' => array(
-			'nok' => 'Cannot find a required library to browse the DOM (php-xml package).',
-			'ok' => 'You have the required library to browse the DOM.',
+			'nok' => 'Cannot find a required library to browse the DOM (php-xml package).',	// IGNORE
+			'ok' => 'You have the required library to browse the DOM.',	// IGNORE
 		),
 		),
 		'entries' => array(
 		'entries' => array(
-			'nok' => 'Entry table is improperly configured.',
-			'ok' => 'Entry table is okay.',
+			'nok' => 'Entry table is improperly configured.',	// IGNORE
+			'ok' => 'Entry table is okay.',	// IGNORE
 		),
 		),
 		'favicons' => array(
 		'favicons' => array(
-			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have write permission.',
-			'ok' => 'Permissions on the favicons directory are good.',
+			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have write permission.',	// IGNORE
+			'ok' => 'Permissions on the favicons directory are good.',	// IGNORE
 		),
 		),
 		'feeds' => array(
 		'feeds' => array(
-			'nok' => 'Feed table is improperly configured.',
-			'ok' => 'Feed table is okay.',
+			'nok' => 'Feed table is improperly configured.',	// IGNORE
+			'ok' => 'Feed table is okay.',	// IGNORE
 		),
 		),
 		'fileinfo' => array(
 		'fileinfo' => array(
-			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',
-			'ok' => 'You have the fileinfo library.',
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// IGNORE
+			'ok' => 'You have the fileinfo library.',	// IGNORE
 		),
 		),
-		'files' => 'File installation',
+		'files' => 'File installation',	// IGNORE
 		'json' => array(
 		'json' => array(
-			'nok' => 'Cannot find JSON (php-json package).',
-			'ok' => 'You have the JSON extension.',
+			'nok' => 'Cannot find JSON (php-json package).',	// IGNORE
+			'ok' => 'You have the JSON extension.',	// IGNORE
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended mbstring library for Unicode.',
-			'ok' => 'You have the recommended mbstring library for Unicode.',
+			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// IGNORE
+			'ok' => 'You have the recommended mbstring library for Unicode.',	// IGNORE
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
-			'nok' => 'Cannot find a required library for regular expressions (php-pcre).',
-			'ok' => 'You have the required library for regular expressions (PCRE).',
+			'nok' => 'Cannot find a required library for regular expressions (php-pcre).',	// IGNORE
+			'ok' => 'You have the required library for regular expressions (PCRE).',	// IGNORE
 		),
 		),
 		'pdo' => array(
 		'pdo' => array(
-			'nok' => 'Cannot find PDO or one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',
-			'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',
+			'nok' => 'Cannot find PDO or one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// IGNORE
+			'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// IGNORE
 		),
 		),
 		'php' => array(
 		'php' => array(
-			'_' => 'PHP installation',
-			'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.',
-			'ok' => 'Your PHP version (%s) is compatible with FreshRSS.',
+			'_' => 'PHP installation',	// IGNORE
+			'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.',	// IGNORE
+			'ok' => 'Your PHP version (%s) is compatible with FreshRSS.',	// IGNORE
 		),
 		),
 		'tables' => array(
 		'tables' => array(
-			'nok' => 'There are one or more missing tables in the database.',
-			'ok' => 'The appropriate tables exist in the database.',
+			'nok' => 'There are one or more missing tables in the database.',	// IGNORE
+			'ok' => 'The appropriate tables exist in the database.',	// IGNORE
 		),
 		),
-		'title' => 'Installation check',
+		'title' => 'Installation check',	// IGNORE
 		'tokens' => array(
 		'tokens' => array(
-			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have write permission',
-			'ok' => 'Permissions on the tokens directory are good.',
+			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have write permission',	// IGNORE
+			'ok' => 'Permissions on the tokens directory are good.',	// IGNORE
 		),
 		),
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have write permission',
-			'ok' => 'Permissions on the users directory are good.',
+			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have write permission',	// IGNORE
+			'ok' => 'Permissions on the users directory are good.',	// IGNORE
 		),
 		),
 		'zip' => array(
 		'zip' => array(
-			'nok' => 'Cannot find the ZIP extension (php-zip package).',
-			'ok' => 'You have the ZIP extension.',
+			'nok' => 'Cannot find the ZIP extension (php-zip package).',	// IGNORE
+			'ok' => 'You have the ZIP extension.',	// IGNORE
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
-		'author' => 'Author',
-		'community' => 'Available community extensions',
-		'description' => 'Description',
-		'disabled' => 'Disabled',
-		'empty_list' => 'There are no installed extensions',
-		'enabled' => 'Enabled',
-		'latest' => 'Installed',
-		'name' => 'Name',
-		'no_configure_view' => 'This extension cannot be configured.',
+		'author' => 'Author',	// IGNORE
+		'community' => 'Available community extensions',	// IGNORE
+		'description' => 'Description',	// IGNORE
+		'disabled' => 'Disabled',	// IGNORE
+		'empty_list' => 'There are no installed extensions',	// IGNORE
+		'enabled' => 'Enabled',	// IGNORE
+		'latest' => 'Installed',	// IGNORE
+		'name' => 'Name',	// IGNORE
+		'no_configure_view' => 'This extension cannot be configured.',	// IGNORE
 		'system' => array(
 		'system' => array(
-			'_' => 'System extensions',
-			'no_rights' => 'System extension (you do not have the required permissions)',
+			'_' => 'System extensions',	// IGNORE
+			'no_rights' => 'System extension (you do not have the required permissions)',	// IGNORE
 		),
 		),
-		'title' => 'Extensions',
-		'update' => 'Update available',
-		'user' => 'User extensions',
-		'version' => 'Version',
+		'title' => 'Extensions',	// IGNORE
+		'update' => 'Update available',	// IGNORE
+		'user' => 'User extensions',	// IGNORE
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'stats' => array(
 	'stats' => array(
-		'_' => 'Statistics',
-		'all_feeds' => 'All feeds',
-		'category' => 'Category',
-		'entry_count' => 'Entry count',
-		'entry_per_category' => 'Entries per category',
-		'entry_per_day' => 'Entries per day (last 30 days)',
-		'entry_per_day_of_week' => 'Per day of week (average: %.2f messages)',
-		'entry_per_hour' => 'Per hour (average: %.2f messages)',
-		'entry_per_month' => 'Per month (average: %.2f messages)',
-		'entry_repartition' => 'Entries repartition',
-		'feed' => 'Feed',
-		'feed_per_category' => 'Feeds per category',
-		'idle' => 'Idle feeds',
-		'main' => 'Main statistics',
-		'main_stream' => 'Main stream',
-		'no_idle' => 'There are no idle feeds!',
-		'number_entries' => '%d articles',
-		'percent_of_total' => '%% of total',
-		'repartition' => 'Articles repartition',
+		'_' => 'Statistics',	// IGNORE
+		'all_feeds' => 'All feeds',	// IGNORE
+		'category' => 'Category',	// IGNORE
+		'entry_count' => 'Entry count',	// IGNORE
+		'entry_per_category' => 'Entries per category',	// IGNORE
+		'entry_per_day' => 'Entries per day (last 30 days)',	// IGNORE
+		'entry_per_day_of_week' => 'Per day of week (average: %.2f messages)',	// IGNORE
+		'entry_per_hour' => 'Per hour (average: %.2f messages)',	// IGNORE
+		'entry_per_month' => 'Per month (average: %.2f messages)',	// IGNORE
+		'entry_repartition' => 'Entries repartition',	// IGNORE
+		'feed' => 'Feed',	// IGNORE
+		'feed_per_category' => 'Feeds per category',	// IGNORE
+		'idle' => 'Idle feeds',	// IGNORE
+		'main' => 'Main statistics',	// IGNORE
+		'main_stream' => 'Main stream',	// IGNORE
+		'no_idle' => 'There are no idle feeds!',	// IGNORE
+		'number_entries' => '%d articles',	// IGNORE
+		'percent_of_total' => '%% of total',	// IGNORE
+		'repartition' => 'Articles repartition',	// IGNORE
 		'status_favorites' => 'Favorites',
 		'status_favorites' => 'Favorites',
-		'status_read' => 'Read',
-		'status_total' => 'Total',
-		'status_unread' => 'Unread',
-		'title' => 'Statistics',
-		'top_feed' => 'Top ten feeds',
+		'status_read' => 'Read',	// IGNORE
+		'status_total' => 'Total',	// IGNORE
+		'status_unread' => 'Unread',	// IGNORE
+		'title' => 'Statistics',	// IGNORE
+		'top_feed' => 'Top ten feeds',	// IGNORE
 	),
 	),
 	'system' => array(
 	'system' => array(
-		'_' => 'System configuration',
-		'auto-update-url' => 'Auto-update server URL',
+		'_' => 'System configuration',	// IGNORE
+		'auto-update-url' => 'Auto-update server URL',	// IGNORE
 		'cookie-duration' => array(
 		'cookie-duration' => array(
-			'help' => 'in seconds',
-			'number' => 'Duration to keep logged in',
+			'help' => 'in seconds',	// IGNORE
+			'number' => 'Duration to keep logged in',	// IGNORE
 		),
 		),
-		'force_email_validation' => 'Force email address validation',
-		'instance-name' => 'Instance name',
-		'max-categories' => 'Max number of categories per user',
-		'max-feeds' => 'Max number of feeds per user',
+		'force_email_validation' => 'Force email address validation',	// IGNORE
+		'instance-name' => 'Instance name',	// IGNORE
+		'max-categories' => 'Max number of categories per user',	// IGNORE
+		'max-feeds' => 'Max number of feeds per user',	// IGNORE
 		'registration' => array(
 		'registration' => array(
-			'help' => '0 means that there is no account limit',
-			'number' => 'Max number of accounts',
+			'help' => '0 means that there is no account limit',	// IGNORE
+			'number' => 'Max number of accounts',	// IGNORE
 		),
 		),
 	),
 	),
 	'update' => array(
 	'update' => array(
-		'_' => 'Update system',
-		'apply' => 'Apply',
-		'check' => 'Check for new updates',
-		'current_version' => 'Your current version of FreshRSS is %s.',
-		'last' => 'Last verification: %s',
-		'none' => 'No update to apply',
-		'title' => 'Update system',
+		'_' => 'Update system',	// IGNORE
+		'apply' => 'Apply',	// IGNORE
+		'check' => 'Check for new updates',	// IGNORE
+		'current_version' => 'Your current version of FreshRSS is %s.',	// IGNORE
+		'last' => 'Last verification: %s',	// IGNORE
+		'none' => 'No update to apply',	// IGNORE
+		'title' => 'Update system',	// IGNORE
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'admin' => 'Administrator',
-		'article_count' => 'Articles',
-		'back_to_manage' => '← Return to user list',
-		'create' => 'Create new user',
-		'database_size' => 'Database size',
-		'email' => 'Email address',
-		'enabled' => 'Enabled',
-		'feed_count' => 'Feeds',
-		'is_admin' => 'Is admin',
-		'language' => 'Language',
-		'last_user_activity' => 'Last user activity',
-		'list' => 'User list',
-		'number' => 'There is %d account created',
-		'numbers' => 'There are %d accounts created',
-		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
-		'password_format' => 'At least 7 characters',
-		'title' => 'Manage users',
-		'username' => 'Username',
+		'admin' => 'Administrator',	// IGNORE
+		'article_count' => 'Articles',	// IGNORE
+		'back_to_manage' => '← Return to user list',	// IGNORE
+		'create' => 'Create new user',	// IGNORE
+		'database_size' => 'Database size',	// IGNORE
+		'email' => 'Email address',	// IGNORE
+		'enabled' => 'Enabled',	// IGNORE
+		'feed_count' => 'Feeds',	// IGNORE
+		'is_admin' => 'Is admin',	// IGNORE
+		'language' => 'Language',	// IGNORE
+		'last_user_activity' => 'Last user activity',	// IGNORE
+		'list' => 'User list',	// IGNORE
+		'number' => 'There is %d account created',	// IGNORE
+		'numbers' => 'There are %d accounts created',	// IGNORE
+		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',	// IGNORE
+		'password_format' => 'At least 7 characters',	// IGNORE
+		'title' => 'Manage users',	// IGNORE
+		'username' => 'Username',	// IGNORE
 	),
 	),
 );
 );

+ 182 - 172
app/i18n/en-us/conf.php

@@ -1,101 +1,111 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
-		'_' => 'Archiving',
-		'exception' => 'Purge exception',
-		'help' => 'More options are available in the individual feed\'s settings',
+		'_' => 'Archiving',	// IGNORE
+		'exception' => 'Purge exception',	// IGNORE
+		'help' => 'More options are available in the individual feed\'s settings',	// IGNORE
 		'keep_favourites' => 'Never delete favorites',
 		'keep_favourites' => 'Never delete favorites',
-		'keep_labels' => 'Never delete labels',
-		'keep_max' => 'Maximum number of articles to keep',
-		'keep_min_by_feed' => 'Minimum number of articles to keep per feed',
-		'keep_period' => 'Maximum age of articles to keep',
-		'keep_unreads' => 'Never delete unread articles',
-		'maintenance' => 'Maintenance',
-		'optimize' => 'Optimize database',
-		'optimize_help' => 'Run occasionally to reduce the size of the database',
-		'policy' => 'Purge policy',
-		'policy_warning' => 'If no purge policy is selected, every article will be kept.',
-		'purge_now' => 'Purge now',
-		'title' => 'Archiving',
-		'ttl' => 'Do not automatically refresh more often than',
+		'keep_labels' => 'Never delete labels',	// IGNORE
+		'keep_max' => 'Maximum number of articles to keep',	// IGNORE
+		'keep_min_by_feed' => 'Minimum number of articles to keep per feed',	// IGNORE
+		'keep_period' => 'Maximum age of articles to keep',	// IGNORE
+		'keep_unreads' => 'Never delete unread articles',	// IGNORE
+		'maintenance' => 'Maintenance',	// IGNORE
+		'optimize' => 'Optimize database',	// IGNORE
+		'optimize_help' => 'Run occasionally to reduce the size of the database',	// IGNORE
+		'policy' => 'Purge policy',	// IGNORE
+		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// IGNORE
+		'purge_now' => 'Purge now',	// IGNORE
+		'title' => 'Archiving',	// IGNORE
+		'ttl' => 'Do not automatically refresh more often than',	// IGNORE
 	),
 	),
 	'display' => array(
 	'display' => array(
-		'_' => 'Display',
+		'_' => 'Display',	// IGNORE
 		'icon' => array(
 		'icon' => array(
-			'bottom_line' => 'Bottom line',
-			'display_authors' => 'Authors',
-			'entry' => 'Article icons',
-			'publication_date' => 'Date of publication',
-			'related_tags' => 'Article tags',
-			'sharing' => 'Sharing',
-			'summary' => 'Summary',
-			'top_line' => 'Top line',
+			'bottom_line' => 'Bottom line',	// IGNORE
+			'display_authors' => 'Authors',	// IGNORE
+			'entry' => 'Article icons',	// IGNORE
+			'publication_date' => 'Date of publication',	// IGNORE
+			'related_tags' => 'Article tags',	// IGNORE
+			'sharing' => 'Sharing',	// IGNORE
+			'summary' => 'Summary',	// IGNORE
+			'top_line' => 'Top line',	// IGNORE
 		),
 		),
-		'language' => 'Language',
+		'language' => 'Language',	// IGNORE
 		'notif_html5' => array(
 		'notif_html5' => array(
-			'seconds' => 'seconds (0 means no timeout)',
-			'timeout' => 'HTML5 notification timeout',
+			'seconds' => 'seconds (0 means no timeout)',	// IGNORE
+			'timeout' => 'HTML5 notification timeout',	// IGNORE
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',
-		'theme' => 'Theme',
-		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',
+		'show_nav_buttons' => 'Show the navigation buttons',	// IGNORE
+		'theme' => 'Theme',	// IGNORE
+		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// IGNORE
 		'thumbnail' => array(
 		'thumbnail' => array(
-			'label' => 'Thumbnail',
-			'landscape' => 'Landscape',
-			'none' => 'None',
-			'portrait' => 'Portrait',
-			'square' => 'Square',
+			'label' => 'Thumbnail',	// IGNORE
+			'landscape' => 'Landscape',	// IGNORE
+			'none' => 'None',	// IGNORE
+			'portrait' => 'Portrait',	// IGNORE
+			'square' => 'Square',	// IGNORE
 		),
 		),
-		'title' => 'Display',
+		'title' => 'Display',	// IGNORE
 		'width' => array(
 		'width' => array(
-			'content' => 'Content width',
-			'large' => 'Wide',
-			'medium' => 'Medium',
-			'no_limit' => 'Full Width',
-			'thin' => 'Narrow',
+			'content' => 'Content width',	// IGNORE
+			'large' => 'Wide',	// IGNORE
+			'medium' => 'Medium',	// IGNORE
+			'no_limit' => 'Full Width',	// IGNORE
+			'thin' => 'Narrow',	// IGNORE
 		),
 		),
 	),
 	),
 	'profile' => array(
 	'profile' => array(
-		'_' => 'Profile management',
-		'api' => 'API management',
+		'_' => 'Profile management',	// IGNORE
+		'api' => 'API management',	// IGNORE
 		'delete' => array(
 		'delete' => array(
-			'_' => 'Account deletion',
-			'warn' => 'Your account and all related data will be deleted.',
+			'_' => 'Account deletion',	// IGNORE
+			'warn' => 'Your account and all related data will be deleted.',	// IGNORE
 		),
 		),
-		'email' => 'Email address',
-		'password_api' => 'API password<br /><small>(e.g., for mobile apps)</small>',
-		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
-		'password_format' => 'At least 7 characters',
-		'title' => 'Profile',
+		'email' => 'Email address',	// IGNORE
+		'password_api' => 'API password<br /><small>(e.g., for mobile apps)</small>',	// IGNORE
+		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',	// IGNORE
+		'password_format' => 'At least 7 characters',	// IGNORE
+		'title' => 'Profile',	// IGNORE
 	),
 	),
 	'query' => array(
 	'query' => array(
-		'_' => 'User queries',
-		'deprecated' => 'This query is no longer valid. The referenced category or feed has been deleted.',
+		'_' => 'User queries',	// IGNORE
+		'deprecated' => 'This query is no longer valid. The referenced category or feed has been deleted.',	// IGNORE
 		'filter' => array(
 		'filter' => array(
-			'_' => 'Filter applied:',
-			'categories' => 'Display by category',
-			'feeds' => 'Display by feed',
-			'order' => 'Sort by date',
-			'search' => 'Expression',
-			'state' => 'State',
-			'tags' => 'Display by tag',
-			'type' => 'Type',
+			'_' => 'Filter applied:',	// IGNORE
+			'categories' => 'Display by category',	// IGNORE
+			'feeds' => 'Display by feed',	// IGNORE
+			'order' => 'Sort by date',	// IGNORE
+			'search' => 'Expression',	// IGNORE
+			'state' => 'State',	// IGNORE
+			'tags' => 'Display by tag',	// IGNORE
+			'type' => 'Type',	// IGNORE
 		),
 		),
-		'get_all' => 'Display all articles',
-		'get_category' => 'Display "%s" category',
+		'get_all' => 'Display all articles',	// IGNORE
+		'get_category' => 'Display "%s" category',	// IGNORE
 		'get_favorite' => 'Display favorite articles',
 		'get_favorite' => 'Display favorite articles',
-		'get_feed' => 'Display "%s" feed',
-		'name' => 'Name',
-		'no_filter' => 'No filter',
-		'number' => 'Query n°%d',
-		'order_asc' => 'Display oldest articles first',
-		'order_desc' => 'Display newest articles first',
-		'search' => 'Search for "%s"',
-		'state_0' => 'Display all articles',
-		'state_1' => 'Display read articles',
-		'state_2' => 'Display unread articles',
-		'state_3' => 'Display all articles',
+		'get_feed' => 'Display "%s" feed',	// IGNORE
+		'name' => 'Name',	// IGNORE
+		'no_filter' => 'No filter',	// IGNORE
+		'number' => 'Query n°%d',	// IGNORE
+		'order_asc' => 'Display oldest articles first',	// IGNORE
+		'order_desc' => 'Display newest articles first',	// IGNORE
+		'search' => 'Search for "%s"',	// IGNORE
+		'state_0' => 'Display all articles',	// IGNORE
+		'state_1' => 'Display read articles',	// IGNORE
+		'state_2' => 'Display unread articles',	// IGNORE
+		'state_3' => 'Display all articles',	// IGNORE
 		'state_4' => 'Display favorite articles',
 		'state_4' => 'Display favorite articles',
 		'state_5' => 'Display read favorite articles',
 		'state_5' => 'Display read favorite articles',
 		'state_6' => 'Display unread favorite articles',
 		'state_6' => 'Display unread favorite articles',
@@ -104,121 +114,121 @@ return array(
 		'state_9' => 'Display read not favorite articles',
 		'state_9' => 'Display read not favorite articles',
 		'state_10' => 'Display unread not favorite articles',
 		'state_10' => 'Display unread not favorite articles',
 		'state_11' => 'Display not favorite articles',
 		'state_11' => 'Display not favorite articles',
-		'state_12' => 'Display all articles',
-		'state_13' => 'Display read articles',
-		'state_14' => 'Display unread articles',
-		'state_15' => 'Display all articles',
-		'title' => 'User queries',
+		'state_12' => 'Display all articles',	// IGNORE
+		'state_13' => 'Display read articles',	// IGNORE
+		'state_14' => 'Display unread articles',	// IGNORE
+		'state_15' => 'Display all articles',	// IGNORE
+		'title' => 'User queries',	// IGNORE
 	),
 	),
 	'reading' => array(
 	'reading' => array(
-		'_' => 'Reading',
-		'after_onread' => 'After “mark all as read”,',
+		'_' => 'Reading',	// IGNORE
+		'after_onread' => 'After “mark all as read”,',	// IGNORE
 		'always_show_favorites' => 'Show all articles in favorites by default',
 		'always_show_favorites' => 'Show all articles in favorites by default',
-		'articles_per_page' => 'Number of articles per page',
-		'auto_load_more' => 'Load more articles at the bottom of the page',
-		'auto_remove_article' => 'Hide articles after reading',
-		'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions',
-		'display_articles_unfolded' => 'Show articles unfolded by default',
-		'display_categories_unfolded' => 'Categories to unfold',
-		'hide_read_feeds' => 'Hide categories & feeds with no unread articles (does not work with “Show all articles” configuration)',
-		'img_with_lazyload' => 'Use "lazy load" mode to load pictures',
-		'jump_next' => 'jump to next unread sibling (feed or category)',
-		'mark_updated_article_unread' => 'Mark updated articles as unread',
-		'number_divided_when_reader' => 'Divide by 2 in the reading view.',
+		'articles_per_page' => 'Number of articles per page',	// IGNORE
+		'auto_load_more' => 'Load more articles at the bottom of the page',	// IGNORE
+		'auto_remove_article' => 'Hide articles after reading',	// IGNORE
+		'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions',	// IGNORE
+		'display_articles_unfolded' => 'Show articles unfolded by default',	// IGNORE
+		'display_categories_unfolded' => 'Categories to unfold',	// IGNORE
+		'hide_read_feeds' => 'Hide categories & feeds with no unread articles (does not work with “Show all articles” configuration)',	// IGNORE
+		'img_with_lazyload' => 'Use "lazy load" mode to load pictures',	// IGNORE
+		'jump_next' => 'jump to next unread sibling (feed or category)',	// IGNORE
+		'mark_updated_article_unread' => 'Mark updated articles as unread',	// IGNORE
+		'number_divided_when_reader' => 'Divide by 2 in the reading view.',	// IGNORE
 		'read' => array(
 		'read' => array(
-			'article_open_on_website' => 'when the article is opened on its original website',
-			'article_viewed' => 'when the article is viewed',
-			'keep_max_n_unread' => 'Max number of articles to keep unread',
-			'scroll' => 'while scrolling',
-			'upon_reception' => 'upon receiving the article',
-			'when' => 'Mark an article as read…',
-			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',
+			'article_open_on_website' => 'when the article is opened on its original website',	// IGNORE
+			'article_viewed' => 'when the article is viewed',	// IGNORE
+			'keep_max_n_unread' => 'Max number of articles to keep unread',	// IGNORE
+			'scroll' => 'while scrolling',	// IGNORE
+			'upon_reception' => 'upon receiving the article',	// IGNORE
+			'when' => 'Mark an article as read…',	// IGNORE
+			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// IGNORE
 		),
 		),
 		'show' => array(
 		'show' => array(
-			'_' => 'Articles to display',
-			'active_category' => 'Active category',
-			'adaptive' => 'Adjust showing',
-			'all_articles' => 'Show all articles',
-			'all_categories' => 'All categories',
-			'no_category' => 'No category',
-			'remember_categories' => 'Remember open categories',
-			'unread' => 'Show only unread',
+			'_' => 'Articles to display',	// IGNORE
+			'active_category' => 'Active category',	// IGNORE
+			'adaptive' => 'Adjust showing',	// IGNORE
+			'all_articles' => 'Show all articles',	// IGNORE
+			'all_categories' => 'All categories',	// IGNORE
+			'no_category' => 'No category',	// IGNORE
+			'remember_categories' => 'Remember open categories',	// IGNORE
+			'unread' => 'Show only unread',	// IGNORE
 		),
 		),
-		'show_fav_unread_help' => 'Applies also on labels',
-		'sides_close_article' => 'Clicking outside of article text area closes the article',
+		'show_fav_unread_help' => 'Applies also on labels',	// IGNORE
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	// IGNORE
 		'sort' => array(
 		'sort' => array(
-			'_' => 'Sort order',
-			'newer_first' => 'Newest first',
-			'older_first' => 'Oldest first',
+			'_' => 'Sort order',	// IGNORE
+			'newer_first' => 'Newest first',	// IGNORE
+			'older_first' => 'Oldest first',	// IGNORE
 		),
 		),
-		'sticky_post' => 'Stick the article to the top when opened',
-		'title' => 'Reading',
+		'sticky_post' => 'Stick the article to the top when opened',	// IGNORE
+		'title' => 'Reading',	// IGNORE
 		'view' => array(
 		'view' => array(
-			'default' => 'Default view',
-			'global' => 'Global view',
-			'normal' => 'Normal view',
-			'reader' => 'Reading view',
+			'default' => 'Default view',	// IGNORE
+			'global' => 'Global view',	// IGNORE
+			'normal' => 'Normal view',	// IGNORE
+			'reader' => 'Reading view',	// IGNORE
 		),
 		),
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
-		'_' => 'Sharing',
-		'add' => 'Add a sharing method',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
-		'more_information' => 'More information',
-		'print' => 'Print',
-		'raindrop' => 'Raindrop.io',
-		'remove' => 'Remove sharing method',
-		'shaarli' => 'Shaarli',
-		'share_name' => 'Share name to display',
-		'share_url' => 'Share URL to use',
-		'title' => 'Sharing',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'_' => 'Sharing',	// IGNORE
+		'add' => 'Add a sharing method',	// IGNORE
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// IGNORE
+		'facebook' => 'Facebook',	// IGNORE
+		'more_information' => 'More information',	// IGNORE
+		'print' => 'Print',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'remove' => 'Remove sharing method',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'share_name' => 'Share name to display',	// IGNORE
+		'share_url' => 'Share URL to use',	// IGNORE
+		'title' => 'Sharing',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
-		'_' => 'Shortcuts',
-		'article_action' => 'Article actions',
-		'auto_share' => 'Share',
-		'auto_share_help' => 'If there is only one sharing mode, it is used. Otherwise, modes are accessible by their number.',
-		'close_dropdown' => 'Close menus',
-		'collapse_article' => 'Collapse',
-		'first_article' => 'Open the first article',
-		'focus_search' => 'Access search box',
-		'global_view' => 'Switch to global view',
-		'help' => 'Display documentation',
-		'javascript' => 'JavaScript must be enabled in order to use shortcuts',
-		'last_article' => 'Open the last article',
-		'load_more' => 'Load more articles',
+		'_' => 'Shortcuts',	// IGNORE
+		'article_action' => 'Article actions',	// IGNORE
+		'auto_share' => 'Share',	// IGNORE
+		'auto_share_help' => 'If there is only one sharing mode, it is used. Otherwise, modes are accessible by their number.',	// IGNORE
+		'close_dropdown' => 'Close menus',	// IGNORE
+		'collapse_article' => 'Collapse',	// IGNORE
+		'first_article' => 'Open the first article',	// IGNORE
+		'focus_search' => 'Access search box',	// IGNORE
+		'global_view' => 'Switch to global view',	// IGNORE
+		'help' => 'Display documentation',	// IGNORE
+		'javascript' => 'JavaScript must be enabled in order to use shortcuts',	// IGNORE
+		'last_article' => 'Open the last article',	// IGNORE
+		'load_more' => 'Load more articles',	// IGNORE
 		'mark_favorite' => 'Toggle favorite',
 		'mark_favorite' => 'Toggle favorite',
-		'mark_read' => 'Toggle read',
-		'navigation' => 'Navigation',
-		'navigation_help' => 'With the <kbd>⇧ Shift</kbd> modifier, navigation shortcuts apply on feeds.<br/>With the <kbd>Alt ⎇</kbd> modifier, navigation shortcuts apply on categories.',
-		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',
-		'next_article' => 'Open the next article',
-		'next_unread_article' => 'Open the next unread article',
-		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',
-		'normal_view' => 'Switch to normal view',
-		'other_action' => 'Other actions',
-		'previous_article' => 'Open the previous article',
-		'reading_view' => 'Switch to reading view',
-		'rss_view' => 'Open as RSS feed',
-		'see_on_website' => 'See on original website',
-		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',
-		'skip_next_article' => 'Focus next without opening',
-		'skip_previous_article' => 'Focus previous without opening',
-		'title' => 'Shortcuts',
-		'toggle_media' => 'Play/pause media',
-		'user_filter' => 'Access user queries',
-		'user_filter_help' => 'If there is only one user query, it is used. Otherwise, queries are accessible by their number.',
-		'views' => 'Views',
+		'mark_read' => 'Toggle read',	// IGNORE
+		'navigation' => 'Navigation',	// IGNORE
+		'navigation_help' => 'With the <kbd>⇧ Shift</kbd> modifier, navigation shortcuts apply on feeds.<br/>With the <kbd>Alt ⎇</kbd> modifier, navigation shortcuts apply on categories.',	// IGNORE
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// IGNORE
+		'next_article' => 'Open the next article',	// IGNORE
+		'next_unread_article' => 'Open the next unread article',	// IGNORE
+		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// IGNORE
+		'normal_view' => 'Switch to normal view',	// IGNORE
+		'other_action' => 'Other actions',	// IGNORE
+		'previous_article' => 'Open the previous article',	// IGNORE
+		'reading_view' => 'Switch to reading view',	// IGNORE
+		'rss_view' => 'Open as RSS feed',	// IGNORE
+		'see_on_website' => 'See on original website',	// IGNORE
+		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// IGNORE
+		'skip_next_article' => 'Focus next without opening',	// IGNORE
+		'skip_previous_article' => 'Focus previous without opening',	// IGNORE
+		'title' => 'Shortcuts',	// IGNORE
+		'toggle_media' => 'Play/pause media',	// IGNORE
+		'user_filter' => 'Access user queries',	// IGNORE
+		'user_filter_help' => 'If there is only one user query, it is used. Otherwise, queries are accessible by their number.',	// IGNORE
+		'views' => 'Views',	// IGNORE
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)',
-		'current' => 'Current user',
-		'is_admin' => 'is administrator',
-		'users' => 'Users',
+		'articles_and_size' => '%s articles (%s)',	// IGNORE
+		'current' => 'Current user',	// IGNORE
+		'is_admin' => 'is administrator',	// IGNORE
+		'users' => 'Users',	// IGNORE
 	),
 	),
 );
 );

+ 92 - 82
app/i18n/en-us/feedback.php

@@ -1,134 +1,144 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
-		'denied' => 'You don’t have permission to access this page',
-		'not_found' => 'You are looking for a page that doesn’t exist',
+		'denied' => 'You don’t have permission to access this page',	// IGNORE
+		'not_found' => 'You are looking for a page that doesn’t exist',	// IGNORE
 	),
 	),
 	'admin' => array(
 	'admin' => array(
-		'optimization_complete' => 'Optimization complete',
+		'optimization_complete' => 'Optimization complete',	// IGNORE
 	),
 	),
 	'api' => array(
 	'api' => array(
 		'password' => array(
 		'password' => array(
-			'failed' => 'Your password cannot be modified',
-			'updated' => 'Your password has been modified',
+			'failed' => 'Your password cannot be modified',	// IGNORE
+			'updated' => 'Your password has been modified',	// IGNORE
 		),
 		),
 	),
 	),
 	'auth' => array(
 	'auth' => array(
 		'login' => array(
 		'login' => array(
-			'invalid' => 'Login is invalid',
-			'success' => 'You are connected',
+			'invalid' => 'Login is invalid',	// IGNORE
+			'success' => 'You are connected',	// IGNORE
 		),
 		),
 		'logout' => array(
 		'logout' => array(
-			'success' => 'You are disconnected',
+			'success' => 'You are disconnected',	// IGNORE
 		),
 		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
-		'error' => 'An error occurred while saving configuration',
-		'query_created' => 'Query "%s" has been created.',
-		'shortcuts_updated' => 'Shortcuts have been updated',
-		'updated' => 'Configuration has been updated',
+		'error' => 'An error occurred while saving configuration',	// IGNORE
+		'query_created' => 'Query "%s" has been created.',	// IGNORE
+		'shortcuts_updated' => 'Shortcuts have been updated',	// IGNORE
+		'updated' => 'Configuration has been updated',	// IGNORE
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
-		'already_enabled' => '%s is already enabled',
-		'cannot_remove' => '%s cannot be removed',
+		'already_enabled' => '%s is already enabled',	// IGNORE
+		'cannot_remove' => '%s cannot be removed',	// IGNORE
 		'disable' => array(
 		'disable' => array(
-			'ko' => '%s cannot be disabled. <a href="%s">Check FreshRSS logs</a> for details.',
-			'ok' => '%s is now disabled',
+			'ko' => '%s cannot be disabled. <a href="%s">Check FreshRSS logs</a> for details.',	// IGNORE
+			'ok' => '%s is now disabled',	// IGNORE
 		),
 		),
 		'enable' => array(
 		'enable' => array(
-			'ko' => '%s cannot be enabled. <a href="%s">Check FreshRSS logs</a> for details.',
-			'ok' => '%s is now enabled',
+			'ko' => '%s cannot be enabled. <a href="%s">Check FreshRSS logs</a> for details.',	// IGNORE
+			'ok' => '%s is now enabled',	// IGNORE
 		),
 		),
-		'no_access' => 'You have no access on %s',
-		'not_enabled' => '%s is not enabled',
-		'not_found' => '%s does not exist',
-		'removed' => '%s removed',
+		'no_access' => 'You have no access on %s',	// IGNORE
+		'not_enabled' => '%s is not enabled',	// IGNORE
+		'not_found' => '%s does not exist',	// IGNORE
+		'removed' => '%s removed',	// IGNORE
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
-		'export_no_zip_extension' => 'The ZIP extension is not present on your server. Please try to export files one by one.',
-		'feeds_imported' => 'Your feeds have been imported and will now be updated',
-		'feeds_imported_with_errors' => 'Your feeds have been imported, but some errors occurred',
-		'file_cannot_be_uploaded' => 'File cannot be uploaded!',
-		'no_zip_extension' => 'The ZIP extension is not present on your server.',
-		'zip_error' => 'An error occurred during ZIP import.',
+		'export_no_zip_extension' => 'The ZIP extension is not present on your server. Please try to export files one by one.',	// IGNORE
+		'feeds_imported' => 'Your feeds have been imported and will now be updated',	// IGNORE
+		'feeds_imported_with_errors' => 'Your feeds have been imported, but some errors occurred',	// IGNORE
+		'file_cannot_be_uploaded' => 'File cannot be uploaded!',	// IGNORE
+		'no_zip_extension' => 'The ZIP extension is not present on your server.',	// IGNORE
+		'zip_error' => 'An error occurred during ZIP import.',	// IGNORE
 	),
 	),
 	'profile' => array(
 	'profile' => array(
-		'error' => 'Your profile cannot be modified',
-		'updated' => 'Your profile has been modified',
+		'error' => 'Your profile cannot be modified',	// IGNORE
+		'updated' => 'Your profile has been modified',	// IGNORE
 	),
 	),
 	'sub' => array(
 	'sub' => array(
-		'actualize' => 'Updating',
+		'actualize' => 'Updating',	// IGNORE
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',
-			'marked_unread' => 'The articles have been marked as unread.',
+			'marked_read' => 'The selected articles have been marked as read.',	// IGNORE
+			'marked_unread' => 'The articles have been marked as unread.',	// IGNORE
 		),
 		),
 		'category' => array(
 		'category' => array(
-			'created' => 'Category %s has been created.',
-			'deleted' => 'Category has been deleted.',
-			'emptied' => 'Category has been emptied',
-			'error' => 'Category cannot be updated',
-			'name_exists' => 'Category name already exists.',
-			'no_id' => 'You must specify the id of the category.',
-			'no_name' => 'Category name cannot be empty.',
-			'not_delete_default' => 'You cannot delete the default category!',
-			'not_exist' => 'The category does not exist!',
-			'over_max' => 'You have reached your limit of categories (%d)',
-			'updated' => 'Category has been updated.',
+			'created' => 'Category %s has been created.',	// IGNORE
+			'deleted' => 'Category has been deleted.',	// IGNORE
+			'emptied' => 'Category has been emptied',	// IGNORE
+			'error' => 'Category cannot be updated',	// IGNORE
+			'name_exists' => 'Category name already exists.',	// IGNORE
+			'no_id' => 'You must specify the id of the category.',	// IGNORE
+			'no_name' => 'Category name cannot be empty.',	// IGNORE
+			'not_delete_default' => 'You cannot delete the default category!',	// IGNORE
+			'not_exist' => 'The category does not exist!',	// IGNORE
+			'over_max' => 'You have reached your limit of categories (%d)',	// IGNORE
+			'updated' => 'Category has been updated.',	// IGNORE
 		),
 		),
 		'feed' => array(
 		'feed' => array(
-			'actualized' => '<em>%s</em> has been updated',
-			'actualizeds' => 'RSS feeds have been updated',
-			'added' => 'RSS feed <em>%s</em> has been added',
-			'already_subscribed' => 'You have already subscribed to <em>%s</em>',
-			'cache_cleared' => '<em>%s</em> cache has been cleared',
-			'deleted' => 'Feed has been deleted',
-			'error' => 'Feed cannot be updated',
-			'internal_problem' => 'The newsfeed could not be added. <a href="%s">Check FreshRSS logs</a> for details. You can try force adding by appending <code>#force_feed</code> to the URL.',
-			'invalid_url' => 'URL <em>%s</em> is invalid',
-			'n_actualized' => '%d feeds have been updated',
-			'n_entries_deleted' => '%d articles have been deleted',
-			'no_refresh' => 'There are no feeds to refresh',
-			'not_added' => '<em>%s</em> could not be added',
-			'not_found' => 'Feed cannot be found',
-			'over_max' => 'You have reached your limit of feeds (%d)',
-			'reloaded' => '<em>%s</em> has been reloaded',
+			'actualized' => '<em>%s</em> has been updated',	// IGNORE
+			'actualizeds' => 'RSS feeds have been updated',	// IGNORE
+			'added' => 'RSS feed <em>%s</em> has been added',	// IGNORE
+			'already_subscribed' => 'You have already subscribed to <em>%s</em>',	// IGNORE
+			'cache_cleared' => '<em>%s</em> cache has been cleared',	// IGNORE
+			'deleted' => 'Feed has been deleted',	// IGNORE
+			'error' => 'Feed cannot be updated',	// IGNORE
+			'internal_problem' => 'The newsfeed could not be added. <a href="%s">Check FreshRSS logs</a> for details. You can try force adding by appending <code>#force_feed</code> to the URL.',	// IGNORE
+			'invalid_url' => 'URL <em>%s</em> is invalid',	// IGNORE
+			'n_actualized' => '%d feeds have been updated',	// IGNORE
+			'n_entries_deleted' => '%d articles have been deleted',	// IGNORE
+			'no_refresh' => 'There are no feeds to refresh',	// IGNORE
+			'not_added' => '<em>%s</em> could not be added',	// IGNORE
+			'not_found' => 'Feed cannot be found',	// IGNORE
+			'over_max' => 'You have reached your limit of feeds (%d)',	// IGNORE
+			'reloaded' => '<em>%s</em> has been reloaded',	// IGNORE
 			'selector_preview' => array(
 			'selector_preview' => array(
-				'http_error' => 'Failed to load website content.',
-				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',
-				'no_feed' => 'Internal error (feed cannot be found).',
-				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',
-				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',
+				'http_error' => 'Failed to load website content.',	// IGNORE
+				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// IGNORE
+				'no_feed' => 'Internal error (feed cannot be found).',	// IGNORE
+				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// IGNORE
+				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// IGNORE
 			),
 			),
-			'updated' => 'Feed has been updated',
+			'updated' => 'Feed has been updated',	// IGNORE
 		),
 		),
-		'purge_completed' => 'Purge completed (%d articles deleted)',
+		'purge_completed' => 'Purge completed (%d articles deleted)',	// IGNORE
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'created' => 'Tag "%s" has been created.',
-		'name_exists' => 'Tag name already exists.',
-		'renamed' => 'Tag "%s" has been renamed to "%s".',
+		'created' => 'Tag "%s" has been created.',	// IGNORE
+		'name_exists' => 'Tag name already exists.',	// IGNORE
+		'renamed' => 'Tag "%s" has been renamed to "%s".',	// IGNORE
 	),
 	),
 	'update' => array(
 	'update' => array(
-		'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.',
-		'error' => 'The update process has encountered an error: %s',
-		'file_is_nok' => 'New <strong>version %s</strong> available, but check permissions on <em>%s</em> directory. HTTP server must have have write permission',
-		'finished' => 'Update complete!',
-		'none' => 'No update to apply',
-		'server_not_found' => 'Update server cannot be found. [%s]',
+		'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.',	// IGNORE
+		'error' => 'The update process has encountered an error: %s',	// IGNORE
+		'file_is_nok' => 'New <strong>version %s</strong> available, but check permissions on <em>%s</em> directory. HTTP server must have have write permission',	// IGNORE
+		'finished' => 'Update complete!',	// IGNORE
+		'none' => 'No update to apply',	// IGNORE
+		'server_not_found' => 'Update server cannot be found. [%s]',	// IGNORE
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'created' => array(
 		'created' => array(
-			'_' => 'User %s has been created',
-			'error' => 'User %s cannot be created',
+			'_' => 'User %s has been created',	// IGNORE
+			'error' => 'User %s cannot be created',	// IGNORE
 		),
 		),
 		'deleted' => array(
 		'deleted' => array(
-			'_' => 'User %s has been deleted',
-			'error' => 'User %s cannot be deleted',
+			'_' => 'User %s has been deleted',	// IGNORE
+			'error' => 'User %s cannot be deleted',	// IGNORE
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated',
-			'error' => 'User %s has not been updated',
+			'_' => 'User %s has been updated',	// IGNORE
+			'error' => 'User %s has not been updated',	// IGNORE
 		),
 		),
 	),
 	),
 );
 );

+ 191 - 181
app/i18n/en-us/gen.php

@@ -1,219 +1,229 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
-		'actualize' => 'Update feeds',
-		'add' => 'Add',
-		'back' => '← Go back',
-		'back_to_rss_feeds' => '← Go back to your RSS feeds',
-		'cancel' => 'Cancel',
-		'create' => 'Create',
-		'demote' => 'Demote',
-		'disable' => 'Disable',
-		'empty' => 'Empty',
-		'enable' => 'Enable',
-		'export' => 'Export',
-		'filter' => 'Filter',
-		'import' => 'Import',
-		'load_default_shortcuts' => 'Load default shortcuts',
-		'manage' => 'Manage',
-		'mark_read' => 'Mark as read',
-		'promote' => 'Promote',
-		'purge' => 'Purge',
-		'remove' => 'Remove',
-		'rename' => 'Rename',
-		'see_website' => 'See website',
-		'submit' => 'Submit',
-		'truncate' => 'Delete all articles',
-		'update' => 'Update',
+		'actualize' => 'Update feeds',	// IGNORE
+		'add' => 'Add',	// IGNORE
+		'back' => '← Go back',	// IGNORE
+		'back_to_rss_feeds' => '← Go back to your RSS feeds',	// IGNORE
+		'cancel' => 'Cancel',	// IGNORE
+		'create' => 'Create',	// IGNORE
+		'demote' => 'Demote',	// IGNORE
+		'disable' => 'Disable',	// IGNORE
+		'empty' => 'Empty',	// IGNORE
+		'enable' => 'Enable',	// IGNORE
+		'export' => 'Export',	// IGNORE
+		'filter' => 'Filter',	// IGNORE
+		'import' => 'Import',	// IGNORE
+		'load_default_shortcuts' => 'Load default shortcuts',	// IGNORE
+		'manage' => 'Manage',	// IGNORE
+		'mark_read' => 'Mark as read',	// IGNORE
+		'promote' => 'Promote',	// IGNORE
+		'purge' => 'Purge',	// IGNORE
+		'remove' => 'Remove',	// IGNORE
+		'rename' => 'Rename',	// IGNORE
+		'see_website' => 'See website',	// IGNORE
+		'submit' => 'Submit',	// IGNORE
+		'truncate' => 'Delete all articles',	// IGNORE
+		'update' => 'Update',	// IGNORE
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',
-		'email' => 'Email address',
-		'keep_logged_in' => 'Keep me logged in <small>(%s days)</small>',
-		'login' => 'Login',
-		'logout' => 'Logout',
+		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// IGNORE
+		'email' => 'Email address',	// IGNORE
+		'keep_logged_in' => 'Keep me logged in <small>(%s days)</small>',	// IGNORE
+		'login' => 'Login',	// IGNORE
+		'logout' => 'Logout',	// IGNORE
 		'password' => array(
 		'password' => array(
-			'_' => 'Password',
-			'format' => '<small>At least 7 characters</small>',
+			'_' => 'Password',	// IGNORE
+			'format' => '<small>At least 7 characters</small>',	// IGNORE
 		),
 		),
 		'registration' => array(
 		'registration' => array(
-			'_' => 'New account',
-			'ask' => 'Create an account?',
-			'title' => 'Account creation',
+			'_' => 'New account',	// IGNORE
+			'ask' => 'Create an account?',	// IGNORE
+			'title' => 'Account creation',	// IGNORE
 		),
 		),
 		'username' => array(
 		'username' => array(
-			'_' => 'Username',
-			'format' => '<small>Maximum 16 alphanumeric characters</small>',
+			'_' => 'Username',	// IGNORE
+			'format' => '<small>Maximum 16 alphanumeric characters</small>',	// IGNORE
 		),
 		),
 	),
 	),
 	'date' => array(
 	'date' => array(
-		'Apr' => '\\A\\p\\r\\i\\l',
-		'Aug' => '\\A\\u\\g\\u\\s\\t',
-		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
-		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',
-		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',
-		'Jul' => '\\J\\u\\l\\y',
-		'Jun' => '\\J\\u\\n\\e',
-		'Mar' => '\\M\\a\\r\\c\\h',
-		'May' => '\\M\\a\\y',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
-		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',
-		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
-		'apr' => 'Apr.',
-		'april' => 'April',
-		'aug' => 'Aug.',
-		'august' => 'August',
-		'before_yesterday' => 'Before yesterday',
-		'dec' => 'Dec.',
-		'december' => 'December',
-		'feb' => 'Feb.',
-		'february' => 'February',
+		'Apr' => '\\A\\p\\r\\i\\l',	// IGNORE
+		'Aug' => '\\A\\u\\g\\u\\s\\t',	// IGNORE
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',	// IGNORE
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',	// IGNORE
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',	// IGNORE
+		'Jul' => '\\J\\u\\l\\y',	// IGNORE
+		'Jun' => '\\J\\u\\n\\e',	// IGNORE
+		'Mar' => '\\M\\a\\r\\c\\h',	// IGNORE
+		'May' => '\\M\\a\\y',	// IGNORE
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',	// IGNORE
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',	// IGNORE
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',	// IGNORE
+		'apr' => 'Apr.',	// IGNORE
+		'april' => 'April',	// IGNORE
+		'aug' => 'Aug.',	// IGNORE
+		'august' => 'August',	// IGNORE
+		'before_yesterday' => 'Before yesterday',	// IGNORE
+		'dec' => 'Dec.',	// IGNORE
+		'december' => 'December',	// IGNORE
+		'feb' => 'Feb.',	// IGNORE
+		'february' => 'February',	// IGNORE
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t g\\:i a',
 		'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t g\\:i a',
-		'fri' => 'Fri',
-		'jan' => 'Jan.',
-		'january' => 'January',
-		'jul' => 'July',
-		'july' => 'July',
-		'jun' => 'June',
-		'june' => 'June',
-		'last_2_year' => 'Last two years',
-		'last_3_month' => 'Last three months',
-		'last_3_year' => 'Last three years',
-		'last_5_year' => 'Last five years',
-		'last_6_month' => 'Last six months',
-		'last_month' => 'Last month',
-		'last_week' => 'Last week',
-		'last_year' => 'Last year',
-		'mar' => 'Mar.',
-		'march' => 'March',
-		'may' => 'May',
-		'may_' => 'May',
-		'mon' => 'Mon',
-		'month' => 'months',
-		'nov' => 'Nov.',
-		'november' => 'November',
-		'oct' => 'Oct.',
-		'october' => 'October',
-		'sat' => 'Sat',
-		'sep' => 'Sept.',
-		'september' => 'September',
-		'sun' => 'Sun',
-		'thu' => 'Thu',
-		'today' => 'Today',
-		'tue' => 'Tue',
-		'wed' => 'Wed',
-		'yesterday' => 'Yesterday',
+		'fri' => 'Fri',	// IGNORE
+		'jan' => 'Jan.',	// IGNORE
+		'january' => 'January',	// IGNORE
+		'jul' => 'July',	// IGNORE
+		'july' => 'July',	// IGNORE
+		'jun' => 'June',	// IGNORE
+		'june' => 'June',	// IGNORE
+		'last_2_year' => 'Last two years',	// IGNORE
+		'last_3_month' => 'Last three months',	// IGNORE
+		'last_3_year' => 'Last three years',	// IGNORE
+		'last_5_year' => 'Last five years',	// IGNORE
+		'last_6_month' => 'Last six months',	// IGNORE
+		'last_month' => 'Last month',	// IGNORE
+		'last_week' => 'Last week',	// IGNORE
+		'last_year' => 'Last year',	// IGNORE
+		'mar' => 'Mar.',	// IGNORE
+		'march' => 'March',	// IGNORE
+		'may' => 'May',	// IGNORE
+		'may_' => 'May',	// IGNORE
+		'mon' => 'Mon',	// IGNORE
+		'month' => 'months',	// IGNORE
+		'nov' => 'Nov.',	// IGNORE
+		'november' => 'November',	// IGNORE
+		'oct' => 'Oct.',	// IGNORE
+		'october' => 'October',	// IGNORE
+		'sat' => 'Sat',	// IGNORE
+		'sep' => 'Sept.',	// IGNORE
+		'september' => 'September',	// IGNORE
+		'sun' => 'Sun',	// IGNORE
+		'thu' => 'Thu',	// IGNORE
+		'today' => 'Today',	// IGNORE
+		'tue' => 'Tue',	// IGNORE
+		'wed' => 'Wed',	// IGNORE
+		'yesterday' => 'Yesterday',	// IGNORE
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
-		'about' => 'About FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
+		'about' => 'About FreshRSS',	// IGNORE
 	),
 	),
 	'js' => array(
 	'js' => array(
-		'category_empty' => 'Empty category',
+		'category_empty' => 'Empty category',	// IGNORE
 		'confirm_action' => 'Are you sure you want to perform this action? It cannot be canceled!',
 		'confirm_action' => 'Are you sure you want to perform this action? It cannot be canceled!',
 		'confirm_action_feed_cat' => 'Are you sure you want to perform this action? You will lose related favorites and user queries. It cannot be canceled!',
 		'confirm_action_feed_cat' => 'Are you sure you want to perform this action? You will lose related favorites and user queries. It cannot be canceled!',
 		'feedback' => array(
 		'feedback' => array(
-			'body_new_articles' => 'There are %%d new articles to read on FreshRSS.',
-			'request_failed' => 'A request has failed, it may have been caused by internet connection problems.',
-			'title_new_articles' => 'FreshRSS: new articles!',
+			'body_new_articles' => 'There are %%d new articles to read on FreshRSS.',	// IGNORE
+			'request_failed' => 'A request has failed, it may have been caused by internet connection problems.',	// IGNORE
+			'title_new_articles' => 'FreshRSS: new articles!',	// IGNORE
 		),
 		),
-		'new_article' => 'There are new articles available, click to refresh the page.',
-		'should_be_activated' => 'JavaScript must be enabled',
+		'new_article' => 'There are new articles available, click to refresh the page.',	// IGNORE
+		'should_be_activated' => 'JavaScript must be enabled',	// IGNORE
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'about' => 'About',
-		'account' => 'Account',
-		'admin' => 'Administration',
-		'archiving' => 'Archiving',
-		'authentication' => 'Authentication',
-		'check_install' => 'Installation check',
-		'configuration' => 'Configuration',
-		'display' => 'Display',
-		'extensions' => 'Extensions',
-		'logs' => 'Logs',
-		'queries' => 'User queries',
-		'reading' => 'Reading',
-		'search' => 'Search words or #tags',
-		'sharing' => 'Sharing',
-		'shortcuts' => 'Shortcuts',
-		'stats' => 'Statistics',
-		'system' => 'System configuration',
-		'update' => 'Update',
-		'user_management' => 'Manage users',
-		'user_profile' => 'Profile',
+		'about' => 'About',	// IGNORE
+		'account' => 'Account',	// IGNORE
+		'admin' => 'Administration',	// IGNORE
+		'archiving' => 'Archiving',	// IGNORE
+		'authentication' => 'Authentication',	// IGNORE
+		'check_install' => 'Installation check',	// IGNORE
+		'configuration' => 'Configuration',	// IGNORE
+		'display' => 'Display',	// IGNORE
+		'extensions' => 'Extensions',	// IGNORE
+		'logs' => 'Logs',	// IGNORE
+		'queries' => 'User queries',	// IGNORE
+		'reading' => 'Reading',	// IGNORE
+		'search' => 'Search words or #tags',	// IGNORE
+		'sharing' => 'Sharing',	// IGNORE
+		'shortcuts' => 'Shortcuts',	// IGNORE
+		'stats' => 'Statistics',	// IGNORE
+		'system' => 'System configuration',	// IGNORE
+		'update' => 'Update',	// IGNORE
+		'user_management' => 'Manage users',	// IGNORE
+		'user_profile' => 'Profile',	// IGNORE
 	),
 	),
 	'pagination' => array(
 	'pagination' => array(
-		'first' => 'First',
-		'last' => 'Last',
-		'load_more' => 'Load more articles',
-		'mark_all_read' => 'Mark all as read',
-		'next' => 'Next',
-		'nothing_to_load' => 'There are no more articles',
-		'previous' => 'Previous',
+		'first' => 'First',	// IGNORE
+		'last' => 'Last',	// IGNORE
+		'load_more' => 'Load more articles',	// IGNORE
+		'mark_all_read' => 'Mark all as read',	// IGNORE
+		'next' => 'Next',	// IGNORE
+		'nothing_to_load' => 'There are no more articles',	// IGNORE
+		'previous' => 'Previous',	// IGNORE
 	),
 	),
 	'period' => array(
 	'period' => array(
-		'days' => 'days',
-		'hours' => 'hours',
-		'months' => 'months',
-		'weeks' => 'weeks',
-		'years' => 'years',
+		'days' => 'days',	// IGNORE
+		'hours' => 'hours',	// IGNORE
+		'months' => 'months',	// IGNORE
+		'weeks' => 'weeks',	// IGNORE
+		'years' => 'years',	// IGNORE
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
-		'blogotext' => 'Blogotext',
-		'clipboard' => 'Clipboard',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
-		'print' => 'Print',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'Known' => 'Known based sites',	// IGNORE
+		'blogotext' => 'Blogotext',	// IGNORE
+		'clipboard' => 'Clipboard',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// IGNORE
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
+		'print' => 'Print',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
-		'attention' => 'Warning!',
-		'blank_to_disable' => 'Leave blank to disable',
-		'by_author' => 'By:',
-		'by_default' => 'By default',
-		'damn' => 'Blast!',
-		'default_category' => 'Uncategorized',
-		'no' => 'No',
-		'not_applicable' => 'Not available',
-		'ok' => 'Okay!',
-		'or' => 'or',
-		'yes' => 'Yes',
+		'attention' => 'Warning!',	// IGNORE
+		'blank_to_disable' => 'Leave blank to disable',	// IGNORE
+		'by_author' => 'By:',	// IGNORE
+		'by_default' => 'By default',	// IGNORE
+		'damn' => 'Blast!',	// IGNORE
+		'default_category' => 'Uncategorized',	// IGNORE
+		'no' => 'No',	// IGNORE
+		'not_applicable' => 'Not available',	// IGNORE
+		'ok' => 'Okay!',	// IGNORE
+		'or' => 'or',	// IGNORE
+		'yes' => 'Yes',	// IGNORE
 	),
 	),
 );
 );

+ 55 - 45
app/i18n/en-us/index.php

@@ -1,65 +1,75 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
-		'_' => 'About',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
-		'bugs_reports' => 'Bug reports',
-		'credits' => 'Credits',
-		'credits_content' => 'Some design elements come from <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> although FreshRSS doesn’t use this framework. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> come from <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> font police has been created by <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS is based on <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, a PHP framework.',
-		'freshrss_description' => 'FreshRSS is a RSS feeds aggregator to self-host like <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> or <a href="https://github.com/LeedRSS/Leed">Leed</a>. It is light and easy to take in hand while being powerful and configurable tool.',
-		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">on Github</a>',
-		'license' => 'License',
-		'project_website' => 'Project website',
-		'title' => 'About',
-		'version' => 'Version',
+		'_' => 'About',	// IGNORE
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
+		'bugs_reports' => 'Bug reports',	// IGNORE
+		'credits' => 'Credits',	// IGNORE
+		'credits_content' => 'Some design elements come from <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> although FreshRSS doesn’t use this framework. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> come from <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> font police has been created by <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS is based on <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, a PHP framework.',	// IGNORE
+		'freshrss_description' => 'FreshRSS is a RSS feeds aggregator to self-host like <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> or <a href="https://github.com/LeedRSS/Leed">Leed</a>. It is light and easy to take in hand while being powerful and configurable tool.',	// IGNORE
+		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">on Github</a>',	// IGNORE
+		'license' => 'License',	// IGNORE
+		'project_website' => 'Project website',	// IGNORE
+		'title' => 'About',	// IGNORE
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'feed' => array(
 	'feed' => array(
-		'add' => 'Please add some feeds.',
-		'empty' => 'There are no articles to show.',
-		'rss_of' => 'RSS feed of %s',
-		'title' => 'Main stream',
+		'add' => 'Please add some feeds.',	// IGNORE
+		'empty' => 'There are no articles to show.',	// IGNORE
+		'rss_of' => 'RSS feed of %s',	// IGNORE
+		'title' => 'Main stream',	// IGNORE
 		'title_fav' => 'Favorites',
 		'title_fav' => 'Favorites',
-		'title_global' => 'Global view',
+		'title_global' => 'Global view',	// IGNORE
 	),
 	),
 	'log' => array(
 	'log' => array(
-		'_' => 'Logs',
-		'clear' => 'Clear the logs',
-		'empty' => 'Log file is empty',
-		'title' => 'Logs',
+		'_' => 'Logs',	// IGNORE
+		'clear' => 'Clear the logs',	// IGNORE
+		'empty' => 'Log file is empty',	// IGNORE
+		'title' => 'Logs',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'about' => 'About FreshRSS',
-		'before_one_day' => 'Older than one day',
-		'before_one_week' => 'Older than one week',
-		'bookmark_query' => 'Bookmark current query',
+		'about' => 'About FreshRSS',	// IGNORE
+		'before_one_day' => 'Older than one day',	// IGNORE
+		'before_one_week' => 'Older than one week',	// IGNORE
+		'bookmark_query' => 'Bookmark current query',	// IGNORE
 		'favorites' => 'Favorites (%s)',
 		'favorites' => 'Favorites (%s)',
-		'global_view' => 'Global view',
-		'main_stream' => 'Main stream',
-		'mark_all_read' => 'Mark all as read',
-		'mark_cat_read' => 'Mark category as read',
-		'mark_feed_read' => 'Mark feed as read',
-		'mark_selection_unread' => 'Mark selection as unread',
-		'newer_first' => 'Newer first',
+		'global_view' => 'Global view',	// IGNORE
+		'main_stream' => 'Main stream',	// IGNORE
+		'mark_all_read' => 'Mark all as read',	// IGNORE
+		'mark_cat_read' => 'Mark category as read',	// IGNORE
+		'mark_feed_read' => 'Mark feed as read',	// IGNORE
+		'mark_selection_unread' => 'Mark selection as unread',	// IGNORE
+		'newer_first' => 'Newer first',	// IGNORE
 		'non-starred' => 'Show non-favorites',
 		'non-starred' => 'Show non-favorites',
-		'normal_view' => 'Normal view',
-		'older_first' => 'Oldest first',
-		'queries' => 'User queries',
-		'read' => 'Show read',
-		'reader_view' => 'Reading view',
-		'rss_view' => 'RSS feed',
-		'search_short' => 'Search',
+		'normal_view' => 'Normal view',	// IGNORE
+		'older_first' => 'Oldest first',	// IGNORE
+		'queries' => 'User queries',	// IGNORE
+		'read' => 'Show read',	// IGNORE
+		'reader_view' => 'Reading view',	// IGNORE
+		'rss_view' => 'RSS feed',	// IGNORE
+		'search_short' => 'Search',	// IGNORE
 		'starred' => 'Show favorites',
 		'starred' => 'Show favorites',
-		'stats' => 'Statistics',
-		'subscription' => 'Subscription management',
-		'tags' => 'My labels',
-		'unread' => 'Show unread',
+		'stats' => 'Statistics',	// IGNORE
+		'subscription' => 'Subscription management',	// IGNORE
+		'tags' => 'My labels',	// IGNORE
+		'unread' => 'Show unread',	// IGNORE
 	),
 	),
-	'share' => 'Share',
+	'share' => 'Share',	// IGNORE
 	'tag' => array(
 	'tag' => array(
-		'related' => 'Article tags',
+		'related' => 'Article tags',	// IGNORE
 	),
 	),
 	'tos' => array(
 	'tos' => array(
-		'title' => 'Terms of Service',
+		'title' => 'Terms of Service',	// IGNORE
 	),
 	),
 );
 );

+ 79 - 69
app/i18n/en-us/install.php

@@ -1,123 +1,133 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
-		'finish' => 'Complete installation',
-		'fix_errors_before' => 'Please all fix errors before continuing to the next step.',
-		'keep_install' => 'Keep previous configuration',
-		'next_step' => 'Go to the next step',
-		'reinstall' => 'Reinstall FreshRSS',
+		'finish' => 'Complete installation',	// IGNORE
+		'fix_errors_before' => 'Please all fix errors before continuing to the next step.',	// IGNORE
+		'keep_install' => 'Keep previous configuration',	// IGNORE
+		'next_step' => 'Go to the next step',	// IGNORE
+		'reinstall' => 'Reinstall FreshRSS',	// IGNORE
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'form' => 'Web form (traditional, requires JavaScript)',
-		'http' => 'HTTP (for advanced users with HTTPS)',
-		'none' => 'None (dangerous)',
-		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
-		'password_format' => 'At least 7 characters',
-		'type' => 'Authentication method',
+		'form' => 'Web form (traditional, requires JavaScript)',	// IGNORE
+		'http' => 'HTTP (for advanced users with HTTPS)',	// IGNORE
+		'none' => 'None (dangerous)',	// IGNORE
+		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',	// IGNORE
+		'password_format' => 'At least 7 characters',	// IGNORE
+		'type' => 'Authentication method',	// IGNORE
 	),
 	),
 	'bdd' => array(
 	'bdd' => array(
-		'_' => 'Database',
+		'_' => 'Database',	// IGNORE
 		'conf' => array(
 		'conf' => array(
-			'_' => 'Database configuration',
-			'ko' => 'Verify your database configuration.',
-			'ok' => 'Database configuration has been saved.',
-		),
-		'host' => 'Host',
-		'password' => 'Database password',
-		'prefix' => 'Table prefix',
-		'type' => 'Type of database',
-		'username' => 'Database username',
+			'_' => 'Database configuration',	// IGNORE
+			'ko' => 'Verify your database configuration.',	// IGNORE
+			'ok' => 'Database configuration has been saved.',	// IGNORE
+		),
+		'host' => 'Host',	// IGNORE
+		'password' => 'Database password',	// IGNORE
+		'prefix' => 'Table prefix',	// IGNORE
+		'type' => 'Type of database',	// IGNORE
+		'username' => 'Database username',	// IGNORE
 	),
 	),
 	'check' => array(
 	'check' => array(
-		'_' => 'Checks',
-		'already_installed' => 'We have detected that FreshRSS is already installed!',
+		'_' => 'Checks',	// IGNORE
+		'already_installed' => 'We have detected that FreshRSS is already installed!',	// IGNORE
 		'cache' => array(
 		'cache' => array(
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
-			'ok' => 'Permissions on the cache directory are good.',
+			'ok' => 'Permissions on the cache directory are good.',	// IGNORE
 		),
 		),
 		'ctype' => array(
 		'ctype' => array(
-			'nok' => 'Cannot find the required library for character type checking (php-ctype).',
-			'ok' => 'You have the required library for character type checking (ctype).',
+			'nok' => 'Cannot find the required library for character type checking (php-ctype).',	// IGNORE
+			'ok' => 'You have the required library for character type checking (ctype).',	// IGNORE
 		),
 		),
 		'curl' => array(
 		'curl' => array(
-			'nok' => 'Cannot find the cURL library (php-curl package).',
-			'ok' => 'You have the cURL library.',
+			'nok' => 'Cannot find the cURL library (php-curl package).',	// IGNORE
+			'ok' => 'You have the cURL library.',	// IGNORE
 		),
 		),
 		'data' => array(
 		'data' => array(
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
-			'ok' => 'Permissions on the data directory are good.',
+			'ok' => 'Permissions on the data directory are good.',	// IGNORE
 		),
 		),
 		'dom' => array(
 		'dom' => array(
-			'nok' => 'Cannot find the required library to browse the DOM.',
-			'ok' => 'You have the required library to browse the DOM.',
+			'nok' => 'Cannot find the required library to browse the DOM.',	// IGNORE
+			'ok' => 'You have the required library to browse the DOM.',	// IGNORE
 		),
 		),
 		'favicons' => array(
 		'favicons' => array(
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
-			'ok' => 'Permissions on the favicons directory are good.',
+			'ok' => 'Permissions on the favicons directory are good.',	// IGNORE
 		),
 		),
 		'fileinfo' => array(
 		'fileinfo' => array(
-			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',
-			'ok' => 'You have the fileinfo library.',
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// IGNORE
+			'ok' => 'You have the fileinfo library.',	// IGNORE
 		),
 		),
 		'json' => array(
 		'json' => array(
-			'nok' => 'Cannot find the recommended library to parse JSON.',
-			'ok' => 'You have the recommended library to parse JSON.',
+			'nok' => 'Cannot find the recommended library to parse JSON.',	// IGNORE
+			'ok' => 'You have the recommended library to parse JSON.',	// IGNORE
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',
-			'ok' => 'You have the recommended library mbstring for Unicode.',
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// IGNORE
+			'ok' => 'You have the recommended library mbstring for Unicode.',	// IGNORE
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
-			'nok' => 'Cannot find the required library for regular expressions (php-pcre).',
-			'ok' => 'You have the required library for regular expressions (PCRE).',
+			'nok' => 'Cannot find the required library for regular expressions (php-pcre).',	// IGNORE
+			'ok' => 'You have the required library for regular expressions (PCRE).',	// IGNORE
 		),
 		),
 		'pdo' => array(
 		'pdo' => array(
-			'nok' => 'Cannot find PDO or one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',
-			'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',
+			'nok' => 'Cannot find PDO or one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// IGNORE
+			'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// IGNORE
 		),
 		),
 		'php' => array(
 		'php' => array(
-			'nok' => 'Your PHP version is %s, but FreshRSS requires at least version %s.',
-			'ok' => 'Your PHP version, %s, is compatible with FreshRSS.',
+			'nok' => 'Your PHP version is %s, but FreshRSS requires at least version %s.',	// IGNORE
+			'ok' => 'Your PHP version, %s, is compatible with FreshRSS.',	// IGNORE
 		),
 		),
-		'reload' => 'Check again',
+		'reload' => 'Check again',	// IGNORE
 		'tmp' => array(
 		'tmp' => array(
-			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
-			'ok' => 'Permissions on the temp directory are good.',
+			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',	// IGNORE
+			'ok' => 'Permissions on the temp directory are good.',	// IGNORE
 		),
 		),
-		'unknown_process_username' => 'unknown',
+		'unknown_process_username' => 'unknown',	// IGNORE
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
-			'ok' => 'Permissions on the users directory are good.',
+			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',	// IGNORE
+			'ok' => 'Permissions on the users directory are good.',	// IGNORE
 		),
 		),
 		'xml' => array(
 		'xml' => array(
-			'nok' => 'Cannot find the required library to parse XML.',
-			'ok' => 'You have the required library to parse XML.',
+			'nok' => 'Cannot find the required library to parse XML.',	// IGNORE
+			'ok' => 'You have the required library to parse XML.',	// IGNORE
 		),
 		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
-		'_' => 'General configuration',
-		'ok' => 'General configuration has been saved.',
+		'_' => 'General configuration',	// IGNORE
+		'ok' => 'General configuration has been saved.',	// IGNORE
 	),
 	),
-	'congratulations' => 'Congratulations!',
-	'default_user' => 'Username of the default user <small>(maximum 16 alphanumeric characters)</small>',
-	'fix_errors_before' => 'Please fix errors before continuing to the next step.',
-	'javascript_is_better' => 'FreshRSS is more pleasant with JavaScript enabled',
+	'congratulations' => 'Congratulations!',	// IGNORE
+	'default_user' => 'Username of the default user <small>(maximum 16 alphanumeric characters)</small>',	// IGNORE
+	'fix_errors_before' => 'Please fix errors before continuing to the next step.',	// IGNORE
+	'javascript_is_better' => 'FreshRSS is more pleasant with JavaScript enabled',	// IGNORE
 	'js' => array(
 	'js' => array(
-		'confirm_reinstall' => 'You will lose your previous configuration by reinstalling FreshRSS. Are you sure you want to continue?',
+		'confirm_reinstall' => 'You will lose your previous configuration by reinstalling FreshRSS. Are you sure you want to continue?',	// IGNORE
 	),
 	),
 	'language' => array(
 	'language' => array(
-		'_' => 'Language',
-		'choose' => 'Choose a language for FreshRSS',
-		'defined' => 'Language has been defined.',
+		'_' => 'Language',	// IGNORE
+		'choose' => 'Choose a language for FreshRSS',	// IGNORE
+		'defined' => 'Language has been defined.',	// IGNORE
 	),
 	),
-	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',
-	'ok' => 'The installation process was successful.',
+	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// IGNORE
+	'ok' => 'The installation process was successful.',	// IGNORE
 	'session' => array(
 	'session' => array(
-		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',
+		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// IGNORE
 	),
 	),
-	'step' => 'step %d',
-	'steps' => 'Steps',
-	'this_is_the_end' => 'This is the end',
-	'title' => 'Installation · FreshRSS',
+	'step' => 'step %d',	// IGNORE
+	'steps' => 'Steps',	// IGNORE
+	'this_is_the_end' => 'This is the end',	// IGNORE
+	'title' => 'Installation · FreshRSS',	// IGNORE
 );
 );

+ 107 - 97
app/i18n/en-us/sub.php

@@ -1,138 +1,148 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',
-		'title' => 'API',
+		'documentation' => 'Copy the following URL to use it within an external tool.',	// IGNORE
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',
-		'label' => 'Subscribe',
-		'title' => 'Bookmarklet',
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// IGNORE
+		'label' => 'Subscribe',	// IGNORE
+		'title' => 'Bookmarklet',	// IGNORE
 	),
 	),
 	'category' => array(
 	'category' => array(
-		'_' => 'Category',
-		'add' => 'Add a category',
-		'archiving' => 'Archiving',
-		'empty' => 'Empty category',
-		'information' => 'Information',
-		'position' => 'Display position',
-		'position_help' => 'To control category sort order',
-		'title' => 'Title',
+		'_' => 'Category',	// IGNORE
+		'add' => 'Add a category',	// IGNORE
+		'archiving' => 'Archiving',	// IGNORE
+		'empty' => 'Empty category',	// IGNORE
+		'information' => 'Information',	// IGNORE
+		'position' => 'Display position',	// IGNORE
+		'position_help' => 'To control category sort order',	// IGNORE
+		'title' => 'Title',	// IGNORE
 	),
 	),
 	'feed' => array(
 	'feed' => array(
-		'add' => 'Add a RSS feed',
-		'advanced' => 'Advanced',
-		'archiving' => 'Archiving',
+		'add' => 'Add a RSS feed',	// IGNORE
+		'advanced' => 'Advanced',	// IGNORE
+		'archiving' => 'Archiving',	// IGNORE
 		'auth' => array(
 		'auth' => array(
-			'configuration' => 'Login',
-			'help' => 'Allows access to HTTP protected RSS feeds',
-			'http' => 'HTTP Authentication',
-			'password' => 'HTTP password',
-			'username' => 'HTTP username',
+			'configuration' => 'Login',	// IGNORE
+			'help' => 'Allows access to HTTP protected RSS feeds',	// IGNORE
+			'http' => 'HTTP Authentication',	// IGNORE
+			'password' => 'HTTP password',	// IGNORE
+			'username' => 'HTTP username',	// IGNORE
 		),
 		),
-		'clear_cache' => 'Always clear cache',
+		'clear_cache' => 'Always clear cache',	// IGNORE
 		'content_action' => array(
 		'content_action' => array(
-			'_' => 'Content action when fetching the article content',
-			'append' => 'Add after existing content',
-			'prepend' => 'Add before existing content',
-			'replace' => 'Replace existing content',
+			'_' => 'Content action when fetching the article content',	// IGNORE
+			'append' => 'Add after existing content',	// IGNORE
+			'prepend' => 'Add before existing content',	// IGNORE
+			'replace' => 'Replace existing content',	// IGNORE
 		),
 		),
-		'css_cookie' => 'Use Cookies when fetching the article content',
-		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',
-		'css_help' => 'Retrieves truncated RSS feeds (caution, requires more time!)',
-		'css_path' => 'Article CSS selector on original website',
-		'description' => 'Description',
-		'empty' => 'This feed is empty. Please verify that it is still maintained.',
-		'error' => 'This feed has encountered a problem. Please verify that it is always reachable then update it.',
+		'css_cookie' => 'Use Cookies when fetching the article content',	// IGNORE
+		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// IGNORE
+		'css_help' => 'Retrieves truncated RSS feeds (caution, requires more time!)',	// IGNORE
+		'css_path' => 'Article CSS selector on original website',	// IGNORE
+		'description' => 'Description',	// IGNORE
+		'empty' => 'This feed is empty. Please verify that it is still maintained.',	// IGNORE
+		'error' => 'This feed has encountered a problem. Please verify that it is always reachable then update it.',	// IGNORE
 		'filteractions' => array(
 		'filteractions' => array(
-			'_' => 'Filter actions',
-			'help' => 'Write one search filter per line.',
+			'_' => 'Filter actions',	// IGNORE
+			'help' => 'Write one search filter per line.',	// IGNORE
 		),
 		),
-		'information' => 'Information',
-		'keep_min' => 'Minimum number of articles to keep',
+		'information' => 'Information',	// IGNORE
+		'keep_min' => 'Minimum number of articles to keep',	// IGNORE
 		'maintenance' => array(
 		'maintenance' => array(
-			'clear_cache' => 'Clear cache',
-			'clear_cache_help' => 'Clear the cache for this feed.',
-			'reload_articles' => 'Reload articles',
-			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',
-			'title' => 'Maintenance',
+			'clear_cache' => 'Clear cache',	// IGNORE
+			'clear_cache_help' => 'Clear the cache for this feed.',	// IGNORE
+			'reload_articles' => 'Reload articles',	// IGNORE
+			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// IGNORE
+			'title' => 'Maintenance',	// IGNORE
 		),
 		),
-		'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',
-		'mute' => 'mute',
-		'no_selected' => 'No feed selected.',
-		'number_entries' => '%d articles',
+		'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',	// IGNORE
+		'mute' => 'mute',	// IGNORE
+		'no_selected' => 'No feed selected.',	// IGNORE
+		'number_entries' => '%d articles',	// IGNORE
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility',
-			'archived' => 'Do not show (archived)',
-			'main_stream' => 'Show in main stream',
-			'normal' => 'Show in its category',
+			'_' => 'Visibility',	// IGNORE
+			'archived' => 'Do not show (archived)',	// IGNORE
+			'main_stream' => 'Show in main stream',	// IGNORE
+			'normal' => 'Show in its category',	// IGNORE
 		),
 		),
-		'proxy' => 'Set a proxy for fetching this feed',
-		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',
+		'proxy' => 'Set a proxy for fetching this feed',	// IGNORE
+		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// IGNORE
 		'selector_preview' => array(
 		'selector_preview' => array(
-			'show_raw' => 'Show source code',
-			'show_rendered' => 'Show content',
+			'show_raw' => 'Show source code',	// IGNORE
+			'show_rendered' => 'Show content',	// IGNORE
 		),
 		),
 		'show' => array(
 		'show' => array(
-			'all' => 'Show all feeds',
-			'error' => 'Show only feeds with errors',
+			'all' => 'Show all feeds',	// IGNORE
+			'error' => 'Show only feeds with errors',	// IGNORE
 		),
 		),
 		'showing' => array(
 		'showing' => array(
-			'error' => 'Showing only feeds with errors',
+			'error' => 'Showing only feeds with errors',	// IGNORE
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',
-		'stats' => 'Statistics',
-		'think_to_add' => 'You may add some feeds.',
-		'timeout' => 'Timeout in seconds',
-		'title' => 'Title',
-		'title_add' => 'Add an RSS feed',
-		'ttl' => 'Do not automatically refresh more often than',
-		'url' => 'Feed URL',
-		'useragent' => 'Set the user agent for fetching this feed',
-		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',
-		'validator' => 'Check the validity of the feed',
-		'website' => 'Website URL',
-		'websub' => 'Instant notification with WebSub',
+		'ssl_verify' => 'Verify SSL security',	// IGNORE
+		'stats' => 'Statistics',	// IGNORE
+		'think_to_add' => 'You may add some feeds.',	// IGNORE
+		'timeout' => 'Timeout in seconds',	// IGNORE
+		'title' => 'Title',	// IGNORE
+		'title_add' => 'Add an RSS feed',	// IGNORE
+		'ttl' => 'Do not automatically refresh more often than',	// IGNORE
+		'url' => 'Feed URL',	// IGNORE
+		'useragent' => 'Set the user agent for fetching this feed',	// IGNORE
+		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// IGNORE
+		'validator' => 'Check the validity of the feed',	// IGNORE
+		'website' => 'Website URL',	// IGNORE
+		'websub' => 'Instant notification with WebSub',	// IGNORE
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
-		'export' => 'Export',
+		'export' => 'Export',	// IGNORE
 		'export_labelled' => 'Export your labeled articles',
 		'export_labelled' => 'Export your labeled articles',
-		'export_opml' => 'Export list of feeds (OPML)',
+		'export_opml' => 'Export list of feeds (OPML)',	// IGNORE
 		'export_starred' => 'Export your favorites',
 		'export_starred' => 'Export your favorites',
-		'feed_list' => 'List of %s articles',
-		'file_to_import' => 'File to import<br />(OPML, JSON or ZIP)',
-		'file_to_import_no_zip' => 'File to import<br />(OPML or JSON)',
-		'import' => 'Import',
+		'feed_list' => 'List of %s articles',	// IGNORE
+		'file_to_import' => 'File to import<br />(OPML, JSON or ZIP)',	// IGNORE
+		'file_to_import_no_zip' => 'File to import<br />(OPML or JSON)',	// IGNORE
+		'import' => 'Import',	// IGNORE
 		'starred_list' => 'List of favorite articles',
 		'starred_list' => 'List of favorite articles',
-		'title' => 'Import / export',
+		'title' => 'Import / export',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'add' => 'Add a feed or category',
-		'import_export' => 'Import / export',
-		'label_management' => 'Label management',
+		'add' => 'Add a feed or category',	// IGNORE
+		'import_export' => 'Import / export',	// IGNORE
+		'label_management' => 'Label management',	// IGNORE
 		'stats' => array(
 		'stats' => array(
-			'idle' => 'Idle feeds',
-			'main' => 'Main statistics',
-			'repartition' => 'Articles repartition',
+			'idle' => 'Idle feeds',	// IGNORE
+			'main' => 'Main statistics',	// IGNORE
+			'repartition' => 'Articles repartition',	// IGNORE
 		),
 		),
-		'subscription_management' => 'Subscription management',
-		'subscription_tools' => 'Subscription tools',
+		'subscription_management' => 'Subscription management',	// IGNORE
+		'subscription_tools' => 'Subscription tools',	// IGNORE
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'name' => 'Name',
-		'new_name' => 'New name',
-		'old_name' => 'Old name',
+		'name' => 'Name',	// IGNORE
+		'new_name' => 'New name',	// IGNORE
+		'old_name' => 'Old name',	// IGNORE
 	),
 	),
 	'title' => array(
 	'title' => array(
-		'_' => 'Subscription management',
-		'add' => 'Add a feed or category',
-		'add_category' => 'Add a category',
-		'add_feed' => 'Add a feed',
-		'add_label' => 'Add a label',
-		'delete_label' => 'Delete a label',
-		'feed_management' => 'RSS feeds management',
-		'rename_label' => 'Rename a label',
-		'subscription_tools' => 'Subscription tools',
+		'_' => 'Subscription management',	// IGNORE
+		'add' => 'Add a feed or category',	// IGNORE
+		'add_category' => 'Add a category',	// IGNORE
+		'add_feed' => 'Add a feed',	// IGNORE
+		'add_label' => 'Add a label',	// IGNORE
+		'delete_label' => 'Delete a label',	// IGNORE
+		'feed_management' => 'RSS feeds management',	// IGNORE
+		'rename_label' => 'Rename a label',	// IGNORE
+		'subscription_tools' => 'Subscription tools',	// IGNORE
 	),
 	),
 );
 );

+ 30 - 20
app/i18n/en-us/user.php

@@ -1,44 +1,54 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'This email address is invalid.',
-			'required' => 'An email address is required.',
+			'invalid' => 'This email address is invalid.',	// IGNORE
+			'required' => 'An email address is required.',	// IGNORE
 		),
 		),
 		'validation' => array(
 		'validation' => array(
-			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',
-			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',
+			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// IGNORE
+			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// IGNORE
 			'feedback' => array(
 			'feedback' => array(
-				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',
-				'email_sent' => 'An email has been sent to your address.',
-				'error' => 'Email address validation failed.',
-				'ok' => 'This email address has been validated.',
-				'unnecessary' => 'This email address was already validated.',
-				'wrong_token' => 'This email address failed to be validated due to a wrong token.',
+				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// IGNORE
+				'email_sent' => 'An email has been sent to your address.',	// IGNORE
+				'error' => 'Email address validation failed.',	// IGNORE
+				'ok' => 'This email address has been validated.',	// IGNORE
+				'unnecessary' => 'This email address was already validated.',	// IGNORE
+				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// IGNORE
 			),
 			),
-			'need_to' => 'You need to validate your email address before being able to use %s.',
-			'resend_email' => 'Resend the email',
-			'title' => 'Email address validation',
+			'need_to' => 'You need to validate your email address before being able to use %s.',	// IGNORE
+			'resend_email' => 'Resend the email',	// IGNORE
+			'title' => 'Email address validation',	// IGNORE
 		),
 		),
 	),
 	),
 	'mailer' => array(
 	'mailer' => array(
 		'email_need_validation' => array(
 		'email_need_validation' => array(
-			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',
-			'title' => 'You need to validate your account',
-			'welcome' => 'Welcome %s,',
+			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// IGNORE
+			'title' => 'You need to validate your account',	// IGNORE
+			'welcome' => 'Welcome %s,',	// IGNORE
 		),
 		),
 	),
 	),
 	'password' => array(
 	'password' => array(
-		'invalid' => 'The password is invalid.',
+		'invalid' => 'The password is invalid.',	// IGNORE
 	),
 	),
 	'tos' => array(
 	'tos' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'You must accept the Terms of Service to be able to register.',
+			'invalid' => 'You must accept the Terms of Service to be able to register.',	// IGNORE
 		),
 		),
 	),
 	),
 	'username' => array(
 	'username' => array(
-		'invalid' => 'This username is invalid.',
-		'taken' => 'This username, %s, is taken.',
+		'invalid' => 'This username is invalid.',	// IGNORE
+		'taken' => 'This username, %s, is taken.',	// IGNORE
 	),
 	),
 );
 );

+ 10 - 0
app/i18n/en/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Allow anonymous reading of the default user\'s articles (%s)',
 		'allow_anonymous' => 'Allow anonymous reading of the default user\'s articles (%s)',

+ 10 - 0
app/i18n/en/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archiving',
 		'_' => 'Archiving',

+ 10 - 0
app/i18n/en/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'You don’t have permission to access this page',
 		'denied' => 'You don’t have permission to access this page',

+ 10 - 0
app/i18n/en/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Update feeds',
 		'actualize' => 'Update feeds',

+ 10 - 0
app/i18n/en/index.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'About',
 		'_' => 'About',

+ 10 - 0
app/i18n/en/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Complete installation',
 		'finish' => 'Complete installation',

+ 10 - 0
app/i18n/en/sub.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => 'Copy the following URL to use it within an external tool.',
 		'documentation' => 'Copy the following URL to use it within an external tool.',

+ 10 - 0
app/i18n/en/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 12 - 2
app/i18n/es/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Permitir la lectura anónima de los artículos del usuario por defecto (%s)',
 		'allow_anonymous' => 'Permitir la lectura anónima de los artículos del usuario por defecto (%s)',
@@ -141,7 +151,7 @@ return array(
 		'repartition' => 'Reprto de artículos',
 		'repartition' => 'Reprto de artículos',
 		'status_favorites' => 'Favoritos',
 		'status_favorites' => 'Favoritos',
 		'status_read' => 'Leídos',
 		'status_read' => 'Leídos',
-		'status_total' => 'Total',
+		'status_total' => 'Total',	// IGNORE
 		'status_unread' => 'Pendientes',
 		'status_unread' => 'Pendientes',
 		'title' => 'Estadísticas',
 		'title' => 'Estadísticas',
 		'top_feed' => 'Las 10 fuentes más activas',
 		'top_feed' => 'Las 10 fuentes más activas',
@@ -179,7 +189,7 @@ return array(
 		'database_size' => 'Tamaño de la base de datos',
 		'database_size' => 'Tamaño de la base de datos',
 		'email' => 'Dirección de correo electrónico',
 		'email' => 'Dirección de correo electrónico',
 		'enabled' => 'Permitido',
 		'enabled' => 'Permitido',
-		'feed_count' => 'Feeds',
+		'feed_count' => 'Feeds',	// IGNORE
 		'is_admin' => 'Es admin',
 		'is_admin' => 'Es admin',
 		'language' => 'Idioma',
 		'language' => 'Idioma',
 		'last_user_activity' => 'Última actividad del usuario',
 		'last_user_activity' => 'Última actividad del usuario',

+ 18 - 8
app/i18n/es/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archivo',
 		'_' => 'Archivo',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Compartir',
 		'_' => 'Compartir',
 		'add' => 'Agregar un método de uso compartido',
 		'add' => 'Agregar un método de uso compartido',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// TODO
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Más información',
 		'more_information' => 'Más información',
 		'print' => 'Imprimir',
 		'print' => 'Imprimir',
-		'raindrop' => 'Raindrop.io',
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => 'Quitar método de uso compartido',
 		'remove' => 'Quitar método de uso compartido',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Compartir nombre a mostrar',
 		'share_name' => 'Compartir nombre a mostrar',
 		'share_url' => 'Compatir URL a usar',
 		'share_url' => 'Compatir URL a usar',
 		'title' => 'Compartir',
 		'title' => 'Compartir',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Atajos de teclado',
 		'_' => 'Atajos de teclado',

+ 10 - 0
app/i18n/es/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'No dispones de permiso para acceder a esta página',
 		'denied' => 'No dispones de permiso para acceder a esta página',

+ 50 - 40
app/i18n/es/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Actualizar fuentes',
 		'actualize' => 'Actualizar fuentes',
@@ -69,8 +79,8 @@ return array(
 		'december' => 'diciembre',
 		'december' => 'diciembre',
 		'feb' => 'feb',
 		'feb' => 'feb',
 		'february' => 'febrero',
 		'february' => 'febrero',
-		'format_date' => 'j %s Y',
-		'format_date_hour' => 'j %s Y \\a\\t H\\:i',
+		'format_date' => 'j %s Y',	// IGNORE
+		'format_date_hour' => 'j %s Y \\a\\t H\\:i',	// IGNORE
 		'fri' => 'Vie',
 		'fri' => 'Vie',
 		'jan' => 'ene',
 		'jan' => 'ene',
 		'january' => 'ene',
 		'january' => 'ene',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'Mie',
 		'wed' => 'Mie',
 		'yesterday' => 'Ayer',
 		'yesterday' => 'Ayer',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'Acerca de FreshRSS',
 		'about' => 'Acerca de FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,24 +134,24 @@ return array(
 		'should_be_activated' => 'JavaScript debe estar activado',
 		'should_be_activated' => 'JavaScript debe estar activado',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'Acerca de',
 		'about' => 'Acerca de',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Sitios basados en conocidos',
 		'Known' => 'Sitios basados en conocidos',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'Portapapeles',
 		'clipboard' => 'Portapapeles',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// IGNORE
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Imprimir',
 		'print' => 'Imprimir',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => '¡Aviso!',
 		'attention' => '¡Aviso!',
@@ -210,7 +220,7 @@ return array(
 		'by_default' => 'Por defecto',
 		'by_default' => 'Por defecto',
 		'damn' => '¡Córcholis!',
 		'damn' => '¡Córcholis!',
 		'default_category' => 'Sin categorizar',
 		'default_category' => 'Sin categorizar',
-		'no' => 'No',
+		'no' => 'No',	// IGNORE
 		'not_applicable' => 'No disponible',
 		'not_applicable' => 'No disponible',
 		'ok' => '¡Vale!',
 		'ok' => '¡Vale!',
 		'or' => 'o',
 		'or' => 'o',

+ 11 - 1
app/i18n/es/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'Acerca de',
 		'_' => 'Acerca de',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Informe de fallos',
 		'bugs_reports' => 'Informe de fallos',
 		'credits' => 'Créditos',
 		'credits' => 'Créditos',
 		'credits_content' => 'Aunque FreshRSS no usa ese entorno, algunos elementos del diseño están obtenidos de <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>. Los <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Iconos</a> han sido obtenidos del <a href="https://www.gnome.org/">proyecto GNOME</a>. La fuente <em>Open Sans</em> es una creación de <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS usa el entorno PHP <a href="https://github.com/marienfressinaud/MINZ">Minz</a>.',
 		'credits_content' => 'Aunque FreshRSS no usa ese entorno, algunos elementos del diseño están obtenidos de <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>. Los <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Iconos</a> han sido obtenidos del <a href="https://www.gnome.org/">proyecto GNOME</a>. La fuente <em>Open Sans</em> es una creación de <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS usa el entorno PHP <a href="https://github.com/marienfressinaud/MINZ">Minz</a>.',

+ 10 - 0
app/i18n/es/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Completar instalación',
 		'finish' => 'Completar instalación',

+ 12 - 2
app/i18n/es/sub.php

@@ -1,14 +1,24 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => 'Copie la siguiente URL para usarla dentro de una herramienta externa.',
 		'documentation' => 'Copie la siguiente URL para usarla dentro de una herramienta externa.',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'Arrastre este botón a la barra de herramientas de marcadores o haga clic derecho en él y elija "Marcar este enlace". Luego haga clic en el botón "Suscribirse" en cualquier página a la que desee suscribirse.',
 		'documentation' => 'Arrastre este botón a la barra de herramientas de marcadores o haga clic derecho en él y elija "Marcar este enlace". Luego haga clic en el botón "Suscribirse" en cualquier página a la que desee suscribirse.',
 		'label' => 'Subscribirse',
 		'label' => 'Subscribirse',
-		'title' => 'Bookmarklet',
+		'title' => 'Bookmarklet',	// IGNORE
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categoría',
 		'_' => 'Categoría',

+ 10 - 0
app/i18n/es/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 15 - 5
app/i18n/fr/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Autoriser la lecture anonyme des articles de l’utilisateur par défaut (%s)',
 		'allow_anonymous' => 'Autoriser la lecture anonyme des articles de l’utilisateur par défaut (%s)',
@@ -103,7 +113,7 @@ return array(
 	'extensions' => array(
 	'extensions' => array(
 		'author' => 'Auteur',
 		'author' => 'Auteur',
 		'community' => 'Extensions utilisateur disponibles',
 		'community' => 'Extensions utilisateur disponibles',
-		'description' => 'Description',
+		'description' => 'Description',	// IGNORE
 		'disabled' => 'Désactivée',
 		'disabled' => 'Désactivée',
 		'empty_list' => 'Aucune extension installée',
 		'empty_list' => 'Aucune extension installée',
 		'enabled' => 'Activée',
 		'enabled' => 'Activée',
@@ -114,10 +124,10 @@ return array(
 			'_' => 'Extensions système',
 			'_' => 'Extensions système',
 			'no_rights' => 'Extensions système (contrôlées par l’administrateur)',
 			'no_rights' => 'Extensions système (contrôlées par l’administrateur)',
 		),
 		),
-		'title' => 'Extensions',
+		'title' => 'Extensions',	// IGNORE
 		'update' => 'Mise à jour disponible',
 		'update' => 'Mise à jour disponible',
 		'user' => 'Extensions utilisateur',
 		'user' => 'Extensions utilisateur',
-		'version' => 'Version',
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Statistiques',
 		'_' => 'Statistiques',
@@ -136,7 +146,7 @@ return array(
 		'main' => 'Statistiques principales',
 		'main' => 'Statistiques principales',
 		'main_stream' => 'Flux principal',
 		'main_stream' => 'Flux principal',
 		'no_idle' => 'Il n’y a aucun flux inactif !',
 		'no_idle' => 'Il n’y a aucun flux inactif !',
-		'number_entries' => '%d articles',
+		'number_entries' => '%d articles',	// IGNORE
 		'percent_of_total' => '%% du total',
 		'percent_of_total' => '%% du total',
 		'repartition' => 'Répartition des articles',
 		'repartition' => 'Répartition des articles',
 		'status_favorites' => 'favoris',
 		'status_favorites' => 'favoris',
@@ -173,7 +183,7 @@ return array(
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'admin' => 'Administrateur',
 		'admin' => 'Administrateur',
-		'article_count' => 'Articles',
+		'article_count' => 'Articles',	// IGNORE
 		'back_to_manage' => '← Revenir à la liste des utilisateurs',
 		'back_to_manage' => '← Revenir à la liste des utilisateurs',
 		'create' => 'Créer un nouvel utilisateur',
 		'create' => 'Créer un nouvel utilisateur',
 		'database_size' => 'Volumétrie',
 		'database_size' => 'Volumétrie',

+ 25 - 15
app/i18n/fr/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archivage',
 		'_' => 'Archivage',
@@ -11,7 +21,7 @@ return array(
 		'keep_min_by_feed' => 'Nombre minimum d’articles à conserver par flux',
 		'keep_min_by_feed' => 'Nombre minimum d’articles à conserver par flux',
 		'keep_period' => 'Âge maximum des articles à conserver',
 		'keep_period' => 'Âge maximum des articles à conserver',
 		'keep_unreads' => 'Ne jamais supprimer les articles non lus',
 		'keep_unreads' => 'Ne jamais supprimer les articles non lus',
-		'maintenance' => 'Maintenance',
+		'maintenance' => 'Maintenance',	// IGNORE
 		'optimize' => 'Optimiser la base de données',
 		'optimize' => 'Optimiser la base de données',
 		'optimize_help' => 'À faire de temps en temps pour réduire la taille de la BDD',
 		'optimize_help' => 'À faire de temps en temps pour réduire la taille de la BDD',
 		'policy' => 'Politique de nettoyage',
 		'policy' => 'Politique de nettoyage',
@@ -44,13 +54,13 @@ return array(
 			'label' => 'Miniature',
 			'label' => 'Miniature',
 			'landscape' => 'Paysage',
 			'landscape' => 'Paysage',
 			'none' => 'Sans',
 			'none' => 'Sans',
-			'portrait' => 'Portrait',
+			'portrait' => 'Portrait',	// IGNORE
 			'square' => 'Carrée',
 			'square' => 'Carrée',
 		),
 		),
 		'title' => 'Affichage',
 		'title' => 'Affichage',
 		'width' => array(
 		'width' => array(
 			'content' => 'Largeur du contenu',
 			'content' => 'Largeur du contenu',
-			'large' => 'Large',
+			'large' => 'Large',	// IGNORE
 			'medium' => 'Moyenne',
 			'medium' => 'Moyenne',
 			'no_limit' => 'Pas de limite',
 			'no_limit' => 'Pas de limite',
 			'thin' => 'Fine',
 			'thin' => 'Fine',
@@ -77,10 +87,10 @@ return array(
 			'categories' => 'Afficher par catégorie',
 			'categories' => 'Afficher par catégorie',
 			'feeds' => 'Afficher par flux',
 			'feeds' => 'Afficher par flux',
 			'order' => 'Tri par date',
 			'order' => 'Tri par date',
-			'search' => 'Expression',
+			'search' => 'Expression',	// IGNORE
 			'state' => 'État',
 			'state' => 'État',
 			'tags' => 'Afficher par étiquette',
 			'tags' => 'Afficher par étiquette',
-			'type' => 'Type',
+			'type' => 'Type',	// IGNORE
 		),
 		),
 		'get_all' => 'Afficher tous les articles',
 		'get_all' => 'Afficher tous les articles',
 		'get_category' => 'Afficher la catégorie "%s"',
 		'get_category' => 'Afficher la catégorie "%s"',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Partage',
 		'_' => 'Partage',
 		'add' => 'Ajouter une méthode de partage',
 		'add' => 'Ajouter une méthode de partage',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'Courriel',
 		'email' => 'Courriel',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Plus d’informations',
 		'more_information' => 'Plus d’informations',
-		'print' => 'Print',
-		'raindrop' => 'Raindrop.io',
+		'print' => 'Print',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => 'Supprimer la méthode de partage',
 		'remove' => 'Supprimer la méthode de partage',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Nom du partage à afficher',
 		'share_name' => 'Nom du partage à afficher',
 		'share_url' => 'URL du partage à utiliser',
 		'share_url' => 'URL du partage à utiliser',
 		'title' => 'Partage',
 		'title' => 'Partage',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Raccourcis',
 		'_' => 'Raccourcis',
@@ -194,7 +204,7 @@ return array(
 		'load_more' => 'Charger plus d’articles',
 		'load_more' => 'Charger plus d’articles',
 		'mark_favorite' => 'Basculer l’indicateur de favori',
 		'mark_favorite' => 'Basculer l’indicateur de favori',
 		'mark_read' => 'Basculer l’indicateur de lecture',
 		'mark_read' => 'Basculer l’indicateur de lecture',
-		'navigation' => 'Navigation',
+		'navigation' => 'Navigation',	// IGNORE
 		'navigation_help' => 'Avec le modificateur <kbd>⇧ Maj</kbd>, les raccourcis de navigation s’appliquent aux flux.<br/>Avec le modificateur <kbd>Alt ⎇</kbd>, les raccourcis de navigation s’appliquent aux catégories.',
 		'navigation_help' => 'Avec le modificateur <kbd>⇧ Maj</kbd>, les raccourcis de navigation s’appliquent aux flux.<br/>Avec le modificateur <kbd>Alt ⎇</kbd>, les raccourcis de navigation s’appliquent aux catégories.',
 		'navigation_no_mod_help' => 'Les raccourcis suivant ne supportent pas les modificateurs.',
 		'navigation_no_mod_help' => 'Les raccourcis suivant ne supportent pas les modificateurs.',
 		'next_article' => 'Passer à l’article suivant',
 		'next_article' => 'Passer à l’article suivant',
@@ -216,7 +226,7 @@ return array(
 		'views' => 'Vues',
 		'views' => 'Vues',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)',
+		'articles_and_size' => '%s articles (%s)',	// IGNORE
 		'current' => 'Utilisateur actuel',
 		'current' => 'Utilisateur actuel',
 		'is_admin' => 'est administrateur',
 		'is_admin' => 'est administrateur',
 		'users' => 'Utilisateurs',
 		'users' => 'Utilisateurs',

+ 10 - 0
app/i18n/fr/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'Vous n’avez pas le droit d’accéder à cette page !',
 		'denied' => 'Vous n’avez pas le droit d’accéder à cette page !',

+ 52 - 42
app/i18n/fr/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Actualiser flux',
 		'actualize' => 'Actualiser flux',
@@ -69,8 +79,8 @@ return array(
 		'december' => 'décembre',
 		'december' => 'décembre',
 		'feb' => 'fév.',
 		'feb' => 'fév.',
 		'february' => 'février',
 		'february' => 'février',
-		'format_date' => 'j %s Y',
-		'format_date_hour' => 'j %s Y \\à H\\:i',
+		'format_date' => 'j %s Y',	// IGNORE
+		'format_date_hour' => 'j %s Y \\à H\\:i',	// IGNORE
 		'fri' => 'ven.',
 		'fri' => 'ven.',
 		'jan' => 'jan.',
 		'jan' => 'jan.',
 		'january' => 'janvier',
 		'january' => 'janvier',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'mer.',
 		'wed' => 'mer.',
 		'yesterday' => 'Hier',
 		'yesterday' => 'Hier',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'À propos de FreshRSS',
 		'about' => 'À propos de FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,36 +134,36 @@ return array(
 		'should_be_activated' => 'Le JavaScript doit être activé.',
 		'should_be_activated' => 'Le JavaScript doit être activé.',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'À propos',
 		'about' => 'À propos',
 		'account' => 'Compte',
 		'account' => 'Compte',
-		'admin' => 'Administration',
+		'admin' => 'Administration',	// IGNORE
 		'archiving' => 'Archivage',
 		'archiving' => 'Archivage',
 		'authentication' => 'Authentification',
 		'authentication' => 'Authentification',
 		'check_install' => 'Vérification de l’installation',
 		'check_install' => 'Vérification de l’installation',
-		'configuration' => 'Configuration',
+		'configuration' => 'Configuration',	// IGNORE
 		'display' => 'Affichage',
 		'display' => 'Affichage',
-		'extensions' => 'Extensions',
-		'logs' => 'Logs',
+		'extensions' => 'Extensions',	// IGNORE
+		'logs' => 'Logs',	// IGNORE
 		'queries' => 'Filtres utilisateurs',
 		'queries' => 'Filtres utilisateurs',
 		'reading' => 'Lecture',
 		'reading' => 'Lecture',
 		'search' => 'Rechercher des mots ou des #tags',
 		'search' => 'Rechercher des mots ou des #tags',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Sites basés sur Known',
 		'Known' => 'Sites basés sur Known',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'Presse-papier',
 		'clipboard' => 'Presse-papier',
-		'diaspora' => 'Diaspora*',
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'Courriel',
 		'email' => 'Courriel',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Imprimer',
 		'print' => 'Imprimer',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Attention !',
 		'attention' => 'Attention !',

+ 14 - 4
app/i18n/fr/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'À propos',
 		'_' => 'À propos',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Rapports de bugs',
 		'bugs_reports' => 'Rapports de bugs',
 		'credits' => 'Crédits',
 		'credits' => 'Crédits',
 		'credits_content' => 'Des éléments de design sont issus du <a href="http://twitter.github.io/bootstrap/">projet Bootstrap</a> bien que FreshRSS n’utilise pas ce framework. Les <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icônes</a> sont issues du <a href="https://www.gnome.org/">projet GNOME</a>. La police <em>Open Sans</em> utilisée a été créée par <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS repose sur <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
 		'credits_content' => 'Des éléments de design sont issus du <a href="http://twitter.github.io/bootstrap/">projet Bootstrap</a> bien que FreshRSS n’utilise pas ce framework. Les <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icônes</a> sont issues du <a href="https://www.gnome.org/">projet GNOME</a>. La police <em>Open Sans</em> utilisée a été créée par <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS repose sur <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
@@ -12,7 +22,7 @@ return array(
 		'license' => 'Licence',
 		'license' => 'Licence',
 		'project_website' => 'Site du projet',
 		'project_website' => 'Site du projet',
 		'title' => 'À propos',
 		'title' => 'À propos',
-		'version' => 'Version',
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'feed' => array(
 	'feed' => array(
 		'add' => 'Vous pouvez ajouter des flux.',
 		'add' => 'Vous pouvez ajouter des flux.',
@@ -23,10 +33,10 @@ return array(
 		'title_global' => 'Vue globale',
 		'title_global' => 'Vue globale',
 	),
 	),
 	'log' => array(
 	'log' => array(
-		'_' => 'Logs',
+		'_' => 'Logs',	// IGNORE
 		'clear' => 'Effacer les logs',
 		'clear' => 'Effacer les logs',
 		'empty' => 'Les logs sont vides.',
 		'empty' => 'Les logs sont vides.',
-		'title' => 'Logs',
+		'title' => 'Logs',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'À propos de FreshRSS',
 		'about' => 'À propos de FreshRSS',

+ 12 - 2
app/i18n/fr/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Terminer l’installation',
 		'finish' => 'Terminer l’installation',
@@ -118,6 +128,6 @@ return array(
 	),
 	),
 	'step' => 'étape %d',
 	'step' => 'étape %d',
 	'steps' => 'Étapes',
 	'steps' => 'Étapes',
-	'this_is_the_end' => 'This is the end',
-	'title' => 'Installation · FreshRSS',
+	'this_is_the_end' => 'This is the end',	// IGNORE
+	'title' => 'Installation · FreshRSS',	// IGNORE
 );
 );

+ 15 - 5
app/i18n/fr/sub.php

@@ -1,14 +1,24 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => 'Copier l’URL suivante dans l’outil qui utilisera l’API.',
 		'documentation' => 'Copier l’URL suivante dans l’outil qui utilisera l’API.',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'Glisser ce bouton dans la barre des favoris ou cliquer droit dessus et choisir "Enregistrer ce lien". Ensuite, cliquer sur le bouton "S’abonner" sur les pages auxquelles vous voulez vous abonner.',
 		'documentation' => 'Glisser ce bouton dans la barre des favoris ou cliquer droit dessus et choisir "Enregistrer ce lien". Ensuite, cliquer sur le bouton "S’abonner" sur les pages auxquelles vous voulez vous abonner.',
 		'label' => 'S’abonner',
 		'label' => 'S’abonner',
-		'title' => 'Bookmarklet',
+		'title' => 'Bookmarklet',	// IGNORE
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Catégorie',
 		'_' => 'Catégorie',
@@ -42,7 +52,7 @@ return array(
 		'css_cookie_help' => 'Exemple : <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',
 		'css_cookie_help' => 'Exemple : <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',
 		'css_help' => 'Permet de récupérer les flux tronqués (attention, demande plus de temps !)',
 		'css_help' => 'Permet de récupérer les flux tronqués (attention, demande plus de temps !)',
 		'css_path' => 'Sélecteur CSS des articles sur le site d’origine',
 		'css_path' => 'Sélecteur CSS des articles sur le site d’origine',
-		'description' => 'Description',
+		'description' => 'Description',	// IGNORE
 		'empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.',
 		'empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.',
 		'error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.',
 		'error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.',
 		'filteractions' => array(
 		'filteractions' => array(
@@ -56,12 +66,12 @@ return array(
 			'clear_cache_help' => 'Supprime le cache de ce flux.',
 			'clear_cache_help' => 'Supprime le cache de ce flux.',
 			'reload_articles' => 'Recharger les articles',
 			'reload_articles' => 'Recharger les articles',
 			'reload_articles_help' => 'Recharge les articles et récupère le contenu complet si un sélecteur est défini.',
 			'reload_articles_help' => 'Recharge les articles et récupère le contenu complet si un sélecteur est défini.',
-			'title' => 'Maintenance',
+			'title' => 'Maintenance',	// IGNORE
 		),
 		),
 		'moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans <em>%s</em>.',
 		'moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans <em>%s</em>.',
 		'mute' => 'muet',
 		'mute' => 'muet',
 		'no_selected' => 'Aucun flux sélectionné.',
 		'no_selected' => 'Aucun flux sélectionné.',
-		'number_entries' => '%d articles',
+		'number_entries' => '%d articles',	// IGNORE
 		'priority' => array(
 		'priority' => array(
 			'_' => 'Visibilité',
 			'_' => 'Visibilité',
 			'archived' => 'Ne pas afficher (archivé)',
 			'archived' => 'Ne pas afficher (archivé)',

+ 10 - 0
app/i18n/fr/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 72 - 62
app/i18n/he/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'הרשאה לאנונימיים לקרוא את מאמרי משתמש ברירת המחדל (%s)',
 		'allow_anonymous' => 'הרשאה לאנונימיים לקרוא את מאמרי משתמש ברירת המחדל (%s)',
@@ -8,7 +18,7 @@ return array(
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'none' => 'ללא (מסוכן)',
 		'none' => 'ללא (מסוכן)',
-		'title' => 'Authentication',	// TODO - Translation
+		'title' => 'Authentication',	// TODO
 		'token' => 'מחרוזת אימות',
 		'token' => 'מחרוזת אימות',
 		'token_help' => 'Allows to access RSS output of the default user without authentication:',
 		'token_help' => 'Allows to access RSS output of the default user without authentication:',
 		'type' => 'שיטת אימות',
 		'type' => 'שיטת אימות',
@@ -21,11 +31,11 @@ return array(
 		),
 		),
 		'categories' => array(
 		'categories' => array(
 			'nok' => 'Category table is bad configured.',
 			'nok' => 'Category table is bad configured.',
-			'ok' => 'Category table is okay.',	// TODO - Translation
+			'ok' => 'Category table is okay.',	// TODO
 		),
 		),
 		'connection' => array(
 		'connection' => array(
 			'nok' => 'Connection to the database cannot being established.',
 			'nok' => 'Connection to the database cannot being established.',
-			'ok' => 'Connection to the database is okay.',	// TODO - Translation
+			'ok' => 'Connection to the database is okay.',	// TODO
 		),
 		),
 		'ctype' => array(
 		'ctype' => array(
 			'nok' => 'הספרייה הנדרשת ל character type checking (php-ctype) אינה מותקנת',
 			'nok' => 'הספרייה הנדרשת ל character type checking (php-ctype) אינה מותקנת',
@@ -39,35 +49,35 @@ return array(
 			'nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.',
 			'nok' => 'יש לבדוק את ההרשאות בתיקייה <em>%s</em>. שרת הHTTP חייב להיות בעל הרשאות כתיבה.',
 			'ok' => 'ההרשאות בתיקיית הדאטא תקינות',
 			'ok' => 'ההרשאות בתיקיית הדאטא תקינות',
 		),
 		),
-		'database' => 'Database installation',	// TODO - Translation
+		'database' => 'Database installation',	// TODO
 		'dom' => array(
 		'dom' => array(
 			'nok' => 'הספרייה הנדרשת לסיור ב DOM אינה מותקנת	(php-xml package)',
 			'nok' => 'הספרייה הנדרשת לסיור ב DOM אינה מותקנת	(php-xml package)',
 			'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת',
 			'ok' => 'הספרייה הנדרשת לסיור ב DOM מותקנת',
 		),
 		),
 		'entries' => array(
 		'entries' => array(
-			'nok' => 'Entry table is improperly configured.',	// TODO - Translation
-			'ok' => 'Entry table is okay.',	// TODO - Translation
+			'nok' => 'Entry table is improperly configured.',	// TODO
+			'ok' => 'Entry table is okay.',	// TODO
 		),
 		),
 		'favicons' => array(
 		'favicons' => array(
-			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have write permission.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have write permission.',	// TODO
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 		),
 		),
 		'feeds' => array(
 		'feeds' => array(
 			'nok' => 'Feed table is bad configured.',
 			'nok' => 'Feed table is bad configured.',
-			'ok' => 'Feed table is okay.',	// TODO - Translation
+			'ok' => 'Feed table is okay.',	// TODO
 		),
 		),
 		'fileinfo' => array(
 		'fileinfo' => array(
-			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// TODO - Translation
-			'ok' => 'You have the fileinfo library.',	// TODO - Translation
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// TODO
+			'ok' => 'You have the fileinfo library.',	// TODO
 		),
 		),
-		'files' => 'File installation',	// TODO - Translation
+		'files' => 'File installation',	// TODO
 		'json' => array(
 		'json' => array(
 			'nok' => 'You lack JSON (php-json package).',
 			'nok' => 'You lack JSON (php-json package).',
-			'ok' => 'You have the JSON extension.',	// TODO - Translation
+			'ok' => 'You have the JSON extension.',	// TODO
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// TODO - Translation
-			'ok' => 'You have the recommended mbstring library for Unicode.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// TODO
+			'ok' => 'You have the recommended mbstring library for Unicode.',	// TODO
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
 			'nok' => 'הספרייה הנדרשת לביטויים רגולריים אינה מותקנת (php-pcre)',
 			'nok' => 'הספרייה הנדרשת לביטויים רגולריים אינה מותקנת (php-pcre)',
@@ -78,7 +88,7 @@ return array(
 			'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)',
 			'ok' => 'PDO מותקן ולפחות אחד ממנהלי ההתקן הנתמכים מותקן (pdo_mysql, pdo_sqlite)',
 		),
 		),
 		'php' => array(
 		'php' => array(
-			'_' => 'PHP installation',	// TODO - Translation
+			'_' => 'PHP installation',	// TODO
 			'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s',
 			'nok' => 'גירסת PHP שלכם היא %s אך FreshRSS דורש לפחות את גירסה %s',
 			'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS',
 			'ok' => 'גירסת PHP שלכם היא %s, שתואמת ל FreshRSS',
 		),
 		),
@@ -86,38 +96,38 @@ return array(
 			'nok' => 'There is one or more lacking tables in the database.',
 			'nok' => 'There is one or more lacking tables in the database.',
 			'ok' => 'Tables are existing in the database.',
 			'ok' => 'Tables are existing in the database.',
 		),
 		),
-		'title' => 'Installation check',	// TODO - Translation
+		'title' => 'Installation check',	// TODO
 		'tokens' => array(
 		'tokens' => array(
-			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have write permission',	// TODO - Translation
-			'ok' => 'Permissions on the tokens directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have write permission',	// TODO
+			'ok' => 'Permissions on the tokens directory are good.',	// TODO
 		),
 		),
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have write permission',	// TODO - Translation
-			'ok' => 'Permissions on the users directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have write permission',	// TODO
+			'ok' => 'Permissions on the users directory are good.',	// TODO
 		),
 		),
 		'zip' => array(
 		'zip' => array(
 			'nok' => 'You lack ZIP extension (php-zip package).',
 			'nok' => 'You lack ZIP extension (php-zip package).',
-			'ok' => 'You have the ZIP extension.',	// TODO - Translation
+			'ok' => 'You have the ZIP extension.',	// TODO
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
-		'author' => 'Author',	// TODO - Translation
-		'community' => 'Available community extensions',	// TODO - Translation
-		'description' => 'Description',	// TODO - Translation
-		'disabled' => 'Disabled',	// TODO - Translation
+		'author' => 'Author',	// TODO
+		'community' => 'Available community extensions',	// TODO
+		'description' => 'Description',	// TODO
+		'disabled' => 'Disabled',	// TODO
 		'empty_list' => 'There is no installed extension',
 		'empty_list' => 'There is no installed extension',
-		'enabled' => 'Enabled',	// TODO - Translation
-		'latest' => 'Installed',	// TODO - Translation
-		'name' => 'Name',	// TODO - Translation
-		'no_configure_view' => 'This extension cannot be configured.',	// TODO - Translation
+		'enabled' => 'Enabled',	// TODO
+		'latest' => 'Installed',	// TODO
+		'name' => 'Name',	// TODO
+		'no_configure_view' => 'This extension cannot be configured.',	// TODO
 		'system' => array(
 		'system' => array(
-			'_' => 'System extensions',	// TODO - Translation
-			'no_rights' => 'System extension (you do not have the required permissions)',	// TODO - Translation
+			'_' => 'System extensions',	// TODO
+			'no_rights' => 'System extension (you do not have the required permissions)',	// TODO
 		),
 		),
-		'title' => 'Extensions',	// TODO - Translation
-		'update' => 'Update available',	// TODO - Translation
-		'user' => 'User extensions',	// TODO - Translation
-		'version' => 'Version',	// TODO - Translation
+		'title' => 'Extensions',	// TODO
+		'update' => 'Update available',	// TODO
+		'user' => 'User extensions',	// TODO
+		'version' => 'Version',	// TODO
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'סטטיסטיקות',
 		'_' => 'סטטיסטיקות',
@@ -126,9 +136,9 @@ return array(
 		'entry_count' => 'סכום המאמרים',
 		'entry_count' => 'סכום המאמרים',
 		'entry_per_category' => 'מאמרים על פי קטגוריה',
 		'entry_per_category' => 'מאמרים על פי קטגוריה',
 		'entry_per_day' => 'מספר מאמרים ליום (30 ימים אחרונים)',
 		'entry_per_day' => 'מספר מאמרים ליום (30 ימים אחרונים)',
-		'entry_per_day_of_week' => 'Per day of week (average: %.2f messages)',	// TODO - Translation
-		'entry_per_hour' => 'Per hour (average: %.2f messages)',	// TODO - Translation
-		'entry_per_month' => 'Per month (average: %.2f messages)',	// TODO - Translation
+		'entry_per_day_of_week' => 'Per day of week (average: %.2f messages)',	// TODO
+		'entry_per_hour' => 'Per hour (average: %.2f messages)',	// TODO
+		'entry_per_month' => 'Per month (average: %.2f messages)',	// TODO
 		'entry_repartition' => 'חלוקת המאמרים',
 		'entry_repartition' => 'חלוקת המאמרים',
 		'feed' => 'הזנה',
 		'feed' => 'הזנה',
 		'feed_per_category' => 'הזנות על פי קטגוריה',
 		'feed_per_category' => 'הזנות על פי קטגוריה',
@@ -147,19 +157,19 @@ return array(
 		'top_feed' => 'עשרת ההזנות המובילות',
 		'top_feed' => 'עשרת ההזנות המובילות',
 	),
 	),
 	'system' => array(
 	'system' => array(
-		'_' => 'System configuration',	// TODO - Translation
-		'auto-update-url' => 'Auto-update server URL',	// TODO - Translation
+		'_' => 'System configuration',	// TODO
+		'auto-update-url' => 'Auto-update server URL',	// TODO
 		'cookie-duration' => array(
 		'cookie-duration' => array(
-			'help' => 'in seconds',	// TODO - Translation
-			'number' => 'Duration to keep logged in',	// TODO - Translation
+			'help' => 'in seconds',	// TODO
+			'number' => 'Duration to keep logged in',	// TODO
 		),
 		),
-		'force_email_validation' => 'Force email address validation',	// TODO - Translation
-		'instance-name' => 'Instance name',	// TODO - Translation
-		'max-categories' => 'Max number of categories per user',	// TODO - Translation
-		'max-feeds' => 'Max number of feeds per user',	// TODO - Translation
+		'force_email_validation' => 'Force email address validation',	// TODO
+		'instance-name' => 'Instance name',	// TODO
+		'max-categories' => 'Max number of categories per user',	// TODO
+		'max-feeds' => 'Max number of feeds per user',	// TODO
 		'registration' => array(
 		'registration' => array(
-			'help' => '0 means that there is no account limit',	// TODO - Translation
-			'number' => 'Max number of accounts',	// TODO - Translation
+			'help' => '0 means that there is no account limit',	// TODO
+			'number' => 'Max number of accounts',	// TODO
 		),
 		),
 	),
 	),
 	'update' => array(
 	'update' => array(
@@ -172,23 +182,23 @@ return array(
 		'title' => 'מערכת העדכון',
 		'title' => 'מערכת העדכון',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'admin' => 'Administrator',	// TODO - Translation
-		'article_count' => 'Articles',	// TODO - Translation
-		'back_to_manage' => '← Return to user list',	// TODO - Translation
+		'admin' => 'Administrator',	// TODO
+		'article_count' => 'Articles',	// TODO
+		'back_to_manage' => '← Return to user list',	// TODO
 		'create' => 'יצירת משתמש חדש',
 		'create' => 'יצירת משתמש חדש',
-		'database_size' => 'Database size',	// TODO - Translation
-		'email' => 'Email address',	// TODO - Translation
-		'enabled' => 'Enabled',	// TODO - Translation
-		'feed_count' => 'Feeds',	// TODO - Translation
-		'is_admin' => 'Is admin',	// TODO - Translation
+		'database_size' => 'Database size',	// TODO
+		'email' => 'Email address',	// TODO
+		'enabled' => 'Enabled',	// TODO
+		'feed_count' => 'Feeds',	// TODO
+		'is_admin' => 'Is admin',	// TODO
 		'language' => 'שפה',
 		'language' => 'שפה',
-		'last_user_activity' => 'Last user activity',	// TODO - Translation
-		'list' => 'User list',	// TODO - Translation
-		'number' => 'There is %d account created',	// TODO - Translation
-		'numbers' => 'There are %d accounts created',	// TODO - Translation
+		'last_user_activity' => 'Last user activity',	// TODO
+		'list' => 'User list',	// TODO
+		'number' => 'There is %d account created',	// TODO
+		'numbers' => 'There are %d accounts created',	// TODO
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
-		'password_format' => 'At least 7 characters',	// TODO - Translation
-		'title' => 'Manage users',	// TODO - Translation
+		'password_format' => 'At least 7 characters',	// TODO
+		'title' => 'Manage users',	// TODO
 		'username' => 'שם משתמש',
 		'username' => 'שם משתמש',
 	),
 	),
 );
 );

+ 79 - 69
app/i18n/he/conf.php

@@ -1,21 +1,31 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'ארכוב',
 		'_' => 'ארכוב',
-		'exception' => 'Purge exception',	// TODO - Translation
+		'exception' => 'Purge exception',	// TODO
 		'help' => 'אפשרויות נוספות זמינות בזרמים ספציפיים',
 		'help' => 'אפשרויות נוספות זמינות בזרמים ספציפיים',
-		'keep_favourites' => 'Never delete favourites',	// TODO - Translation
-		'keep_labels' => 'Never delete labels',	// TODO - Translation
-		'keep_max' => 'Maximum number of articles to keep',	// TODO - Translation
-		'keep_min_by_feed' => 'Minimum number of articles to keep per feed',	// TODO - Translation
-		'keep_period' => 'Maximum age of articles to keep',	// TODO - Translation
-		'keep_unreads' => 'Never delete unread articles',	// TODO - Translation
-		'maintenance' => 'Maintenance',	// TODO - Translation
+		'keep_favourites' => 'Never delete favourites',	// TODO
+		'keep_labels' => 'Never delete labels',	// TODO
+		'keep_max' => 'Maximum number of articles to keep',	// TODO
+		'keep_min_by_feed' => 'Minimum number of articles to keep per feed',	// TODO
+		'keep_period' => 'Maximum age of articles to keep',	// TODO
+		'keep_unreads' => 'Never delete unread articles',	// TODO
+		'maintenance' => 'Maintenance',	// TODO
 		'optimize' => 'מיטוב בסיס הנתונים',
 		'optimize' => 'מיטוב בסיס הנתונים',
 		'optimize_help' => 'ביצוע לעיתים קרובות על מנת למטב את בסיס הנתונים',
 		'optimize_help' => 'ביצוע לעיתים קרובות על מנת למטב את בסיס הנתונים',
-		'policy' => 'Purge policy',	// TODO - Translation
-		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// TODO - Translation
+		'policy' => 'Purge policy',	// TODO
+		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// TODO
 		'purge_now' => 'ניקוי עכשיו',
 		'purge_now' => 'ניקוי עכשיו',
 		'title' => 'ארכוב',
 		'title' => 'ארכוב',
 		'ttl' => 'אין לרענן אוטומטית יותר מ',
 		'ttl' => 'אין לרענן אוטומטית יותר מ',
@@ -24,12 +34,12 @@ return array(
 		'_' => 'תצוגה',
 		'_' => 'תצוגה',
 		'icon' => array(
 		'icon' => array(
 			'bottom_line' => 'שורה תחתונה',
 			'bottom_line' => 'שורה תחתונה',
-			'display_authors' => 'Authors',	// TODO - Translation
+			'display_authors' => 'Authors',	// TODO
 			'entry' => 'סמלילי מאמרים',
 			'entry' => 'סמלילי מאמרים',
 			'publication_date' => 'תאריך הפרסום',
 			'publication_date' => 'תאריך הפרסום',
 			'related_tags' => 'תגיות קשורות',
 			'related_tags' => 'תגיות קשורות',
 			'sharing' => 'שיתוף',
 			'sharing' => 'שיתוף',
-			'summary' => 'Summary',	// TODO - Translation
+			'summary' => 'Summary',	// TODO
 			'top_line' => 'שורה עליונה',
 			'top_line' => 'שורה עליונה',
 		),
 		),
 		'language' => 'שפה',
 		'language' => 'שפה',
@@ -37,15 +47,15 @@ return array(
 			'seconds' => 'שניות (0 משמעותה ללא פג תוקף)',
 			'seconds' => 'שניות (0 משמעותה ללא פג תוקף)',
 			'timeout' => 'HTML5 התראה פג תוקף',
 			'timeout' => 'HTML5 התראה פג תוקף',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	// TODO - Translation
+		'show_nav_buttons' => 'Show the navigation buttons',	// TODO
 		'theme' => 'ערכת נושא',
 		'theme' => 'ערכת נושא',
-		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// TODO - Translation
+		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// TODO
 		'thumbnail' => array(
 		'thumbnail' => array(
-			'label' => 'Thumbnail',	// TODO - Translation
-			'landscape' => 'Landscape',	// TODO - Translation
-			'none' => 'None',	// TODO - Translation
-			'portrait' => 'Portrait',	// TODO - Translation
-			'square' => 'Square',	// TODO - Translation
+			'label' => 'Thumbnail',	// TODO
+			'landscape' => 'Landscape',	// TODO
+			'none' => 'None',	// TODO
+			'portrait' => 'Portrait',	// TODO
+			'square' => 'Square',	// TODO
 		),
 		),
 		'title' => 'תצוגה',
 		'title' => 'תצוגה',
 		'width' => array(
 		'width' => array(
@@ -57,36 +67,36 @@ return array(
 		),
 		),
 	),
 	),
 	'profile' => array(
 	'profile' => array(
-		'_' => 'Profile management',	// TODO - Translation
-		'api' => 'API management',	// TODO - Translation
+		'_' => 'Profile management',	// TODO
+		'api' => 'API management',	// TODO
 		'delete' => array(
 		'delete' => array(
-			'_' => 'Account deletion',	// TODO - Translation
-			'warn' => 'Your account and all related data will be deleted.',	// TODO - Translation
+			'_' => 'Account deletion',	// TODO
+			'warn' => 'Your account and all related data will be deleted.',	// TODO
 		),
 		),
-		'email' => 'Email address',	// TODO - Translation
+		'email' => 'Email address',	// TODO
 		'password_api' => 'סיסמת API<br /><small>(לדוגמה ליישומים סלולריים)</small>',
 		'password_api' => 'סיסמת API<br /><small>(לדוגמה ליישומים סלולריים)</small>',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
-		'password_format' => 'At least 7 characters',	// TODO - Translation
-		'title' => 'Profile',	// TODO - Translation
+		'password_format' => 'At least 7 characters',	// TODO
+		'title' => 'Profile',	// TODO
 	),
 	),
 	'query' => array(
 	'query' => array(
 		'_' => 'שאילתות',
 		'_' => 'שאילתות',
 		'deprecated' => 'שאילתה זו אינה בתוקף יותר, הפיד או הקטגוריה לייחוס נמחקו.',
 		'deprecated' => 'שאילתה זו אינה בתוקף יותר, הפיד או הקטגוריה לייחוס נמחקו.',
 		'filter' => array(
 		'filter' => array(
 			'_' => 'מסננים בשימוש:',
 			'_' => 'מסננים בשימוש:',
-			'categories' => 'Display by category',	// TODO - Translation
-			'feeds' => 'Display by feed',	// TODO - Translation
-			'order' => 'Sort by date',	// TODO - Translation
-			'search' => 'Expression',	// TODO - Translation
-			'state' => 'State',	// TODO - Translation
-			'tags' => 'Display by tag',	// TODO - Translation
-			'type' => 'Type',	// TODO - Translation
+			'categories' => 'Display by category',	// TODO
+			'feeds' => 'Display by feed',	// TODO
+			'order' => 'Sort by date',	// TODO
+			'search' => 'Expression',	// TODO
+			'state' => 'State',	// TODO
+			'tags' => 'Display by tag',	// TODO
+			'type' => 'Type',	// TODO
 		),
 		),
 		'get_all' => 'הצגת כל המאמרים',
 		'get_all' => 'הצגת כל המאמרים',
 		'get_category' => 'הצגת קטגוריה "%s"',
 		'get_category' => 'הצגת קטגוריה "%s"',
 		'get_favorite' => 'הצגת מאמרים מועדפים',
 		'get_favorite' => 'הצגת מאמרים מועדפים',
 		'get_feed' => 'הצגת הזנה %s',
 		'get_feed' => 'הצגת הזנה %s',
-		'name' => 'Name',	// TODO - Translation
+		'name' => 'Name',	// TODO
 		'no_filter' => 'ללא סינון',
 		'no_filter' => 'ללא סינון',
 		'number' => 'שאילתה מספר °%d',
 		'number' => 'שאילתה מספר °%d',
 		'order_asc' => 'הצגת מאמרים ישנים בראש',
 		'order_asc' => 'הצגת מאמרים ישנים בראש',
@@ -113,39 +123,39 @@ return array(
 	'reading' => array(
 	'reading' => array(
 		'_' => 'קריאה',
 		'_' => 'קריאה',
 		'after_onread' => 'לאחר “סימון הכל כנקרא”,',
 		'after_onread' => 'לאחר “סימון הכל כנקרא”,',
-		'always_show_favorites' => 'Show all articles in favourites by default',	// TODO - Translation
+		'always_show_favorites' => 'Show all articles in favourites by default',	// TODO
 		'articles_per_page' => 'מספר המאמרים בעמוד',
 		'articles_per_page' => 'מספר המאמרים בעמוד',
 		'auto_load_more' => 'טעינת המאמר הבא סוף העמוד',
 		'auto_load_more' => 'טעינת המאמר הבא סוף העמוד',
-		'auto_remove_article' => 'Hide articles after reading',	// TODO - Translation
+		'auto_remove_article' => 'Hide articles after reading',	// TODO
 		'confirm_enabled' => 'הצגת דו-שיח לאישור “סימון הכל כנקרא” ',
 		'confirm_enabled' => 'הצגת דו-שיח לאישור “סימון הכל כנקרא” ',
 		'display_articles_unfolded' => 'הצגת מאמרים בשלמותם כברירת מחדל',
 		'display_articles_unfolded' => 'הצגת מאמרים בשלמותם כברירת מחדל',
-		'display_categories_unfolded' => 'Categories to unfold',	// TODO - Translation
+		'display_categories_unfolded' => 'Categories to unfold',	// TODO
 		'hide_read_feeds' => 'הסתרת קטגוריות &amp; הזנות ללא מאמרים שלא נקראו (לא עובד יחד עם “הצגת כל המאמרים”)',
 		'hide_read_feeds' => 'הסתרת קטגוריות &amp; הזנות ללא מאמרים שלא נקראו (לא עובד יחד עם “הצגת כל המאמרים”)',
 		'img_with_lazyload' => 'שימוש ב "טעינה עצלה" על מנת לטעון תמונות',
 		'img_with_lazyload' => 'שימוש ב "טעינה עצלה" על מנת לטעון תמונות',
 		'jump_next' => 'קפיצה לפריט הבא שלא נקרא (הזנה או קטגוריה)',
 		'jump_next' => 'קפיצה לפריט הבא שלא נקרא (הזנה או קטגוריה)',
-		'mark_updated_article_unread' => 'Mark updated articles as unread',	// TODO - Translation
+		'mark_updated_article_unread' => 'Mark updated articles as unread',	// TODO
 		'number_divided_when_reader' => 'חלוקה ב2 במצב קריאה.',
 		'number_divided_when_reader' => 'חלוקה ב2 במצב קריאה.',
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'כאשר מאמר נפתח באתר המקורי',
 			'article_open_on_website' => 'כאשר מאמר נפתח באתר המקורי',
 			'article_viewed' => 'כאשר מאמר נצפה',
 			'article_viewed' => 'כאשר מאמר נצפה',
-			'keep_max_n_unread' => 'Max number of articles to keep unread',	// TODO - Translation
+			'keep_max_n_unread' => 'Max number of articles to keep unread',	// TODO
 			'scroll' => 'כאשר גוללים',
 			'scroll' => 'כאשר גוללים',
 			'upon_reception' => 'כאשר המאמר מתקבל',
 			'upon_reception' => 'כאשר המאמר מתקבל',
 			'when' => 'סימון מאמרים כנקראו…',
 			'when' => 'סימון מאמרים כנקראו…',
-			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// TODO - Translation
+			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// TODO
 		),
 		),
 		'show' => array(
 		'show' => array(
 			'_' => 'מאמרים להצגה',
 			'_' => 'מאמרים להצגה',
-			'active_category' => 'Active category',	// TODO - Translation
+			'active_category' => 'Active category',	// TODO
 			'adaptive' => 'תצוגה מתעדכנת',
 			'adaptive' => 'תצוגה מתעדכנת',
 			'all_articles' => 'הצגת כל המאמרים',
 			'all_articles' => 'הצגת כל המאמרים',
-			'all_categories' => 'All categories',	// TODO - Translation
-			'no_category' => 'No category',	// TODO - Translation
-			'remember_categories' => 'Remember open categories',	// TODO - Translation
+			'all_categories' => 'All categories',	// TODO
+			'no_category' => 'No category',	// TODO
+			'remember_categories' => 'Remember open categories',	// TODO
 			'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 			'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 		),
 		),
-		'show_fav_unread_help' => 'Applies also on labels',	// TODO - Translation
-		'sides_close_article' => 'Clicking outside of article text area closes the article',	// TODO - Translation
+		'show_fav_unread_help' => 'Applies also on labels',	// TODO
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	// TODO
 		'sort' => array(
 		'sort' => array(
 			'_' => 'סדר המיון',
 			'_' => 'סדר המיון',
 			'newer_first' => 'חדשים בראש',
 			'newer_first' => 'חדשים בראש',
@@ -162,32 +172,32 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'שיתוף',
 		'_' => 'שיתוף',
-		'add' => 'Add a sharing method',	// TODO - Translation
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'add' => 'Add a sharing method',	// TODO
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'דואר אלקטרוני',
 		'email' => 'דואר אלקטרוני',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'מידע נוסף',
 		'more_information' => 'מידע נוסף',
 		'print' => 'הדפסה',
 		'print' => 'הדפסה',
-		'raindrop' => 'Raindrop.io',
-		'remove' => 'Remove sharing method',	// TODO - Translation
-		'shaarli' => 'Shaarli',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'remove' => 'Remove sharing method',	// TODO
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'שיתוף שם לתצוגה',
 		'share_name' => 'שיתוף שם לתצוגה',
 		'share_url' => 'לשימוש שתפו URL',
 		'share_url' => 'לשימוש שתפו URL',
 		'title' => 'שיתוף',
 		'title' => 'שיתוף',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'קיצורי דרך',
 		'_' => 'קיצורי דרך',
 		'article_action' => 'פעולות על מאמרים',
 		'article_action' => 'פעולות על מאמרים',
 		'auto_share' => 'שיתוף',
 		'auto_share' => 'שיתוף',
 		'auto_share_help' => 'אם יש רק מצב שיתוף אחד, הוא מופעל. אחרת המצבים נבחרים על בסיס המספר שלהם.',
 		'auto_share_help' => 'אם יש רק מצב שיתוף אחד, הוא מופעל. אחרת המצבים נבחרים על בסיס המספר שלהם.',
-		'close_dropdown' => 'Close menus',	// TODO - Translation
+		'close_dropdown' => 'Close menus',	// TODO
 		'collapse_article' => 'כיווץ',
 		'collapse_article' => 'כיווץ',
 		'first_article' => 'דילוג למאמר הראשון',
 		'first_article' => 'דילוג למאמר הראשון',
 		'focus_search' => 'גישה לתיבת החיפוש',
 		'focus_search' => 'גישה לתיבת החיפוש',
-		'global_view' => 'Switch to global view',	// TODO - Translation
+		'global_view' => 'Switch to global view',	// TODO
 		'help' => 'הצגת התיעוד',
 		'help' => 'הצגת התיעוד',
 		'javascript' => 'חובה להפעיל JavaScript על מנת לעשות שימוש בקיצורי דרך',
 		'javascript' => 'חובה להפעיל JavaScript על מנת לעשות שימוש בקיצורי דרך',
 		'last_article' => 'דילוג למאמר האחרון',
 		'last_article' => 'דילוג למאמר האחרון',
@@ -196,27 +206,27 @@ return array(
 		'mark_read' => 'סימון כנקרא',
 		'mark_read' => 'סימון כנקרא',
 		'navigation' => 'ניווט',
 		'navigation' => 'ניווט',
 		'navigation_help' => 'בעזרת מקש השיפט קיצורי דרך חלים על הזנות .<br/>עם מקש האלט הם חלים על קטגוריות.',
 		'navigation_help' => 'בעזרת מקש השיפט קיצורי דרך חלים על הזנות .<br/>עם מקש האלט הם חלים על קטגוריות.',
-		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// TODO - Translation
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// TODO
 		'next_article' => 'דילוג למאמר הבא',
 		'next_article' => 'דילוג למאמר הבא',
-		'next_unread_article' => 'Open the next unread article',	// TODO - Translation
-		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// TODO - Translation
-		'normal_view' => 'Switch to normal view',	// TODO - Translation
+		'next_unread_article' => 'Open the next unread article',	// TODO
+		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// TODO
+		'normal_view' => 'Switch to normal view',	// TODO
 		'other_action' => 'פעולות אחרות',
 		'other_action' => 'פעולות אחרות',
 		'previous_article' => 'דילוג למאמר הקודם',
 		'previous_article' => 'דילוג למאמר הקודם',
-		'reading_view' => 'Switch to reading view',	// TODO - Translation
-		'rss_view' => 'Open as RSS feed',	// TODO - Translation
+		'reading_view' => 'Switch to reading view',	// TODO
+		'rss_view' => 'Open as RSS feed',	// TODO
 		'see_on_website' => 'ראו את המקור באתר',
 		'see_on_website' => 'ראו את המקור באתר',
-		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// TODO - Translation
-		'skip_next_article' => 'Focus next without opening',	// TODO - Translation
-		'skip_previous_article' => 'Focus previous without opening',	// TODO - Translation
+		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// TODO
+		'skip_next_article' => 'Focus next without opening',	// TODO
+		'skip_previous_article' => 'Focus previous without opening',	// TODO
 		'title' => 'קיצורי דרך',
 		'title' => 'קיצורי דרך',
-		'toggle_media' => 'Play/pause media',	// TODO - Translation
+		'toggle_media' => 'Play/pause media',	// TODO
 		'user_filter' => 'גישה למססנים',
 		'user_filter' => 'גישה למססנים',
 		'user_filter_help' => 'אם יש רק מזנן אחד הוא יהיה בשימוש. אחרת המסננים ישמשו על בסיס המספר שלהם.',
 		'user_filter_help' => 'אם יש רק מזנן אחד הוא יהיה בשימוש. אחרת המסננים ישמשו על בסיס המספר שלהם.',
-		'views' => 'Views',	// TODO - Translation
+		'views' => 'Views',	// TODO
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)',	// TODO - Translation
+		'articles_and_size' => '%s articles (%s)',	// TODO
 		'current' => 'משתמש נוכחי',
 		'current' => 'משתמש נוכחי',
 		'is_admin' => 'מנהל',
 		'is_admin' => 'מנהל',
 		'users' => 'משתמשים',
 		'users' => 'משתמשים',

+ 54 - 44
app/i18n/he/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'אין לך הרשאות לצפות בדף זה',
 		'denied' => 'אין לך הרשאות לצפות בדף זה',
@@ -10,40 +20,40 @@ return array(
 	),
 	),
 	'api' => array(
 	'api' => array(
 		'password' => array(
 		'password' => array(
-			'failed' => 'Your password cannot be modified',	// TODO - Translation
-			'updated' => 'Your password has been modified',	// TODO - Translation
+			'failed' => 'Your password cannot be modified',	// TODO
+			'updated' => 'Your password has been modified',	// TODO
 		),
 		),
 	),
 	),
 	'auth' => array(
 	'auth' => array(
 		'login' => array(
 		'login' => array(
 			'invalid' => 'הכניסה לחשבון שגויה',
 			'invalid' => 'הכניסה לחשבון שגויה',
-			'success' => 'You are connected',	// TODO - Translation
+			'success' => 'You are connected',	// TODO
 		),
 		),
 		'logout' => array(
 		'logout' => array(
-			'success' => 'You are disconnected',	// TODO - Translation
+			'success' => 'You are disconnected',	// TODO
 		),
 		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
-		'error' => 'An error occurred while saving configuration',	// TODO - Translation
+		'error' => 'An error occurred while saving configuration',	// TODO
 		'query_created' => 'השאילתה "%s" נוצרה.',
 		'query_created' => 'השאילתה "%s" נוצרה.',
 		'shortcuts_updated' => 'קיצורי הדרך עודכנו',
 		'shortcuts_updated' => 'קיצורי הדרך עודכנו',
 		'updated' => 'ההגדרות עודכנו',
 		'updated' => 'ההגדרות עודכנו',
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
-		'already_enabled' => '%s is already enabled',	// TODO - Translation
-		'cannot_remove' => '%s cannot be removed',	// TODO - Translation
+		'already_enabled' => '%s is already enabled',	// TODO
+		'cannot_remove' => '%s cannot be removed',	// TODO
 		'disable' => array(
 		'disable' => array(
-			'ko' => '%s cannot be disabled. <a href="%s">Check FreshRSS logs</a> for details.',	// TODO - Translation
-			'ok' => '%s is now disabled',	// TODO - Translation
+			'ko' => '%s cannot be disabled. <a href="%s">Check FreshRSS logs</a> for details.',	// TODO
+			'ok' => '%s is now disabled',	// TODO
 		),
 		),
 		'enable' => array(
 		'enable' => array(
-			'ko' => '%s cannot be enabled. <a href="%s">Check FreshRSS logs</a> for details.',	// TODO - Translation
-			'ok' => '%s is now enabled',	// TODO - Translation
+			'ko' => '%s cannot be enabled. <a href="%s">Check FreshRSS logs</a> for details.',	// TODO
+			'ok' => '%s is now enabled',	// TODO
 		),
 		),
-		'no_access' => 'You have no access on %s',	// TODO - Translation
+		'no_access' => 'You have no access on %s',	// TODO
 		'not_enabled' => '%s is not enabled yet',
 		'not_enabled' => '%s is not enabled yet',
-		'not_found' => '%s does not exist',	// TODO - Translation
-		'removed' => '%s removed',	// TODO - Translation
+		'not_found' => '%s does not exist',	// TODO
+		'removed' => '%s removed',	// TODO
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export_no_zip_extension' => 'הרחבת ZIP אינה מותקנת על השרת.',
 		'export_no_zip_extension' => 'הרחבת ZIP אינה מותקנת על השרת.',
@@ -54,60 +64,60 @@ return array(
 		'zip_error' => 'אירעה שגיאה במהלך ייבוא קובץ הZIP.',
 		'zip_error' => 'אירעה שגיאה במהלך ייבוא קובץ הZIP.',
 	),
 	),
 	'profile' => array(
 	'profile' => array(
-		'error' => 'Your profile cannot be modified',	// TODO - Translation
-		'updated' => 'Your profile has been modified',	// TODO - Translation
+		'error' => 'Your profile cannot be modified',	// TODO
+		'updated' => 'Your profile has been modified',	// TODO
 	),
 	),
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'מימוש',
 		'actualize' => 'מימוש',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	// TODO - Translation
-			'marked_unread' => 'The articles have been marked as unread.',	// TODO - Translation
+			'marked_read' => 'The selected articles have been marked as read.',	// TODO
+			'marked_unread' => 'The articles have been marked as unread.',	// TODO
 		),
 		),
 		'category' => array(
 		'category' => array(
-			'created' => 'Category %s has been created.',	// TODO - Translation
-			'deleted' => 'Category has been deleted.',	// TODO - Translation
+			'created' => 'Category %s has been created.',	// TODO
+			'deleted' => 'Category has been deleted.',	// TODO
 			'emptied' => 'הקטגוריה רוקנה',
 			'emptied' => 'הקטגוריה רוקנה',
-			'error' => 'Category cannot be updated',	// TODO - Translation
-			'name_exists' => 'Category name already exists.',	// TODO - Translation
+			'error' => 'Category cannot be updated',	// TODO
+			'name_exists' => 'Category name already exists.',	// TODO
 			'no_id' => 'You must precise the id of the category.',
 			'no_id' => 'You must precise the id of the category.',
-			'no_name' => 'Category name cannot be empty.',	// TODO - Translation
-			'not_delete_default' => 'You cannot delete the default category!',	// TODO - Translation
-			'not_exist' => 'The category does not exist!',	// TODO - Translation
-			'over_max' => 'You have reached your limit of categories (%d)',	// TODO - Translation
-			'updated' => 'Category has been updated.',	// TODO - Translation
+			'no_name' => 'Category name cannot be empty.',	// TODO
+			'not_delete_default' => 'You cannot delete the default category!',	// TODO
+			'not_exist' => 'The category does not exist!',	// TODO
+			'over_max' => 'You have reached your limit of categories (%d)',	// TODO
+			'updated' => 'Category has been updated.',	// TODO
 		),
 		),
 		'feed' => array(
 		'feed' => array(
 			'actualized' => '<em>%s</em> עודכן',
 			'actualized' => '<em>%s</em> עודכן',
 			'actualizeds' => 'הזנות RSS עודכנו',
 			'actualizeds' => 'הזנות RSS עודכנו',
 			'added' => 'RSS הזנת <em>%s</em> נוספה',
 			'added' => 'RSS הזנת <em>%s</em> נוספה',
 			'already_subscribed' => 'אתה כבר רשום ל <em>%s</em>',
 			'already_subscribed' => 'אתה כבר רשום ל <em>%s</em>',
-			'cache_cleared' => '<em>%s</em> cache has been cleared',	// TODO - Translation
+			'cache_cleared' => '<em>%s</em> cache has been cleared',	// TODO
 			'deleted' => 'ההזנה נמחקה',
 			'deleted' => 'ההזנה נמחקה',
-			'error' => 'Feed cannot be updated',	// TODO - Translation
+			'error' => 'Feed cannot be updated',	// TODO
 			'internal_problem' => 'אין אפשרות להוסיף את ההזנה. <a href="%s">בדקו את הלוגים</a> לפרטים.',
 			'internal_problem' => 'אין אפשרות להוסיף את ההזנה. <a href="%s">בדקו את הלוגים</a> לפרטים.',
 			'invalid_url' => 'URL <em>%s</em> אינו תקין',
 			'invalid_url' => 'URL <em>%s</em> אינו תקין',
 			'n_actualized' => '%d הזנות עודכנו',
 			'n_actualized' => '%d הזנות עודכנו',
 			'n_entries_deleted' => '%d המאמרים נמחקו',
 			'n_entries_deleted' => '%d המאמרים נמחקו',
 			'no_refresh' => 'אין הזנה שניתן לרענן…',
 			'no_refresh' => 'אין הזנה שניתן לרענן…',
 			'not_added' => '<em>%s</em> אין אפשרות להוסיף את',
 			'not_added' => '<em>%s</em> אין אפשרות להוסיף את',
-			'not_found' => 'Feed cannot be found',	// TODO - Translation
-			'over_max' => 'You have reached your limit of feeds (%d)',	// TODO - Translation
-			'reloaded' => '<em>%s</em> has been reloaded',	// TODO - Translation
+			'not_found' => 'Feed cannot be found',	// TODO
+			'over_max' => 'You have reached your limit of feeds (%d)',	// TODO
+			'reloaded' => '<em>%s</em> has been reloaded',	// TODO
 			'selector_preview' => array(
 			'selector_preview' => array(
-				'http_error' => 'Failed to load website content.',	// TODO - Translation
-				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// TODO - Translation
-				'no_feed' => 'Internal error (feed cannot be found).',	// TODO - Translation
-				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// TODO - Translation
-				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// TODO - Translation
+				'http_error' => 'Failed to load website content.',	// TODO
+				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// TODO
+				'no_feed' => 'Internal error (feed cannot be found).',	// TODO
+				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// TODO
+				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// TODO
 			),
 			),
 			'updated' => 'ההזנה התעדכנה',
 			'updated' => 'ההזנה התעדכנה',
 		),
 		),
 		'purge_completed' => 'הניקוי הושלם (%d מאמרים נמחקו)',
 		'purge_completed' => 'הניקוי הושלם (%d מאמרים נמחקו)',
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'created' => 'Tag "%s" has been created.',	// TODO - Translation
-		'name_exists' => 'Tag name already exists.',	// TODO - Translation
-		'renamed' => 'Tag "%s" has been renamed to "%s".',	// TODO - Translation
+		'created' => 'Tag "%s" has been created.',	// TODO
+		'name_exists' => 'Tag name already exists.',	// TODO
+		'renamed' => 'Tag "%s" has been renamed to "%s".',	// TODO
 	),
 	),
 	'update' => array(
 	'update' => array(
 		'can_apply' => 'FreshRSS will be now updated to the <strong>version %s</strong>.',
 		'can_apply' => 'FreshRSS will be now updated to the <strong>version %s</strong>.',
@@ -120,15 +130,15 @@ return array(
 	'user' => array(
 	'user' => array(
 		'created' => array(
 		'created' => array(
 			'_' => 'המשתמש %s נוצר',
 			'_' => 'המשתמש %s נוצר',
-			'error' => 'User %s cannot be created',	// TODO - Translation
+			'error' => 'User %s cannot be created',	// TODO
 		),
 		),
 		'deleted' => array(
 		'deleted' => array(
 			'_' => 'המשתמש %s נמחק',
 			'_' => 'המשתמש %s נמחק',
-			'error' => 'User %s cannot be deleted',	// TODO - Translation
+			'error' => 'User %s cannot be deleted',	// TODO
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated',	// TODO - Translation
-			'error' => 'User %s has not been updated',	// TODO - Translation
+			'_' => 'User %s has been updated',	// TODO
+			'error' => 'User %s has not been updated',	// TODO
 		),
 		),
 	),
 	),
 );
 );

+ 108 - 98
app/i18n/he/gen.php

@@ -1,65 +1,75 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'מימוש',
 		'actualize' => 'מימוש',
-		'add' => 'Add',	// TODO - Translation
-		'back' => '← Go back',	// TODO - Translation
+		'add' => 'Add',	// TODO
+		'back' => '← Go back',	// TODO
 		'back_to_rss_feeds' => '← חזרה להזנות הRSS שלך',
 		'back_to_rss_feeds' => '← חזרה להזנות הRSS שלך',
 		'cancel' => 'ביטול',
 		'cancel' => 'ביטול',
 		'create' => 'יצירה',
 		'create' => 'יצירה',
-		'demote' => 'Demote',	// TODO - Translation
-		'disable' => 'Disable',	// TODO - Translation
-		'empty' => 'Empty',	// TODO - Translation
-		'enable' => 'Enable',	// TODO - Translation
+		'demote' => 'Demote',	// TODO
+		'disable' => 'Disable',	// TODO
+		'empty' => 'Empty',	// TODO
+		'enable' => 'Enable',	// TODO
 		'export' => 'ייצוא',
 		'export' => 'ייצוא',
 		'filter' => 'מסנן',
 		'filter' => 'מסנן',
 		'import' => 'ייבוא',
 		'import' => 'ייבוא',
-		'load_default_shortcuts' => 'Load default shortcuts',	// TODO - Translation
+		'load_default_shortcuts' => 'Load default shortcuts',	// TODO
 		'manage' => 'ניהול',
 		'manage' => 'ניהול',
 		'mark_read' => 'סימון כנקרא',
 		'mark_read' => 'סימון כנקרא',
-		'promote' => 'Promote',	// TODO - Translation
-		'purge' => 'Purge',	// TODO - Translation
-		'remove' => 'Remove',	// TODO - Translation
-		'rename' => 'Rename',	// TODO - Translation
+		'promote' => 'Promote',	// TODO
+		'purge' => 'Purge',	// TODO
+		'remove' => 'Remove',	// TODO
+		'rename' => 'Rename',	// TODO
 		'see_website' => 'ראו אתר',
 		'see_website' => 'ראו אתר',
 		'submit' => 'אישור',
 		'submit' => 'אישור',
 		'truncate' => 'מחיקת כל המאמרים',
 		'truncate' => 'מחיקת כל המאמרים',
-		'update' => 'Update',	// TODO - Translation
+		'update' => 'Update',	// TODO
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// TODO - Translation
-		'email' => 'Email address',	// TODO - Translation
+		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// TODO
+		'email' => 'Email address',	// TODO
 		'keep_logged_in' => 'השאר מחובר <small>חודש</small>',
 		'keep_logged_in' => 'השאר מחובר <small>חודש</small>',
 		'login' => 'כניסה לחשבון',
 		'login' => 'כניסה לחשבון',
 		'logout' => 'יציאה מהחשבון',
 		'logout' => 'יציאה מהחשבון',
 		'password' => array(
 		'password' => array(
 			'_' => 'סיסמה',
 			'_' => 'סיסמה',
-			'format' => '<small>At least 7 characters</small>',	// TODO - Translation
+			'format' => '<small>At least 7 characters</small>',	// TODO
 		),
 		),
 		'registration' => array(
 		'registration' => array(
-			'_' => 'New account',	// TODO - Translation
-			'ask' => 'Create an account?',	// TODO - Translation
-			'title' => 'Account creation',	// TODO - Translation
+			'_' => 'New account',	// TODO
+			'ask' => 'Create an account?',	// TODO
+			'title' => 'Account creation',	// TODO
 		),
 		),
 		'username' => array(
 		'username' => array(
 			'_' => 'שם משתמש',
 			'_' => 'שם משתמש',
-			'format' => '<small>Maximum 16 alphanumeric characters</small>',	// TODO - Translation
+			'format' => '<small>Maximum 16 alphanumeric characters</small>',	// TODO
 		),
 		),
 	),
 	),
 	'date' => array(
 	'date' => array(
-		'Apr' => '\\A\\p\\r\\i\\l',	// TODO - Translation
-		'Aug' => '\\A\\u\\g\\u\\s\\t',	// TODO - Translation
-		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',	// TODO - Translation
-		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',	// TODO - Translation
-		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',	// TODO - Translation
-		'Jul' => '\\J\\u\\l\\y',	// TODO - Translation
-		'Jun' => '\\J\\u\\n\\e',	// TODO - Translation
-		'Mar' => '\\M\\a\\r\\c\\h',	// TODO - Translation
-		'May' => '\\M\\a\\y',	// TODO - Translation
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',	// TODO - Translation
-		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',	// TODO - Translation
-		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',	// TODO - Translation
+		'Apr' => '\\A\\p\\r\\i\\l',	// TODO
+		'Aug' => '\\A\\u\\g\\u\\s\\t',	// TODO
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',	// TODO
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y',	// TODO
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\y',	// TODO
+		'Jul' => '\\J\\u\\l\\y',	// TODO
+		'Jun' => '\\J\\u\\n\\e',	// TODO
+		'Mar' => '\\M\\a\\r\\c\\h',	// TODO
+		'May' => '\\M\\a\\y',	// TODO
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',	// TODO
+		'Oct' => '\\O\\c\\t\\o\\b\\e\\r',	// TODO
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',	// TODO
 		'apr' => 'apr',
 		'apr' => 'apr',
 		'april' => 'Apr',
 		'april' => 'Apr',
 		'aug' => 'aug',
 		'aug' => 'aug',
@@ -69,90 +79,90 @@ return array(
 		'december' => 'Dec',
 		'december' => 'Dec',
 		'feb' => 'feb',
 		'feb' => 'feb',
 		'february' => 'Feb',
 		'february' => 'Feb',
-		'format_date' => 'j %s Y',
-		'format_date_hour' => 'j %s Y \\a\\t H\\:i',
-		'fri' => 'Fri',	// TODO - Translation
+		'format_date' => 'j %s Y',	// IGNORE
+		'format_date_hour' => 'j %s Y \\a\\t H\\:i',	// IGNORE
+		'fri' => 'Fri',	// TODO
 		'jan' => 'jan',
 		'jan' => 'jan',
 		'january' => 'Jan',
 		'january' => 'Jan',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'Jul',
 		'july' => 'Jul',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'Jun',
 		'june' => 'Jun',
-		'last_2_year' => 'Last two years',	// TODO - Translation
+		'last_2_year' => 'Last two years',	// TODO
 		'last_3_month' => 'בשלושת החודשים האחרונים',
 		'last_3_month' => 'בשלושת החודשים האחרונים',
-		'last_3_year' => 'Last three years',	// TODO - Translation
-		'last_5_year' => 'Last five years',	// TODO - Translation
+		'last_3_year' => 'Last three years',	// TODO
+		'last_5_year' => 'Last five years',	// TODO
 		'last_6_month' => 'בששת החודשים האחרונים',
 		'last_6_month' => 'בששת החודשים האחרונים',
 		'last_month' => 'בחודש שעבר',
 		'last_month' => 'בחודש שעבר',
 		'last_week' => 'בשבוע שעבר',
 		'last_week' => 'בשבוע שעבר',
 		'last_year' => 'בשנה האחרונה',
 		'last_year' => 'בשנה האחרונה',
 		'mar' => 'mar',
 		'mar' => 'mar',
 		'march' => 'Mar',
 		'march' => 'Mar',
-		'may' => 'May',	// TODO - Translation
-		'may_' => 'May',	// TODO - Translation
-		'mon' => 'Mon',	// TODO - Translation
+		'may' => 'May',	// TODO
+		'may_' => 'May',	// TODO
+		'mon' => 'Mon',	// TODO
 		'month' => 'חודשים',
 		'month' => 'חודשים',
 		'nov' => 'nov',
 		'nov' => 'nov',
 		'november' => 'Nov',
 		'november' => 'Nov',
 		'oct' => 'oct',
 		'oct' => 'oct',
 		'october' => 'Oct',
 		'october' => 'Oct',
-		'sat' => 'Sat',	// TODO - Translation
+		'sat' => 'Sat',	// TODO
 		'sep' => 'sep',
 		'sep' => 'sep',
 		'september' => 'Sep',
 		'september' => 'Sep',
-		'sun' => 'Sun',	// TODO - Translation
-		'thu' => 'Thu',	// TODO - Translation
+		'sun' => 'Sun',	// TODO
+		'thu' => 'Thu',	// TODO
 		'today' => 'היום',
 		'today' => 'היום',
-		'tue' => 'Tue',	// TODO - Translation
-		'wed' => 'Wed',	// TODO - Translation
+		'tue' => 'Tue',	// TODO
+		'wed' => 'Wed',	// TODO
 		'yesterday' => 'אתמול',
 		'yesterday' => 'אתמול',
 	),
 	),
 	'dir' => 'rtl',
 	'dir' => 'rtl',
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',	// TODO - Translation
+		'_' => 'FreshRSS',	// TODO
 		'about' => 'אודות FreshRSS',
 		'about' => 'אודות FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
-		'category_empty' => 'Empty category',	// TODO - Translation
+		'category_empty' => 'Empty category',	// TODO
 		'confirm_action' => 'האם אתם בטוחים שברצונכם לבצע פעולה זו? אין אפשרות לבטל אותה!',
 		'confirm_action' => 'האם אתם בטוחים שברצונכם לבצע פעולה זו? אין אפשרות לבטל אותה!',
 		'confirm_action_feed_cat' => 'האם אתם בטוחים שברצוניכם לבצע פעולה זו? מועדפים ושאילתות עשויות לאבוד. אין אפשרות לבטל אותה!',
 		'confirm_action_feed_cat' => 'האם אתם בטוחים שברצוניכם לבצע פעולה זו? מועדפים ושאילתות עשויות לאבוד. אין אפשרות לבטל אותה!',
 		'feedback' => array(
 		'feedback' => array(
 			'body_new_articles' => 'ישנם	\\d מאמרים חדשים לקרוא ב FreshRSS.',
 			'body_new_articles' => 'ישנם	\\d מאמרים חדשים לקרוא ב FreshRSS.',
-			'request_failed' => 'A request has failed, it may have been caused by internet connection problems.',	// TODO - Translation
+			'request_failed' => 'A request has failed, it may have been caused by internet connection problems.',	// TODO
 			'title_new_articles' => 'FreshRSS: מאמרים חדשים!',
 			'title_new_articles' => 'FreshRSS: מאמרים חדשים!',
 		),
 		),
 		'new_article' => 'מאמרים חדשים זמינים, לחצו לרענון העמוד.',
 		'new_article' => 'מאמרים חדשים זמינים, לחצו לרענון העמוד.',
 		'should_be_activated' => 'חובה להפעיל JavaScript',
 		'should_be_activated' => 'חובה להפעיל JavaScript',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'אודות',
 		'about' => 'אודות',
-		'account' => 'Account',	// TODO - Translation
+		'account' => 'Account',	// TODO
 		'admin' => 'ניהול',
 		'admin' => 'ניהול',
 		'archiving' => 'ארכוב',
 		'archiving' => 'ארכוב',
-		'authentication' => 'Authentication',	// TODO - Translation
-		'check_install' => 'Installation check',	// TODO - Translation
+		'authentication' => 'Authentication',	// TODO
+		'check_install' => 'Installation check',	// TODO
 		'configuration' => 'הגדרות',
 		'configuration' => 'הגדרות',
 		'display' => 'תצוגה',
 		'display' => 'תצוגה',
-		'extensions' => 'Extensions',	// TODO - Translation
+		'extensions' => 'Extensions',	// TODO
 		'logs' => 'לוגים',
 		'logs' => 'לוגים',
 		'queries' => 'שאילתות',
 		'queries' => 'שאילתות',
 		'reading' => 'קריאה',
 		'reading' => 'קריאה',
@@ -160,10 +170,10 @@ return array(
 		'sharing' => 'שיתוף',
 		'sharing' => 'שיתוף',
 		'shortcuts' => 'קיצורי דרך',
 		'shortcuts' => 'קיצורי דרך',
 		'stats' => 'סטטיסטיקות',
 		'stats' => 'סטטיסטיקות',
-		'system' => 'System configuration',	// TODO - Translation
+		'system' => 'System configuration',	// TODO
 		'update' => 'עדכון',
 		'update' => 'עדכון',
-		'user_management' => 'Manage users',	// TODO - Translation
-		'user_profile' => 'Profile',	// TODO - Translation
+		'user_management' => 'Manage users',	// TODO
+		'user_profile' => 'Profile',	// TODO
 	),
 	),
 	'pagination' => array(
 	'pagination' => array(
 		'first' => 'הראשון',
 		'first' => 'הראשון',
@@ -175,33 +185,33 @@ return array(
 		'previous' => 'הקודם',
 		'previous' => 'הקודם',
 	),
 	),
 	'period' => array(
 	'period' => array(
-		'days' => 'days',	// TODO - Translation
-		'hours' => 'hours',	// TODO - Translation
-		'months' => 'months',	// TODO - Translation
-		'weeks' => 'weeks',	// TODO - Translation
-		'years' => 'years',	// TODO - Translation
+		'days' => 'days',	// TODO
+		'hours' => 'hours',	// TODO
+		'months' => 'months',	// TODO
+		'weeks' => 'weeks',	// TODO
+		'years' => 'years',	// TODO
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',	// TODO - Translation
-		'blogotext' => 'Blogotext',
-		'clipboard' => 'Clipboard',	// TODO - Translation
-		'diaspora' => 'Diaspora*',
+		'Known' => 'Known based sites',	// TODO
+		'blogotext' => 'Blogotext',	// IGNORE
+		'clipboard' => 'Clipboard',	// TODO
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'דואר אלקטרוני',
 		'email' => 'דואר אלקטרוני',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'הדפסה',
 		'print' => 'הדפסה',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'זהירות!',
 		'attention' => 'זהירות!',
@@ -210,8 +220,8 @@ return array(
 		'by_default' => 'ברירת מחדל',
 		'by_default' => 'ברירת מחדל',
 		'damn' => 'הו לא!',
 		'damn' => 'הו לא!',
 		'default_category' => 'ללא קטגוריה',
 		'default_category' => 'ללא קטגוריה',
-		'no' => 'לא',
-		'not_applicable' => 'Not available',	// TODO - Translation
+		'no' => 'לא',	// IGNORE
+		'not_applicable' => 'Not available',	// TODO
 		'ok' => 'כן!',
 		'ok' => 'כן!',
 		'or' => 'או',
 		'or' => 'או',
 		'yes' => 'כן',
 		'yes' => 'כן',

+ 15 - 5
app/i18n/he/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'אודות',
 		'_' => 'אודות',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'דיווח באגים',
 		'bugs_reports' => 'דיווח באגים',
 		'credits' => 'קרדיטים',
 		'credits' => 'קרדיטים',
 		'credits_content' => 'מאפייני עיצוב מסויימים הגיעו מ <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> אף על פי ש FreshRSS אינו משתמש בתשתית הזו. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">סמלילים</a> הגיעו מ <a href="https://www.gnome.org/"> פרוייקט GNOME </a>. <em>Open Sans</em> הגופן police נוצר על ידי <a href="https://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Favicons נאספים בעזרת <a href="https://getfavicon.appspot.com/">getFavicon API</a>. FreshRSS מבוסס על <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, תשתית PHP.',
 		'credits_content' => 'מאפייני עיצוב מסויימים הגיעו מ <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> אף על פי ש FreshRSS אינו משתמש בתשתית הזו. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">סמלילים</a> הגיעו מ <a href="https://www.gnome.org/"> פרוייקט GNOME </a>. <em>Open Sans</em> הגופן police נוצר על ידי <a href="https://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Favicons נאספים בעזרת <a href="https://getfavicon.appspot.com/">getFavicon API</a>. FreshRSS מבוסס על <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, תשתית PHP.',
@@ -32,14 +42,14 @@ return array(
 		'about' => 'אודות FreshRSS',
 		'about' => 'אודות FreshRSS',
 		'before_one_day' => 'אתמול',
 		'before_one_day' => 'אתמול',
 		'before_one_week' => 'לפני שבוע',
 		'before_one_week' => 'לפני שבוע',
-		'bookmark_query' => 'Bookmark current query',	// TODO - Translation
+		'bookmark_query' => 'Bookmark current query',	// TODO
 		'favorites' => 'מועדפים (%s)',
 		'favorites' => 'מועדפים (%s)',
 		'global_view' => 'תצוגה גלובלית',
 		'global_view' => 'תצוגה גלובלית',
 		'main_stream' => 'הזנה ראשית',
 		'main_stream' => 'הזנה ראשית',
 		'mark_all_read' => 'סימון הכל כנקרא',
 		'mark_all_read' => 'סימון הכל כנקרא',
 		'mark_cat_read' => 'סימון קטגוריה כנקראה',
 		'mark_cat_read' => 'סימון קטגוריה כנקראה',
 		'mark_feed_read' => 'סימון הזנה כנקראה',
 		'mark_feed_read' => 'סימון הזנה כנקראה',
-		'mark_selection_unread' => 'Mark selection as unread',	// TODO - Translation
+		'mark_selection_unread' => 'Mark selection as unread',	// TODO
 		'newer_first' => 'חדשים בראש',
 		'newer_first' => 'חדשים בראש',
 		'non-starred' => 'הצגת הכל פרט למועדפים',
 		'non-starred' => 'הצגת הכל פרט למועדפים',
 		'normal_view' => 'תצוגה רגילה',
 		'normal_view' => 'תצוגה רגילה',
@@ -52,7 +62,7 @@ return array(
 		'starred' => 'הצגת מועדפים בלבד',
 		'starred' => 'הצגת מועדפים בלבד',
 		'stats' => 'סטטיסטיקות',
 		'stats' => 'סטטיסטיקות',
 		'subscription' => 'ניהול הרשמות',
 		'subscription' => 'ניהול הרשמות',
-		'tags' => 'My labels',	// TODO - Translation
+		'tags' => 'My labels',	// TODO
 		'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 		'unread' => 'הצגת מאמרים שלא נקראו בלבד',
 	),
 	),
 	'share' => 'שיתוף',
 	'share' => 'שיתוף',
@@ -60,6 +70,6 @@ return array(
 		'related' => 'תגיות קשורות',
 		'related' => 'תגיות קשורות',
 	),
 	),
 	'tos' => array(
 	'tos' => array(
-		'title' => 'Terms of Service',	// TODO - Translation
+		'title' => 'Terms of Service',	// TODO
 	),
 	),
 );
 );

+ 32 - 22
app/i18n/he/install.php

@@ -1,19 +1,29 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'השלמת ההתקנה',
 		'finish' => 'השלמת ההתקנה',
 		'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
 		'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
-		'keep_install' => 'Keep previous configuration',	// TODO - Translation
+		'keep_install' => 'Keep previous configuration',	// TODO
 		'next_step' => 'לשלב הבא',
 		'next_step' => 'לשלב הבא',
-		'reinstall' => 'Reinstall FreshRSS',	// TODO - Translation
+		'reinstall' => 'Reinstall FreshRSS',	// TODO
 	),
 	),
 	'auth' => array(
 	'auth' => array(
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'form' => 'טופס אינטרנטי (מסורתי, דורש JavaScript)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'http' => 'HTTP (למשתמשים מתקדמים עם HTTPS)',
 		'none' => 'ללא (מסוכן)',
 		'none' => 'ללא (מסוכן)',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
-		'password_format' => 'At least 7 characters',	// TODO - Translation
+		'password_format' => 'At least 7 characters',	// TODO
 		'type' => 'שיטת אימות',
 		'type' => 'שיטת אימות',
 	),
 	),
 	'bdd' => array(
 	'bdd' => array(
@@ -31,7 +41,7 @@ return array(
 	),
 	),
 	'check' => array(
 	'check' => array(
 		'_' => 'בדיקות',
 		'_' => 'בדיקות',
-		'already_installed' => 'We have detected that FreshRSS is already installed!',	// TODO - Translation
+		'already_installed' => 'We have detected that FreshRSS is already installed!',	// TODO
 		'cache' => array(
 		'cache' => array(
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
 			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',
 			'ok' => 'ההרשאות בתיקיית המטמון תקינות',
 			'ok' => 'ההרשאות בתיקיית המטמון תקינות',
@@ -57,16 +67,16 @@ return array(
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 			'ok' => 'ההרשאות בתיקיית הfavicons תקינות',
 		),
 		),
 		'fileinfo' => array(
 		'fileinfo' => array(
-			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// TODO - Translation
-			'ok' => 'You have the fileinfo library.',	// TODO - Translation
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// TODO
+			'ok' => 'You have the fileinfo library.',	// TODO
 		),
 		),
 		'json' => array(
 		'json' => array(
-			'nok' => 'Cannot find the recommended library to parse JSON.',	// TODO - Translation
-			'ok' => 'You have the recommended library to parse JSON.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended library to parse JSON.',	// TODO
+			'ok' => 'You have the recommended library to parse JSON.',	// TODO
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// TODO - Translation
-			'ok' => 'You have the recommended library mbstring for Unicode.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// TODO
+			'ok' => 'You have the recommended library mbstring for Unicode.',	// TODO
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
 			'nok' => 'הספרייה הנדרשת לביטויים רגולריים אינה מותקנת (php-pcre)',
 			'nok' => 'הספרייה הנדרשת לביטויים רגולריים אינה מותקנת (php-pcre)',
@@ -82,17 +92,17 @@ return array(
 		),
 		),
 		'reload' => 'בדוק שוב',
 		'reload' => 'בדוק שוב',
 		'tmp' => array(
 		'tmp' => array(
-			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',	// TODO - Translation
-			'ok' => 'Permissions on the temp directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',	// TODO
+			'ok' => 'Permissions on the temp directory are good.',	// TODO
 		),
 		),
-		'unknown_process_username' => 'unknown',	// TODO - Translation
+		'unknown_process_username' => 'unknown',	// TODO
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',	// TODO - Translation
-			'ok' => 'Permissions on the users directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on the <em>%1$s</em> directory for <em>%2$s</em> user. The HTTP server must have write permissions.',	// TODO
+			'ok' => 'Permissions on the users directory are good.',	// TODO
 		),
 		),
 		'xml' => array(
 		'xml' => array(
-			'nok' => 'Cannot find the required library to parse XML.',	// TODO - Translation
-			'ok' => 'You have the required library to parse XML.',	// TODO - Translation
+			'nok' => 'Cannot find the required library to parse XML.',	// TODO
+			'ok' => 'You have the required library to parse XML.',	// TODO
 		),
 		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
@@ -104,19 +114,19 @@ return array(
 	'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
 	'fix_errors_before' => 'יש לתקן את השגיאות לפני המעבר לשלב הבא.',
 	'javascript_is_better' => 'FreshRSS מעדיף שתאפשרו JavaScript',
 	'javascript_is_better' => 'FreshRSS מעדיף שתאפשרו JavaScript',
 	'js' => array(
 	'js' => array(
-		'confirm_reinstall' => 'You will lose your previous configuration by reinstalling FreshRSS. Are you sure you want to continue?',	// TODO - Translation
+		'confirm_reinstall' => 'You will lose your previous configuration by reinstalling FreshRSS. Are you sure you want to continue?',	// TODO
 	),
 	),
 	'language' => array(
 	'language' => array(
 		'_' => 'שפה',
 		'_' => 'שפה',
 		'choose' => 'בחירת שפה ל FreshRSS',
 		'choose' => 'בחירת שפה ל FreshRSS',
 		'defined' => 'השפה הוגדרה.',
 		'defined' => 'השפה הוגדרה.',
 	),
 	),
-	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// TODO - Translation
-	'ok' => 'The installation process was successful.',	// TODO - Translation
+	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// TODO
+	'ok' => 'The installation process was successful.',	// TODO
 	'session' => array(
 	'session' => array(
-		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// TODO - Translation
+		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// TODO
 	),
 	),
-	'step' => 'step %d',	// TODO - Translation
+	'step' => 'step %d',	// TODO
 	'steps' => 'שלבים',
 	'steps' => 'שלבים',
 	'this_is_the_end' => 'סיום',
 	'this_is_the_end' => 'סיום',
 	'title' => 'התקנה · FreshRSS',
 	'title' => 'התקנה · FreshRSS',

+ 63 - 53
app/i18n/he/sub.php

@@ -1,23 +1,33 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',	// TODO - Translation
-		'title' => 'API',	// TODO - Translation
+		'documentation' => 'Copy the following URL to use it within an external tool.',	// TODO
+		'title' => 'API',	// TODO
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// TODO - Translation
-		'label' => 'Subscribe',	// TODO - Translation
-		'title' => 'Bookmarklet',	// TODO - Translation
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// TODO
+		'label' => 'Subscribe',	// TODO
+		'title' => 'Bookmarklet',	// TODO
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'קטגוריה',
 		'_' => 'קטגוריה',
-		'add' => 'Add a category',	// TODO - Translation
+		'add' => 'Add a category',	// TODO
 		'archiving' => 'ארכוב',
 		'archiving' => 'ארכוב',
-		'empty' => 'Empty category',	// TODO - Translation
+		'empty' => 'Empty category',	// TODO
 		'information' => 'מידע',
 		'information' => 'מידע',
-		'position' => 'Display position',	// TODO - Translation
-		'position_help' => 'To control category sort order',	// TODO - Translation
+		'position' => 'Display position',	// TODO
+		'position_help' => 'To control category sort order',	// TODO
 		'title' => 'כותרת',
 		'title' => 'כותרת',
 	),
 	),
 	'feed' => array(
 	'feed' => array(
@@ -31,73 +41,73 @@ return array(
 			'password' => 'HTTP סיסמה',
 			'password' => 'HTTP סיסמה',
 			'username' => 'HTTP שם משתמש',
 			'username' => 'HTTP שם משתמש',
 		),
 		),
-		'clear_cache' => 'Always clear cache',	// TODO - Translation
+		'clear_cache' => 'Always clear cache',	// TODO
 		'content_action' => array(
 		'content_action' => array(
-			'_' => 'Content action when fetching the article content',	// TODO - Translation
-			'append' => 'Add after existing content',	// TODO - Translation
-			'prepend' => 'Add before existing content',	// TODO - Translation
-			'replace' => 'Replace existing content',	// TODO - Translation
+			'_' => 'Content action when fetching the article content',	// TODO
+			'append' => 'Add after existing content',	// TODO
+			'prepend' => 'Add before existing content',	// TODO
+			'replace' => 'Replace existing content',	// TODO
 		),
 		),
-		'css_cookie' => 'Use Cookies when fetching the article content',	// TODO - Translation
-		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// TODO - Translation
+		'css_cookie' => 'Use Cookies when fetching the article content',	// TODO
+		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// TODO
 		'css_help' => 'קבלת הזנות RSS קטומות	(זהירות, לוקח זמן רב יותר!)',
 		'css_help' => 'קבלת הזנות RSS קטומות	(זהירות, לוקח זמן רב יותר!)',
 		'css_path' => 'נתיב הCSS של המאמר באתר המקורי',
 		'css_path' => 'נתיב הCSS של המאמר באתר המקורי',
 		'description' => 'תיאור',
 		'description' => 'תיאור',
 		'empty' => 'הזנה זו ריקה. אנא ודאו שהיא עדיין מתוחזקת.',
 		'empty' => 'הזנה זו ריקה. אנא ודאו שהיא עדיין מתוחזקת.',
 		'error' => 'הזנה זו נתקלה בשגיאה, אנא ודאו שהיא תקינה ואז נסו שנית.',
 		'error' => 'הזנה זו נתקלה בשגיאה, אנא ודאו שהיא תקינה ואז נסו שנית.',
 		'filteractions' => array(
 		'filteractions' => array(
-			'_' => 'Filter actions',	// TODO - Translation
-			'help' => 'Write one search filter per line.',	// TODO - Translation
+			'_' => 'Filter actions',	// TODO
+			'help' => 'Write one search filter per line.',	// TODO
 		),
 		),
 		'information' => 'מידע',
 		'information' => 'מידע',
 		'keep_min' => 'מסםר מינימלי של מאמרים לשמור',
 		'keep_min' => 'מסםר מינימלי של מאמרים לשמור',
 		'maintenance' => array(
 		'maintenance' => array(
-			'clear_cache' => 'Clear cache',	// TODO - Translation
-			'clear_cache_help' => 'Clear the cache for this feed.',	// TODO - Translation
-			'reload_articles' => 'Reload articles',	// TODO - Translation
-			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// TODO - Translation
-			'title' => 'Maintenance',	// TODO - Translation
+			'clear_cache' => 'Clear cache',	// TODO
+			'clear_cache_help' => 'Clear the cache for this feed.',	// TODO
+			'reload_articles' => 'Reload articles',	// TODO
+			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// TODO
+			'title' => 'Maintenance',	// TODO
 		),
 		),
 		'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת	<em>%s</em>.',
 		'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת	<em>%s</em>.',
-		'mute' => 'mute',	// TODO - Translation
+		'mute' => 'mute',	// TODO
 		'no_selected' => 'אף הזנה לא נבחרה.',
 		'no_selected' => 'אף הזנה לא נבחרה.',
 		'number_entries' => '%d מאמרים',
 		'number_entries' => '%d מאמרים',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility',	// TODO - Translation
-			'archived' => 'Do not show (archived)',	// TODO - Translation
+			'_' => 'Visibility',	// TODO
+			'archived' => 'Do not show (archived)',	// TODO
 			'main_stream' => 'הצגה בזרם המרכזי',
 			'main_stream' => 'הצגה בזרם המרכזי',
-			'normal' => 'Show in its category',	// TODO - Translation
+			'normal' => 'Show in its category',	// TODO
 		),
 		),
-		'proxy' => 'Set a proxy for fetching this feed',	// TODO - Translation
-		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// TODO - Translation
+		'proxy' => 'Set a proxy for fetching this feed',	// TODO
+		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// TODO
 		'selector_preview' => array(
 		'selector_preview' => array(
-			'show_raw' => 'Show source code',	// TODO - Translation
-			'show_rendered' => 'Show content',	// TODO - Translation
+			'show_raw' => 'Show source code',	// TODO
+			'show_rendered' => 'Show content',	// TODO
 		),
 		),
 		'show' => array(
 		'show' => array(
-			'all' => 'Show all feeds',	// TODO - Translation
-			'error' => 'Show only feeds with errors',	// TODO - Translation
+			'all' => 'Show all feeds',	// TODO
+			'error' => 'Show only feeds with errors',	// TODO
 		),
 		),
 		'showing' => array(
 		'showing' => array(
-			'error' => 'Showing only feeds with errors',	// TODO - Translation
+			'error' => 'Showing only feeds with errors',	// TODO
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	// TODO - Translation
+		'ssl_verify' => 'Verify SSL security',	// TODO
 		'stats' => 'סטטיסטיקות',
 		'stats' => 'סטטיסטיקות',
 		'think_to_add' => 'ניתן להוסיף הזנות חדשות.',
 		'think_to_add' => 'ניתן להוסיף הזנות חדשות.',
-		'timeout' => 'Timeout in seconds',	// TODO - Translation
+		'timeout' => 'Timeout in seconds',	// TODO
 		'title' => 'כותרת',
 		'title' => 'כותרת',
 		'title_add' => 'הוספת הזנה',
 		'title_add' => 'הוספת הזנה',
 		'ttl' => 'אין לרענן אוטומטית יותר מ',
 		'ttl' => 'אין לרענן אוטומטית יותר מ',
 		'url' => 'הזנה URL',
 		'url' => 'הזנה URL',
-		'useragent' => 'Set the user agent for fetching this feed',	// TODO - Translation
-		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// TODO - Translation
+		'useragent' => 'Set the user agent for fetching this feed',	// TODO
+		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// TODO
 		'validator' => 'בדיקות תקינות ההזנה',
 		'validator' => 'בדיקות תקינות ההזנה',
 		'website' => 'אתר URL',
 		'website' => 'אתר URL',
-		'websub' => 'Instant notification with WebSub',	// TODO - Translation
+		'websub' => 'Instant notification with WebSub',	// TODO
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'ייצוא',
 		'export' => 'ייצוא',
-		'export_labelled' => 'Export your labelled articles',	// TODO - Translation
+		'export_labelled' => 'Export your labelled articles',	// TODO
 		'export_opml' => 'ייצוא רשימת הזנות (OPML)',
 		'export_opml' => 'ייצוא רשימת הזנות (OPML)',
 		'export_starred' => 'ייצוא מועדפים',
 		'export_starred' => 'ייצוא מועדפים',
 		'feed_list' => 'רשימה של %s מאמרים',
 		'feed_list' => 'רשימה של %s מאמרים',
@@ -108,31 +118,31 @@ return array(
 		'title' => 'יבוא / יצוא ',
 		'title' => 'יבוא / יצוא ',
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'add' => 'Add a feed or category',	// TODO - Translation
+		'add' => 'Add a feed or category',	// TODO
 		'import_export' => 'יבוא / יצוא ',
 		'import_export' => 'יבוא / יצוא ',
-		'label_management' => 'Label management',	// TODO - Translation
+		'label_management' => 'Label management',	// TODO
 		'stats' => array(
 		'stats' => array(
 			'idle' => 'הזנות שלא עודכנו',
 			'idle' => 'הזנות שלא עודכנו',
 			'main' => 'סטטיסטיקות ראשיות',
 			'main' => 'סטטיסטיקות ראשיות',
 			'repartition' => 'חלוקת המאמרים',
 			'repartition' => 'חלוקת המאמרים',
 		),
 		),
 		'subscription_management' => 'ניהול הרשמות',
 		'subscription_management' => 'ניהול הרשמות',
-		'subscription_tools' => 'Subscription tools',	// TODO - Translation
+		'subscription_tools' => 'Subscription tools',	// TODO
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'name' => 'Name',	// TODO - Translation
-		'new_name' => 'New name',	// TODO - Translation
-		'old_name' => 'Old name',	// TODO - Translation
+		'name' => 'Name',	// TODO
+		'new_name' => 'New name',	// TODO
+		'old_name' => 'Old name',	// TODO
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'ניהול הרשמות',
 		'_' => 'ניהול הרשמות',
-		'add' => 'Add a feed or category',	// TODO - Translation
-		'add_category' => 'Add a category',	// TODO - Translation
-		'add_feed' => 'Add a feed',	// TODO - Translation
-		'add_label' => 'Add a label',	// TODO - Translation
-		'delete_label' => 'Delete a label',	// TODO - Translation
+		'add' => 'Add a feed or category',	// TODO
+		'add_category' => 'Add a category',	// TODO
+		'add_feed' => 'Add a feed',	// TODO
+		'add_label' => 'Add a label',	// TODO
+		'delete_label' => 'Delete a label',	// TODO
 		'feed_management' => 'ניהול הזנות RSS',
 		'feed_management' => 'ניהול הזנות RSS',
-		'rename_label' => 'Rename a label',	// TODO - Translation
-		'subscription_tools' => 'Subscription tools',	// TODO - Translation
+		'rename_label' => 'Rename a label',	// TODO
+		'subscription_tools' => 'Subscription tools',	// TODO
 	),
 	),
 );
 );

+ 30 - 20
app/i18n/he/user.php

@@ -1,44 +1,54 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'This email address is invalid.',	// TODO - Translation
-			'required' => 'An email address is required.',	// TODO - Translation
+			'invalid' => 'This email address is invalid.',	// TODO
+			'required' => 'An email address is required.',	// TODO
 		),
 		),
 		'validation' => array(
 		'validation' => array(
-			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// TODO - Translation
-			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// TODO - Translation
+			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// TODO
+			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// TODO
 			'feedback' => array(
 			'feedback' => array(
-				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// TODO - Translation
-				'email_sent' => 'An email has been sent to your address.',	// TODO - Translation
-				'error' => 'Email address validation failed.',	// TODO - Translation
-				'ok' => 'This email address has been validated.',	// TODO - Translation
-				'unnecessary' => 'This email address was already validated.',	// TODO - Translation
-				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// TODO - Translation
+				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// TODO
+				'email_sent' => 'An email has been sent to your address.',	// TODO
+				'error' => 'Email address validation failed.',	// TODO
+				'ok' => 'This email address has been validated.',	// TODO
+				'unnecessary' => 'This email address was already validated.',	// TODO
+				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// TODO
 			),
 			),
-			'need_to' => 'You need to validate your email address before being able to use %s.',	// TODO - Translation
-			'resend_email' => 'Resend the email',	// TODO - Translation
-			'title' => 'Email address validation',	// TODO - Translation
+			'need_to' => 'You need to validate your email address before being able to use %s.',	// TODO
+			'resend_email' => 'Resend the email',	// TODO
+			'title' => 'Email address validation',	// TODO
 		),
 		),
 	),
 	),
 	'mailer' => array(
 	'mailer' => array(
 		'email_need_validation' => array(
 		'email_need_validation' => array(
-			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// TODO - Translation
-			'title' => 'You need to validate your account',	// TODO - Translation
-			'welcome' => 'Welcome %s,',	// TODO - Translation
+			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// TODO
+			'title' => 'You need to validate your account',	// TODO
+			'welcome' => 'Welcome %s,',	// TODO
 		),
 		),
 	),
 	),
 	'password' => array(
 	'password' => array(
-		'invalid' => 'The password is invalid.',	// TODO - Translation
+		'invalid' => 'The password is invalid.',	// TODO
 	),
 	),
 	'tos' => array(
 	'tos' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'You must accept the Terms of Service to be able to register.',	// TODO - Translation
+			'invalid' => 'You must accept the Terms of Service to be able to register.',	// TODO
 		),
 		),
 	),
 	),
 	'username' => array(
 	'username' => array(
-		'invalid' => 'This username is invalid.',	// TODO - Translation
-		'taken' => 'This username, %s, is taken.',	// TODO - Translation
+		'invalid' => 'This username is invalid.',	// TODO
+		'taken' => 'This username, %s, is taken.',	// TODO
 	),
 	),
 );
 );

+ 21 - 11
app/i18n/it/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Consenti la lettura agli utenti anonimi degli articoli dell utente predefinito (%s)',
 		'allow_anonymous' => 'Consenti la lettura agli utenti anonimi degli articoli dell utente predefinito (%s)',
@@ -130,7 +140,7 @@ return array(
 		'entry_per_hour' => 'Per ora (media: %.2f articoli)',
 		'entry_per_hour' => 'Per ora (media: %.2f articoli)',
 		'entry_per_month' => 'Per mese (media: %.2f articoli)',
 		'entry_per_month' => 'Per mese (media: %.2f articoli)',
 		'entry_repartition' => 'Ripartizione contenuti',
 		'entry_repartition' => 'Ripartizione contenuti',
-		'feed' => 'Feed',	// TODO - Translation
+		'feed' => 'Feed',	// TODO
 		'feed_per_category' => 'Feeds per categoria',
 		'feed_per_category' => 'Feeds per categoria',
 		'idle' => 'Feeds non aggiornati',
 		'idle' => 'Feeds non aggiornati',
 		'main' => 'Statistiche principali',
 		'main' => 'Statistiche principali',
@@ -148,12 +158,12 @@ return array(
 	),
 	),
 	'system' => array(
 	'system' => array(
 		'_' => 'Configurazione di sistema',
 		'_' => 'Configurazione di sistema',
-		'auto-update-url' => 'Auto-update server URL',	// TODO - Translation
+		'auto-update-url' => 'Auto-update server URL',	// TODO
 		'cookie-duration' => array(
 		'cookie-duration' => array(
-			'help' => 'in seconds',	// TODO - Translation
-			'number' => 'Duration to keep logged in',	// TODO - Translation
+			'help' => 'in seconds',	// TODO
+			'number' => 'Duration to keep logged in',	// TODO
 		),
 		),
-		'force_email_validation' => 'Force email address validation',	// TODO - Translation
+		'force_email_validation' => 'Force email address validation',	// TODO
 		'instance-name' => 'Nome istanza',
 		'instance-name' => 'Nome istanza',
 		'max-categories' => 'Limite categorie per utente',
 		'max-categories' => 'Limite categorie per utente',
 		'max-feeds' => 'Limite feeds per utente',
 		'max-feeds' => 'Limite feeds per utente',
@@ -174,16 +184,16 @@ return array(
 	'user' => array(
 	'user' => array(
 		'admin' => 'Amministratore',
 		'admin' => 'Amministratore',
 		'article_count' => 'Articoli',
 		'article_count' => 'Articoli',
-		'back_to_manage' => '← Return to user list',	// TODO - Translation
+		'back_to_manage' => '← Return to user list',	// TODO
 		'create' => 'Crea nuovo utente',
 		'create' => 'Crea nuovo utente',
-		'database_size' => 'Database size',	// TODO - Translation
+		'database_size' => 'Database size',	// TODO
 		'email' => 'Indirizzo e-mail',
 		'email' => 'Indirizzo e-mail',
-		'enabled' => 'Enabled',	// TODO - Translation
-		'feed_count' => 'Feeds',	// TODO - Translation
-		'is_admin' => 'Is admin',	// TODO - Translation
+		'enabled' => 'Enabled',	// TODO
+		'feed_count' => 'Feeds',	// TODO
+		'is_admin' => 'Is admin',	// TODO
 		'language' => 'Lingua',
 		'language' => 'Lingua',
 		'last_user_activity' => 'Ultime attività degli utenti',
 		'last_user_activity' => 'Ultime attività degli utenti',
-		'list' => 'User list',	// TODO - Translation
+		'list' => 'User list',	// TODO
 		'number' => ' %d profilo utente creato',
 		'number' => ' %d profilo utente creato',
 		'numbers' => 'Sono presenti %d profili utente',
 		'numbers' => 'Sono presenti %d profili utente',
 		'password_form' => 'Password<br /><small>(per il login classico)</small>',
 		'password_form' => 'Password<br /><small>(per il login classico)</small>',

+ 69 - 59
app/i18n/it/conf.php

@@ -1,21 +1,31 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archiviazione',
 		'_' => 'Archiviazione',
-		'exception' => 'Purge exception',	// TODO - Translation
+		'exception' => 'Purge exception',	// TODO
 		'help' => 'Altre opzioni sono disponibili nelle impostazioni dei singoli feed',
 		'help' => 'Altre opzioni sono disponibili nelle impostazioni dei singoli feed',
-		'keep_favourites' => 'Never delete favourites',	// TODO - Translation
-		'keep_labels' => 'Never delete labels',	// TODO - Translation
-		'keep_max' => 'Maximum number of articles to keep',	// TODO - Translation
+		'keep_favourites' => 'Never delete favourites',	// TODO
+		'keep_labels' => 'Never delete labels',	// TODO
+		'keep_max' => 'Maximum number of articles to keep',	// TODO
 		'keep_min_by_feed' => 'Numero minimo di articoli da mantenere per feed',
 		'keep_min_by_feed' => 'Numero minimo di articoli da mantenere per feed',
-		'keep_period' => 'Maximum age of articles to keep',	// TODO - Translation
-		'keep_unreads' => 'Never delete unread articles',	// TODO - Translation
-		'maintenance' => 'Maintenance',	// TODO - Translation
+		'keep_period' => 'Maximum age of articles to keep',	// TODO
+		'keep_unreads' => 'Never delete unread articles',	// TODO
+		'maintenance' => 'Maintenance',	// TODO
 		'optimize' => 'Ottimizza database',
 		'optimize' => 'Ottimizza database',
 		'optimize_help' => 'Da fare occasionalmente per ridurre le dimensioni del database',
 		'optimize_help' => 'Da fare occasionalmente per ridurre le dimensioni del database',
-		'policy' => 'Purge policy',	// TODO - Translation
-		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// TODO - Translation
+		'policy' => 'Purge policy',	// TODO
+		'policy_warning' => 'If no purge policy is selected, every article will be kept.',	// TODO
 		'purge_now' => 'Cancella ora',
 		'purge_now' => 'Cancella ora',
 		'title' => 'Archiviazione',
 		'title' => 'Archiviazione',
 		'ttl' => 'Non effettuare aggiornamenti per più di',
 		'ttl' => 'Non effettuare aggiornamenti per più di',
@@ -24,12 +34,12 @@ return array(
 		'_' => 'Visualizzazione',
 		'_' => 'Visualizzazione',
 		'icon' => array(
 		'icon' => array(
 			'bottom_line' => 'Barra in fondo',
 			'bottom_line' => 'Barra in fondo',
-			'display_authors' => 'Authors',	// TODO - Translation
+			'display_authors' => 'Authors',	// TODO
 			'entry' => 'Icone degli articoli',
 			'entry' => 'Icone degli articoli',
 			'publication_date' => 'Data di pubblicazione',
 			'publication_date' => 'Data di pubblicazione',
 			'related_tags' => 'Tags correlati',
 			'related_tags' => 'Tags correlati',
 			'sharing' => 'Condivisione',
 			'sharing' => 'Condivisione',
-			'summary' => 'Summary',	// TODO - Translation
+			'summary' => 'Summary',	// TODO
 			'top_line' => 'Barra in alto',
 			'top_line' => 'Barra in alto',
 		),
 		),
 		'language' => 'Lingua',
 		'language' => 'Lingua',
@@ -37,15 +47,15 @@ return array(
 			'seconds' => 'secondi (0 significa nessun timeout)',
 			'seconds' => 'secondi (0 significa nessun timeout)',
 			'timeout' => 'Notifica timeout HTML5',
 			'timeout' => 'Notifica timeout HTML5',
 		),
 		),
-		'show_nav_buttons' => 'Show the navigation buttons',	// TODO - Translation
+		'show_nav_buttons' => 'Show the navigation buttons',	// TODO
 		'theme' => 'Tema',
 		'theme' => 'Tema',
-		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// TODO - Translation
+		'theme_not_available' => 'The “%s” theme is not available anymore. Please choose another theme.',	// TODO
 		'thumbnail' => array(
 		'thumbnail' => array(
-			'label' => 'Thumbnail',	// TODO - Translation
-			'landscape' => 'Landscape',	// TODO - Translation
-			'none' => 'None',	// TODO - Translation
-			'portrait' => 'Portrait',	// TODO - Translation
-			'square' => 'Square',	// TODO - Translation
+			'label' => 'Thumbnail',	// TODO
+			'landscape' => 'Landscape',	// TODO
+			'none' => 'None',	// TODO
+			'portrait' => 'Portrait',	// TODO
+			'square' => 'Square',	// TODO
 		),
 		),
 		'title' => 'Visualizzazione',
 		'title' => 'Visualizzazione',
 		'width' => array(
 		'width' => array(
@@ -58,7 +68,7 @@ return array(
 	),
 	),
 	'profile' => array(
 	'profile' => array(
 		'_' => 'Gestione profili',
 		'_' => 'Gestione profili',
-		'api' => 'API management',	// TODO - Translation
+		'api' => 'API management',	// TODO
 		'delete' => array(
 		'delete' => array(
 			'_' => 'Cancellazione account',
 			'_' => 'Cancellazione account',
 			'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.',
 			'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.',
@@ -74,19 +84,19 @@ return array(
 		'deprecated' => 'Questa query non è più valida. La categoria o il feed di riferimento non stati cancellati.',
 		'deprecated' => 'Questa query non è più valida. La categoria o il feed di riferimento non stati cancellati.',
 		'filter' => array(
 		'filter' => array(
 			'_' => 'Filtro applicato:',
 			'_' => 'Filtro applicato:',
-			'categories' => 'Display by category',	// TODO - Translation
-			'feeds' => 'Display by feed',	// TODO - Translation
-			'order' => 'Sort by date',	// TODO - Translation
-			'search' => 'Expression',	// TODO - Translation
-			'state' => 'State',	// TODO - Translation
-			'tags' => 'Display by tag',	// TODO - Translation
-			'type' => 'Type',	// TODO - Translation
+			'categories' => 'Display by category',	// TODO
+			'feeds' => 'Display by feed',	// TODO
+			'order' => 'Sort by date',	// TODO
+			'search' => 'Expression',	// TODO
+			'state' => 'State',	// TODO
+			'tags' => 'Display by tag',	// TODO
+			'type' => 'Type',	// TODO
 		),
 		),
 		'get_all' => 'Mostra tutti gli articoli',
 		'get_all' => 'Mostra tutti gli articoli',
 		'get_category' => 'Mostra la categoria "%s" ',
 		'get_category' => 'Mostra la categoria "%s" ',
 		'get_favorite' => 'Mostra articoli preferiti',
 		'get_favorite' => 'Mostra articoli preferiti',
 		'get_feed' => 'Mostra feed "%s" ',
 		'get_feed' => 'Mostra feed "%s" ',
-		'name' => 'Name',	// TODO - Translation
+		'name' => 'Name',	// TODO
 		'no_filter' => 'Nessun filtro',
 		'no_filter' => 'Nessun filtro',
 		'number' => 'Ricerca n°%d',
 		'number' => 'Ricerca n°%d',
 		'order_asc' => 'Mostra prima gli articoli più vecchi',
 		'order_asc' => 'Mostra prima gli articoli più vecchi',
@@ -113,13 +123,13 @@ return array(
 	'reading' => array(
 	'reading' => array(
 		'_' => 'Lettura',
 		'_' => 'Lettura',
 		'after_onread' => 'Dopo “segna tutto come letto”,',
 		'after_onread' => 'Dopo “segna tutto come letto”,',
-		'always_show_favorites' => 'Show all articles in favourites by default',	// TODO - Translation
+		'always_show_favorites' => 'Show all articles in favourites by default',	// TODO
 		'articles_per_page' => 'Numero di articoli per pagina',
 		'articles_per_page' => 'Numero di articoli per pagina',
 		'auto_load_more' => 'Carica articoli successivi a fondo pagina',
 		'auto_load_more' => 'Carica articoli successivi a fondo pagina',
 		'auto_remove_article' => 'Nascondi articoli dopo la lettura',
 		'auto_remove_article' => 'Nascondi articoli dopo la lettura',
 		'confirm_enabled' => 'Mostra una conferma per “segna tutto come letto”',
 		'confirm_enabled' => 'Mostra una conferma per “segna tutto come letto”',
 		'display_articles_unfolded' => 'Mostra articoli aperti di predefinito',
 		'display_articles_unfolded' => 'Mostra articoli aperti di predefinito',
-		'display_categories_unfolded' => 'Categories to unfold',	// TODO - Translation
+		'display_categories_unfolded' => 'Categories to unfold',	// TODO
 		'hide_read_feeds' => 'Nascondi categorie e feeds con articoli già letti (non funziona se “Mostra tutti gli articoli” è selezionato)',
 		'hide_read_feeds' => 'Nascondi categorie e feeds con articoli già letti (non funziona se “Mostra tutti gli articoli” è selezionato)',
 		'img_with_lazyload' => 'Usa la modalità "caricamento ritardato" per le immagini',
 		'img_with_lazyload' => 'Usa la modalità "caricamento ritardato" per le immagini',
 		'jump_next' => 'Salta al successivo feed o categoria non letto',
 		'jump_next' => 'Salta al successivo feed o categoria non letto',
@@ -128,24 +138,24 @@ return array(
 		'read' => array(
 		'read' => array(
 			'article_open_on_website' => 'Quando un articolo è aperto nel suo sito di origine',
 			'article_open_on_website' => 'Quando un articolo è aperto nel suo sito di origine',
 			'article_viewed' => 'Quando un articolo viene letto',
 			'article_viewed' => 'Quando un articolo viene letto',
-			'keep_max_n_unread' => 'Max number of articles to keep unread',	// TODO - Translation
+			'keep_max_n_unread' => 'Max number of articles to keep unread',	// TODO
 			'scroll' => 'Scorrendo la pagina',
 			'scroll' => 'Scorrendo la pagina',
 			'upon_reception' => 'Alla ricezione del contenuto',
 			'upon_reception' => 'Alla ricezione del contenuto',
 			'when' => 'Segna articoli come letti…',
 			'when' => 'Segna articoli come letti…',
-			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// TODO - Translation
+			'when_same_title' => 'if an identical title already exists in the top <i>n</i> newest articles',	// TODO
 		),
 		),
 		'show' => array(
 		'show' => array(
 			'_' => 'Articoli da visualizzare',
 			'_' => 'Articoli da visualizzare',
-			'active_category' => 'Active category',	// TODO - Translation
+			'active_category' => 'Active category',	// TODO
 			'adaptive' => 'Adatta visualizzazione',
 			'adaptive' => 'Adatta visualizzazione',
 			'all_articles' => 'Mostra tutti gli articoli',
 			'all_articles' => 'Mostra tutti gli articoli',
-			'all_categories' => 'All categories',	// TODO - Translation
-			'no_category' => 'No category',	// TODO - Translation
-			'remember_categories' => 'Remember open categories',	// TODO - Translation
+			'all_categories' => 'All categories',	// TODO
+			'no_category' => 'No category',	// TODO
+			'remember_categories' => 'Remember open categories',	// TODO
 			'unread' => 'Mostra solo non letti',
 			'unread' => 'Mostra solo non letti',
 		),
 		),
-		'show_fav_unread_help' => 'Applies also on labels',	// TODO - Translation
-		'sides_close_article' => 'Clicking outside of article text area closes the article',	// TODO - Translation
+		'show_fav_unread_help' => 'Applies also on labels',	// TODO
+		'sides_close_article' => 'Clicking outside of article text area closes the article',	// TODO
 		'sort' => array(
 		'sort' => array(
 			'_' => 'Ordinamento',
 			'_' => 'Ordinamento',
 			'newer_first' => 'Prima i più recenti',
 			'newer_first' => 'Prima i più recenti',
@@ -162,21 +172,21 @@ return array(
 	),
 	),
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Condivisione',
 		'_' => 'Condivisione',
-		'add' => 'Add a sharing method',	// TODO - Translation
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',	// TODO - Translation
-		'facebook' => 'Facebook',
+		'add' => 'Add a sharing method',	// TODO
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// TODO
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Ulteriori informazioni',
 		'more_information' => 'Ulteriori informazioni',
 		'print' => 'Stampa',
 		'print' => 'Stampa',
-		'raindrop' => 'Raindrop.io',
-		'remove' => 'Remove sharing method',	// TODO - Translation
-		'shaarli' => 'Shaarli',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'remove' => 'Remove sharing method',	// TODO
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Nome condivisione',
 		'share_name' => 'Nome condivisione',
 		'share_url' => 'URL condivisione',
 		'share_url' => 'URL condivisione',
 		'title' => 'Condividi',
 		'title' => 'Condividi',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Comandi tastiera',
 		'_' => 'Comandi tastiera',
@@ -187,7 +197,7 @@ return array(
 		'collapse_article' => 'Collassa articoli',
 		'collapse_article' => 'Collassa articoli',
 		'first_article' => 'Salta al primo articolo',
 		'first_article' => 'Salta al primo articolo',
 		'focus_search' => 'Modulo di ricerca',
 		'focus_search' => 'Modulo di ricerca',
-		'global_view' => 'Switch to global view',	// TODO - Translation
+		'global_view' => 'Switch to global view',	// TODO
 		'help' => 'Mostra documentazione',
 		'help' => 'Mostra documentazione',
 		'javascript' => 'JavaScript deve essere abilitato per poter usare i comandi da tastiera',
 		'javascript' => 'JavaScript deve essere abilitato per poter usare i comandi da tastiera',
 		'last_article' => 'Salta all ultimo articolo',
 		'last_article' => 'Salta all ultimo articolo',
@@ -196,24 +206,24 @@ return array(
 		'mark_read' => 'Segna come letto',
 		'mark_read' => 'Segna come letto',
 		'navigation' => 'Navigazione',
 		'navigation' => 'Navigazione',
 		'navigation_help' => 'Con il tasto <kbd>⇧ Shift</kbd> i comandi di navigazione verranno applicati ai feeds.<br/>Con il tasto <kbd>Alt ⎇</kbd> i comandi di navigazione verranno applicati alle categorie.',
 		'navigation_help' => 'Con il tasto <kbd>⇧ Shift</kbd> i comandi di navigazione verranno applicati ai feeds.<br/>Con il tasto <kbd>Alt ⎇</kbd> i comandi di navigazione verranno applicati alle categorie.',
-		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// TODO - Translation
+		'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.',	// TODO
 		'next_article' => 'Salta al contenuto successivo',
 		'next_article' => 'Salta al contenuto successivo',
-		'next_unread_article' => 'Open the next unread article',	// TODO - Translation
-		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// TODO - Translation
-		'normal_view' => 'Switch to normal view',	// TODO - Translation
+		'next_unread_article' => 'Open the next unread article',	// TODO
+		'non_standard' => 'Some keys (<kbd>%s</kbd>) may not work as shortcuts.',	// TODO
+		'normal_view' => 'Switch to normal view',	// TODO
 		'other_action' => 'Altre azioni',
 		'other_action' => 'Altre azioni',
 		'previous_article' => 'Salta al contenuto precedente',
 		'previous_article' => 'Salta al contenuto precedente',
-		'reading_view' => 'Switch to reading view',	// TODO - Translation
-		'rss_view' => 'Open as RSS feed',	// TODO - Translation
+		'reading_view' => 'Switch to reading view',	// TODO
+		'rss_view' => 'Open as RSS feed',	// TODO
 		'see_on_website' => 'Vai al sito fonte',
 		'see_on_website' => 'Vai al sito fonte',
-		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// TODO - Translation
-		'skip_next_article' => 'Focus next without opening',	// TODO - Translation
-		'skip_previous_article' => 'Focus previous without opening',	// TODO - Translation
+		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> to mark previous articles as read<br />+ <kbd>⇧ Shift</kbd> to mark all articles as read',	// TODO
+		'skip_next_article' => 'Focus next without opening',	// TODO
+		'skip_previous_article' => 'Focus previous without opening',	// TODO
 		'title' => 'Comandi da tastiera',
 		'title' => 'Comandi da tastiera',
-		'toggle_media' => 'Play/pause media',	// TODO - Translation
+		'toggle_media' => 'Play/pause media',	// TODO
 		'user_filter' => 'Accedi alle ricerche personali',
 		'user_filter' => 'Accedi alle ricerche personali',
 		'user_filter_help' => 'Se è presente una sola ricerca personale verrà usata quella, altrimenti usare anche il numero associato.',
 		'user_filter_help' => 'Se è presente una sola ricerca personale verrà usata quella, altrimenti usare anche il numero associato.',
-		'views' => 'Views',	// TODO - Translation
+		'views' => 'Views',	// TODO
 	),
 	),
 	'user' => array(
 	'user' => array(
 		'articles_and_size' => '%s articoli (%s)',
 		'articles_and_size' => '%s articoli (%s)',

+ 29 - 19
app/i18n/it/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'Non hai i permessi per accedere a questa pagina',
 		'denied' => 'Non hai i permessi per accedere a questa pagina',
@@ -10,8 +20,8 @@ return array(
 	),
 	),
 	'api' => array(
 	'api' => array(
 		'password' => array(
 		'password' => array(
-			'failed' => 'Your password cannot be modified',	// TODO - Translation
-			'updated' => 'Your password has been modified',	// TODO - Translation
+			'failed' => 'Your password cannot be modified',	// TODO
+			'updated' => 'Your password has been modified',	// TODO
 		),
 		),
 	),
 	),
 	'auth' => array(
 	'auth' => array(
@@ -31,7 +41,7 @@ return array(
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
 		'already_enabled' => '%s è già abilitata',
 		'already_enabled' => '%s è già abilitata',
-		'cannot_remove' => '%s cannot be removed',	// TODO - Translation
+		'cannot_remove' => '%s cannot be removed',	// TODO
 		'disable' => array(
 		'disable' => array(
 			'ko' => '%s non può essere disabilitata. <a href="%s">Verifica i logs</a> per dettagli.',
 			'ko' => '%s non può essere disabilitata. <a href="%s">Verifica i logs</a> per dettagli.',
 			'ok' => '%s è disabilitata',
 			'ok' => '%s è disabilitata',
@@ -43,7 +53,7 @@ return array(
 		'no_access' => 'Accesso negato a %s',
 		'no_access' => 'Accesso negato a %s',
 		'not_enabled' => '%s non abilitato',
 		'not_enabled' => '%s non abilitato',
 		'not_found' => '%s non disponibile',
 		'not_found' => '%s non disponibile',
-		'removed' => '%s removed',	// TODO - Translation
+		'removed' => '%s removed',	// TODO
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export_no_zip_extension' => 'Estensione ZIP non presente sul server. Per favore esporta i files singolarmente.',
 		'export_no_zip_extension' => 'Estensione ZIP non presente sul server. Per favore esporta i files singolarmente.',
@@ -60,8 +70,8 @@ return array(
 	'sub' => array(
 	'sub' => array(
 		'actualize' => 'Aggiorna',
 		'actualize' => 'Aggiorna',
 		'articles' => array(
 		'articles' => array(
-			'marked_read' => 'The selected articles have been marked as read.',	// TODO - Translation
-			'marked_unread' => 'The articles have been marked as unread.',	// TODO - Translation
+			'marked_read' => 'The selected articles have been marked as read.',	// TODO
+			'marked_unread' => 'The articles have been marked as unread.',	// TODO
 		),
 		),
 		'category' => array(
 		'category' => array(
 			'created' => 'Categoria %s creata.',
 			'created' => 'Categoria %s creata.',
@@ -81,7 +91,7 @@ return array(
 			'actualizeds' => 'RSS feeds aggiornati',
 			'actualizeds' => 'RSS feeds aggiornati',
 			'added' => 'RSS feed <em>%s</em> aggiunti',
 			'added' => 'RSS feed <em>%s</em> aggiunti',
 			'already_subscribed' => 'Hai già sottoscritto <em>%s</em>',
 			'already_subscribed' => 'Hai già sottoscritto <em>%s</em>',
-			'cache_cleared' => '<em>%s</em> cache has been cleared',	// TODO - Translation
+			'cache_cleared' => '<em>%s</em> cache has been cleared',	// TODO
 			'deleted' => 'Feed cancellato',
 			'deleted' => 'Feed cancellato',
 			'error' => 'Feed non aggiornato',
 			'error' => 'Feed non aggiornato',
 			'internal_problem' => 'RSS feed non aggiunto. <a href="%s">Verifica i logs</a> per dettagli.',
 			'internal_problem' => 'RSS feed non aggiunto. <a href="%s">Verifica i logs</a> per dettagli.',
@@ -90,24 +100,24 @@ return array(
 			'n_entries_deleted' => '%d articoli cancellati',
 			'n_entries_deleted' => '%d articoli cancellati',
 			'no_refresh' => 'Nessun aggiornamento disponibile…',
 			'no_refresh' => 'Nessun aggiornamento disponibile…',
 			'not_added' => '<em>%s</em> non può essere aggiunto',
 			'not_added' => '<em>%s</em> non può essere aggiunto',
-			'not_found' => 'Feed cannot be found',	// TODO - Translation
+			'not_found' => 'Feed cannot be found',	// TODO
 			'over_max' => 'Hai raggiunto il numero limite di feed (%d)',
 			'over_max' => 'Hai raggiunto il numero limite di feed (%d)',
-			'reloaded' => '<em>%s</em> has been reloaded',	// TODO - Translation
+			'reloaded' => '<em>%s</em> has been reloaded',	// TODO
 			'selector_preview' => array(
 			'selector_preview' => array(
-				'http_error' => 'Failed to load website content.',	// TODO - Translation
-				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// TODO - Translation
-				'no_feed' => 'Internal error (feed cannot be found).',	// TODO - Translation
-				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// TODO - Translation
-				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// TODO - Translation
+				'http_error' => 'Failed to load website content.',	// TODO
+				'no_entries' => 'There are no articles in this feed. You need at least one article to create a preview.',	// TODO
+				'no_feed' => 'Internal error (feed cannot be found).',	// TODO
+				'no_result' => 'The selector didn\'t match anything. As a fallback the original feed text will be displayed instead.',	// TODO
+				'selector_empty' => 'The selector is empty. You need to define one to create a preview.',	// TODO
 			),
 			),
 			'updated' => 'Feed aggiornato',
 			'updated' => 'Feed aggiornato',
 		),
 		),
 		'purge_completed' => 'Svecchiamento completato (%d articoli cancellati)',
 		'purge_completed' => 'Svecchiamento completato (%d articoli cancellati)',
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'created' => 'Tag "%s" has been created.',	// TODO - Translation
-		'name_exists' => 'Tag name already exists.',	// TODO - Translation
-		'renamed' => 'Tag "%s" has been renamed to "%s".',	// TODO - Translation
+		'created' => 'Tag "%s" has been created.',	// TODO
+		'name_exists' => 'Tag name already exists.',	// TODO
+		'renamed' => 'Tag "%s" has been renamed to "%s".',	// TODO
 	),
 	),
 	'update' => array(
 	'update' => array(
 		'can_apply' => 'FreshRSS verrà aggiornato alla <strong>versione %s</strong>.',
 		'can_apply' => 'FreshRSS verrà aggiornato alla <strong>versione %s</strong>.',
@@ -127,8 +137,8 @@ return array(
 			'error' => 'Utente %s non cancellato',
 			'error' => 'Utente %s non cancellato',
 		),
 		),
 		'updated' => array(
 		'updated' => array(
-			'_' => 'User %s has been updated',	// TODO - Translation
-			'error' => 'User %s has not been updated',	// TODO - Translation
+			'_' => 'User %s has been updated',	// TODO
+			'error' => 'User %s has not been updated',	// TODO
 		),
 		),
 	),
 	),
 );
 );

+ 77 - 67
app/i18n/it/gen.php

@@ -1,40 +1,50 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Aggiorna feeds',
 		'actualize' => 'Aggiorna feeds',
-		'add' => 'Add',	// TODO - Translation
-		'back' => '← Go back',	// TODO - Translation
+		'add' => 'Add',	// TODO
+		'back' => '← Go back',	// TODO
 		'back_to_rss_feeds' => '← Indietro',
 		'back_to_rss_feeds' => '← Indietro',
 		'cancel' => 'Annulla',
 		'cancel' => 'Annulla',
 		'create' => 'Crea',
 		'create' => 'Crea',
-		'demote' => 'Demote',	// TODO - Translation
+		'demote' => 'Demote',	// TODO
 		'disable' => 'Disabilita',
 		'disable' => 'Disabilita',
 		'empty' => 'Vuoto',
 		'empty' => 'Vuoto',
 		'enable' => 'Abilita',
 		'enable' => 'Abilita',
 		'export' => 'Esporta',
 		'export' => 'Esporta',
 		'filter' => 'Filtra',
 		'filter' => 'Filtra',
 		'import' => 'Importa',
 		'import' => 'Importa',
-		'load_default_shortcuts' => 'Load default shortcuts',	// TODO - Translation
+		'load_default_shortcuts' => 'Load default shortcuts',	// TODO
 		'manage' => 'Gestisci',
 		'manage' => 'Gestisci',
 		'mark_read' => 'Segna come letto',
 		'mark_read' => 'Segna come letto',
-		'promote' => 'Promote',	// TODO - Translation
-		'purge' => 'Purge',	// TODO - Translation
+		'promote' => 'Promote',	// TODO
+		'purge' => 'Purge',	// TODO
 		'remove' => 'Rimuovi',
 		'remove' => 'Rimuovi',
-		'rename' => 'Rename',	// TODO - Translation
+		'rename' => 'Rename',	// TODO
 		'see_website' => 'Vai al sito',
 		'see_website' => 'Vai al sito',
 		'submit' => 'Conferma',
 		'submit' => 'Conferma',
 		'truncate' => 'Cancella tutti gli articoli',
 		'truncate' => 'Cancella tutti gli articoli',
-		'update' => 'Update',	// TODO - Translation
+		'update' => 'Update',	// TODO
 	),
 	),
 	'auth' => array(
 	'auth' => array(
-		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// TODO - Translation
+		'accept_tos' => 'I accept the <a href="%s">Terms of Service</a>.',	// TODO
 		'email' => 'Indirizzo email',
 		'email' => 'Indirizzo email',
 		'keep_logged_in' => 'Ricorda i dati <small>(%s giorni)</small>',
 		'keep_logged_in' => 'Ricorda i dati <small>(%s giorni)</small>',
 		'login' => 'Accedi',
 		'login' => 'Accedi',
 		'logout' => 'Esci',
 		'logout' => 'Esci',
 		'password' => array(
 		'password' => array(
-			'_' => 'Password',	// TODO - Translation
+			'_' => 'Password',	// TODO
 			'format' => '<small>almeno 7 caratteri</small>',
 			'format' => '<small>almeno 7 caratteri</small>',
 		),
 		),
 		'registration' => array(
 		'registration' => array(
@@ -43,7 +53,7 @@ return array(
 			'title' => 'Creazione profilo',
 			'title' => 'Creazione profilo',
 		),
 		),
 		'username' => array(
 		'username' => array(
-			'_' => 'Username',	// TODO - Translation
+			'_' => 'Username',	// TODO
 			'format' => '<small>Massimo 16 caratteri alfanumerici</small>',
 			'format' => '<small>Massimo 16 caratteri alfanumerici</small>',
 		),
 		),
 	),
 	),
@@ -71,17 +81,17 @@ return array(
 		'february' => 'febbraio',
 		'february' => 'febbraio',
 		'format_date' => 'j\\ %s Y',
 		'format_date' => 'j\\ %s Y',
 		'format_date_hour' => 'j\\ %s Y \\o\\r\\e H\\:i',
 		'format_date_hour' => 'j\\ %s Y \\o\\r\\e H\\:i',
-		'fri' => 'Fri',	// TODO - Translation
+		'fri' => 'Fri',	// TODO
 		'jan' => 'genn.',
 		'jan' => 'genn.',
 		'january' => 'gennaio',
 		'january' => 'gennaio',
 		'jul' => 'jul',
 		'jul' => 'jul',
 		'july' => 'luglio',
 		'july' => 'luglio',
 		'jun' => 'jun',
 		'jun' => 'jun',
 		'june' => 'giugno',
 		'june' => 'giugno',
-		'last_2_year' => 'Last two years',	// TODO - Translation
+		'last_2_year' => 'Last two years',	// TODO
 		'last_3_month' => 'Ultimi 3 mesi',
 		'last_3_month' => 'Ultimi 3 mesi',
-		'last_3_year' => 'Last three years',	// TODO - Translation
-		'last_5_year' => 'Last five years',	// TODO - Translation
+		'last_3_year' => 'Last three years',	// TODO
+		'last_5_year' => 'Last five years',	// TODO
 		'last_6_month' => 'Ultimi 6 mesi',
 		'last_6_month' => 'Ultimi 6 mesi',
 		'last_month' => 'Ultimo mese',
 		'last_month' => 'Ultimo mese',
 		'last_week' => 'Ultima settimana',
 		'last_week' => 'Ultima settimana',
@@ -89,24 +99,24 @@ return array(
 		'mar' => 'mar.',
 		'mar' => 'mar.',
 		'march' => 'marzo',
 		'march' => 'marzo',
 		'may' => 'maggio',
 		'may' => 'maggio',
-		'may_' => 'May',	// TODO - Translation
-		'mon' => 'Mon',	// TODO - Translation
+		'may_' => 'May',	// TODO
+		'mon' => 'Mon',	// TODO
 		'month' => 'mesi',
 		'month' => 'mesi',
 		'nov' => 'nov.',
 		'nov' => 'nov.',
 		'november' => 'novembre',
 		'november' => 'novembre',
 		'oct' => 'ott.',
 		'oct' => 'ott.',
 		'october' => 'ottobre',
 		'october' => 'ottobre',
-		'sat' => 'Sat',	// TODO - Translation
+		'sat' => 'Sat',	// TODO
 		'sep' => 'sett.',
 		'sep' => 'sett.',
 		'september' => 'settembre',
 		'september' => 'settembre',
-		'sun' => 'Sun',	// TODO - Translation
-		'thu' => 'Thu',	// TODO - Translation
+		'sun' => 'Sun',	// TODO
+		'thu' => 'Thu',	// TODO
 		'today' => 'Oggi',
 		'today' => 'Oggi',
-		'tue' => 'Tue',	// TODO - Translation
-		'wed' => 'Wed',	// TODO - Translation
+		'tue' => 'Tue',	// TODO
+		'wed' => 'Wed',	// TODO
 		'yesterday' => 'Ieri',
 		'yesterday' => 'Ieri',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
 		'_' => 'Feed RSS Reader',
 		'_' => 'Feed RSS Reader',
 		'about' => 'Informazioni',
 		'about' => 'Informazioni',
@@ -124,28 +134,28 @@ return array(
 		'should_be_activated' => 'JavaScript deve essere abilitato',
 		'should_be_activated' => 'JavaScript deve essere abilitato',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'Informazioni',
 		'about' => 'Informazioni',
-		'account' => 'Account',	// TODO - Translation
+		'account' => 'Account',	// TODO
 		'admin' => 'Amministrazione',
 		'admin' => 'Amministrazione',
 		'archiving' => 'Archiviazione',
 		'archiving' => 'Archiviazione',
 		'authentication' => 'Autenticazione',
 		'authentication' => 'Autenticazione',
@@ -153,7 +163,7 @@ return array(
 		'configuration' => 'Configurazione',
 		'configuration' => 'Configurazione',
 		'display' => 'Visualizzazione',
 		'display' => 'Visualizzazione',
 		'extensions' => 'Estensioni',
 		'extensions' => 'Estensioni',
-		'logs' => 'Logs',	// TODO - Translation
+		'logs' => 'Logs',	// TODO
 		'queries' => 'Ricerche personali',
 		'queries' => 'Ricerche personali',
 		'reading' => 'Lettura',
 		'reading' => 'Lettura',
 		'search' => 'Ricerca parole o #tags',
 		'search' => 'Ricerca parole o #tags',
@@ -175,33 +185,33 @@ return array(
 		'previous' => 'Precedente',
 		'previous' => 'Precedente',
 	),
 	),
 	'period' => array(
 	'period' => array(
-		'days' => 'days',	// TODO - Translation
-		'hours' => 'hours',	// TODO - Translation
-		'months' => 'months',	// TODO - Translation
-		'weeks' => 'weeks',	// TODO - Translation
-		'years' => 'years',	// TODO - Translation
+		'days' => 'days',	// TODO
+		'hours' => 'hours',	// TODO
+		'months' => 'months',	// TODO
+		'weeks' => 'weeks',	// TODO
+		'years' => 'years',	// TODO
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Siti basati su Known',
 		'Known' => 'Siti basati su Known',
-		'blogotext' => 'Blogotext',
-		'clipboard' => 'Clipboard',	// TODO - Translation
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',	// TODO - Translation
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'clipboard' => 'Clipboard',	// TODO
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// TODO
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Stampa',
 		'print' => 'Stampa',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Attenzione!',
 		'attention' => 'Attenzione!',
@@ -210,7 +220,7 @@ return array(
 		'by_default' => 'predefinito',
 		'by_default' => 'predefinito',
 		'damn' => 'Ops!',
 		'damn' => 'Ops!',
 		'default_category' => 'Senza categoria',
 		'default_category' => 'Senza categoria',
-		'no' => 'No',
+		'no' => 'No',	// IGNORE
 		'not_applicable' => 'Non disponibile',
 		'not_applicable' => 'Non disponibile',
 		'ok' => 'OK!',
 		'ok' => 'OK!',
 		'or' => 'o',
 		'or' => 'o',

+ 18 - 8
app/i18n/it/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'Informazioni',
 		'_' => 'Informazioni',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Bugs',
 		'bugs_reports' => 'Bugs',
 		'credits' => 'Crediti',
 		'credits' => 'Crediti',
 		'credits_content' => 'Alcuni elementi di design provengono da <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> sebbene FreshRSS non usi questo framework. Le <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icone</a> provengono dal progetto <a href="https://www.gnome.org/">GNOME</a>. Il carattere <em>Open Sans</em> è stato creato da <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS è basato su <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
 		'credits_content' => 'Alcuni elementi di design provengono da <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> sebbene FreshRSS non usi questo framework. Le <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icone</a> provengono dal progetto <a href="https://www.gnome.org/">GNOME</a>. Il carattere <em>Open Sans</em> è stato creato da <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS è basato su <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
@@ -23,23 +33,23 @@ return array(
 		'title_global' => 'Vista globale per categorie',
 		'title_global' => 'Vista globale per categorie',
 	),
 	),
 	'log' => array(
 	'log' => array(
-		'_' => 'Logs',	// TODO - Translation
+		'_' => 'Logs',	// TODO
 		'clear' => 'Svuota logs',
 		'clear' => 'Svuota logs',
 		'empty' => 'File di log vuoto',
 		'empty' => 'File di log vuoto',
-		'title' => 'Logs',	// TODO - Translation
+		'title' => 'Logs',	// TODO
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'Informazioni',
 		'about' => 'Informazioni',
 		'before_one_day' => 'Giorno precedente',
 		'before_one_day' => 'Giorno precedente',
 		'before_one_week' => 'Settimana precedente',
 		'before_one_week' => 'Settimana precedente',
-		'bookmark_query' => 'Bookmark current query',	// TODO - Translation
+		'bookmark_query' => 'Bookmark current query',	// TODO
 		'favorites' => 'Preferiti (%s)',
 		'favorites' => 'Preferiti (%s)',
 		'global_view' => 'Vista globale per categorie',
 		'global_view' => 'Vista globale per categorie',
 		'main_stream' => 'Flusso principale',
 		'main_stream' => 'Flusso principale',
 		'mark_all_read' => 'Segna tutto come letto',
 		'mark_all_read' => 'Segna tutto come letto',
 		'mark_cat_read' => 'Segna la categoria come letta',
 		'mark_cat_read' => 'Segna la categoria come letta',
 		'mark_feed_read' => 'Segna il feed come letto',
 		'mark_feed_read' => 'Segna il feed come letto',
-		'mark_selection_unread' => 'Mark selection as unread',	// TODO - Translation
+		'mark_selection_unread' => 'Mark selection as unread',	// TODO
 		'newer_first' => 'Mostra prima i recenti',
 		'newer_first' => 'Mostra prima i recenti',
 		'non-starred' => 'Escludi preferiti',
 		'non-starred' => 'Escludi preferiti',
 		'normal_view' => 'Vista elenco',
 		'normal_view' => 'Vista elenco',
@@ -47,12 +57,12 @@ return array(
 		'queries' => 'Chiavi di ricerca',
 		'queries' => 'Chiavi di ricerca',
 		'read' => 'Mostra solo letti',
 		'read' => 'Mostra solo letti',
 		'reader_view' => 'Modalità di lettura',
 		'reader_view' => 'Modalità di lettura',
-		'rss_view' => 'RSS feed',	// TODO - Translation
+		'rss_view' => 'RSS feed',	// TODO
 		'search_short' => 'Cerca',
 		'search_short' => 'Cerca',
 		'starred' => 'Mostra solo preferiti',
 		'starred' => 'Mostra solo preferiti',
 		'stats' => 'Statistiche',
 		'stats' => 'Statistiche',
 		'subscription' => 'Gestione sottoscrizioni',
 		'subscription' => 'Gestione sottoscrizioni',
-		'tags' => 'My labels',	// TODO - Translation
+		'tags' => 'My labels',	// TODO
 		'unread' => 'Mostra solo non letti',
 		'unread' => 'Mostra solo non letti',
 	),
 	),
 	'share' => 'Condividi',
 	'share' => 'Condividi',
@@ -60,6 +70,6 @@ return array(
 		'related' => 'Tags correlati',
 		'related' => 'Tags correlati',
 	),
 	),
 	'tos' => array(
 	'tos' => array(
-		'title' => 'Terms of Service',	// TODO - Translation
+		'title' => 'Terms of Service',	// TODO
 	),
 	),
 );
 );

+ 20 - 10
app/i18n/it/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Installazione completata',
 		'finish' => 'Installazione completata',
@@ -17,13 +27,13 @@ return array(
 		'type' => 'Metodo di autenticazione',
 		'type' => 'Metodo di autenticazione',
 	),
 	),
 	'bdd' => array(
 	'bdd' => array(
-		'_' => 'Database',	// TODO - Translation
+		'_' => 'Database',	// TODO
 		'conf' => array(
 		'conf' => array(
 			'_' => 'Configurazione database',
 			'_' => 'Configurazione database',
 			'ko' => 'Verifica le informazioni del database.',
 			'ko' => 'Verifica le informazioni del database.',
 			'ok' => 'Le configurazioni del database sono state salvate.',
 			'ok' => 'Le configurazioni del database sono state salvate.',
 		),
 		),
-		'host' => 'Host',	// TODO - Translation
+		'host' => 'Host',	// TODO
 		'password' => 'Password del database',
 		'password' => 'Password del database',
 		'prefix' => 'Prefisso tabella',
 		'prefix' => 'Prefisso tabella',
 		'type' => 'Tipo di database',
 		'type' => 'Tipo di database',
@@ -62,11 +72,11 @@ return array(
 		),
 		),
 		'json' => array(
 		'json' => array(
 			'nok' => 'You lack a recommended library to parse JSON.',
 			'nok' => 'You lack a recommended library to parse JSON.',
-			'ok' => 'You have the recommended library to parse JSON.',	// TODO - Translation
+			'ok' => 'You have the recommended library to parse JSON.',	// TODO
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// TODO - Translation
-			'ok' => 'You have the recommended library mbstring for Unicode.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended library mbstring for Unicode.',	// TODO
+			'ok' => 'You have the recommended library mbstring for Unicode.',	// TODO
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
 			'nok' => 'Manca una libreria richiesta per le regular expressions (php-pcre).',
 			'nok' => 'Manca una libreria richiesta per le regular expressions (php-pcre).',
@@ -83,16 +93,16 @@ return array(
 		'reload' => 'Controlla di nuovo',
 		'reload' => 'Controlla di nuovo',
 		'tmp' => array(
 		'tmp' => array(
 			'nok' => 'Verifica i permessi sulla cartella <em>%s</em>. Il server HTTP deve avere i permessi per scriverci dentro.',
 			'nok' => 'Verifica i permessi sulla cartella <em>%s</em>. Il server HTTP deve avere i permessi per scriverci dentro.',
-			'ok' => 'Permissions on the temp directory are good.',	// TODO - Translation
+			'ok' => 'Permissions on the temp directory are good.',	// TODO
 		),
 		),
-		'unknown_process_username' => 'unknown',	// TODO - Translation
+		'unknown_process_username' => 'unknown',	// TODO
 		'users' => array(
 		'users' => array(
 			'nok' => 'Verifica i permessi sulla cartella <em>%s</em>. Il server HTTP deve avere i permessi per scriverci dentro.',
 			'nok' => 'Verifica i permessi sulla cartella <em>%s</em>. Il server HTTP deve avere i permessi per scriverci dentro.',
 			'ok' => 'I permessi sulla cartella users sono corretti.',
 			'ok' => 'I permessi sulla cartella users sono corretti.',
 		),
 		),
 		'xml' => array(
 		'xml' => array(
 			'nok' => 'You lack the required library to parse XML.',
 			'nok' => 'You lack the required library to parse XML.',
-			'ok' => 'You have the required library to parse XML.',	// TODO - Translation
+			'ok' => 'You have the required library to parse XML.',	// TODO
 		),
 		),
 	),
 	),
 	'conf' => array(
 	'conf' => array(
@@ -111,10 +121,10 @@ return array(
 		'choose' => 'Seleziona la lingua per FreshRSS',
 		'choose' => 'Seleziona la lingua per FreshRSS',
 		'defined' => 'Lingua impostata.',
 		'defined' => 'Lingua impostata.',
 	),
 	),
-	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// TODO - Translation
+	'missing_applied_migrations' => 'Something went wrong; you should create an empty file <em>%s</em> manually.',	// TODO
 	'ok' => 'Processo di installazione terminato con successo.',
 	'ok' => 'Processo di installazione terminato con successo.',
 	'session' => array(
 	'session' => array(
-		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// TODO - Translation
+		'nok' => 'The web server seems to be incorrectly configured for cookies required for PHP sessions!',	// TODO
 	),
 	),
 	'step' => 'Passaggio %d',
 	'step' => 'Passaggio %d',
 	'steps' => 'Passaggi',
 	'steps' => 'Passaggi',

+ 63 - 53
app/i18n/it/sub.php

@@ -1,14 +1,24 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
-		'documentation' => 'Copy the following URL to use it within an external tool.',	// TODO - Translation
-		'title' => 'API',	// TODO - Translation
+		'documentation' => 'Copy the following URL to use it within an external tool.',	// TODO
+		'title' => 'API',	// TODO
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
-		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// TODO - Translation
-		'label' => 'Subscribe',	// TODO - Translation
-		'title' => 'Bookmarklet',	// TODO - Translation
+		'documentation' => 'Drag this button to your bookmarks toolbar or right-click it and choose "Bookmark This Link". Then click the "Subscribe" button in any page you want to subscribe to.',	// TODO
+		'label' => 'Subscribe',	// TODO
+		'title' => 'Bookmarklet',	// TODO
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categoria',
 		'_' => 'Categoria',
@@ -16,8 +26,8 @@ return array(
 		'archiving' => 'Archiviazione',
 		'archiving' => 'Archiviazione',
 		'empty' => 'Categoria vuota',
 		'empty' => 'Categoria vuota',
 		'information' => 'Informazioni',
 		'information' => 'Informazioni',
-		'position' => 'Display position',	// TODO - Translation
-		'position_help' => 'To control category sort order',	// TODO - Translation
+		'position' => 'Display position',	// TODO
+		'position_help' => 'To control category sort order',	// TODO
 		'title' => 'Titolo',
 		'title' => 'Titolo',
 	),
 	),
 	'feed' => array(
 	'feed' => array(
@@ -28,76 +38,76 @@ return array(
 			'configuration' => 'Autenticazione',
 			'configuration' => 'Autenticazione',
 			'help' => 'Accesso per feeds protetti',
 			'help' => 'Accesso per feeds protetti',
 			'http' => 'Autenticazione HTTP',
 			'http' => 'Autenticazione HTTP',
-			'password' => 'HTTP password',	// TODO - Translation
-			'username' => 'HTTP username',	// TODO - Translation
+			'password' => 'HTTP password',	// TODO
+			'username' => 'HTTP username',	// TODO
 		),
 		),
-		'clear_cache' => 'Always clear cache',	// TODO - Translation
+		'clear_cache' => 'Always clear cache',	// TODO
 		'content_action' => array(
 		'content_action' => array(
-			'_' => 'Content action when fetching the article content',	// TODO - Translation
-			'append' => 'Add after existing content',	// TODO - Translation
-			'prepend' => 'Add before existing content',	// TODO - Translation
-			'replace' => 'Replace existing content',	// TODO - Translation
+			'_' => 'Content action when fetching the article content',	// TODO
+			'append' => 'Add after existing content',	// TODO
+			'prepend' => 'Add before existing content',	// TODO
+			'replace' => 'Replace existing content',	// TODO
 		),
 		),
-		'css_cookie' => 'Use Cookies when fetching the article content',	// TODO - Translation
-		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// TODO - Translation
+		'css_cookie' => 'Use Cookies when fetching the article content',	// TODO
+		'css_cookie_help' => 'Example: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',	// TODO
 		'css_help' => 'In caso di RSS feeds troncati (attenzione, richiede molto tempo!)',
 		'css_help' => 'In caso di RSS feeds troncati (attenzione, richiede molto tempo!)',
 		'css_path' => 'Percorso del foglio di stile CSS del sito di origine',
 		'css_path' => 'Percorso del foglio di stile CSS del sito di origine',
 		'description' => 'Descrizione',
 		'description' => 'Descrizione',
 		'empty' => 'Questo feed non contiene articoli. Per favore verifica il sito direttamente.',
 		'empty' => 'Questo feed non contiene articoli. Per favore verifica il sito direttamente.',
 		'error' => 'Questo feed ha generato un errore. Per favore verifica se ancora disponibile.',
 		'error' => 'Questo feed ha generato un errore. Per favore verifica se ancora disponibile.',
 		'filteractions' => array(
 		'filteractions' => array(
-			'_' => 'Filter actions',	// TODO - Translation
-			'help' => 'Write one search filter per line.',	// TODO - Translation
+			'_' => 'Filter actions',	// TODO
+			'help' => 'Write one search filter per line.',	// TODO
 		),
 		),
 		'information' => 'Informazioni',
 		'information' => 'Informazioni',
 		'keep_min' => 'Numero minimo di articoli da mantenere',
 		'keep_min' => 'Numero minimo di articoli da mantenere',
 		'maintenance' => array(
 		'maintenance' => array(
-			'clear_cache' => 'Clear cache',	// TODO - Translation
-			'clear_cache_help' => 'Clear the cache for this feed.',	// TODO - Translation
-			'reload_articles' => 'Reload articles',	// TODO - Translation
-			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// TODO - Translation
-			'title' => 'Maintenance',	// TODO - Translation
+			'clear_cache' => 'Clear cache',	// TODO
+			'clear_cache_help' => 'Clear the cache for this feed.',	// TODO
+			'reload_articles' => 'Reload articles',	// TODO
+			'reload_articles_help' => 'Reload articles and fetch complete content if a selector is defined.',	// TODO
+			'title' => 'Maintenance',	// TODO
 		),
 		),
 		'moved_category_deleted' => 'Cancellando una categoria i feed al suo interno verranno classificati automaticamente come <em>%s</em>.',
 		'moved_category_deleted' => 'Cancellando una categoria i feed al suo interno verranno classificati automaticamente come <em>%s</em>.',
-		'mute' => 'mute',	// TODO - Translation
+		'mute' => 'mute',	// TODO
 		'no_selected' => 'Nessun feed selezionato.',
 		'no_selected' => 'Nessun feed selezionato.',
 		'number_entries' => '%d articoli',
 		'number_entries' => '%d articoli',
 		'priority' => array(
 		'priority' => array(
-			'_' => 'Visibility',	// TODO - Translation
-			'archived' => 'Do not show (archived)',	// TODO - Translation
+			'_' => 'Visibility',	// TODO
+			'archived' => 'Do not show (archived)',	// TODO
 			'main_stream' => 'Mostra in homepage',
 			'main_stream' => 'Mostra in homepage',
-			'normal' => 'Show in its category',	// TODO - Translation
+			'normal' => 'Show in its category',	// TODO
 		),
 		),
-		'proxy' => 'Set a proxy for fetching this feed',	// TODO - Translation
-		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// TODO - Translation
+		'proxy' => 'Set a proxy for fetching this feed',	// TODO
+		'proxy_help' => 'Select a protocol (e.g: SOCKS5) and enter the proxy address (e.g: <kbd>127.0.0.1:1080</kbd>)',	// TODO
 		'selector_preview' => array(
 		'selector_preview' => array(
-			'show_raw' => 'Show source code',	// TODO - Translation
-			'show_rendered' => 'Show content',	// TODO - Translation
+			'show_raw' => 'Show source code',	// TODO
+			'show_rendered' => 'Show content',	// TODO
 		),
 		),
 		'show' => array(
 		'show' => array(
-			'all' => 'Show all feeds',	// TODO - Translation
-			'error' => 'Show only feeds with errors',	// TODO - Translation
+			'all' => 'Show all feeds',	// TODO
+			'error' => 'Show only feeds with errors',	// TODO
 		),
 		),
 		'showing' => array(
 		'showing' => array(
-			'error' => 'Showing only feeds with errors',	// TODO - Translation
+			'error' => 'Showing only feeds with errors',	// TODO
 		),
 		),
-		'ssl_verify' => 'Verify SSL security',	// TODO - Translation
+		'ssl_verify' => 'Verify SSL security',	// TODO
 		'stats' => 'Statistiche',
 		'stats' => 'Statistiche',
 		'think_to_add' => 'Aggiungi feed.',
 		'think_to_add' => 'Aggiungi feed.',
-		'timeout' => 'Timeout in seconds',	// TODO - Translation
+		'timeout' => 'Timeout in seconds',	// TODO
 		'title' => 'Titolo',
 		'title' => 'Titolo',
 		'title_add' => 'Aggiungi RSS feed',
 		'title_add' => 'Aggiungi RSS feed',
 		'ttl' => 'Non aggiornare automaticamente piu di',
 		'ttl' => 'Non aggiornare automaticamente piu di',
-		'url' => 'Feed URL',	// TODO - Translation
-		'useragent' => 'Set the user agent for fetching this feed',	// TODO - Translation
-		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// TODO - Translation
+		'url' => 'Feed URL',	// TODO
+		'useragent' => 'Set the user agent for fetching this feed',	// TODO
+		'useragent_help' => 'Example: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',	// TODO
 		'validator' => 'Controlla la validita del feed ',
 		'validator' => 'Controlla la validita del feed ',
 		'website' => 'URL del sito',
 		'website' => 'URL del sito',
 		'websub' => 'Notifica istantanea con WebSub',
 		'websub' => 'Notifica istantanea con WebSub',
 	),
 	),
 	'import_export' => array(
 	'import_export' => array(
 		'export' => 'Esporta',
 		'export' => 'Esporta',
-		'export_labelled' => 'Export your labelled articles',	// TODO - Translation
+		'export_labelled' => 'Export your labelled articles',	// TODO
 		'export_opml' => 'Esporta tutta la lista dei feed (OPML)',
 		'export_opml' => 'Esporta tutta la lista dei feed (OPML)',
 		'export_starred' => 'Esporta i tuoi preferiti',
 		'export_starred' => 'Esporta i tuoi preferiti',
 		'feed_list' => 'Elenco di %s articoli',
 		'feed_list' => 'Elenco di %s articoli',
@@ -108,31 +118,31 @@ return array(
 		'title' => 'Importa / esporta',
 		'title' => 'Importa / esporta',
 	),
 	),
 	'menu' => array(
 	'menu' => array(
-		'add' => 'Add a feed or category',	// TODO - Translation
+		'add' => 'Add a feed or category',	// TODO
 		'import_export' => 'Importa / esporta',
 		'import_export' => 'Importa / esporta',
-		'label_management' => 'Label management',	// TODO - Translation
+		'label_management' => 'Label management',	// TODO
 		'stats' => array(
 		'stats' => array(
 			'idle' => 'Feeds non aggiornati',
 			'idle' => 'Feeds non aggiornati',
 			'main' => 'Statistiche principali',
 			'main' => 'Statistiche principali',
 			'repartition' => 'Ripartizione articoli',
 			'repartition' => 'Ripartizione articoli',
 		),
 		),
 		'subscription_management' => 'Gestione sottoscrizioni',
 		'subscription_management' => 'Gestione sottoscrizioni',
-		'subscription_tools' => 'Subscription tools',	// TODO - Translation
+		'subscription_tools' => 'Subscription tools',	// TODO
 	),
 	),
 	'tag' => array(
 	'tag' => array(
-		'name' => 'Name',	// TODO - Translation
-		'new_name' => 'New name',	// TODO - Translation
-		'old_name' => 'Old name',	// TODO - Translation
+		'name' => 'Name',	// TODO
+		'new_name' => 'New name',	// TODO
+		'old_name' => 'Old name',	// TODO
 	),
 	),
 	'title' => array(
 	'title' => array(
 		'_' => 'Gestione sottoscrizioni',
 		'_' => 'Gestione sottoscrizioni',
-		'add' => 'Add a feed or category',	// TODO - Translation
-		'add_category' => 'Add a category',	// TODO - Translation
-		'add_feed' => 'Add a feed',	// TODO - Translation
-		'add_label' => 'Add a label',	// TODO - Translation
-		'delete_label' => 'Delete a label',	// TODO - Translation
+		'add' => 'Add a feed or category',	// TODO
+		'add_category' => 'Add a category',	// TODO
+		'add_feed' => 'Add a feed',	// TODO
+		'add_label' => 'Add a label',	// TODO
+		'delete_label' => 'Delete a label',	// TODO
 		'feed_management' => 'Gestione RSS feeds',
 		'feed_management' => 'Gestione RSS feeds',
-		'rename_label' => 'Rename a label',	// TODO - Translation
-		'subscription_tools' => 'Subscription tools',	// TODO - Translation
+		'rename_label' => 'Rename a label',	// TODO
+		'subscription_tools' => 'Subscription tools',	// TODO
 	),
 	),
 );
 );

+ 30 - 20
app/i18n/it/user.php

@@ -1,44 +1,54 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'This email address is invalid.',	// TODO - Translation
-			'required' => 'An email address is required.',	// TODO - Translation
+			'invalid' => 'This email address is invalid.',	// TODO
+			'required' => 'An email address is required.',	// TODO
 		),
 		),
 		'validation' => array(
 		'validation' => array(
-			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// TODO - Translation
-			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// TODO - Translation
+			'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',	// TODO
+			'email_sent_to' => 'We sent you an email at <strong>%s</strong>. Please follow its instructions to validate your address.',	// TODO
 			'feedback' => array(
 			'feedback' => array(
-				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// TODO - Translation
-				'email_sent' => 'An email has been sent to your address.',	// TODO - Translation
-				'error' => 'Email address validation failed.',	// TODO - Translation
-				'ok' => 'This email address has been validated.',	// TODO - Translation
-				'unnecessary' => 'This email address was already validated.',	// TODO - Translation
-				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// TODO - Translation
+				'email_failed' => 'We couldn’t send you an email because of a server configuration error.',	// TODO
+				'email_sent' => 'An email has been sent to your address.',	// TODO
+				'error' => 'Email address validation failed.',	// TODO
+				'ok' => 'This email address has been validated.',	// TODO
+				'unnecessary' => 'This email address was already validated.',	// TODO
+				'wrong_token' => 'This email address failed to be validated due to a wrong token.',	// TODO
 			),
 			),
-			'need_to' => 'You need to validate your email address before being able to use %s.',	// TODO - Translation
-			'resend_email' => 'Resend the email',	// TODO - Translation
-			'title' => 'Email address validation',	// TODO - Translation
+			'need_to' => 'You need to validate your email address before being able to use %s.',	// TODO
+			'resend_email' => 'Resend the email',	// TODO
+			'title' => 'Email address validation',	// TODO
 		),
 		),
 	),
 	),
 	'mailer' => array(
 	'mailer' => array(
 		'email_need_validation' => array(
 		'email_need_validation' => array(
-			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// TODO - Translation
-			'title' => 'You need to validate your account',	// TODO - Translation
-			'welcome' => 'Welcome %s,',	// TODO - Translation
+			'body' => 'You’ve just registered on %s, but you still need to validate your email address. For that, just follow the link:',	// TODO
+			'title' => 'You need to validate your account',	// TODO
+			'welcome' => 'Welcome %s,',	// TODO
 		),
 		),
 	),
 	),
 	'password' => array(
 	'password' => array(
-		'invalid' => 'The password is invalid.',	// TODO - Translation
+		'invalid' => 'The password is invalid.',	// TODO
 	),
 	),
 	'tos' => array(
 	'tos' => array(
 		'feedback' => array(
 		'feedback' => array(
-			'invalid' => 'You must accept the Terms of Service to be able to register.',	// TODO - Translation
+			'invalid' => 'You must accept the Terms of Service to be able to register.',	// TODO
 		),
 		),
 	),
 	),
 	'username' => array(
 	'username' => array(
-		'invalid' => 'This username is invalid.',	// TODO - Translation
-		'taken' => 'This username, %s, is taken.',	// TODO - Translation
+		'invalid' => 'This username is invalid.',	// TODO
+		'taken' => 'This username, %s, is taken.',	// TODO
 	),
 	),
 );
 );

+ 10 - 0
app/i18n/ja/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => '標準のユーザーの記事が匿名のユーザーでも読めるようにします。 (%s)',
 		'allow_anonymous' => '標準のユーザーの記事が匿名のユーザーでも読めるようにします。 (%s)',

+ 18 - 8
app/i18n/ja/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'アーカイブ',
 		'_' => 'アーカイブ',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => '共有',
 		'_' => '共有',
 		'add' => '共有方法を追加する',
 		'add' => '共有方法を追加する',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'Eメール',
 		'email' => 'Eメール',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'もっと多くの情報',
 		'more_information' => 'もっと多くの情報',
-		'print' => '印刷',
-		'raindrop' => 'Raindrop.io',
+		'print' => '印刷',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => '共有方法を削除する',
 		'remove' => '共有方法を削除する',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => '表示する共有方法の名前',
 		'share_name' => '表示する共有方法の名前',
 		'share_url' => '使用するURLを共有する',
 		'share_url' => '使用するURLを共有する',
 		'title' => '共有',
 		'title' => '共有',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'ショートカット',
 		'_' => 'ショートカット',

+ 10 - 0
app/i18n/ja/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'このページにアクセスする権限がありません。',
 		'denied' => 'このページにアクセスする権限がありません。',

+ 46 - 36
app/i18n/ja/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'フィードを更新する',
 		'actualize' => 'フィードを更新する',
@@ -106,9 +116,9 @@ return array(
 		'wed' => '水',
 		'wed' => '水',
 		'yesterday' => '昨日',
 		'yesterday' => '昨日',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'FreshRSSについて',
 		'about' => 'FreshRSSについて',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,24 +134,24 @@ return array(
 		'should_be_activated' => 'JavaScriptは有効になっている必要があります。',
 		'should_be_activated' => 'JavaScriptは有効になっている必要があります。',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'FreshRSSについて',
 		'about' => 'FreshRSSについて',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'よく使われるサイト',
 		'Known' => 'よく使われるサイト',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'クリップボード',
 		'clipboard' => 'クリップボード',
-		'diaspora' => 'Diaspora*',
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'Eメール',
 		'email' => 'Eメール',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => '印刷',
 		'print' => '印刷',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => '警告!',
 		'attention' => '警告!',

+ 11 - 1
app/i18n/ja/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'FreshRSSについて',
 		'_' => 'FreshRSSについて',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'バグレポート',
 		'bugs_reports' => 'バグレポート',
 		'credits' => 'クレジット',
 		'credits' => 'クレジット',
 		'credits_content' => 'いくつかのデザイン要素は <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>から来ています。しかしFreshRSSはこのフレームワークを使用していません。 <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">アイコン</a> は <a href="https://www.gnome.org/">GNOME プロジェクトから作られています</a>。 <em>Open Sans</em> フォントは <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson によって作成されました</a>。 FreshRSS は<a href="https://github.com/marienfressinaud/MINZ">Minz</a>,PHP フレームワークをもとにしています。',
 		'credits_content' => 'いくつかのデザイン要素は <a href="http://twitter.github.io/bootstrap/">Bootstrap</a>から来ています。しかしFreshRSSはこのフレームワークを使用していません。 <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">アイコン</a> は <a href="https://www.gnome.org/">GNOME プロジェクトから作られています</a>。 <em>Open Sans</em> フォントは <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson によって作成されました</a>。 FreshRSS は<a href="https://github.com/marienfressinaud/MINZ">Minz</a>,PHP フレームワークをもとにしています。',

+ 10 - 0
app/i18n/ja/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'インストール作業を終わりにする',
 		'finish' => 'インストール作業を終わりにする',

+ 11 - 1
app/i18n/ja/sub.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => '外部ツール内で使うURLをコピーします。',
 		'documentation' => '外部ツール内で使うURLをコピーします。',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'このボタンをブックマークツールバーへドラッグするか、右クリックして、「このリンクをブックマークする」を選択します。そうすることでどのページでも購読できるようになります。',
 		'documentation' => 'このボタンをブックマークツールバーへドラッグするか、右クリックして、「このリンクをブックマークする」を選択します。そうすることでどのページでも購読できるようになります。',

+ 10 - 0
app/i18n/ja/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 10 - 0
app/i18n/ko/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => '누구나 기본 사용자의 글을 읽을 수 있도록 합니다(%s)',
 		'allow_anonymous' => '누구나 기본 사용자의 글을 읽을 수 있도록 합니다(%s)',

+ 17 - 7
app/i18n/ko/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => '보관',
 		'_' => '보관',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => '공유',
 		'_' => '공유',
 		'add' => '공유 방법 추가',
 		'add' => '공유 방법 추가',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => '메일',
 		'email' => '메일',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => '자세한 정보',
 		'more_information' => '자세한 정보',
 		'print' => '인쇄',
 		'print' => '인쇄',
-		'raindrop' => 'Raindrop.io',
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => '공유 방법 삭제',
 		'remove' => '공유 방법 삭제',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => '표시할 이름',
 		'share_name' => '표시할 이름',
 		'share_url' => '사용할 공유 URL',
 		'share_url' => '사용할 공유 URL',
 		'title' => '공유',
 		'title' => '공유',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => '단축키',
 		'_' => '단축키',

+ 10 - 0
app/i18n/ko/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => '이 페이지에 접근할 수 있는 권한이 없습니다',
 		'denied' => '이 페이지에 접근할 수 있는 권한이 없습니다',

+ 59 - 49
app/i18n/ko/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => '새 글 가져오기',
 		'actualize' => '새 글 가져오기',
@@ -48,18 +58,18 @@ return array(
 		),
 		),
 	),
 	),
 	'date' => array(
 	'date' => array(
-		'Apr' => '\\4\\월',
-		'Aug' => '\\8\\월',
-		'Dec' => '\\1\\2\\월',
-		'Feb' => '\\2\\월',
-		'Jan' => '\\1\\월',
-		'Jul' => '\\7\\월',
-		'Jun' => '\\6\\월',
-		'Mar' => '\\3\\월',
-		'May' => '\\5\\월',
-		'Nov' => '\\1\\1\\월',
-		'Oct' => '\\1\\0\\월',
-		'Sep' => '\\9\\월',
+		'Apr' => '\\4\\월',	// IGNORE
+		'Aug' => '\\8\\월',	// IGNORE
+		'Dec' => '\\1\\2\\월',	// IGNORE
+		'Feb' => '\\2\\월',	// IGNORE
+		'Jan' => '\\1\\월',	// IGNORE
+		'Jul' => '\\7\\월',	// IGNORE
+		'Jun' => '\\6\\월',	// IGNORE
+		'Mar' => '\\3\\월',	// IGNORE
+		'May' => '\\5\\월',	// IGNORE
+		'Nov' => '\\1\\1\\월',	// IGNORE
+		'Oct' => '\\1\\0\\월',	// IGNORE
+		'Sep' => '\\9\\월',	// IGNORE
 		'apr' => '4월',
 		'apr' => '4월',
 		'april' => '4월',
 		'april' => '4월',
 		'aug' => '8월',
 		'aug' => '8월',
@@ -106,9 +116,9 @@ return array(
 		'wed' => '수',
 		'wed' => '수',
 		'yesterday' => '어제',
 		'yesterday' => '어제',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => '정보',
 		'about' => '정보',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,24 +134,24 @@ return array(
 		'should_be_activated' => '자바스크립트를 사용하도록 설정해야합니다',
 		'should_be_activated' => '자바스크립트를 사용하도록 설정해야합니다',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => '정보',
 		'about' => '정보',
@@ -182,26 +192,26 @@ return array(
 		'years' => '년',
 		'years' => '년',
 	),
 	),
 	'share' => array(
 	'share' => array(
-		'Known' => 'Known based sites',
-		'blogotext' => 'Blogotext',
+		'Known' => 'Known based sites',	// IGNORE
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => '클립보드',
 		'clipboard' => '클립보드',
-		'diaspora' => 'Diaspora*',
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => '메일',
 		'email' => '메일',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => '인쇄',
 		'print' => '인쇄',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => '경고!',
 		'attention' => '경고!',

+ 11 - 1
app/i18n/ko/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => '정보',
 		'_' => '정보',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => '버그 제보하기',
 		'bugs_reports' => '버그 제보하기',
 		'credits' => '크레딧',
 		'credits' => '크레딧',
 		'credits_content' => 'FreshRSS는 <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> 프레임워크를 사용하진 않지만, 일부 디자인 요소를 가져왔습니다. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">아이콘들</a>은 <a href="https://www.gnome.org/">GNOME 프로젝트</a>에서 가져왔습니다. <em>Open Sans</em> 글꼴은 <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>가 제작하였습니다. FreshRSS는 PHP 프레임워크인 <a href="https://github.com/marienfressinaud/MINZ">Minz</a>에 기반하고 있습니다.',
 		'credits_content' => 'FreshRSS는 <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> 프레임워크를 사용하진 않지만, 일부 디자인 요소를 가져왔습니다. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">아이콘들</a>은 <a href="https://www.gnome.org/">GNOME 프로젝트</a>에서 가져왔습니다. <em>Open Sans</em> 글꼴은 <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>가 제작하였습니다. FreshRSS는 PHP 프레임워크인 <a href="https://github.com/marienfressinaud/MINZ">Minz</a>에 기반하고 있습니다.',

+ 10 - 0
app/i18n/ko/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => '설치 완료',
 		'finish' => '설치 완료',

+ 11 - 1
app/i18n/ko/sub.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => '외부 도구에서 API를 사용하기 위해서 아래 URL을 사용하세요.',
 		'documentation' => '외부 도구에서 API를 사용하기 위해서 아래 URL을 사용하세요.',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => '이 버튼을 즐겨찾기 막대로 끌어다 놓거나 마우스 오른쪽 클릭으로 나타나는 메뉴에서 "이 링크를 즐겨찾기에 추가"를 선택하세요. 그리고 피드를 구독하길 원하는 페이지에서 "구독하기" 버튼을 클릭하세요.',
 		'documentation' => '이 버튼을 즐겨찾기 막대로 끌어다 놓거나 마우스 오른쪽 클릭으로 나타나는 메뉴에서 "이 링크를 즐겨찾기에 추가"를 선택하세요. 그리고 피드를 구독하길 원하는 페이지에서 "구독하기" 버튼을 클릭하세요.',

+ 10 - 0
app/i18n/ko/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 12 - 2
app/i18n/nl/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Sta bezoekers toe om artikelen te lezen van de standaard gebruiker (%s)',
 		'allow_anonymous' => 'Sta bezoekers toe om artikelen te lezen van de standaard gebruiker (%s)',
@@ -130,7 +140,7 @@ return array(
 		'entry_per_hour' => 'Per uur (gemiddeld: %.2f berichten)',
 		'entry_per_hour' => 'Per uur (gemiddeld: %.2f berichten)',
 		'entry_per_month' => 'Per maand (gemiddeld: %.2f berichten)',
 		'entry_per_month' => 'Per maand (gemiddeld: %.2f berichten)',
 		'entry_repartition' => 'Invoer verdeling',
 		'entry_repartition' => 'Invoer verdeling',
-		'feed' => 'Feed',
+		'feed' => 'Feed',	// IGNORE
 		'feed_per_category' => 'Feeds per categorie',
 		'feed_per_category' => 'Feeds per categorie',
 		'idle' => 'Gepauzeerde feeds',
 		'idle' => 'Gepauzeerde feeds',
 		'main' => 'Hoofd statistieken',
 		'main' => 'Hoofd statistieken',
@@ -179,7 +189,7 @@ return array(
 		'database_size' => 'Databasegrootte',
 		'database_size' => 'Databasegrootte',
 		'email' => 'Emailadres',
 		'email' => 'Emailadres',
 		'enabled' => 'Ingeschakeld',
 		'enabled' => 'Ingeschakeld',
-		'feed_count' => 'Feeds',
+		'feed_count' => 'Feeds',	// IGNORE
 		'is_admin' => 'Is beheerder',
 		'is_admin' => 'Is beheerder',
 		'language' => 'Taal',
 		'language' => 'Taal',
 		'last_user_activity' => 'Laatste gebruikersactiviteit',
 		'last_user_activity' => 'Laatste gebruikersactiviteit',

+ 21 - 11
app/i18n/nl/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archivering',
 		'_' => 'Archivering',
@@ -80,7 +90,7 @@ return array(
 			'search' => 'Expressie',
 			'search' => 'Expressie',
 			'state' => 'Status',
 			'state' => 'Status',
 			'tags' => 'Weergeven op tag',
 			'tags' => 'Weergeven op tag',
-			'type' => 'Type',
+			'type' => 'Type',	// IGNORE
 		),
 		),
 		'get_all' => 'Toon alle artikelen',
 		'get_all' => 'Toon alle artikelen',
 		'get_category' => 'Toon "%s" categorie',
 		'get_category' => 'Toon "%s" categorie',
@@ -88,7 +98,7 @@ return array(
 		'get_feed' => 'Toon "%s" feed',
 		'get_feed' => 'Toon "%s" feed',
 		'name' => 'Naam',
 		'name' => 'Naam',
 		'no_filter' => 'Geen filter',
 		'no_filter' => 'Geen filter',
-		'number' => 'Query n°%d',
+		'number' => 'Query n°%d',	// IGNORE
 		'order_asc' => 'Toon oudste artikelen eerst',
 		'order_asc' => 'Toon oudste artikelen eerst',
 		'order_desc' => 'Toon nieuwste artikelen eerst',
 		'order_desc' => 'Toon nieuwste artikelen eerst',
 		'search' => 'Zoek naar "%s"',
 		'search' => 'Zoek naar "%s"',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Delen',
 		'_' => 'Delen',
 		'add' => 'Deelmethode toevoegen',
 		'add' => 'Deelmethode toevoegen',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// IGNORE
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Meer informatie',
 		'more_information' => 'Meer informatie',
-		'print' => 'Afdrukken',
-		'raindrop' => 'Raindrop.io',
+		'print' => 'Afdrukken',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => 'Deelmethode verwijderen',
 		'remove' => 'Deelmethode verwijderen',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Gedeelde naam om weer te geven',
 		'share_name' => 'Gedeelde naam om weer te geven',
 		'share_url' => 'Deel URL voor gebruik',
 		'share_url' => 'Deel URL voor gebruik',
 		'title' => 'Delen',
 		'title' => 'Delen',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Snelkoppelingen',
 		'_' => 'Snelkoppelingen',

+ 10 - 0
app/i18n/nl/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'U hebt geen rechten om deze pagina te bekijken.',
 		'denied' => 'U hebt geen rechten om deze pagina te bekijken.',

+ 56 - 46
app/i18n/nl/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Feeds actualiseren',
 		'actualize' => 'Feeds actualiseren',
@@ -48,18 +58,18 @@ return array(
 		),
 		),
 	),
 	),
 	'date' => array(
 	'date' => array(
-		'Apr' => '\\A\\p\\r\\i\\l',
+		'Apr' => '\\A\\p\\r\\i\\l',	// IGNORE
 		'Aug' => '\\A\\u\\g\\u\\s\\t\\u\\s',
 		'Aug' => '\\A\\u\\g\\u\\s\\t\\u\\s',
-		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',	// IGNORE
 		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\i',
 		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\i',
 		'Jan' => '\\J\\a\\n\\u\\a\\r\\i',
 		'Jan' => '\\J\\a\\n\\u\\a\\r\\i',
 		'Jul' => '\\J\\u\\l\\i',
 		'Jul' => '\\J\\u\\l\\i',
 		'Jun' => '\\J\\u\\n\\i',
 		'Jun' => '\\J\\u\\n\\i',
 		'Mar' => '\\M\\a\\a\\r\\t',
 		'Mar' => '\\M\\a\\a\\r\\t',
 		'May' => '\\M\\e\\i',
 		'May' => '\\M\\e\\i',
-		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',	// IGNORE
 		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
 		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
-		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',	// IGNORE
 		'apr' => 'apr',
 		'apr' => 'apr',
 		'april' => 'Apr',
 		'april' => 'Apr',
 		'aug' => 'aug',
 		'aug' => 'aug',
@@ -69,8 +79,8 @@ return array(
 		'december' => 'Dec',
 		'december' => 'Dec',
 		'feb' => 'feb',
 		'feb' => 'feb',
 		'february' => 'Feb',
 		'february' => 'Feb',
-		'format_date' => 'j %s Y',
-		'format_date_hour' => 'j %s Y \\o\\m H\\:i',
+		'format_date' => 'j %s Y',	// IGNORE
+		'format_date_hour' => 'j %s Y \\o\\m H\\:i',	// IGNORE
 		'fri' => 'Vr',
 		'fri' => 'Vr',
 		'jan' => 'jan',
 		'jan' => 'jan',
 		'january' => 'Jan',
 		'january' => 'Jan',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'Wo',
 		'wed' => 'Wo',
 		'yesterday' => 'Gisteren',
 		'yesterday' => 'Gisteren',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'Over FreshRSS',
 		'about' => 'Over FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,28 +134,28 @@ return array(
 		'should_be_activated' => 'JavaScript moet aanstaan',
 		'should_be_activated' => 'JavaScript moet aanstaan',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'Over',
 		'about' => 'Over',
-		'account' => 'Account',
+		'account' => 'Account',	// IGNORE
 		'admin' => 'Administratie',
 		'admin' => 'Administratie',
 		'archiving' => 'Archiveren',
 		'archiving' => 'Archiveren',
 		'authentication' => 'Authenticatie',
 		'authentication' => 'Authenticatie',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Known-gebaseerde sites',
 		'Known' => 'Known-gebaseerde sites',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'Klembord',
 		'clipboard' => 'Klembord',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
-		'print' => 'Print',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Email',	// IGNORE
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
+		'print' => 'Print',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Attentie!',
 		'attention' => 'Attentie!',
@@ -212,7 +222,7 @@ return array(
 		'default_category' => 'Niet ingedeeld',
 		'default_category' => 'Niet ingedeeld',
 		'no' => 'Nee',
 		'no' => 'Nee',
 		'not_applicable' => 'Niet aanwezig',
 		'not_applicable' => 'Niet aanwezig',
-		'ok' => 'Ok!',
+		'ok' => 'Ok!',	// IGNORE
 		'or' => 'of',
 		'or' => 'of',
 		'yes' => 'Ja',
 		'yes' => 'Ja',
 	),
 	),

+ 12 - 2
app/i18n/nl/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'Over',
 		'_' => 'Over',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Rapporteer fouten',
 		'bugs_reports' => 'Rapporteer fouten',
 		'credits' => 'Waarderingen',
 		'credits' => 'Waarderingen',
 		'credits_content' => 'Sommige ontwerp elementen komen van <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> alhoewel FreshRSS dit raamwerk niet gebruikt. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Pictogrammen</a> komen van het <a href="https://www.gnome.org/">GNOME project</a>. <em>De Open Sans</em> font police is gemaakt door <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS is gebaseerd op <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, een PHP raamwerk. Nederlandse vertaling door Wanabo, <a href="http://www.nieuwskop.be" title="NieuwsKop">NieuwsKop.be</a>. Link naar de Nederlandse vertaling, <a href="https://github.com/Wanabo/FreshRSS-Dutch-translation/tree/master">FreshRSS-Dutch-translation</a>.',
 		'credits_content' => 'Sommige ontwerp elementen komen van <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> alhoewel FreshRSS dit raamwerk niet gebruikt. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Pictogrammen</a> komen van het <a href="https://www.gnome.org/">GNOME project</a>. <em>De Open Sans</em> font police is gemaakt door <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS is gebaseerd op <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, een PHP raamwerk. Nederlandse vertaling door Wanabo, <a href="http://www.nieuwskop.be" title="NieuwsKop">NieuwsKop.be</a>. Link naar de Nederlandse vertaling, <a href="https://github.com/Wanabo/FreshRSS-Dutch-translation/tree/master">FreshRSS-Dutch-translation</a>.',
@@ -12,7 +22,7 @@ return array(
 		'license' => 'Licentie',
 		'license' => 'Licentie',
 		'project_website' => 'Projectwebsite',
 		'project_website' => 'Projectwebsite',
 		'title' => 'Over',
 		'title' => 'Over',
-		'version' => 'Versie',
+		'version' => 'Versie',	// IGNORE
 	),
 	),
 	'feed' => array(
 	'feed' => array(
 		'add' => 'U kunt wat feeds toevoegen.',
 		'add' => 'U kunt wat feeds toevoegen.',

+ 12 - 2
app/i18n/nl/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Completeer installatie',
 		'finish' => 'Completeer installatie',
@@ -17,13 +27,13 @@ return array(
 		'type' => 'Authenticatiemethode',
 		'type' => 'Authenticatiemethode',
 	),
 	),
 	'bdd' => array(
 	'bdd' => array(
-		'_' => 'Database',
+		'_' => 'Database',	// IGNORE
 		'conf' => array(
 		'conf' => array(
 			'_' => 'Database configuratie',
 			'_' => 'Database configuratie',
 			'ko' => 'Controleer uw database informatie.',
 			'ko' => 'Controleer uw database informatie.',
 			'ok' => 'Database configuratie is opgeslagen.',
 			'ok' => 'Database configuratie is opgeslagen.',
 		),
 		),
-		'host' => 'Host',
+		'host' => 'Host',	// IGNORE
 		'password' => 'Database wachtwoord',
 		'password' => 'Database wachtwoord',
 		'prefix' => 'Tabel voorvoegsel',
 		'prefix' => 'Tabel voorvoegsel',
 		'type' => 'Type database',
 		'type' => 'Type database',

+ 12 - 2
app/i18n/nl/sub.php

@@ -1,14 +1,24 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => 'Kopieer de volgende URL om deze in een externe toepassing te gebruiken.',
 		'documentation' => 'Kopieer de volgende URL om deze in een externe toepassing te gebruiken.',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'Sleep deze knop naar je bladwijzerwerkbalk of klik erop met de rechtermuisknop en kies "Deze link aan bladwijzers toevoegen."',
 		'documentation' => 'Sleep deze knop naar je bladwijzerwerkbalk of klik erop met de rechtermuisknop en kies "Deze link aan bladwijzers toevoegen."',
 		'label' => 'Abonneren',
 		'label' => 'Abonneren',
-		'title' => 'Bookmarklet',
+		'title' => 'Bookmarklet',	// IGNORE
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categorie',
 		'_' => 'Categorie',

+ 10 - 0
app/i18n/nl/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 16 - 6
app/i18n/oc/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Autorizar la lectura anonima dels articles de l’utilizaire per defaut (%s)',
 		'allow_anonymous' => 'Autorizar la lectura anonima dels articles de l’utilizaire per defaut (%s)',
@@ -114,10 +124,10 @@ return array(
 			'_' => 'Extensions sistèma',
 			'_' => 'Extensions sistèma',
 			'no_rights' => 'Extensions sistèma (contrarotlat per l’administrator)',
 			'no_rights' => 'Extensions sistèma (contrarotlat per l’administrator)',
 		),
 		),
-		'title' => 'Extensions',
+		'title' => 'Extensions',	// IGNORE
 		'update' => 'Mesa a jorn disponibla',
 		'update' => 'Mesa a jorn disponibla',
 		'user' => 'Extensions utilizaire',
 		'user' => 'Extensions utilizaire',
-		'version' => 'Version',
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'stats' => array(
 	'stats' => array(
 		'_' => 'Estatisticas',
 		'_' => 'Estatisticas',
@@ -136,12 +146,12 @@ return array(
 		'main' => 'Estatisticas principalas',
 		'main' => 'Estatisticas principalas',
 		'main_stream' => 'Flux màger',
 		'main_stream' => 'Flux màger',
 		'no_idle' => 'I a pas cap d’article inactiu !',
 		'no_idle' => 'I a pas cap d’article inactiu !',
-		'number_entries' => '%d articles',
+		'number_entries' => '%d articles',	// IGNORE
 		'percent_of_total' => '%% del total',
 		'percent_of_total' => '%% del total',
 		'repartition' => 'Reparticion dels articles',
 		'repartition' => 'Reparticion dels articles',
 		'status_favorites' => 'Favorits',
 		'status_favorites' => 'Favorits',
 		'status_read' => 'Legit',
 		'status_read' => 'Legit',
-		'status_total' => 'Total',
+		'status_total' => 'Total',	// IGNORE
 		'status_unread' => 'Pas legits',
 		'status_unread' => 'Pas legits',
 		'title' => 'Estatisticas',
 		'title' => 'Estatisticas',
 		'top_feed' => 'Los dètz fluxes mai gròsses',
 		'top_feed' => 'Los dètz fluxes mai gròsses',
@@ -172,8 +182,8 @@ return array(
 		'title' => 'Sistèma de mesa a jorn',
 		'title' => 'Sistèma de mesa a jorn',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'admin' => 'Administrator',
-		'article_count' => 'Articles',
+		'admin' => 'Administrator',	// IGNORE
+		'article_count' => 'Articles',	// IGNORE
 		'back_to_manage' => '← Tornar a la lista dels utilizaires',
 		'back_to_manage' => '← Tornar a la lista dels utilizaires',
 		'create' => 'Crear un nòu utilizaire',
 		'create' => 'Crear un nòu utilizaire',
 		'database_size' => 'Talha basa de donadas',
 		'database_size' => 'Talha basa de donadas',

+ 21 - 11
app/i18n/oc/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archius',
 		'_' => 'Archius',
@@ -77,7 +87,7 @@ return array(
 			'categories' => 'Afichatge per categoria',
 			'categories' => 'Afichatge per categoria',
 			'feeds' => 'Afichatge per flux',
 			'feeds' => 'Afichatge per flux',
 			'order' => 'Triar per data',
 			'order' => 'Triar per data',
-			'search' => 'Expression',
+			'search' => 'Expression',	// IGNORE
 			'state' => 'Estat',
 			'state' => 'Estat',
 			'tags' => 'Afichatge per etiqueta',
 			'tags' => 'Afichatge per etiqueta',
 			'type' => 'Tipe',
 			'type' => 'Tipe',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Partatge',
 		'_' => 'Partatge',
 		'add' => 'Ajustar un metòde de partatge',
 		'add' => 'Ajustar un metòde de partatge',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'Corrièl',
 		'email' => 'Corrièl',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Mai d’informacions',
 		'more_information' => 'Mai d’informacions',
-		'print' => 'Imprimir',
-		'raindrop' => 'Raindrop.io',
+		'print' => 'Imprimir',	// IGNORE
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => 'Suprimir lo metòde de partatge',
 		'remove' => 'Suprimir lo metòde de partatge',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Nom del partatge de mostrar',
 		'share_name' => 'Nom del partatge de mostrar',
 		'share_url' => 'URL del partatge d’utilizar',
 		'share_url' => 'URL del partatge d’utilizar',
 		'title' => 'Partatge',
 		'title' => 'Partatge',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Acorchis',
 		'_' => 'Acorchis',
@@ -194,7 +204,7 @@ return array(
 		'load_more' => 'Cargar mai d’articles',
 		'load_more' => 'Cargar mai d’articles',
 		'mark_favorite' => 'Ajustar als favorits',
 		'mark_favorite' => 'Ajustar als favorits',
 		'mark_read' => 'Marcar coma legit',
 		'mark_read' => 'Marcar coma legit',
-		'navigation' => 'Navigacion',
+		'navigation' => 'Navigacion',	// IGNORE
 		'navigation_help' => 'Amb lo modificador <kbd>⇧ Shift</kbd>, los acorchis de navigacion s’aplican als fluxes.<br/>Amb lo modificador <kbd>Alt ⎇</kbd>, los acorchis de navigacion s’aplican a las categorias.',
 		'navigation_help' => 'Amb lo modificador <kbd>⇧ Shift</kbd>, los acorchis de navigacion s’aplican als fluxes.<br/>Amb lo modificador <kbd>Alt ⎇</kbd>, los acorchis de navigacion s’aplican a las categorias.',
 		'navigation_no_mod_help' => 'Los acorchis clavièrs de navigacion son pas compatibles amb los modificadors.',
 		'navigation_no_mod_help' => 'Los acorchis clavièrs de navigacion son pas compatibles amb los modificadors.',
 		'next_article' => 'Passar a l’article seguent',
 		'next_article' => 'Passar a l’article seguent',
@@ -216,7 +226,7 @@ return array(
 		'views' => 'Vistas',
 		'views' => 'Vistas',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'articles_and_size' => '%s articles (%s)',
+		'articles_and_size' => '%s articles (%s)',	// IGNORE
 		'current' => 'Utilizaire actual',
 		'current' => 'Utilizaire actual',
 		'is_admin' => 'es administrator',
 		'is_admin' => 'es administrator',
 		'users' => 'Utilizaires',
 		'users' => 'Utilizaires',

+ 10 - 0
app/i18n/oc/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'Avètz pas l’autorizacion d’accedir a aquesta pagina',
 		'denied' => 'Avètz pas l’autorizacion d’accedir a aquesta pagina',

+ 50 - 40
app/i18n/oc/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Actualizar flux',
 		'actualize' => 'Actualizar flux',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'Dc',
 		'wed' => 'Dc',
 		'yesterday' => 'Ièr',
 		'yesterday' => 'Ièr',
 	),
 	),
-	'dir' => 'ltr',
+	'dir' => 'ltr',	// IGNORE
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'A prepaus de FreshRSS',
 		'about' => 'A prepaus de FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,36 +134,36 @@ return array(
 		'should_be_activated' => 'JavaScript deu èsser activat',
 		'should_be_activated' => 'JavaScript deu èsser activat',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'A prepaus',
 		'about' => 'A prepaus',
 		'account' => 'Compte',
 		'account' => 'Compte',
-		'admin' => 'Administracion',
+		'admin' => 'Administracion',	// IGNORE
 		'archiving' => 'Archivar',
 		'archiving' => 'Archivar',
 		'authentication' => 'Autentificacion',
 		'authentication' => 'Autentificacion',
 		'check_install' => 'Verificacion de l’installacion',
 		'check_install' => 'Verificacion de l’installacion',
-		'configuration' => 'Configuracion',
+		'configuration' => 'Configuracion',	// IGNORE
 		'display' => 'Afichatge',
 		'display' => 'Afichatge',
-		'extensions' => 'Extensions',
-		'logs' => 'Jornals d’audit',
+		'extensions' => 'Extensions',	// IGNORE
+		'logs' => 'Jornals d’audit',	// IGNORE
 		'queries' => 'Filtres utilizaire',
 		'queries' => 'Filtres utilizaire',
 		'reading' => 'Lectura',
 		'reading' => 'Lectura',
 		'search' => 'Recercar de mots o d’#etiquetas',
 		'search' => 'Recercar de mots o d’#etiquetas',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Sites basats sus Known',
 		'Known' => 'Sites basats sus Known',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'Quicha-papiers.',
 		'clipboard' => 'Quicha-papiers.',
-		'diaspora' => 'Diaspora*',
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'Corrièl',
 		'email' => 'Corrièl',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Imprimir',
 		'print' => 'Imprimir',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Atencion !',
 		'attention' => 'Atencion !',

+ 14 - 4
app/i18n/oc/index.php

@@ -1,9 +1,19 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'about' => array(
 	'about' => array(
 		'_' => 'A prepaus',
 		'_' => 'A prepaus',
-		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
 		'bugs_reports' => 'Senhalament de problèmas',
 		'bugs_reports' => 'Senhalament de problèmas',
 		'credits' => 'Crèdits',
 		'credits' => 'Crèdits',
 		'credits_content' => 'Unes elements de l’estil venon del <a href="http://twitter.github.io/bootstrap/">projècte Bootstrap</a> encara que FreshRSS utilize pas aqueste framework. Las <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icònas</a> venon del <a href="https://www.gnome.org/">projècte GNOME</a>. La polissa <em>Open Sans</em> utilizada foguèt creada per en <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS es basat sus <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
 		'credits_content' => 'Unes elements de l’estil venon del <a href="http://twitter.github.io/bootstrap/">projècte Bootstrap</a> encara que FreshRSS utilize pas aqueste framework. Las <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icònas</a> venon del <a href="https://www.gnome.org/">projècte GNOME</a>. La polissa <em>Open Sans</em> utilizada foguèt creada per en <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS es basat sus <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
@@ -12,7 +22,7 @@ return array(
 		'license' => 'Licéncia',
 		'license' => 'Licéncia',
 		'project_website' => 'Site del projècte',
 		'project_website' => 'Site del projècte',
 		'title' => 'A prepaus',
 		'title' => 'A prepaus',
-		'version' => 'Version',
+		'version' => 'Version',	// IGNORE
 	),
 	),
 	'feed' => array(
 	'feed' => array(
 		'add' => 'Podètz ajustar de fluxes.',
 		'add' => 'Podètz ajustar de fluxes.',
@@ -23,10 +33,10 @@ return array(
 		'title_global' => 'Vista generala',
 		'title_global' => 'Vista generala',
 	),
 	),
 	'log' => array(
 	'log' => array(
-		'_' => 'Jornals d’audit',
+		'_' => 'Jornals d’audit',	// IGNORE
 		'clear' => 'Escafar los jornals',
 		'clear' => 'Escafar los jornals',
 		'empty' => 'Los jornals son voids',
 		'empty' => 'Los jornals son voids',
-		'title' => 'Jornals d’audit',
+		'title' => 'Jornals d’audit',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'A prepaus de FreshRSS',
 		'about' => 'A prepaus de FreshRSS',

+ 10 - 0
app/i18n/oc/install.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'finish' => 'Acabar l’installacion',
 		'finish' => 'Acabar l’installacion',

+ 14 - 4
app/i18n/oc/sub.php

@@ -1,14 +1,24 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'api' => array(
 	'api' => array(
 		'documentation' => 'Copiatz l’URL seguenta per l’utilizaire dins d’una aisina extèrna.',
 		'documentation' => 'Copiatz l’URL seguenta per l’utilizaire dins d’una aisina extèrna.',
-		'title' => 'API',
+		'title' => 'API',	// IGNORE
 	),
 	),
 	'bookmarklet' => array(
 	'bookmarklet' => array(
 		'documentation' => 'Depausatz aqueste boton per la barra de marcapaginas o clicatz-lo a drecha e causissètz « Enregistrar aqueste ligam». Puèi clicatz «S’abonar» sus las paginas que volètz seguir.',
 		'documentation' => 'Depausatz aqueste boton per la barra de marcapaginas o clicatz-lo a drecha e causissètz « Enregistrar aqueste ligam». Puèi clicatz «S’abonar» sus las paginas que volètz seguir.',
 		'label' => 'S’abonar',
 		'label' => 'S’abonar',
-		'title' => 'Bookmarklet',
+		'title' => 'Bookmarklet',	// IGNORE
 	),
 	),
 	'category' => array(
 	'category' => array(
 		'_' => 'Categoria',
 		'_' => 'Categoria',
@@ -42,7 +52,7 @@ return array(
 		'css_cookie_help' => 'Exemple : <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',
 		'css_cookie_help' => 'Exemple : <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',
 		'css_help' => 'Permet de recuperar los fluxes troncats (atencion, demanda mai de temps !)',
 		'css_help' => 'Permet de recuperar los fluxes troncats (atencion, demanda mai de temps !)',
 		'css_path' => 'Selector CSS dels articles sul site d’origina',
 		'css_path' => 'Selector CSS dels articles sul site d’origina',
-		'description' => 'Descripcion',
+		'description' => 'Descripcion',	// IGNORE
 		'empty' => 'Aqueste flux es void. Assegurats-vos qu’es totjorn mantengut.',
 		'empty' => 'Aqueste flux es void. Assegurats-vos qu’es totjorn mantengut.',
 		'error' => 'Aqueste flux a rescontrat un problèma. Volgatz verificar que siá totjorn accessible puèi actualizatz-lo.',
 		'error' => 'Aqueste flux a rescontrat un problèma. Volgatz verificar que siá totjorn accessible puèi actualizatz-lo.',
 		'filteractions' => array(
 		'filteractions' => array(
@@ -61,7 +71,7 @@ return array(
 		'moved_category_deleted' => 'Quand escafatz una categoria, sos fluxes son automaticament classats dins <em>%s</em>.',
 		'moved_category_deleted' => 'Quand escafatz una categoria, sos fluxes son automaticament classats dins <em>%s</em>.',
 		'mute' => 'mut',
 		'mute' => 'mut',
 		'no_selected' => 'Cap de flux pas seleccionat.',
 		'no_selected' => 'Cap de flux pas seleccionat.',
-		'number_entries' => '%d articles',
+		'number_entries' => '%d articles',	// IGNORE
 		'priority' => array(
 		'priority' => array(
 			'_' => 'Visibilitat',
 			'_' => 'Visibilitat',
 			'archived' => 'Mostrar pas (archivat)',
 			'archived' => 'Mostrar pas (archivat)',

+ 10 - 0
app/i18n/oc/user.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'email' => array(
 	'email' => array(
 		'feedback' => array(
 		'feedback' => array(

+ 55 - 45
app/i18n/pl/admin.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'auth' => array(
 	'auth' => array(
 		'allow_anonymous' => 'Pozwól na anonimowy odczyt wiadomości domyślnego użytkownika (%s)',
 		'allow_anonymous' => 'Pozwól na anonimowy odczyt wiadomości domyślnego użytkownika (%s)',
@@ -16,88 +26,88 @@ return array(
 	),
 	),
 	'check_install' => array(
 	'check_install' => array(
 		'cache' => array(
 		'cache' => array(
-			'nok' => 'Check permissions on <em>./data/cache</em> directory. HTTP server must have write permission.',	// TODO - Translation
-			'ok' => 'Permissions on the cache directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/cache</em> directory. HTTP server must have write permission.',	// TODO
+			'ok' => 'Permissions on the cache directory are good.',	// TODO
 		),
 		),
 		'categories' => array(
 		'categories' => array(
-			'nok' => 'Category table is improperly configured.',	// TODO - Translation
-			'ok' => 'Category table is okay.',	// TODO - Translation
+			'nok' => 'Category table is improperly configured.',	// TODO
+			'ok' => 'Category table is okay.',	// TODO
 		),
 		),
 		'connection' => array(
 		'connection' => array(
-			'nok' => 'Connection to the database cannot be established.',	// TODO - Translation
-			'ok' => 'Connection to the database is okay.',	// TODO - Translation
+			'nok' => 'Connection to the database cannot be established.',	// TODO
+			'ok' => 'Connection to the database is okay.',	// TODO
 		),
 		),
 		'ctype' => array(
 		'ctype' => array(
-			'nok' => 'Cannot find a required library for character type checking (php-ctype).',	// TODO - Translation
-			'ok' => 'You have the required library for character type checking (ctype).',	// TODO - Translation
+			'nok' => 'Cannot find a required library for character type checking (php-ctype).',	// TODO
+			'ok' => 'You have the required library for character type checking (ctype).',	// TODO
 		),
 		),
 		'curl' => array(
 		'curl' => array(
-			'nok' => 'Cannot find the cURL library (php-curl package).',	// TODO - Translation
-			'ok' => 'You have the cURL library.',	// TODO - Translation
+			'nok' => 'Cannot find the cURL library (php-curl package).',	// TODO
+			'ok' => 'You have the cURL library.',	// TODO
 		),
 		),
 		'data' => array(
 		'data' => array(
-			'nok' => 'Check permissions on <em>./data</em> directory. HTTP server must have write permission.',	// TODO - Translation
-			'ok' => 'Permissions on the data directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data</em> directory. HTTP server must have write permission.',	// TODO
+			'ok' => 'Permissions on the data directory are good.',	// TODO
 		),
 		),
-		'database' => 'Database installation',	// TODO - Translation
+		'database' => 'Database installation',	// TODO
 		'dom' => array(
 		'dom' => array(
-			'nok' => 'Cannot find a required library to browse the DOM (php-xml package).',	// TODO - Translation
-			'ok' => 'You have the required library to browse the DOM.',	// TODO - Translation
+			'nok' => 'Cannot find a required library to browse the DOM (php-xml package).',	// TODO
+			'ok' => 'You have the required library to browse the DOM.',	// TODO
 		),
 		),
 		'entries' => array(
 		'entries' => array(
-			'nok' => 'Entry table is improperly configured.',	// TODO - Translation
-			'ok' => 'Entry table is okay.',	// TODO - Translation
+			'nok' => 'Entry table is improperly configured.',	// TODO
+			'ok' => 'Entry table is okay.',	// TODO
 		),
 		),
 		'favicons' => array(
 		'favicons' => array(
-			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have write permission.',	// TODO - Translation
-			'ok' => 'Permissions on the favicons directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/favicons</em> directory. HTTP server must have write permission.',	// TODO
+			'ok' => 'Permissions on the favicons directory are good.',	// TODO
 		),
 		),
 		'feeds' => array(
 		'feeds' => array(
-			'nok' => 'Feed table is improperly configured.',	// TODO - Translation
-			'ok' => 'Feed table is okay.',	// TODO - Translation
+			'nok' => 'Feed table is improperly configured.',	// TODO
+			'ok' => 'Feed table is okay.',	// TODO
 		),
 		),
 		'fileinfo' => array(
 		'fileinfo' => array(
-			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// TODO - Translation
-			'ok' => 'You have the fileinfo library.',	// TODO - Translation
+			'nok' => 'Cannot find the PHP fileinfo library (fileinfo package).',	// TODO
+			'ok' => 'You have the fileinfo library.',	// TODO
 		),
 		),
-		'files' => 'File installation',	// TODO - Translation
+		'files' => 'File installation',	// TODO
 		'json' => array(
 		'json' => array(
-			'nok' => 'Cannot find JSON (php-json package).',	// TODO - Translation
-			'ok' => 'You have the JSON extension.',	// TODO - Translation
+			'nok' => 'Cannot find JSON (php-json package).',	// TODO
+			'ok' => 'You have the JSON extension.',	// TODO
 		),
 		),
 		'mbstring' => array(
 		'mbstring' => array(
-			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// TODO - Translation
-			'ok' => 'You have the recommended mbstring library for Unicode.',	// TODO - Translation
+			'nok' => 'Cannot find the recommended mbstring library for Unicode.',	// TODO
+			'ok' => 'You have the recommended mbstring library for Unicode.',	// TODO
 		),
 		),
 		'pcre' => array(
 		'pcre' => array(
-			'nok' => 'Cannot find a required library for regular expressions (php-pcre).',	// TODO - Translation
-			'ok' => 'You have the required library for regular expressions (PCRE).',	// TODO - Translation
+			'nok' => 'Cannot find a required library for regular expressions (php-pcre).',	// TODO
+			'ok' => 'You have the required library for regular expressions (PCRE).',	// TODO
 		),
 		),
 		'pdo' => array(
 		'pdo' => array(
-			'nok' => 'Cannot find PDO or one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// TODO - Translation
-			'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// TODO - Translation
+			'nok' => 'Cannot find PDO or one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// TODO
+			'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite, pdo_pgsql).',	// TODO
 		),
 		),
 		'php' => array(
 		'php' => array(
-			'_' => 'PHP installation',	// TODO - Translation
-			'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.',	// TODO - Translation
-			'ok' => 'Your PHP version (%s) is compatible with FreshRSS.',	// TODO - Translation
+			'_' => 'PHP installation',	// TODO
+			'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.',	// TODO
+			'ok' => 'Your PHP version (%s) is compatible with FreshRSS.',	// TODO
 		),
 		),
 		'tables' => array(
 		'tables' => array(
-			'nok' => 'There are one or more missing tables in the database.',	// TODO - Translation
-			'ok' => 'The appropriate tables exist in the database.',	// TODO - Translation
+			'nok' => 'There are one or more missing tables in the database.',	// TODO
+			'ok' => 'The appropriate tables exist in the database.',	// TODO
 		),
 		),
-		'title' => 'Installation check',	// TODO - Translation
+		'title' => 'Installation check',	// TODO
 		'tokens' => array(
 		'tokens' => array(
-			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have write permission',	// TODO - Translation
-			'ok' => 'Permissions on the tokens directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have write permission',	// TODO
+			'ok' => 'Permissions on the tokens directory are good.',	// TODO
 		),
 		),
 		'users' => array(
 		'users' => array(
-			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have write permission',	// TODO - Translation
-			'ok' => 'Permissions on the users directory are good.',	// TODO - Translation
+			'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have write permission',	// TODO
+			'ok' => 'Permissions on the users directory are good.',	// TODO
 		),
 		),
 		'zip' => array(
 		'zip' => array(
-			'nok' => 'Cannot find the ZIP extension (php-zip package).',	// TODO - Translation
-			'ok' => 'You have the ZIP extension.',	// TODO - Translation
+			'nok' => 'Cannot find the ZIP extension (php-zip package).',	// TODO
+			'ok' => 'You have the ZIP extension.',	// TODO
 		),
 		),
 	),
 	),
 	'extensions' => array(
 	'extensions' => array(
@@ -172,7 +182,7 @@ return array(
 		'title' => 'Aktualizacja',
 		'title' => 'Aktualizacja',
 	),
 	),
 	'user' => array(
 	'user' => array(
-		'admin' => 'Administrator',
+		'admin' => 'Administrator',	// IGNORE
 		'article_count' => 'Liczba wiadomości',
 		'article_count' => 'Liczba wiadomości',
 		'back_to_manage' => '← Powrót do listy użytkowników',
 		'back_to_manage' => '← Powrót do listy użytkowników',
 		'create' => 'Dodaj nowego użytkownika',
 		'create' => 'Dodaj nowego użytkownika',

+ 17 - 7
app/i18n/pl/conf.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'archiving' => array(
 	'archiving' => array(
 		'_' => 'Archiwizacja',
 		'_' => 'Archiwizacja',
@@ -163,20 +173,20 @@ return array(
 	'sharing' => array(
 	'sharing' => array(
 		'_' => 'Podawanie dalej',
 		'_' => 'Podawanie dalej',
 		'add' => 'Dodaj sposób na podanie dalej wiadomości',
 		'add' => 'Dodaj sposób na podanie dalej wiadomości',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
+		'blogotext' => 'Blogotext',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'E-mail',
 		'email' => 'E-mail',
-		'facebook' => 'Facebook',
+		'facebook' => 'Facebook',	// IGNORE
 		'more_information' => 'Więcej informacji',
 		'more_information' => 'Więcej informacji',
 		'print' => 'Wydruk',
 		'print' => 'Wydruk',
-		'raindrop' => 'Raindrop.io',
+		'raindrop' => 'Raindrop.io',	// IGNORE
 		'remove' => 'Usuń sposób na podanie dalej wiadomości',
 		'remove' => 'Usuń sposób na podanie dalej wiadomości',
-		'shaarli' => 'Shaarli',
+		'shaarli' => 'Shaarli',	// IGNORE
 		'share_name' => 'Wyświetlana nazwa serwisu',
 		'share_name' => 'Wyświetlana nazwa serwisu',
 		'share_url' => 'Adres API serwisu',
 		'share_url' => 'Adres API serwisu',
 		'title' => 'Podawanie dalej',
 		'title' => 'Podawanie dalej',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
 	),
 	),
 	'shortcut' => array(
 	'shortcut' => array(
 		'_' => 'Skróty klawiszowe',
 		'_' => 'Skróty klawiszowe',

+ 10 - 0
app/i18n/pl/feedback.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'access' => array(
 	'access' => array(
 		'denied' => 'Nie masz uprawnień dostępu do tej strony',
 		'denied' => 'Nie masz uprawnień dostępu do tej strony',

+ 49 - 39
app/i18n/pl/gen.php

@@ -1,5 +1,15 @@
 <?php
 <?php
 
 
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
 return array(
 return array(
 	'action' => array(
 	'action' => array(
 		'actualize' => 'Aktualizuj kanałów',
 		'actualize' => 'Aktualizuj kanałów',
@@ -69,8 +79,8 @@ return array(
 		'december' => 'Grudzień',
 		'december' => 'Grudzień',
 		'feb' => 'Lut',
 		'feb' => 'Lut',
 		'february' => 'Luty',
 		'february' => 'Luty',
-		'format_date' => 'j %s Y',
-		'format_date_hour' => 'j %s Y\\, H\\:i',
+		'format_date' => 'j %s Y',	// IGNORE
+		'format_date_hour' => 'j %s Y\\, H\\:i',	// IGNORE
 		'fri' => 'Pt.',
 		'fri' => 'Pt.',
 		'jan' => 'Sty.',
 		'jan' => 'Sty.',
 		'january' => 'Styczeń',
 		'january' => 'Styczeń',
@@ -106,9 +116,9 @@ return array(
 		'wed' => 'Śr.',
 		'wed' => 'Śr.',
 		'yesterday' => 'Wczorajsze',
 		'yesterday' => 'Wczorajsze',
 	),
 	),
-	'dir' => 'ltr',	// TODO - Translation
+	'dir' => 'ltr',	// TODO
 	'freshrss' => array(
 	'freshrss' => array(
-		'_' => 'FreshRSS',
+		'_' => 'FreshRSS',	// IGNORE
 		'about' => 'O serwisie FreshRSS',
 		'about' => 'O serwisie FreshRSS',
 	),
 	),
 	'js' => array(
 	'js' => array(
@@ -124,24 +134,24 @@ return array(
 		'should_be_activated' => 'JavaScript musi być włączony',
 		'should_be_activated' => 'JavaScript musi być włączony',
 	),
 	),
 	'lang' => array(
 	'lang' => array(
-		'cz' => 'Čeština',
-		'de' => 'Deutsch',
-		'en' => 'English',
-		'en-us' => 'English (United States)',
-		'es' => 'Español',
-		'fr' => 'Français',
-		'he' => 'עברית',
-		'it' => 'Italiano',
-		'ja' => '日本語',
-		'ko' => '한국어',
-		'nl' => 'Nederlands',
-		'oc' => 'Occitan',
-		'pl' => 'Polski',
-		'pt-br' => 'Português (Brasil)',
-		'ru' => 'Русский',
-		'sk' => 'Slovenčina',
-		'tr' => 'Türkçe',
-		'zh-cn' => '简体中文',
+		'cz' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
 	),
 	),
 	'menu' => array(
 	'menu' => array(
 		'about' => 'O serwisie',
 		'about' => 'O serwisie',
@@ -183,25 +193,25 @@ return array(
 	),
 	),
 	'share' => array(
 	'share' => array(
 		'Known' => 'Strony bazujące na usłudze Known',
 		'Known' => 'Strony bazujące na usłudze Known',
-		'blogotext' => 'Blogotext',
+		'blogotext' => 'Blogotext',	// IGNORE
 		'clipboard' => 'Schowek',
 		'clipboard' => 'Schowek',
-		'diaspora' => 'Diaspora*',
+		'diaspora' => 'Diaspora*',	// IGNORE
 		'email' => 'E-mail',
 		'email' => 'E-mail',
-		'facebook' => 'Facebook',
-		'gnusocial' => 'GNU social',
-		'jdh' => 'Journal du hacker',
-		'lemmy' => 'Lemmy',
-		'linkedin' => 'LinkedIn',
-		'mastodon' => 'Mastodon',
-		'movim' => 'Movim',
-		'pinboard' => 'Pinboard',
-		'pocket' => 'Pocket',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
 		'print' => 'Wydruk',
 		'print' => 'Wydruk',
-		'raindrop' => 'Raindrop.io',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag v1',
-		'wallabagv2' => 'wallabag v2',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
 	),
 	),
 	'short' => array(
 	'short' => array(
 		'attention' => 'Uwaga!',
 		'attention' => 'Uwaga!',
@@ -212,7 +222,7 @@ return array(
 		'default_category' => 'Brak kategorii',
 		'default_category' => 'Brak kategorii',
 		'no' => 'Nie',
 		'no' => 'Nie',
 		'not_applicable' => 'Niedostępne',
 		'not_applicable' => 'Niedostępne',
-		'ok' => 'Okay!',
+		'ok' => 'Okay!',	// IGNORE
 		'or' => 'lub',
 		'or' => 'lub',
 		'yes' => 'Tak',
 		'yes' => 'Tak',
 	),
 	),

Неке датотеке нису приказане због велике количине промена