Marien Fressinaud 10 лет назад
Родитель
Сommit
133e369aff

+ 16 - 2
CHANGELOG.md

@@ -1,5 +1,19 @@
 # Changelog
 
+## 2015-09-12 FreshRSS 1.1.3-beta
+
+* UI
+	* Configuration page for global settings such as limits [#958](https://github.com/FreshRSS/FreshRSS/pull/958)
+	* Add feed ID in articles to ease styling [#953](https://github.com/FreshRSS/FreshRSS/issues/953)
+* I18n
+	* Dutch [#949](https://github.com/FreshRSS/FreshRSS/issues/949)
+* Bug fixing
+	* Session cookie bug [#924](https://github.com/FreshRSS/FreshRSS/issues/924)
+	* Better error handling for PubSubHubbub [#939](https://github.com/FreshRSS/FreshRSS/issues/939)
+	* Fix tag search link from articles [#970](https://github.com/FreshRSS/FreshRSS/issues/970)
+	* Fix all quieries deleted when deleting a feed or category [#982](https://github.com/FreshRSS/FreshRSS/pull/982)
+
+
 ## 2015-07-30 FreshRSS 1.1.2-beta
 
 * Features
@@ -40,7 +54,7 @@
 * UI
 	* New confirmation message when leaving a configuration page without saving the changes.
 * Bug fixing
-	* Corrected bug introduced in previous beta about handling of HTTP 301 (feeds that have changed address) 
+	* Corrected bug introduced in previous beta about handling of HTTP 301 (feeds that have changed address)
 	* Corrected bug in FreshRSS RSS feeds.
 * Security
 	* Sanitize HTTP request header `Host`.
@@ -304,7 +318,7 @@
 		* Amélioration des performances
 		* Tolère un beaucoup plus grand nombre d’articles
 		* Compression des données côté MySQL plutôt que côté PHP
-		* Incompatible avec la version 0.6 (nécessite une mise à jour grâce à l’installateur) 
+		* Incompatible avec la version 0.6 (nécessite une mise à jour grâce à l’installateur)
 	* Affichage de la taille de la base de données dans FreshRSS
 	* Correction problème de marquage de tous les favoris comme lus
 * HTML5 :

+ 5 - 1
CREDITS.md

@@ -12,8 +12,12 @@ People are sorted by name so please keep this order.
 * [Amaury Carrade](https://github.com/AmauryCarrade): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=AmauryCarrade)
 * [ealdraed](https://github.com/ealdraed): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=ealdraed)
 * [Luc Didry](https://github.com/ldidry): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=ldidry)
-* [Marien Fressinaud](https://github.com/marienfressinaud): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=marienfressinaud), [Web](http://marienfressinaud.fr/), [Email](mailto:dev@marienfressinaud.fr)
+* [Marien Fressinaud](https://github.com/marienfressinaud): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=marienfressinaud), [Web](http://marienfressinaud.fr/)
 * [Melvyn Laïly](https://github.com/yaurthek): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=yaurthek)
 * [Nicolas Elie](https://github.com/nicolaselie): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=nicolaselie)
 * [plopoyop](https://github.com/plopoyop): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=plopoyop)
+* [Tets42](https://github.com/Tets42):
+[contributions](https://github.com/FreshRSS/FreshRSS/commits?author=Tets42)
+* [thomasE1993](https://github.com/thomasE1993):
+[contributions](https://github.com/FreshRSS/FreshRSS/commits?author=thomasE1993)
 * [tomgue](https://github.com/tomgue): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=tomgue)

+ 34 - 0
app/Controllers/configureController.php

@@ -293,4 +293,38 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 		Minz_Request::good(_t('feedback.conf.query_created', $query['name']),
 		                   array('c' => 'configure', 'a' => 'queries'));
 	}
+
+	/**
+	 * This action handles the system configuration page.
+	 *
+	 * It displays the system configuration page.
+	 * If this action is reach through a POST request, it stores all new
+	 * configuration values then sends a notification to the user.
+	 *
+	 * The options available on the page are:
+	 *   - user limit (default: 1)
+	 *   - user category limit (default: 16384)
+	 *   - user feed limit (default: 16384)
+	 */
+	public function systemAction() {
+		if (!FreshRSS_Auth::hasAccess('admin')) {
+			Minz_Error::error(403);
+		}
+		if (Minz_Request::isPost()) {
+			$limits = FreshRSS_Context::$system_conf->limits;
+			$limits['max_registrations'] = Minz_Request::param('max-registrations', 1);
+			$limits['max_feeds'] = Minz_Request::param('max-feeds', 16384);
+			$limits['max_categories'] = Minz_Request::param('max-categories', 16384);
+			FreshRSS_Context::$system_conf->limits = $limits;
+			FreshRSS_Context::$system_conf->title = Minz_Request::param('instance-name', 'FreshRSS');
+			FreshRSS_Context::$system_conf->save();
+
+			invalidateHttpCache();
+
+			Minz_Session::_param('notification', array(
+				'type' => 'good',
+				'content' => _t('feedback.conf.updated')
+			));
+		}
+	}
 }

+ 0 - 24
app/Controllers/userController.php

@@ -272,28 +272,4 @@ class FreshRSS_user_Controller extends Minz_ActionController {
 
 		Minz_Request::forward($redirect_url, true);
 	}
-
-	/**
-	 * This action updates the max number of registrations.
-	 *
-	 * Request parameter is:
-	 *   - max-registrations (int >= 0)
-	 */
-	public function setRegistrationAction() {
-		if (Minz_Request::isPost() && FreshRSS_Auth::hasAccess('admin')) {
-			$limits = FreshRSS_Context::$system_conf->limits;
-			$limits['max_registrations'] = Minz_Request::param('max-registrations', 1);
-			FreshRSS_Context::$system_conf->limits = $limits;
-			FreshRSS_Context::$system_conf->save();
-
-			invalidateHttpCache();
-
-			Minz_Session::_param('notification', array(
-				'type' => 'good',
-				'content' => _t('feedback.user.set_registration')
-			));
-		}
-
-		Minz_Request::forward(array('c' => 'user', 'a' => 'manage'), true);
-	}
 }

+ 2 - 0
app/Models/ConfigurationSetter.php

@@ -119,6 +119,8 @@ class FreshRSS_ConfigurationSetter {
 		foreach ($values as $value) {
 			if ($value instanceof FreshRSS_UserQuery) {
 				$data['queries'][] = $value->toArray();
+			} elseif (is_array($value)) {
+				$data['queries'][] = $value;
 			}
 		}
 	}

+ 8 - 1
app/Models/Feed.php

@@ -475,7 +475,14 @@ class FreshRSS_Feed extends Minz_Model {
 				file_put_contents($hubFilename, json_encode($hubJson));
 			}
 
-			return substr($info['http_code'], 0, 1) == '2';
+			if (substr($info['http_code'], 0, 1) == '2') {
+				return true;
+			} else {
+				$hubJson['lease_start'] = time();	//Prevent trying again too soon
+				$hubJson['error'] = true;
+				file_put_contents($hubFilename, json_encode($hubJson));
+				return false;
+			}
 		}
 		return false;
 	}

+ 10 - 5
app/i18n/cz/admin.php

@@ -146,6 +146,16 @@ return array(
 		'title' => 'Statistika',
 		'top_feed' => 'Top ten kanálů',
 	),
+	'system' => array(
+		'_' => 'System configuration', // @todo translate
+		'instance-name' => 'Instance name', // @todo translate
+		'max-categories' => 'Categories per user limit', // @todo translate
+		'max-feeds' => 'Feeds per user limit', // @todo translate
+		'registration' => array(
+			'help' => '0 znamená žádná omezení účtu',
+			'number' => 'Maximální počet účtů',
+		),
+	),
 	'update' => array(
 		'_' => 'Aktualizace systému',
 		'apply' => 'Použít',
@@ -164,11 +174,6 @@ return array(
 		'numbers' => 'Zatím je vytvořeno %d účtů',
 		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
 		'password_format' => 'Alespoň 7 znaků',
-		'registration' => array(
-			'allow' => 'Povolit vytváření účtů',
-			'help' => '0 znamená žádná omezení účtu',
-			'number' => 'Maximální počet účtů',
-		),
 		'title' => 'Správa uživatelů',
 		'user_list' => 'Seznam uživatelů',
 		'username' => 'Přihlašovací jméno',

+ 0 - 1
app/i18n/cz/feedback.php

@@ -102,7 +102,6 @@ return array(
 			'_' => 'Uživatel %s byl smazán',
 			'error' => 'Uživatele %s nelze smazat',
 		),
-		'set_registration' => 'Maximální počet účtů byl změněn',
 	),
 	'profile' => array(
 		'error' => 'Váš profil nelze změnit',

+ 3 - 1
app/i18n/cz/gen.php

@@ -116,10 +116,11 @@ return array(
 		'should_be_activated' => 'JavaScript musí být povolen',
 	),
 	'lang' => array(
+		'cz' => 'Čeština',
 		'de' => 'Deutsch',
 		'en' => 'English',
 		'fr' => 'Français',
-		'cz' => 'Čeština',
+		'nl' => 'Nederlands',
 	),
 	'menu' => array(
 		'about' => 'O aplikaci',
@@ -137,6 +138,7 @@ return array(
 		'sharing' => 'Sdílení',
 		'shortcuts' => 'Zkratky',
 		'stats' => 'Statistika',
+		'system' => 'System configuration',// @todo translate
 		'update' => 'Aktualizace',
 		'user_management' => 'Správa uživatelů',
 		'user_profile' => 'Profil',

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

@@ -146,6 +146,16 @@ return array(
 		'title' => 'Statistiken',
 		'top_feed' => 'Top 10-Feeds',
 	),
+	'system' => array(
+		'_' => 'System configuration', // @todo translate
+		'instance-name' => 'Instance name', // @todo translate
+		'max-categories' => 'Categories per user limit', // @todo translate
+		'max-feeds' => 'Feeds per user limit', // @todo translate
+		'registration' => array(
+			'help' => '0 meint, dass es kein Account Limit gibt',
+			'number' => 'Maximale Anzahl von Accounts',
+		),
+	),
 	'update' => array(
 		'_' => 'System aktualisieren',
 		'apply' => 'Anwenden',
@@ -164,11 +174,6 @@ return array(
 		'numbers' => 'Es wurden bis jetzt %d Accounts erstellt',
 		'password_form' => 'Passwort<br /><small>(für die Anmeldemethode per Webformular)</small>',
 		'password_format' => 'mindestens 7 Zeichen',
-		'registration' => array(
-			'allow' => 'Erlaube die Accounterstellung',
-			'help' => '0 meint, dass es kein Account Limit gibt',
-			'number' => 'Maximale Anzahl von Accounts',
-		),
 		'title' => 'Benutzer verwalten',
 		'user_list' => 'Liste der Benutzer',
 		'username' => 'Nutzername',

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

@@ -102,7 +102,6 @@ return array(
 			'_' => 'Der Benutzer %s ist gelöscht worden',
 			'error' => 'Der Benutzer %s kann nicht gelöscht werden',
 		),
-		'set_registration' => 'Die maximale Anzahl von Accounts wurde aktualisiert.',
 	),
 	'profile' => array(
 		'error' => 'Ihr Profil kann nicht geändert werden',

+ 2 - 0
app/i18n/de/gen.php

@@ -120,6 +120,7 @@ return array(
 		'de' => 'Deutsch',
 		'en' => 'English',
 		'fr' => 'Français',
+		'nl' => 'Nederlands',
 	),
 	'menu' => array(
 		'about' => 'Über',
@@ -137,6 +138,7 @@ return array(
 		'sharing' => 'Teilen',
 		'shortcuts' => 'Tastaturkürzel',
 		'stats' => 'Statistiken',
+		'system' => 'System configuration',// @todo translate
 		'update' => 'Aktualisieren',
 		'user_management' => 'Benutzer verwalten',
 		'user_profile' => 'Profil',

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

@@ -27,9 +27,9 @@ return array(
 		),
 		'host' => 'Host',
 		'prefix' => 'Tabellen-Präfix',
-		'password' => 'HTTP-Password',
+		'password' => 'SQL-Password',
 		'type' => 'Datenbank-Typ',
-		'username' => 'HTTP-Nutzername',
+		'username' => 'SQL-Nutzername',
 	),
 	'check' => array(
 		'_' => 'Überprüfungen',

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

@@ -146,6 +146,16 @@ return array(
 		'title' => 'Statistics',
 		'top_feed' => 'Top ten feeds',
 	),
+	'system' => array(
+		'_' => 'System configuration',
+		'instance-name' => 'Instance name',
+		'max-categories' => 'Categories per user limit',
+		'max-feeds' => 'Feeds per user limit',
+		'registration' => array(
+			'help' => '0 means that there is no account limit',
+			'number' => 'Max number of accounts',
+		),
+	),
 	'update' => array(
 		'_' => 'Update system',
 		'apply' => 'Apply',
@@ -164,11 +174,6 @@ return array(
 		'numbers' => 'There are %d accounts created yet',
 		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
 		'password_format' => 'At least 7 characters',
-		'registration' => array(
-			'allow' => 'Allow account creation',
-			'help' => '0 means that there is no account limit',
-			'number' => 'Max number of accounts',
-		),
 		'title' => 'Manage users',
 		'user_list' => 'List of users',
 		'username' => 'Username',

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

@@ -102,7 +102,6 @@ return array(
 			'_' => 'User %s has been deleted',
 			'error' => 'User %s cannot be deleted',
 		),
-		'set_registration' => 'The maximum amount of accounts has been updated.',
 	),
 	'profile' => array(
 		'error' => 'Your profile cannot be modified',

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

@@ -120,6 +120,7 @@ return array(
 		'de' => 'Deutsch',
 		'en' => 'English',
 		'fr' => 'Français',
+		'nl' => 'Nederlands',
 	),
 	'menu' => array(
 		'about' => 'About',
@@ -137,6 +138,7 @@ return array(
 		'sharing' => 'Sharing',
 		'shortcuts' => 'Shortcuts',
 		'stats' => 'Statistics',
+		'system' => 'System configuration',
 		'update' => 'Update',
 		'user_management' => 'Manage users',
 		'user_profile' => 'Profile',

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

@@ -146,6 +146,16 @@ return array(
 		'title' => 'Statistiques',
 		'top_feed' => 'Les dix plus gros flux',
 	),
+	'system' => array(
+		'_' => 'Configuration du système',
+		'instance-name' => 'Nom de l’instance',
+		'max-categories' => 'Limite de catégories par utilisateur',
+		'max-feeds' => 'Limite de flux par utilisateur',
+		'registration' => array(
+			'help' => 'Un chiffre de 0 signifie que l’on peut créer un nombre infini de comptes',
+			'number' => 'Nombre max de comptes',
+		),
+	),
 	'update' => array(
 		'_' => 'Système de mise à jour',
 		'apply' => 'Appliquer la mise à jour',
@@ -164,11 +174,6 @@ return array(
 		'numbers' => '%d comptes ont déjà été créés',
 		'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>',
 		'password_format' => '7 caractères minimum',
-		'registration' => array(
-			'allow' => 'Autoriser la création de comptes',
-			'help' => 'Un chiffre de 0 signifie que l’on peut créer un nombre infini de comptes',
-			'number' => 'Nombre max de comptes',
-		),
 		'title' => 'Gestion des utilisateurs',
 		'user_list' => 'Liste des utilisateurs',
 		'username' => 'Nom d’utilisateur',

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

@@ -102,7 +102,6 @@ return array(
 			'_' => 'L’utilisateur %s a été supprimé.',
 			'error' => 'L’utilisateur %s ne peut pas être supprimé.',
 		),
-		'set_registration' => 'Le nombre maximal de comptes a été mis à jour.',
 	),
 	'profile' => array(
 		'error' => 'Votre profil n’a pas pu être mis à jour',

+ 2 - 0
app/i18n/fr/gen.php

@@ -120,6 +120,7 @@ return array(
 		'de' => 'Deutsch',
 		'en' => 'English',
 		'fr' => 'Français',
+		'nl' => 'Nederlands',
 	),
 	'menu' => array(
 		'about' => 'À propos',
@@ -137,6 +138,7 @@ return array(
 		'sharing' => 'Partage',
 		'shortcuts' => 'Raccourcis',
 		'stats' => 'Statistiques',
+		'system' => 'Configuration du système',
 		'update' => 'Mise à jour',
 		'user_management' => 'Gestion des utilisateurs',
 		'user_profile' => 'Profil',

+ 177 - 0
app/i18n/nl/admin.php

@@ -0,0 +1,177 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'auth' => array(
+		'allow_anonymous' => 'Sta bezoekers toe om artikelen te lezen van de standaard gebruiker (%s)',
+		'allow_anonymous_refresh' => 'Sta bezoekers toe om de artikelen te vernieuwen',
+		'api_enabled' => 'Sta <abbr>API</abbr> toegang toe <small>(nodig voor mobiele apps)</small>',
+		'form' => 'Web formulier (traditioneel, benodigd JavaScript)',
+		'http' => 'HTTP (voor geavanceerde gebruikers met HTTPS)',
+		'none' => 'Geen (gevaarlijk)',
+		'persona' => 'Mozilla Persona (modern, benodigd JavaScript)',
+		'title' => 'Authenticatie',
+		'title_reset' => 'Authenticatie terugzetten',
+		'token' => 'Authenticatie teken',
+		'token_help' => 'Sta toegang toe tot de RSS uitvoer van de standaard gebruiker zonder authenticatie:',
+		'type' => 'Authenticatie methode',
+		'unsafe_autologin' => 'Sta onveilige automatische log in toe met het volgende formaat: ',
+	),
+	'check_install' => array(
+		'cache' => array(
+			'nok' => 'Controleer de permissies van de <em>./data/cache</em> map. HTTP server moet rechten hebben om hierin te schrijven',
+			'ok' => 'Permissies van de cache map zijn goed.',
+		),
+		'categories' => array(
+			'nok' => 'Categorie tabel is slecht geconfigureerd.',
+			'ok' => 'Categorie tabel is ok.',
+		),
+		'connection' => array(
+			'nok' => 'Verbinding met de database kan niet worden gemaakt.',
+			'ok' => 'Verbinding met de database is ok.',
+		),
+		'ctype' => array(
+			'nok' => 'U mist de benodigde bibliotheek voor character type checking (php-ctype).',
+			'ok' => 'U hebt de benodigde bibliotheek voor character type checking (ctype).',
+		),
+		'curl' => array(
+			'nok' => 'U mist de cURL (php5-curl package).',
+			'ok' => 'U hebt de cURL uitbreiding.',
+		),
+		'data' => array(
+			'nok' => 'Controleer de permissies op de <em>./data</em> map. HTTP server moet rechten hebben om hierin te schrijven',
+			'ok' => 'Permissies op de data map zijn goed.',
+		),
+		'database' => 'Database installatie',
+		'dom' => array(
+			'nok' => 'U mist de benodigde bibliotheek voor het bladeren van DOM (php-xml package).',
+			'ok' => 'U hebt de benodigde bibliotheek voor het bladeren van DOM.',
+		),
+		'entries' => array(
+			'nok' => 'Invoer tabel is slecht geconfigureerd.',
+			'ok' => 'Invoer tabel is ok.',
+		),
+		'favicons' => array(
+			'nok' => 'Controleer de permissies op de <em>./data/favicons</em> map. HTTP server moet rechten hebben om hierin te schrijven',
+			'ok' => 'Permissies op de favicons map zijn goed.',
+		),
+		'feeds' => array(
+			'nok' => 'Feed tabel is slecht geconfigureerd.',
+			'ok' => 'Feed tabel is ok.',
+		),
+		'files' => 'Bestanden installatie',
+		'json' => array(
+			'nok' => 'U mist JSON (php5-json package).',
+			'ok' => 'U hebt JSON uitbreiding.',
+		),
+		'minz' => array(
+			'nok' => 'U mist Minz framework.',
+			'ok' => 'U hebt Minz framework.',
+		),
+		'pcre' => array(
+			'nok' => 'U mist de benodigde bibliotheek voor regular expressions (php-pcre).',
+			'ok' => 'U hebt de benodigde bibliotheek voor regular expressions (PCRE).',
+		),
+		'pdo' => array(
+			'nok' => 'U mist PDO of een van de ondersteunde drivers (pdo_mysql, pdo_sqlite).',
+			'ok' => 'U hebt PDO en ten minste één van de ondersteunde drivers (pdo_mysql, pdo_sqlite).',
+		),
+		'persona' => array(
+			'nok' => 'Controleer de permissies op de <em>./data/persona</em> map. HTTP server moet rechten hebben om hierin te schrijven',
+			'ok' => 'Permissies op de Mozilla Persona map zijn goed.',
+		),
+		'php' => array(
+			'_' => 'PHP installatie',
+			'nok' => 'Uw PHP versie is %s maar FreshRSS benodigd tenminste versie %s.',
+			'ok' => 'Uw PHP versie is %s, welke compatibel is met FreshRSS.',
+		),
+		'tables' => array(
+			'nok' => 'Er zijn één of meer ontbrekende tabellen in de database.',
+			'ok' => 'Alle tabellen zijn aanwezig in de database.',
+		),
+		'title' => 'Installatie controle',
+		'tokens' => array(
+			'nok' => 'Controleer de permissies op de <em>./data/tokens</em> map. HTTP server moet rechten hebben om hierin te schrijven',
+			'ok' => 'Permissies op de tokens map zijn goed.',
+		),
+		'users' => array(
+			'nok' => 'Controleer de permissies op de <em>./data/users</em> map. HTTP server moet rechten hebben om hierin te schrijven',
+			'ok' => 'Permissies op de users map zijn goed.',
+		),
+		'zip' => array(
+			'nok' => 'U mist ZIP uitbreiding (php5-zip package).',
+			'ok' => 'U hebt ZIP uitbreiding.',
+		),
+	),
+	'extensions' => array(
+		'disabled' => 'Uitgeschakeld',
+		'empty_list' => 'Er zijn geïnstalleerde uitbreidingen',
+		'enabled' => 'Ingeschakeld',
+		'no_configure_view' => 'Deze uitbreiding kan niet worden geconfigureerd.',
+		'system' => array(
+			'_' => 'Systeem uitbreidingen',
+			'no_rights' => 'Systeem uitbreidingen (U hebt hier geen rechten op)',
+		),
+		'title' => 'Uitbreidingen',
+		'user' => 'Gebruikers uitbreidingen',
+	),
+	'stats' => array(
+		'_' => 'Statistieken',
+		'all_feeds' => 'Alle feeds',
+		'category' => 'Categorie',
+		'entry_count' => 'Invoer aantallen',
+		'entry_per_category' => 'Aantallen per categorie',
+		'entry_per_day' => 'Aantallen per day (laatste 30 dagen)',
+		'entry_per_day_of_week' => 'Per dag of week (gemiddeld: %.2f berichten)',
+		'entry_per_hour' => 'Per uur (gemiddeld: %.2f berichten)',
+		'entry_per_month' => 'Per maand (gemiddeld: %.2f berichten)',
+		'entry_repartition' => 'Invoer verdeling',
+		'feed' => 'Feed',
+		'feed_per_category' => 'Feeds per categorie',
+		'idle' => 'Gepauzeerde feeds',
+		'main' => 'Hoofd statistieken',
+		'main_stream' => 'Overzicht',
+		'menu' => array(
+			'idle' => 'Gepauzeerde feeds',
+			'main' => 'Hoofd statistieken',
+			'repartition' => 'Artikelen verdeling',
+		),
+		'no_idle' => 'Er is geen gepauzeerde feed!',
+		'number_entries' => '%d artikelen',
+		'percent_of_total' => '%% van totaal',
+		'repartition' => 'Artikelen verdeling',
+		'status_favorites' => 'Favorieten',
+		'status_read' => 'Gelezen',
+		'status_total' => 'Totaal',
+		'status_unread' => 'Ongelezen',
+		'title' => 'Statistieken',
+		'top_feed' => 'Top tien feeds',
+	),
+	'update' => array(
+		'_' => 'Versie controle',
+		'apply' => 'Toepassen',
+		'check' => 'Controleer op nieuwe versies',
+		'current_version' => 'Uw huidige versie van FreshRSS is %s.',
+		'last' => 'Laatste controle: %s',
+		'none' => 'Geen nieuwe versie om toe te passen',
+		'title' => 'Vernieuw systeem',
+	),
+	'user' => array(
+		'articles_and_size' => '%s artikelen (%s)',
+		'create' => 'Creëer  nieuwe gebruiker',
+		'email_persona' => 'Log in mail adres<br /><small>(voor <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>',
+		'language' => 'Taal',
+		'number' => 'Er is %d accounts gemaakt',
+		'numbers' => 'Er zijn %d accounts gemaakt',
+		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier log in methode)</small>',
+		'password_format' => 'Ten minste 7 tekens',
+		'registration' => array(
+			'allow' => 'Sta het maken van nieuwe accounts toe',
+			'help' => '0 betekent dat er geen account limiet is',
+			'number' => 'Max aantal van accounts',
+		),
+		'title' => 'Beheer gebruikers',
+		'user_list' => 'Lijst van gebruikers ',
+		'username' => 'Gebruikers naam',
+		'users' => 'Gebruikers',
+	),
+);

+ 174 - 0
app/i18n/nl/conf.php

@@ -0,0 +1,174 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'archiving' => array(
+		'_' => 'Archivering',
+		'advanced' => 'Geavanceerd',
+		'delete_after' => 'Verwijder artikelen na',
+		'help' => 'Meer opties zijn beschikbaar in de persoonlijke stroom instellingen',
+		'keep_history_by_feed' => 'Minimum aantal te behouden artikelen in de feed',
+		'optimize' => 'Optimaliseer database',
+		'optimize_help' => 'Doe dit zo af en toe om de omvang van de database te verkleinen',
+		'purge_now' => 'Schoon nu op',
+		'title' => 'Archivering',
+		'ttl' => 'Vernieuw niet automatisch meer dan',
+	),
+	'display' => array(
+		'_' => 'Opmaak',
+		'icon' => array(
+			'bottom_line' => 'Onderaan',
+			'entry' => 'Artikel pictogrammen',
+			'publication_date' => 'Publicatie datum',
+			'related_tags' => 'Gerelateerde labels',
+			'sharing' => 'Delen',
+			'top_line' => 'Bovenaan',
+		),
+		'language' => 'Taal',
+		'notif_html5' => array(
+			'seconds' => 'seconden (0 betekent geen stop)',
+			'timeout' => 'HTML5 notificatie stop',
+		),
+		'theme' => 'Thema',
+		'title' => 'Opmaak',
+		'width' => array(
+			'content' => 'Inhoud breedte',
+			'large' => 'Breed',
+			'medium' => 'Normaal',
+			'no_limit' => 'Geen limiet',
+			'thin' => 'Smal',
+		),
+	),
+	'query' => array(
+		'_' => 'Gebruikers queries (informatie aanvragen)',
+		'deprecated' => 'Deze query (informatie aanvraag) is niet langer geldig. De bedoelde categorie of feed is al verwijderd.',
+		'filter' => 'Filter toegepast:',
+		'get_all' => 'Toon alle artikelen',
+		'get_category' => 'Toon "%s" categorie',
+		'get_favorite' => 'Toon favoriete artikelen',
+		'get_feed' => 'Toon "%s" feed',
+		'no_filter' => 'Geen filter',
+		'none' => 'U hebt nog geen gebruikers query aangemaakt..',
+		'number' => 'Query n°%d',
+		'order_asc' => 'Toon oudste artikelen eerst',
+		'order_desc' => 'Toon nieuwste artikelen eerst',
+		'search' => 'Zoek naar "%s"',
+		'state_0' => 'Toon alle artikelen',
+		'state_1' => 'Toon gelezen artikelen',
+		'state_2' => 'Toon ongelezen artikelen',
+		'state_3' => 'Toon alle artikelen',
+		'state_4' => 'Toon favoriete artikelen',
+		'state_5' => 'Toon gelezen favoriete artikelen',
+		'state_6' => 'Toon ongelezen favoriete artikelen',
+		'state_7' => 'Toon favoriete artikelen',
+		'state_8' => 'Toon niet favoriete artikelen',
+		'state_9' => 'Toon gelezen niet favoriete artikelen',
+		'state_10' => 'Toon ongelezen niet favoriete artikelen',
+		'state_11' => 'Toon niet favoriete artikelen',
+		'state_12' => 'Toon alle artikelen',
+		'state_13' => 'Toon gelezen artikelen',
+		'state_14' => 'Toon ongelezen artikelen',
+		'state_15' => 'Toon alle artikelen',
+		'title' => 'Gebruikers queries',
+	),
+	'profile' => array(
+		'_' => 'Profiel beheer',
+		'delete' => array(
+			'_' => 'Account verwijderen',
+			'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.',
+		),
+		'email_persona' => 'Log in mail adres<br /><small>(voor <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>',
+		'password_api' => 'Wachtwoord API<br /><small>(e.g., voor mobiele apps)</small>',
+		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier log in methode)</small>',
+		'password_format' => 'Ten minste 7 tekens',
+		'title' => 'Profiel',
+	),
+	'reading' => array(
+		'_' => 'Lezen',
+		'after_onread' => 'Na “markeer alles als gelezen”,',
+		'articles_per_page' => 'Aantal artikelen per pagina',
+		'auto_load_more' => 'Laad volgende artikel onderaan de pagina',
+		'auto_remove_article' => 'Verberg artikel na lezen',
+		'confirm_enabled' => 'Toon een bevestigings dialoog op “markeer alles als gelezen” acties',
+		'display_articles_unfolded' => 'Toon artikelen uitgeklapt als standaard',
+		'display_categories_unfolded' => 'Toon categoriën ingeklapt als standaard',
+		'hide_read_feeds' => 'Verberg categoriën en feeds zonder ongelezen artikelen (werkt niet met “Toon alle artikelen” configuratie)',
+		'img_with_lazyload' => 'Gebruik "lazy load" methode om afbeeldingen te laden',
+		'jump_next' => 'Ga naar volgende ongelezen (feed of categorie)',
+		'mark_updated_article_unread' => 'Markeer vernieuwd artikel als ongelezen',
+		'number_divided_when_reader' => 'Gedeeld door 2 in de lees modus.',
+		'read' => array(
+			'article_open_on_website' => 'Als het artikel is geopend op de originele website',
+			'article_viewed' => 'Als het artikel is bekeken',
+			'scroll' => 'Tijdens scrollen',
+			'upon_reception' => 'Tijdens ontvangst van het artikel',
+			'when' => 'Markeer artikel als gelezen…',
+		),
+		'show' => array(
+			'_' => 	'Artikelen om te tonen',
+			'adaptive' => 'Pas weergave aan',
+			'all_articles' => 'Bekijk alle artikelen',
+			'unread' => 'Bekijk alleen ongelezen',
+		),
+		'sort' => array(
+			'_' => 'Sorteer volgorde',
+			'newer_first' => 'Nieuwste eerst',
+			'older_first' => 'Oudste eerst',
+		),
+		'sticky_post' => 'Koppel artikel aan de bovenkant als het geopend wordt',
+		'title' => 'Lees modus',
+		'view' => array(
+			'default' => 'Standaard weergave',
+			'global' => 'Globale weergave',
+			'normal' => 'Normale weergave',
+			'reader' => 'Lees weergave',
+		),
+	),
+	'sharing' => array(
+		'_' => 'Delen',
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Email',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'more_information' => 'Meer informatie',
+		'print' => 'Afdrukken',
+		'shaarli' => 'Shaarli',
+		'share_name' => 'Gedeelde naam om weer te geven',
+		'share_url' => 'Deel URL voor gebruik',
+		'title' => 'Delen',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag',
+	),
+	'shortcut' => array(
+		'_' => 'Shortcuts',
+		'article_action' => 'Artikel acties',
+		'auto_share' => 'Delen',
+		'auto_share_help' => 'Als er slechts één deel methode i, dan wordt deze gebruikt. Anders zijn ze toegankelijk met hun nummer.',
+		'close_dropdown' => 'Sluit menu',
+		'collapse_article' => 'Inklappen',
+		'first_article' => 'Spring naar eerste artikel',
+		'focus_search' => 'Toegang zoek venster',
+		'help' => 'Toon documentatie',
+		'javascript' => 'JavaScript moet geactiveerd zijn om verwijzingen te gebruiken',
+		'last_article' => 'Spring naar laatste artikel',
+		'load_more' => 'Laad meer artikelen',
+		'mark_read' => 'Markeer als gelezen',
+		'mark_favorite' => 'Markeer als favoriet',
+		'navigation' => 'Navigatie',
+		'navigation_help' => 'Met de "Shift" toets, kunt u navigatie verwijzingen voor feeds gebruiken.<br/>Met de "Alt" toets, kunt u navigatie verwijzingen voor categoriën gebruiken.',
+		'next_article' => 'Spring naar volgende artikel',
+		'other_action' => 'Andere acties',
+		'previous_article' => 'Spring naar vorige artikel',
+		'see_on_website' => 'Bekijk op originale website',
+		'shift_for_all_read' => '+ <code>shift</code> om alle artikelen als gelezen te markeren',
+		'title' => 'Verwijzingen',
+		'user_filter' => 'Toegang gebruikers filters',
+		'user_filter_help' => 'Als er slechts één gebruikers filter s, dan wordt deze gebruikt. Anders zijn ze toegankelijk met hun nummer.',
+	),
+	'user' => array(
+		'articles_and_size' => '%s artikelen (%s)',
+		'current' => 'Huidige gebruiker',
+		'is_admin' => 'is administrateur',
+		'users' => 'Gebruikers',
+	),
+);

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

@@ -0,0 +1,111 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'admin' => array(
+		'optimization_complete' => 'Optimalisatie compleet',
+	),
+	'access' => array(
+		'denied' => 'U hebt geen rechten om deze pagina te bekijken.',
+		'not_found' => 'Deze pagina bestaat niet',
+	),
+	'auth' => array(
+		'form' => array(
+			'not_set' => 'Een probleem is opgetreden tijdens de controle van de systeem configuratie. Probeer het later nog eens.',
+			'set' => 'Formulier is nu uw standaard authenticatie systeem.',
+		),
+		'login' => array(
+			'invalid' => 'Log in is ongeldig',
+			'success' => 'U bent ingelogd',
+		),
+		'logout' => array(
+			'success' => 'U bent uitgelogd',
+		),
+		'no_password_set' => 'Administrateur wachtwoord is niet ingesteld. Deze mogelijkheid is niet beschikbaar.',
+		'not_persona' => 'Alleen Persona systeem kan worden gereset.',
+	),
+	'conf' => array(
+		'error' => 'Er is een fout opgetreden tijdens het opslaan van de configuratie',
+		'query_created' => 'Query "%s" is gemaakt.',
+		'shortcuts_updated' => 'Verwijzingen zijn vernieuwd',
+		'updated' => 'Configuratie is vernieuwd',
+	),
+	'extensions' => array(
+		'already_enabled' => '%s is al ingeschakeld',
+		'disable' => array(
+			'ko' => '%s kan niet worden uitgeschakeld. <a href="%s">Controleer FressRSS log bestanden</a> voor details.',
+			'ok' => '%s is nu uitgeschakeld',
+		),
+		'enable' => array(
+			'ko' => '%s kan niet worden ingeschakeld. <a href="%s">Controleer FressRSS log bestanden</a> voor details.',
+			'ok' => '%s is nn ingeschakeld',
+		),
+		'no_access' => 'U hebt geen toegang voor %s',
+		'not_enabled' => '%s is nog niet ingeschakeld',
+		'not_found' => '%s bestaat niet',
+	),
+	'import_export' => array(
+		'export_no_zip_extension' => 'Zip uitbreiding is niet aanwezig op uw server. Exporteer a.u.b. uw bestanden één voor één.',
+		'feeds_imported' => 'Uw feeds zijn geimporteerd en worden nu vernieuwd',
+		'feeds_imported_with_errors' => 'Uw feeds zijn geimporteerd maar er zijn enige fouten opgetreden',
+		'file_cannot_be_uploaded' => 'Bestand kan niet worden verzonden!',
+		'no_zip_extension' => 'Zip uitbreiding is niet aanwezig op uw server.',
+		'zip_error' => 'Er is een fout opgetreden tijdens het imporeren van het Zip bestand.',
+	),
+	'sub' => array(
+		'actualize' => 'Actualiseren',
+		'category' => array(
+			'created' => 'Categorie %s is gemaakt.',
+			'deleted' => 'Categorie is verwijderd.',
+			'emptied' => 'Categorie is leeg gemaakt',
+			'error' => 'Categorie kan niet worden vernieuwd',
+			'name_exists' => 'Categorie naam bestaat al.',
+			'no_id' => 'U moet de id specificeren of de categorie.',
+			'no_name' => 'Categorie naam mag niet leeg zijn.',
+			'not_delete_default' => 'U kunt de standaard categorie niet verwijderen!',
+			'not_exist' => 'De categorie bestaat niet!',
+			'over_max' => 'U hebt het maximale aantal categoriën bereikt (%d)',
+			'updated' => 'Categorie is vernieuwd.',
+		),
+		'feed' => array(
+			'actualized' => '<em>%s</em> is vernieuwd',
+			'actualizeds' => 'RSS feeds zijn vernieuwd',
+			'added' => 'RSS feed <em>%s</em> is toegevoegd',
+			'already_subscribed' => 'U bent al geabonneerd op <em>%s</em>',
+			'deleted' => 'Feed is verwijderd',
+			'error' => 'Feed kan niet worden vernieuwd',
+			'internal_problem' => 'De RSS feed kon niet worden toegevoegd. <a href="%s">Controleer FressRSS log bestanden</a> voor details.',
+			'invalid_url' => 'URL <em>%s</em> is ongeldig',
+			'marked_read' => 'Feeds zijn gemarkeerd als gelezen',
+			'n_actualized' => '%d feeds zijn vernieuwd',
+			'n_entries_deleted' => '%d artikelen zijn verwijderd',
+			'no_refresh' => 'Er is geen feed om te vernieuwen…',
+			'not_added' => '<em>%s</em> kon niet worden toegevoegd',
+			'over_max' => 'U hebt het maximale aantal feeds bereikt(%d)',
+			'updated' => 'Feed is vernieuwd',
+		),
+		'purge_completed' => 'Opschonen klaar (%d artikelen verwijderd)',
+	),
+	'update' => array(
+		'can_apply' => 'FreshRSS word nu vernieud naar <strong>versie %s</strong>.',
+		'error' => 'Het vernieuwingsproces kwam een fout tegen: %s',
+		'file_is_nok' => 'Controleer permissies op <em>%s</em> map. HTTP server moet rechten hebben om er in te schrijven',
+		'finished' => 'Vernieuwing compleet!',
+		'none' => 'Geen vernieuwing om toe te passen',
+		'server_not_found' => 'Vernieuwings server kan niet worden gevonden. [%s]',
+	),
+	'user' => array(
+		'created' => array(
+			'_' => 'Gebruiker %s is aangemaakt',
+			'error' => 'Gebruiker %s kan niet worden aangemaakt',
+		),
+		'deleted' => array(
+			'_' => 'Gebruiker %s is verwijderd',
+			'error' => 'Gebruiker %s kan niet worden verwijderd',
+		),
+		'set_registration' => 'Het maximale aantal accounts is vernieuwd.',
+	),
+	'profile' => array(
+		'error' => 'Uw profiel kan niet worden aangepast',
+		'updated' => 'Uw profiel is aangepast',
+	),
+);

+ 178 - 0
app/i18n/nl/gen.php

@@ -0,0 +1,178 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'action' => array(
+		'actualize' => 'Actualiseren',
+		'back_to_rss_feeds' => '← Ga terug naar je RSS feeds',
+		'cancel' => 'Annuleren',
+		'create' => 'Opslaan',
+		'disable' => 'Uitzetten',
+		'empty' => 'Leeg',
+		'enable' => 'Aanzetten',
+		'export' => 'Exporteren',
+		'filter' => 'Filteren',
+		'import' => 'Importeren',
+		'manage' => 'Beheren',
+		'mark_read' => 'Markeer als gelezen',
+		'mark_favorite' => 'Markeer als favoriet',
+		'remove' => 'Verwijder',
+		'see_website' => 'Bekijk website',
+		'submit' => 'Opslaan',
+		'truncate' => 'Verwijder alle artikelen',
+	),
+	'auth' => array(
+		'email' => 'Email adres',
+		'keep_logged_in' => 'Ingelogd blijven voor <small>(1 maand)</small>',
+		'login' => 'Log in',
+		'login_persona' => 'Login met Persona',
+		'login_persona_problem' => 'Connectiviteits problemen met Persona',
+		'logout' => 'Log uit',
+		'password' => array(
+			'_' => 'Wachtwoord',
+			'format' => '<small>Ten minste 7 tekens</small>',
+		),
+		'registration' => array(
+			'_' => 'Nieuw account',
+			'ask' => 'Maak een account?',
+			'title' => 'Account maken',
+		),
+		'reset' => 'Authenticatie reset',
+		'username' => array(
+			'_' => 'Gebruikersnaam',
+			'admin' => 'Administrator gebruikersnaam',
+			'format' => '<small>maximaal 16 alphanumerieke tekens</small>',
+		),
+		'will_reset' => 'Het authenticatie system zal worden gereset: een formulier zal worden gebruikt in plaats van Persona.',
+	),
+	'date' => array(
+		'Apr' => '\\A\\p\\r\\i\\l',
+		'Aug' => '\\A\\u\\g\\u\\s\\t\\u\\s',
+		'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r',
+		'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\i',
+		'Jan' => '\\J\\a\\n\\u\\a\\r\\i',
+		'Jul' => '\\J\\u\\l\\i',
+		'Jun' => '\\J\\u\\n\\i',
+		'Mar' => '\\M\\a\\a\\r\\t',
+		'May' => '\\M\\e\\i',
+		'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r',
+		'Oct' => '\\O\\k\\t\\o\\b\\e\\r',
+		'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r',
+		'apr' => 'apr',
+		'april' => 'Apr',
+		'aug' => 'aug',
+		'august' => 'Aug',
+		'before_yesterday' => 'Ouder',
+		'dec' => 'dec',
+		'december' => 'Dec',
+		'feb' => 'feb',
+		'february' => 'Feb',
+		'format_date' => 'j %s Y', //<-- European date format // 'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y',
+		'format_date_hour' => 'j %s Y \\o\\m H\\:i', //<-- European date format // 'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i',
+		'fri' => 'Vr',
+		'jan' => 'jan',
+		'january' => 'Jan',
+		'jul' => 'jul',
+		'july' => 'Jul',
+		'jun' => 'jun',
+		'june' => 'Jun',
+		'last_3_month' => 'Laatste drie maanden',
+		'last_6_month' => 'Laatste zes maanden',
+		'last_month' => 'Vorige maand',
+		'last_week' => 'Vorige week',
+		'last_year' => 'Vorig jaar',
+		'mar' => 'mar',
+		'march' => 'Mar',
+		'may' => 'Mei',
+		'mon' => 'Ma',
+		'month' => 'maanden',
+		'nov' => 'nov',
+		'november' => 'Nov',
+		'oct' => 'okt',
+		'october' => 'Okt',
+		'sat' => 'Za',
+		'sep' => 'sep',
+		'september' => 'Sep',
+		'sun' => 'Zo',
+		'thu' => 'Do',
+		'today' => 'Vandaag',
+		'tue' => 'Di',
+		'wed' => 'Wo',
+		'yesterday' => 'Gisteren',
+	),
+	'freshrss' => array(
+		'_' => 'FreshRSS',
+		'about' => 'Over FreshRSS',
+	),
+	'js' => array(
+		'category_empty' => 'Lege categorie',
+		'confirm_action' => 'Weet u zeker dat u dit wilt doen? Het kan niet ongedaan worden gemaakt!',
+		'confirm_action_feed_cat' => 'Weet u zeker dat u dit wilt doen? U verliest alle gereleteerde favorieten en gebruikers informatie. Het kan niet ongedaan worden gemaakt!',
+		'feedback' => array(
+			'body_new_articles' => 'Er zijn \\d nieuwe artikelen om te lezen op FreshRSS.',
+			'request_failed' => 'Een opdracht is mislukt, mogelijk door Internet verbindings problemen.',
+			'title_new_articles' => 'FreshRSS: nieuwe artikelen!',
+		),
+		'new_article' => 'Er zijn nieuwe artikelen beschikbaar, klik om de pagina te vernieuwen.',
+		'should_be_activated' => 'JavaScript moet aan staan',
+	),
+	'lang' => array(
+		'cz' => 'Čeština',
+		'de' => 'Deutsch',
+		'en' => 'English',
+		'fr' => 'Français',
+		'nl' => 'Nederlands',
+	),
+	'menu' => array(
+		'about' => 'Over',
+		'admin' => 'Administratie',
+		'archiving' => 'Archiveren',
+		'authentication' => 'Authenticatie',
+		'check_install' => 'Installatie controle',
+		'configuration' => 'Configuratie',
+		'display' => 'Opmaak',
+		'extensions' => 'Uitbreidingen',
+		'logs' => 'Log boeken',
+		'queries' => 'Gebruikers informatie',
+		'reading' => 'Lezen',
+		'search' => 'Zoek woorden of #labels',
+		'sharing' => 'Delen',
+		'shortcuts' => 'Snelle toegang',
+		'stats' => 'Statistieken',
+		'update' => 'Versie controle',
+		'user_management' => 'Beheer gebruikers',
+		'user_profile' => 'Profiel',
+	),
+	'pagination' => array(
+		'first' => 'Eerste',
+		'last' => 'Laatste',
+		'load_more' => 'Laad meer artikelen',
+		'mark_all_read' => 'Markeer alle als gelezen',
+		'next' => 'Volgende',
+		'nothing_to_load' => 'Er zijn geen artikelen meer',
+		'previous' => 'Vorige',
+	),
+	'share' => array(
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Email',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'print' => 'Print',
+		'shaarli' => 'Shaarli',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag',
+	),
+	'short' => array(
+		'attention' => 'Attentie!',
+		'blank_to_disable' => 'Laat leeg om uit te zetten',
+		'by_author' => 'Door <em>%s</em>',
+		'by_default' => 'Door standaard',
+		'damn' => 'Potverdorie!',
+		'default_category' => 'Niet ingedeeld',
+		'no' => 'Nee',
+		'not_applicable' => 'Niet aanwezig',
+		'ok' => 'Ok!',
+		'or' => 'of',
+		'yes' => 'Ja',
+	),
+);

+ 61 - 0
app/i18n/nl/index.php

@@ -0,0 +1,61 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'about' => array(
+		'_' => 'Over',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+		'bugs_reports' => 'Rapporteer fouten',
+		'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://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Favicons zijn verzameld met de <a href="https://getfavicon.appspot.com/">getFavicon API</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>.',
+		'freshrss_description' => 'FreshRSS is een RSS feed aggregator om zelf te hosten zoals <a href="http://tontof.net/kriss/feed/">Kriss Feed</a> of <a href="http://projet.idleman.fr/leed/">Leed</a>. Het gebruikt weinig systeembronnen en is makkelijk te administreren terwijl het een krachtig en makkelijk te configureren programma is.',
+		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">op Github</a>',
+		'license' => 'License',
+		'project_website' => 'Project website',
+		'title' => 'Over',
+		'version' => 'Versie',
+		'website' => 'Website',
+	),
+	'feed' => array(
+		'add' => 'U kunt wat feeds toevoegen.',
+		'empty' => 'Er is geen artikel om te laten zien.',
+		'rss_of' => 'RSS feed van %s',
+		'title' => 'Overzicht RSS feeds',
+		'title_global' => 'Globale weergave',
+		'title_fav' => 'Uw favorieten',
+	),
+	'log' => array(
+		'_' => 'Log bestanden',
+		'clear' => 'Leeg de log bestanden',
+		'empty' => 'Log bestand is leeg',
+		'title' => 'Log bestanden',
+	),
+	'menu' => array(
+		'about' => 'Over FreshRSS',
+		'add_query' => 'Voeg een query toe',
+		'before_one_day' => 'Ouder als een dag',
+		'before_one_week' => 'Ouder als een week',
+		'favorites' => 'Favorieten (%s)',
+		'global_view' => 'Globale weergave',
+		'main_stream' => 'Overzicht',
+		'mark_all_read' => 'Markeer alles als gelezen',
+		'mark_cat_read' => 'Markeer categorie als gelezen',
+		'mark_feed_read' => 'Markeer feed als gelezen',
+		'newer_first' => 'Nieuwste eerst',
+		'non-starred' => 'Laat alles zien behalve favorieten',
+		'normal_view' => 'Normale weergave',
+		'older_first' => 'Oudste eerst',
+		'queries' => 'Gebruikers queries',
+		'read' => 'Laat alleen gelezen zien',
+		'reader_view' => 'Lees modus',
+		'rss_view' => 'RSS feed',
+		'search_short' => 'Zoeken',
+		'starred' => 'Laat alleen favorieten zien',
+		'stats' => 'Statistieken',
+		'subscription' => 'Abonnementen beheer',
+		'unread' => 'Laat alleen ongelezen zien',
+	),
+	'share' => 'Delen',
+	'tag' => array(
+		'related' => 'Verwante labels',
+	),
+);

+ 113 - 0
app/i18n/nl/install.php

@@ -0,0 +1,113 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'action' => array(
+		'finish' => 'Completeer installatie',
+		'fix_errors_before' => 'Repareer de fouten alvorens naar de volgende stap te gaan.',
+		'keep_install' => 'Behoud de vorige installatie',
+		'next_step' => 'Ga naar de volgende stap',
+		'reinstall' => 'Installeer FreshRSS opnieuw',
+	),
+	'auth' => array(
+		'email_persona' => 'Log in mail adres<br /><small>(voor <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>',
+		'form' => 'Web formulier (traditioneel, benodigd JavaScript)',
+		'http' => 'HTTP (voor geavanceerde gebruikers met HTTPS)',
+		'none' => 'Geen (gevaarlijk)',
+		'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier log in methode)</small>',
+		'password_format' => 'Tenminste 7 tekens',
+		'persona' => 'Mozilla Persona (modern, benodigd JavaScript)',
+		'type' => 'Authenticatie methode',
+	),
+	'bdd' => array(
+		'_' => 'Database',
+		'conf' => array(
+			'_' => 'Database configuratie',
+			'ko' => 'Controleer uw database informatie.',
+			'ok' => 'Database configuratie is opgeslagen.',
+		),
+		'host' => 'Host',
+		'prefix' => 'Tabel voorvoegsel',
+		'password' => 'HTTP wachtwoord',
+		'type' => 'Type database',
+		'username' => 'HTTP gebruikersnaam',
+	),
+	'check' => array(
+		'_' => 'Controles',
+		'already_installed' => 'We hebben geconstateerd dat FreshRSS al is geïnstallerd!',
+		'cache' => array(
+			'nok' => 'Controleer permissies van de <em>./data/cache</em> map. HTTP server moet rechten hebben om er in te kunnen schrijven',
+			'ok' => 'Permissies van de cache map zijn goed.',
+		),
+		'ctype' => array(
+			'nok' => 'U mist een benodigde bibliotheek voor character type checking (php-ctype).',
+			'ok' => 'U hebt de benodigde bibliotheek voor character type checking (ctype).',
+		),
+		'curl' => array(
+			'nok' => 'U mist cURL (php5-curl package).',
+			'ok' => 'U hebt de cURL uitbreiding.',
+		),
+		'data' => array(
+			'nok' => 'Controleer permissies van de <em>./data</em> map. HTTP server moet rechten hebben om er in te kunnen schrijven',
+			'ok' => 'Permissies van de data map zijn goed.',
+		),
+		'dom' => array(
+			'nok' => 'U mist een benodigde bibliotheek om te bladeren in de DOM (php-xml package).',
+			'ok' => 'U hebt de benodigde bibliotheek om te bladeren in de DOM.',
+		),
+		'favicons' => array(
+			'nok' => 'Controleer permissies van de <em>./data/favicons</em> map. HTTP server moet rechten hebben om er in te kunnen schrijven',
+			'ok' => 'Permissies van de favicons map zijn goed.',
+		),
+		'http_referer' => array(
+			'nok' => 'Controleer a.u.b. dat u niet uw HTTP REFERER wijzigd.',
+			'ok' => 'Uw HTTP REFERER is bekend en komt overeen met uw server.',
+		),
+		'minz' => array(
+			'nok' => 'U mist het Minz framework.',
+			'ok' => 'U hebt het Minz framework.',
+		),
+		'pcre' => array(
+			'nok' => 'U mist een benodigde bibliotheek voor regular expressions (php-pcre).',
+			'ok' => 'U hebt de benodigde bibliotheek voor regular expressions (PCRE).',
+		),
+		'pdo' => array(
+			'nok' => 'U mist PDO of één van de ondersteunde (pdo_mysql, pdo_sqlite).',
+			'ok' => 'U hebt PDO en ten minste één van de ondersteunde drivers (pdo_mysql, pdo_sqlite).',
+		),
+		'persona' => array(
+			'nok' => 'Controleer permissies van de <em>./data/persona</em> map. HTTP server moet rechten hebben om er in te kunnen schrijven',
+			'ok' => 'Permissies van de Mozilla Persona map zijn goed.',
+		),
+		'php' => array(
+			'nok' => 'Uw PHP versie is %s maar FreshRSS benodigd tenminste versie %s.',
+			'ok' => 'Uw PHP versie is %s, welke compatibel is met FreshRSS.',
+		),
+		'users' => array(
+			'nok' => 'Controleer permissies van de <em>./data/users</em> map. HTTP server moet rechten hebben om er in te kunnen schrijven',
+			'ok' => 'Permissies van de users map zijn goed.',
+		),
+	),
+	'conf' => array(
+		'_' => 'Algemene configuratie',
+		'ok' => 'Algemene configuratie is opgeslagen.',
+	),
+	'congratulations' => 'Gefeliciteerd!',
+	'default_user' => 'Gebruikersnaam van de standaard gebruiker <small>(maximaal 16 alphanumerieke tekens)</small>',
+	'delete_articles_after' => 'Verwijder artikelen na',
+	'fix_errors_before' => 'Repareer fouten alvorens U naar de volgende stap gaat.',
+	'javascript_is_better' => 'FreshRSS werkt beter JavaScript ingeschakeld',
+	'js' => array(
+		'confirm_reinstall' => 'U verliest uw vorige configuratie door FreshRSS opnieuw te installeren. Weet u zeker dat u verder wilt gaan?',
+	),
+	'language' => array(
+		'_' => 'Taal',
+		'choose' => 'Kies een taal voor FreshRSS',
+		'defined' => 'Taal is bepaald.',
+	),
+	'not_deleted' => 'Er ging iets fout! U moet het bestand <em>%s</em> handmatig verwijderen.',
+	'ok' => 'De installatie procedure is geslaagd.',
+	'step' => 'stap %d',
+	'steps' => 'Stappen',
+	'title' => 'Installatie · FreshRSS',
+	'this_is_the_end' => 'Dit is het einde',
+);

+ 62 - 0
app/i18n/nl/sub.php

@@ -0,0 +1,62 @@
+<?php
+/* Dutch translation by Wanabo. http://www.nieuwskop.be */
+return array(
+	'category' => array(
+		'_' => 'Categorie',
+		'add' => 'Voeg categorie toe',
+		'empty' => 'Lege categorie',
+		'new' => 'Nieuwe categorie',
+	),
+	'feed' => array(
+		'add' => 'Voeg een RSS feed toe',
+		'advanced' => 'Geavanceerd',
+		'archiving' => 'Archiveren',
+		'auth' => array(
+			'configuration' => 'Log in',
+			'help' => 'Verbinding toestaan toegang te krijgen tot HTTP beveiligde RSS feeds',
+			'http' => 'HTTP Authenticatie',
+			'password' => 'HTTP wachtwoord',
+			'username' => 'HTTP gebruikers naam',
+		),
+		'css_help' => 'Haalt verstoorde RSS feeds op (attentie, heeft meer tijd nodig!)',
+		'css_path' => 'Artikelen CSS pad op originele website',
+		'description' => 'Omschrijving',
+		'empty' => 'Deze feed is leeg. Controleer of deze nog actueel is.',
+		'error' => 'Deze feed heeft problemen. Verifieer a.u.b het doeladres en actualiseer het.',
+		'in_main_stream' => 'Zichtbaar in het overzicht',
+		'informations' => 'Informatie',
+		'keep_history' => 'Minimum aantal artikelen om te houden',
+		'moved_category_deleted' => 'Als u een categorie verwijderd, worden de feeds automatisch geclassificeerd onder <em>%s</em>.',
+		'no_selected' => 'Geen feed geselecteerd.',
+		'number_entries' => '%d artikelen',
+		'pubsubhubbub' => 'Directe notificaties met PubSubHubbub',
+		'stats' => 'Statistieken',
+		'think_to_add' => 'Voeg wat feeds toe.',
+		'title' => 'Titel',
+		'title_add' => 'Voeg een RSS feed toe',
+		'ttl' => 'Vernieuw automatisch niet vaker dan',
+		'url' => 'Feed URL',
+		'validator' => 'Controleer de geldigheid van de feed',
+		'website' => 'Website URL',
+	),
+	'import_export' => array(
+		'export' => 'Exporteer',
+		'export_opml' => 'Exporteer lijst van feeds (OPML)',
+		'export_starred' => 'Exporteer je fovorieten',
+		'feed_list' => 'Lijst van %s artikelen',
+		'file_to_import' => 'Bestand om te importeren<br />(OPML, Json of Zip)',
+		'file_to_import_no_zip' => 'Bestand om te importeren<br />(OPML of Json)',
+		'import' => 'Importeer',
+		'starred_list' => 'Lijst van favoriete artikelen',
+		'title' => 'Importeren / exporteren',
+	),
+	'menu' => array(
+		'bookmark' => 'Abonneer (FreshRSS bladwijzer)',
+		'import_export' => 'Importeer / exporteer',
+		'subscription_management' => 'Abonnementen beheer',
+	),
+	'title' => array(
+		'_' => 'Abonnementen beheer',
+		'feed_management' => 'RSS feed beheer',
+	),
+);

+ 3 - 0
app/layout/aside_configure.phtml

@@ -27,6 +27,9 @@
 	</li>
 	<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
 	<li class="nav-header"><?php echo _t('gen.menu.admin'); ?></li>
+	<li class="item<?php echo Minz_Request::actionName() === 'system' ? ' active' : ''; ?>">
+		<a href="<?php echo _url('configure', 'system')?>"><?php echo _t('gen.menu.system'); ?></a>
+	</li>
 	<li class="item<?php echo Minz_Request::controllerName() === 'user' &&
 	                          Minz_Request::actionName() === 'manage' ? ' active' : ''; ?>">
 		<a href="<?php echo _url('user', 'manage'); ?>"><?php echo _t('gen.menu.user_management'); ?></a>

+ 1 - 0
app/layout/header.phtml

@@ -67,6 +67,7 @@ if (FreshRSS_Auth::accessNeedsAction()) {
 				<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
 				<li class="separator"></li>
 				<li class="dropdown-header"><?php echo _t('gen.menu.admin'); ?></li>
+				<li class="item"><a href="<?php echo _url('configure', 'system'); ?>"><?php echo _t('gen.menu.system'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('user', 'manage'); ?>"><?php echo _t('gen.menu.user_management'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('auth', 'index'); ?>"><?php echo _t('gen.menu.authentication'); ?></a></li>
 				<li class="item"><a href="<?php echo _url('update', 'checkInstall'); ?>"><?php echo _t('gen.menu.check_install'); ?></a></li>

+ 54 - 0
app/views/configure/system.phtml

@@ -0,0 +1,54 @@
+<?php $this->partial('aside_configure'); ?>
+
+<div class="post">
+	<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('gen.action.back_to_rss_feeds'); ?></a>
+
+	<form method="post" action="<?php echo _url('configure', 'system'); ?>">
+		<legend><?php echo _t('admin.system'); ?></legend>
+
+		<div class="form-group">
+			<label class="group-name" for="instance-name"><?php echo _t('admin.system.instance-name'); ?></label>
+			<div class="group-controls">
+			    <input type="text" id="max-feeds" name="instance-name" value="<?php echo FreshRSS_Context::$system_conf->title; ?>" min="1" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->title; ?>"/>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="max-registrations"><?php echo _t('admin.system.registration.number'); ?></label>
+			<div class="group-controls">
+				<input type="number" id="max-registrations" name="max-registrations" value="<?php echo FreshRSS_Context::$system_conf->limits['max_registrations']; ?>" min="0" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['max_registrations']; ?>"/>
+				<?php echo _i('help'); ?> <?php echo _t('admin.system.registration.help'); ?>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<div class="group-controls">
+				<?php
+					$number = count(listUsers());
+					echo _t($number > 1 ? 'admin.user.numbers' : 'admin.user.number', $number);
+				?>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="max-feeds"><?php echo _t('admin.system.max-feeds'); ?></label>
+			<div class="group-controls">
+			    <input type="number" id="max-feeds" name="max-feeds" value="<?php echo FreshRSS_Context::$system_conf->limits['max_feeds']; ?>" min="1" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['max_feeds']; ?>"/>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="max-categories"><?php echo _t('admin.system.max-categories'); ?></label>
+			<div class="group-controls">
+			    <input type="number" id="max-categories" name="max-categories" value="<?php echo FreshRSS_Context::$system_conf->limits['max_categories']; ?>" min="1" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['max_categories']; ?>"/>
+			</div>
+		</div>
+
+		<div class="form-group form-actions">
+			<div class="group-controls">
+				<button type="submit" class="btn btn-important"><?php echo _t('gen.action.submit'); ?></button>
+				<button type="reset" class="btn"><?php echo _t('gen.action.cancel'); ?></button>
+			</div>
+		</div>
+	</form>
+</div>

+ 1 - 1
app/views/helpers/index/normal/entry_bottom.phtml

@@ -71,7 +71,7 @@
 			<ul class="dropdown-menu">
 				<li class="dropdown-close"><a href="#close">❌</a></li><?php
 				foreach($tags as $tag) {
-					?><li class="item"><a href="<?php echo _url('index', 'index', 'search', urlencode('#' . $tag)); ?>"><?php echo $tag; ?></a></li><?php
+					?><li class="item"><a href="<?php echo _url('index', 'index', 'search', '#' . htmlspecialchars_decode($tag)); ?>"><?php echo $tag; ?></a></li><?php
 				} ?>
 			</ul>
 		</div>

+ 5 - 1
app/views/index/normal.phtml

@@ -56,7 +56,11 @@ if (!empty($this->entries)) {
 			?></div><?php
 			$display_others = false;
 		}
-	?><div class="flux<?php echo !$this->entry->isRead() ? ' not_read' : ''; ?><?php echo $this->entry->isFavorite() ? ' favorite' : ''; ?>" id="flux_<?php echo $this->entry->id(); ?>"><?php
+	?><div class="flux<?php echo !$this->entry->isRead() ? ' not_read' : '';
+		?><?php echo $this->entry->isFavorite() ? ' favorite' : '';
+		?>" id="flux_<?php echo $this->entry->id();
+		?>" data-feed="<?php echo $this->feed->id();
+		?>"><?php
 
 			$this->renderHelper('index/normal/entry_header');
 

+ 0 - 28
app/views/user/manage.phtml

@@ -3,34 +3,6 @@
 <div class="post">
 	<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('gen.action.back_to_rss_feeds'); ?></a>
 
-	<form method="post" action="<?php echo _url('user', 'setRegistration'); ?>">
-		<legend><?php echo _t('admin.user.registration.allow'); ?></legend>
-
-		<div class="form-group">
-			<label class="group-name" for="max-registrations"><?php echo _t('admin.user.registration.number'); ?></label>
-			<div class="group-controls">
-				<input type="number" id="max-registrations" name="max-registrations" value="<?php echo FreshRSS_Context::$system_conf->limits['max_registrations']; ?>" min="0" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['max_registrations']; ?>"/>
-				<?php echo _i('help'); ?> <?php echo _t('admin.user.registration.help'); ?>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<div class="group-controls">
-				<?php
-					$number = count(listUsers());
-					echo _t($number > 1 ? 'admin.user.numbers' : 'admin.user.number', $number);
-				?>
-			</div>
-		</div>
-
-		<div class="form-group form-actions">
-			<div class="group-controls">
-				<button type="submit" class="btn btn-important"><?php echo _t('gen.action.submit'); ?></button>
-				<button type="reset" class="btn"><?php echo _t('gen.action.cancel'); ?></button>
-			</div>
-		</div>
-	</form>
-
 	<form method="post" action="<?php echo _url('user', 'create'); ?>">
 		<legend><?php echo _t('admin.user.create'); ?></legend>
 

+ 1 - 1
constants.php

@@ -1,5 +1,5 @@
 <?php
-define('FRESHRSS_VERSION', '1.1.2-beta');
+define('FRESHRSS_VERSION', '1.1.3-beta');
 define('FRESHRSS_WEBSITE', 'http://freshrss.org');
 define('FRESHRSS_UPDATE_WEBSITE', 'https://update.freshrss.org?v=' . FRESHRSS_VERSION);
 define('FRESHRSS_WIKI', 'http://doc.freshrss.org');

+ 4 - 2
lib/Minz/Session.php

@@ -66,8 +66,10 @@ class Minz_Session {
 	 */
 	public static function keepCookie($l) {
 		// Get the script_name (e.g. /p/i/index.php) and keep only the path.
-		$cookie_dir = empty($_SERVER['SCRIPT_NAME']) ? '' : $_SERVER['SCRIPT_NAME'];
-		$cookie_dir = dirname($cookie_dir);
+		$cookie_dir = empty($_SERVER['REQUEST_URI']) ? '/' : $_SERVER['REQUEST_URI'];
+		if (substr($cookie_dir, -1) !== '/') {
+			$cookie_dir = dirname($cookie_dir) . '/';
+		}
 		session_set_cookie_params($l, $cookie_dir, '', false, true);
 	}