aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGravatar PeterVavercak <168563044+PeterVavercak@users.noreply.github.com> 2026-02-01 13:12:47 +0100
committerGravatar GitHub <noreply@github.com> 2026-02-01 13:12:47 +0100
commitee7eb67f3c2e7795c51da95e770eb2d34e93a546 (patch)
tree29f280996e9ef28ea3fcf050ffb8feea6500d5a9 /app
parent5beebfcd45d48b9afde09694c85d04bfa71c14d5 (diff)
Implement sort order per feed (#8234)
* added local feed sorting Addresses https://github.com/FreshRSS/FreshRSS/issues/4761 - Added number of sorted feeds and associative array for feed sorting option in Context. - Number of sorted feeds and local sorting option by its index saved into Minz Request Parameters. - Number of sorted feeds and local sorting options deleted when choosing another Option Of Global Sorting. - Added option of allowing sorting by feed in configuration. - Added variable for allowing local sorting in userConf. - Added function to get feeds by current get in context. - Added menu button for all individual feed sorting. - New database options for individual feed sorting in EntryDAO. - Considered choosing new entries based on chosen load limit. - Local sorting parameter saved into continuation value in Index Controller. How to test the feature manually: 1. At the bottom of Reading Configuration menu turn on individual sorting option menu 2. Choose Sorting by feed option 3. Choose feed at next sorting menu and choose sorting option for that feed * added feed sorting option * added sort feeds display * added template for sort feed name * added title to feed sorting button * added comments * added local sorting option * Added Docs * css reset * added getter and seter for local sort * added getter and seter for local sort * allowed sorting per feed * allowed sorting per feed * added sorting option for category * deleted changes from NetryDAO * add setting up sorting for category * docs reset * i18 reset * updated i18 for category * added i18 for categories * added i18 for category * added setting sorting for feeds and category * removing userConf.allow-local-sort * removing userConf.allow-local-sort * removing white space * added credits * removed feeds_by_get * removed whitespace * changed escaping for values * added escaping to user set values * added in_array * added secondary sort and order * added secondary sort and order * fixed readme * removed whitespace change * reseted i18n * added translations * added feed setting translations * fixed i18n * fixed i18n * changes in sort order per feed * changes in sort order per feed * added secondary sort order * primary sort * changed to preferred sort order * i18n * Revert wrong whitespace changes * Re-order new options * added blank option * fixed escaping * fixed default sort in feed * fixed default sort recovery * siplyfied option * added rand option * Revert unrelated change * Minor plaintext * Whitespace and formatting fixes * Avoid unneeded SQL requests and processing * Improve syntax * Improve logic * Reuse existing translations as much as possible * i18n * Remove some options that make little sense * Separators * Fix old transation key * Add help messages * Progress on secondary sort * raw name * Pass parameters. Add TODO * Progress * Minor ordering * Fix parenthesis --------- Co-authored-by: root <root@LAPTOP-C8TCHHPN.localdomain> Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Diffstat (limited to 'app')
-rw-r--r--app/Controllers/categoryController.php16
-rw-r--r--app/Controllers/configureController.php32
-rw-r--r--app/Controllers/indexController.php20
-rw-r--r--app/Controllers/subscriptionController.php16
-rw-r--r--app/Models/Category.php7
-rw-r--r--app/Models/Context.php48
-rw-r--r--app/Models/EntryDAO.php126
-rw-r--r--app/Models/Feed.php7
-rw-r--r--app/Models/UserConfiguration.php4
-rw-r--r--app/i18n/cs/conf.php5
-rw-r--r--app/i18n/cs/index.php13
-rw-r--r--app/i18n/de/conf.php5
-rw-r--r--app/i18n/de/index.php13
-rw-r--r--app/i18n/el/conf.php5
-rw-r--r--app/i18n/el/index.php13
-rw-r--r--app/i18n/en-US/conf.php5
-rw-r--r--app/i18n/en-US/index.php13
-rw-r--r--app/i18n/en/admin.php2
-rw-r--r--app/i18n/en/api.php8
-rw-r--r--app/i18n/en/conf.php5
-rw-r--r--app/i18n/en/index.php13
-rw-r--r--app/i18n/en/sub.php2
-rw-r--r--app/i18n/es/conf.php5
-rw-r--r--app/i18n/es/index.php13
-rw-r--r--app/i18n/fa/conf.php5
-rw-r--r--app/i18n/fa/index.php13
-rw-r--r--app/i18n/fi/conf.php5
-rw-r--r--app/i18n/fi/index.php13
-rw-r--r--app/i18n/fr/conf.php5
-rw-r--r--app/i18n/fr/index.php13
-rw-r--r--app/i18n/he/conf.php5
-rw-r--r--app/i18n/he/index.php13
-rw-r--r--app/i18n/hu/conf.php5
-rw-r--r--app/i18n/hu/index.php13
-rw-r--r--app/i18n/id/conf.php5
-rw-r--r--app/i18n/id/index.php13
-rw-r--r--app/i18n/it/conf.php5
-rw-r--r--app/i18n/it/index.php13
-rw-r--r--app/i18n/ja/conf.php5
-rw-r--r--app/i18n/ja/index.php13
-rw-r--r--app/i18n/ko/conf.php5
-rw-r--r--app/i18n/ko/index.php13
-rw-r--r--app/i18n/lv/conf.php5
-rw-r--r--app/i18n/lv/index.php13
-rw-r--r--app/i18n/nl/conf.php5
-rw-r--r--app/i18n/nl/index.php13
-rw-r--r--app/i18n/oc/conf.php5
-rw-r--r--app/i18n/oc/index.php13
-rw-r--r--app/i18n/pl/conf.php5
-rw-r--r--app/i18n/pl/index.php13
-rw-r--r--app/i18n/pt-BR/conf.php5
-rw-r--r--app/i18n/pt-BR/index.php13
-rw-r--r--app/i18n/pt-PT/conf.php5
-rw-r--r--app/i18n/pt-PT/index.php13
-rw-r--r--app/i18n/ru/conf.php5
-rw-r--r--app/i18n/ru/index.php13
-rw-r--r--app/i18n/sk/conf.php5
-rw-r--r--app/i18n/sk/index.php13
-rw-r--r--app/i18n/tr/conf.php5
-rw-r--r--app/i18n/tr/index.php13
-rw-r--r--app/i18n/uk/conf.php5
-rw-r--r--app/i18n/uk/index.php13
-rw-r--r--app/i18n/zh-CN/conf.php5
-rw-r--r--app/i18n/zh-CN/index.php13
-rw-r--r--app/i18n/zh-TW/conf.php5
-rw-r--r--app/i18n/zh-TW/index.php13
-rw-r--r--app/layout/nav_menu.phtml6
-rw-r--r--app/views/configure/reading.phtml53
-rw-r--r--app/views/helpers/category/update.phtml31
-rw-r--r--app/views/helpers/feed/update.phtml30
70 files changed, 622 insertions, 272 deletions
diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php
index 9bea88a1f..ffd6e68b8 100644
--- a/app/Controllers/categoryController.php
+++ b/app/Controllers/categoryController.php
@@ -150,6 +150,22 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
$category->_attribute('opml_url', null);
}
+ $defaultSortOrder = Minz_Request::paramString('defaultSortOrder', plaintext: true);
+ if (str_ends_with($defaultSortOrder, '_asc')) {
+ $category->_attribute('defaultOrder', 'ASC');
+ $defaultSortOrder = substr($defaultSortOrder, 0, -strlen('_asc'));
+ } elseif (str_ends_with($defaultSortOrder, '_desc')) {
+ $category->_attribute('defaultOrder', 'DESC');
+ $defaultSortOrder = substr($defaultSortOrder, 0, -strlen('_desc'));
+ } else {
+ $category->_attribute('defaultOrder');
+ }
+ if (in_array($defaultSortOrder, ['id', 'date', 'link', 'title', 'length', 'f.name', 'rand'], true)) {
+ $category->_attribute('defaultSort', $defaultSortOrder);
+ } else {
+ $category->_attribute('defaultSort');
+ }
+
$values = [
'kind' => $category->kind(),
'name' => Minz_Request::paramString('name'),
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index 3153cb8c8..00a27f0e7 100644
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -149,11 +149,39 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
FreshRSS_Context::userConf()->reading_confirm = Minz_Request::paramBoolean('reading_confirm');
FreshRSS_Context::userConf()->auto_remove_article = Minz_Request::paramBoolean('auto_remove_article');
FreshRSS_Context::userConf()->mark_updated_article_unread = Minz_Request::paramBoolean('mark_updated_article_unread');
- if (in_array(Minz_Request::paramString('sort_order'), ['ASC', 'DESC'], true)) {
- FreshRSS_Context::userConf()->sort_order = Minz_Request::paramString('sort_order');
+
+ $sorting = Minz_Request::paramString('primary_sort', plaintext: true);
+ if (str_ends_with($sorting, '_asc')) {
+ FreshRSS_Context::userConf()->sort_order = 'ASC';
+ $sorting = substr($sorting, 0, -strlen('_asc'));
+ } elseif (str_ends_with($sorting, '_desc')) {
+ FreshRSS_Context::userConf()->sort_order = 'DESC';
+ $sorting = substr($sorting, 0, -strlen('_desc'));
} else {
FreshRSS_Context::userConf()->sort_order = 'DESC';
}
+ if (in_array($sorting, ['id', 'c.name', 'date', 'f.name', 'length', 'link', 'title', 'rand'], true)) {
+ FreshRSS_Context::userConf()->sort = $sorting;
+ } else {
+ FreshRSS_Context::userConf()->sort = 'id';
+ }
+
+ $sorting = Minz_Request::paramString('secondary_sort', plaintext: true);
+ if (str_ends_with($sorting, '_asc')) {
+ FreshRSS_Context::userConf()->secondary_sort_order = 'ASC';
+ $sorting = substr($sorting, 0, -strlen('_asc'));
+ } elseif (str_ends_with($sorting, '_desc')) {
+ FreshRSS_Context::userConf()->secondary_sort_order = 'DESC';
+ $sorting = substr($sorting, 0, -strlen('_desc'));
+ } else {
+ FreshRSS_Context::userConf()->secondary_sort_order = 'DESC';
+ }
+ if (in_array($sorting, ['id', 'date', 'link', 'title'], true)) {
+ FreshRSS_Context::userConf()->secondary_sort = $sorting;
+ } else {
+ FreshRSS_Context::userConf()->secondary_sort = 'id';
+ }
+
FreshRSS_Context::userConf()->mark_when = [
'article' => Minz_Request::paramBoolean('mark_open_article'),
'gone' => Minz_Request::paramBoolean('read_upon_gone'),
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php
index 17975fa86..7fe1e43a0 100644
--- a/app/Controllers/indexController.php
+++ b/app/Controllers/indexController.php
@@ -367,15 +367,24 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController {
'c.name' => $pagingEntry->feed()?->categoryId() === FreshRSS_CategoryDAO::DEFAULTCATEGORYID ?
FreshRSS_CategoryDAO::DEFAULT_CATEGORY_NAME : $pagingEntry->feed()?->category()?->name() ?? '',
'date' => $pagingEntry->date(raw: true),
- 'f.name' => $pagingEntry->feed()?->name() ?? '',
+ 'f.name' => $pagingEntry->feed()?->name(raw: true) ?? '',
'link' => $pagingEntry->link(raw: true),
'title' => $pagingEntry->title(),
'lastUserModified' => $pagingEntry->lastUserModified(),
'length' => $pagingEntry->sqlContentLength() ?? 0,
};
- if ($pagingEntry !== null && FreshRSS_Context::$sort === 'c.name') {
- // Secondary sort criterion
- $continuation_values[] = $pagingEntry->feed()?->name() ?? '';
+ if (FreshRSS_Context::$sort === 'c.name') {
+ // Internal secondary sort criterion for category name
+ $continuation_values[] = $pagingEntry?->feed()?->name(raw: true) ?? '';
+ }
+ if (in_array(FreshRSS_Context::$sort, ['c.name', 'f.name'], true)) {
+ // User secondary sort criterion
+ $continuation_values[] = $pagingEntry === null ? 0 : match (FreshRSS_Context::$secondary_sort) {
+ 'id' => $pagingEntry->id(),
+ 'date' => $pagingEntry->date(raw: true),
+ 'link' => $pagingEntry->link(raw: true),
+ 'title' => $pagingEntry->title(),
+ };
}
} elseif (FreshRSS_Context::$sort === 'rand') {
FreshRSS_Context::$continuation_id = '0';
@@ -386,7 +395,8 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController {
$type, $id, FreshRSS_Context::$state, FreshRSS_Context::$search,
id_min: $id_min, id_max: FreshRSS_Context::$id_max, sort: FreshRSS_Context::$sort, order: FreshRSS_Context::$order,
continuation_id: FreshRSS_Context::$continuation_id, continuation_values: $continuation_values,
- limit: $postsPerPage ?? FreshRSS_Context::$number, offset: FreshRSS_Context::$offset) as $entry) {
+ limit: $postsPerPage ?? FreshRSS_Context::$number, offset: FreshRSS_Context::$offset,
+ secondary_sort: FreshRSS_Context::$secondary_sort, secondary_sort_order: FreshRSS_Context::$secondary_sort_order) as $entry) {
yield $entry;
}
}
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index eb9fbf58f..be2dc5f70 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -334,6 +334,22 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
$feed->resetCustomFavicon();
}
+ $defaultSortOrder = Minz_Request::paramString('defaultSortOrder', plaintext: true);
+ if (str_ends_with($defaultSortOrder, '_asc')) {
+ $feed->_attribute('defaultOrder', 'ASC');
+ $defaultSortOrder = substr($defaultSortOrder, 0, -strlen('_asc'));
+ } elseif (str_ends_with($defaultSortOrder, '_desc')) {
+ $feed->_attribute('defaultOrder', 'DESC');
+ $defaultSortOrder = substr($defaultSortOrder, 0, -strlen('_desc'));
+ } else {
+ $feed->_attribute('defaultOrder');
+ }
+ if (in_array($defaultSortOrder, ['id', 'date', 'link', 'title', 'length', 'rand'], true)) {
+ $feed->_attribute('defaultSort', $defaultSortOrder);
+ } else {
+ $feed->_attribute('defaultSort');
+ }
+
$values = [
'name' => Minz_Request::paramString('name'),
'kind' => $feed->kind(),
diff --git a/app/Models/Category.php b/app/Models/Category.php
index 2bdad2904..08ab22c19 100644
--- a/app/Models/Category.php
+++ b/app/Models/Category.php
@@ -171,6 +171,13 @@ class FreshRSS_Category extends Minz_Model {
$this->sortFeeds();
}
+ public function defaultSort(): ?string {
+ return $this->attributeString('defaultSort');
+ }
+ public function defaultOrder(): ?string {
+ return $this->attributeString('defaultOrder');
+ }
+
/**
* To manually add feeds to this category (not committing to database).
*/
diff --git a/app/Models/Context.php b/app/Models/Context.php
index c9d743e76..7bd028780 100644
--- a/app/Models/Context.php
+++ b/app/Models/Context.php
@@ -42,8 +42,12 @@ final class FreshRSS_Context {
public static int $state = 0;
/** @var 'ASC'|'DESC' */
public static string $order = 'DESC';
- /** @var 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'lastUserModified'|'length' */
+ /** @var 'id'|'c.name'|'date'|'f.name'|'lastUserModified'|'length'|'link'|'rand'|'title' */
public static string $sort = 'id';
+ /** @var 'ASC'|'DESC' */
+ public static string $secondary_sort_order = 'DESC';
+ /** @var 'id'|'date'|'link'|'title' */
+ public static string $secondary_sort = 'id';
public static int $number = 0;
public static int $offset = 0;
public static FreshRSS_BooleanSearch $search;
@@ -258,10 +262,46 @@ final class FreshRSS_Context {
}
self::$search = new FreshRSS_BooleanSearch(Minz_Request::paramString('search', plaintext: true));
- $order = Minz_Request::paramString('order', plaintext: true) ?: FreshRSS_Context::userConf()->sort_order;
+
+ $default_order = null;
+ $default_sort = null;
+ if (Minz_Request::paramString('order', plaintext: true) === '' || Minz_Request::paramString('sort', plaintext: true) === '') {
+ if (!empty(self::$current_get['feed'])) {
+ $id = self::$current_get['feed'];
+ // We most likely already have the feed object in cache
+ $feed = FreshRSS_Category::findFeed(FreshRSS_Context::categories(), $id);
+ if ($feed === null) {
+ $feedDAO = FreshRSS_Factory::createFeedDao();
+ $feed = $feedDAO->searchById($id);
+ }
+ $default_order = $feed?->defaultOrder();
+ $default_sort = $feed?->defaultSort();
+ } elseif (!empty(self::$current_get['category'])) {
+ $id = self::$current_get['category'];
+ // We most likely already have the category object in cache
+ $category = FreshRSS_Context::categories()[$id] ?? null;
+ if ($category === null) {
+ $categoryDAO = FreshRSS_Factory::createCategoryDao();
+ $category = $categoryDAO->searchById($id);
+ }
+ $default_order = $category?->defaultOrder();
+ $default_sort = $category?->defaultSort();
+ }
+ }
+ $order = Minz_Request::paramString('order', plaintext: true) ?: $default_order ?: FreshRSS_Context::userConf()->sort_order;
self::$order = in_array($order, ['ASC', 'DESC'], true) ? $order : 'DESC';
- $sort = Minz_Request::paramString('sort', plaintext: true) ?: FreshRSS_Context::userConf()->sort;
- self::$sort = in_array($sort, ['id', 'c.name', 'date', 'f.name', 'link', 'title', 'rand', 'lastUserModified', 'length'], true) ? $sort : 'id';
+ $sort = Minz_Request::paramString('sort', plaintext: true) ?: $default_sort ?: FreshRSS_Context::userConf()->sort;
+ self::$sort = in_array($sort, ['id', 'c.name', 'date', 'f.name', 'lastUserModified', 'length', 'link', 'title', 'rand'], true) ? $sort : 'id';
+
+ if (in_array(self::$sort, ['c.name', 'f.name'], true)) {
+ self::$secondary_sort = FreshRSS_Context::userConf()->secondary_sort;
+ self::$secondary_sort_order = FreshRSS_Context::userConf()->secondary_sort_order;
+ if ($order !== ($default_order ?: FreshRSS_Context::userConf()->sort_order)) {
+ // User swapped order so swap secondary order as well
+ self::$secondary_sort_order = self::$secondary_sort_order === 'DESC' ? 'ASC' : 'DESC';
+ }
+ }
+
self::$number = Minz_Request::paramInt('nb') ?: FreshRSS_Context::userConf()->posts_per_page;
if (self::$number > FreshRSS_Context::userConf()->max_posts_per_rss) {
self::$number = max(
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index d247b84b7..024aef4e8 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -1270,15 +1270,18 @@ SQL;
/**
* @param numeric-string $id_min
* @param numeric-string $id_max
- * @param 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'lastUserModified'|'length' $sort
+ * @param 'id'|'c.name'|'date'|'f.name'|'lastUserModified'|'length'|'link'|'rand'|'title' $sort
* @param 'ASC'|'DESC' $order
* @param numeric-string $continuation_id
* @param list<string|int> $continuation_values
+ * @param 'id'|'date'|'link'|'title' $secondary_sort
+ * @param 'ASC'|'DESC' $secondary_sort_order
* @return array{0:list<int|string>,1:string}
*/
protected function sqlListEntriesWhere(string $alias = '', int $state = FreshRSS_Entry::STATE_ALL, ?FreshRSS_BooleanSearch $filters = null,
string $id_min = '0', string $id_max = '0', string $sort = 'id', string $order = 'DESC',
- string $continuation_id = '0', array $continuation_values = []): array {
+ string $continuation_id = '0', array $continuation_values = [],
+ string $secondary_sort = 'id', string $secondary_sort_order = 'DESC'): array {
$search = ' ';
$values = [];
if ($state & FreshRSS_Entry::STATE_ANDS) {
@@ -1338,29 +1341,53 @@ SQL;
$values[] = $id_min;
}
- if ($continuation_id !== '0' && in_array($sort, ['c.name', 'date', 'f.name', 'link', 'title', 'lastUserModified', 'length'], true)) {
+ if ($continuation_id !== '0' && in_array($sort, ['c.name', 'date', 'f.name', 'lastUserModified', 'length', 'link', 'title'], true)) {
$sign = $order === 'ASC' ? '>' : '<';
+ $sign2 = $secondary_sort_order === 'ASC' ? '>' : '<';
$orderBy = match ($sort) {
'c.name' => 'c.name',
+ 'date' => $alias . 'date',
'f.name' => 'f.name',
'lastUserModified' => $alias . '`lastUserModified`',
'length' => 'LENGTH(' . $alias . (static::isCompressed() ? 'content_bin' : 'content') . ')',
- default => $alias . $sort,
+ 'link' => $alias . 'link',
+ 'title' => $alias . 'title',
+ };
+ $orderBy2 = match ($secondary_sort) {
+ 'id' => $alias . 'id',
+ 'date' => $alias . 'date',
+ 'link' => $alias . 'link',
+ 'title' => $alias . 'title',
};
// Keyset pagination (Compatibility syntax due to poor performance of tuple syntax in MySQL https://bugs.mysql.com/bug.php?id=104128)
if ($sort === 'c.name') {
- // Includes a secondary sort by feed name
- $search .= "AND ((c.name {$sign} ?) OR (c.name = ? AND f.name {$sign} ?) OR (c.name = ? AND f.name = ? AND {$alias}id {$sign}= ?)) ";
- $values[] = $continuation_values[0];
- $values[] = $continuation_values[0];
- $values[] = $continuation_values[1];
- $values[] = $continuation_values[0];
- $values[] = $continuation_values[1];
+ // Includes the feed-name sort and a user secondary sort
+ $search .= "AND ((c.name {$sign} ?) OR (c.name = ? AND f.name {$sign} ?) OR (c.name = ? AND f.name = ? AND {$orderBy2} {$sign2}= ?) " .
+ "OR (c.name = ? AND f.name = ? AND {$orderBy2} = ? AND {$alias}id {$sign}= ?)) ";
+ $values[] = $continuation_values[0]; // c.name (primary sort)
+ $values[] = $continuation_values[0]; // c.name (primary sort)
+ $values[] = $continuation_values[1]; // f.name (internal secondary sort)
+ $values[] = $continuation_values[0]; // c.name (primary sort)
+ $values[] = $continuation_values[1]; // f.name (internal secondary sort)
+ $values[] = $continuation_values[2]; // secondary sort
+ $values[] = $continuation_values[0]; // c.name (primary sort)
+ $values[] = $continuation_values[1]; // f.name (internal secondary sort)
+ $values[] = $continuation_values[2]; // secondary sort
+ $values[] = $continuation_id;
+ } elseif ($sort === 'f.name') {
+ // Includes the user secondary sort
+ $search .= "AND ((f.name {$sign} ?) OR (f.name = ? AND {$orderBy2} {$sign2} ?) " .
+ "OR (f.name = ? AND {$orderBy2} = ? AND {$alias}id {$sign}= ?)) ";
+ $values[] = $continuation_values[0]; // f.name (primary sort)
+ $values[] = $continuation_values[0]; // f.name (primary sort)
+ $values[] = $continuation_values[1]; // secondary sort
+ $values[] = $continuation_values[0]; // f.name (primary sort)
+ $values[] = $continuation_values[1]; // secondary sort
$values[] = $continuation_id;
} else {
$search .= "AND ({$orderBy} {$sign} ? OR ({$orderBy} = ? AND {$alias}id {$sign}= ?)) ";
- $values[] = $continuation_values[0];
- $values[] = $continuation_values[0];
+ $values[] = $continuation_values[0]; // primary sort
+ $values[] = $continuation_values[0]; // primary sort
$values[] = $continuation_id;
}
}
@@ -1382,16 +1409,19 @@ SQL;
* @param int $id category/feed/tag ID
* @param numeric-string $id_min
* @param numeric-string $id_max
- * @param 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'lastUserModified'|'length' $sort
+ * @param 'id'|'c.name'|'date'|'f.name'|'lastUserModified'|'length'|'link'|'rand'|'title' $sort
* @param 'ASC'|'DESC' $order
* @param numeric-string $continuation_id
* @param list<string|int> $continuation_values
+ * @param 'id'|'date'|'link'|'title' $secondary_sort
+ * @param 'ASC'|'DESC' $secondary_sort_order
* @return array{0:list<int|string>,1:string}
* @throws FreshRSS_EntriesGetter_Exception
*/
private function sqlListWhere(string $type = 'a', int $id = 0, int $state = FreshRSS_Entry::STATE_ALL, ?FreshRSS_BooleanSearch $filters = null,
string $id_min = '0', string $id_max = '0', string $sort = 'id', string $order = 'DESC',
- string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0): array {
+ string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0,
+ string $secondary_sort = 'id', string $secondary_sort_order = 'DESC'): array {
if (!$state) {
$state = FreshRSS_Entry::STATE_ALL;
}
@@ -1441,17 +1471,27 @@ SQL;
}
$order = in_array($order, ['ASC', 'DESC'], true) ? $order : 'DESC';
- $sort = in_array($sort, ['id', 'c.name', 'date', 'f.name', 'link', 'title', 'rand', 'lastUserModified', 'length'], true) ? $sort : 'id';
+ $order2 = in_array($secondary_sort_order, ['ASC', 'DESC'], true) ? $secondary_sort_order : 'DESC';
$orderBy = match ($sort) {
+ 'id' => 'e.id',
'c.name' => 'c.name',
+ 'date' => 'e.date',
'f.name' => 'f.name',
'lastUserModified' => 'e.`lastUserModified`',
'length' => 'LENGTH(e.' . (static::isCompressed() ? 'content_bin' : 'content') . ')',
+ 'link' => 'e.link',
+ 'title' => 'e.title',
'rand' => static::sqlRandom(),
- default => 'e.' . $sort,
+ };
+ $orderBy2 = match ($secondary_sort) {
+ 'id' => 'e.id',
+ 'date' => 'e.date',
+ 'link' => 'e.link',
+ 'title' => 'e.title',
};
[$searchValues, $search] = $this->sqlListEntriesWhere(alias: 'e.', state: $state, filters: $filters, id_min: $id_min, id_max: $id_max,
- sort: $sort, order: $order, continuation_id: $continuation_id, continuation_values: $continuation_values);
+ sort: $sort, order: $order, continuation_id: $continuation_id, continuation_values: $continuation_values,
+ secondary_sort: $secondary_sort, secondary_sort_order: $secondary_sort_order);
// Help MySQL/MariaDB's optimizer with the query plan:
$useEntryIndex = ($this->pdo->dbType() === 'mysql' && // Only relevant for MySQL/MariaDB,
@@ -1470,7 +1510,8 @@ SQL;
. 'WHERE ' . $where
. $search
. 'ORDER BY ' . $orderBy . ' ' . $order
- . ($sort === 'c.name' ? ', f.name ' . $order : '') // Secondary sort
+ . ($sort === 'c.name' ? ', f.name ' . $order : '') // Internal secondary sort
+ . (in_array($sort, ['c.name', 'f.name'], true) ? ', ' . $orderBy2 . ' ' . $order2 : '') // User secondary sort
. ($sort === 'id' ? '' : ', e.id ' . $order) // For keyset pagination
. ($limit > 0 ? ' LIMIT ' . $limit : '') // http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/
. ($offset > 0 ? ' OFFSET ' . $offset : '')
@@ -1482,28 +1523,41 @@ SQL;
* @param int $id category/feed/tag ID
* @param numeric-string $id_min
* @param numeric-string $id_max
- * @param 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'lastUserModified'|'length' $sort
+ * @param 'id'|'c.name'|'date'|'f.name'|'lastUserModified'|'length'|'link'|'rand'|'title' $sort
* @param 'ASC'|'DESC' $order
* @param numeric-string $continuation_id
* @param list<string|int> $continuation_values
+ * @param 'id'|'date'|'link'|'title' $secondary_sort
+ * @param 'ASC'|'DESC' $secondary_sort_order
* @throws FreshRSS_EntriesGetter_Exception
*/
private function listWhereRaw(string $type = 'a', int $id = 0, int $state = FreshRSS_Entry::STATE_ALL, ?FreshRSS_BooleanSearch $filters = null,
string $id_min = '0', string $id_max = '0', string $sort = 'id', string $order = 'DESC',
- string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0): PDOStatement|false {
+ string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0,
+ string $secondary_sort = 'id', string $secondary_sort_order = 'DESC'): PDOStatement|false {
$order = in_array($order, ['ASC', 'DESC'], true) ? $order : 'DESC';
- $sort = in_array($sort, ['id', 'c.name', 'date', 'f.name', 'link', 'title', 'rand', 'lastUserModified', 'length'], true) ? $sort : 'id';
+ $secondary_sort_order = in_array($secondary_sort_order, ['ASC', 'DESC'], true) ? $secondary_sort_order : 'DESC';
[$values, $sql] = $this->sqlListWhere($type, $id, $state, $filters, id_min: $id_min, id_max: $id_max, sort: $sort, order: $order,
- continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset);
+ continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset,
+ secondary_sort: $secondary_sort, secondary_sort_order: $secondary_sort_order);
$orderBy = match ($sort) {
+ 'id' => 'e0.id',
'c.name' => 'c0.name',
+ 'date' => 'e0.date',
'f.name' => 'f0.name',
'lastUserModified' => 'e0.`lastUserModified`',
'length' => 'LENGTH(e0.' . (static::isCompressed() ? 'content_bin' : 'content') . ')',
+ 'link' => 'e0.link',
+ 'title' => 'e0.title',
'rand' => static::sqlRandom(),
- default => 'e0.' . $sort,
+ };
+ $orderBy2 = match ($secondary_sort) {
+ 'id' => 'e0.id',
+ 'date' => 'e0.date',
+ 'link' => 'e0.link',
+ 'title' => 'e0.title',
};
$content = static::isCompressed() ? 'UNCOMPRESS(e0.content_bin) AS content' : 'e0.content';
$hash = static::sqlHexEncode('e0.hash');
@@ -1520,7 +1574,10 @@ SQL;
}
$sql .= ' ORDER BY ' . $orderBy . ' ' . $order;
if ($sort === 'c.name') {
- $sql .= ', f0.name ' . $order; // Secondary sort
+ $sql .= ', f0.name ' . $order; // Internal secondary sort
+ }
+ if (in_array($sort, ['c.name', 'f.name'], true)) {
+ $sql .= ', ' . $orderBy2 . ' ' . $secondary_sort_order; // User secondary sort
}
if ($sort !== 'id') {
// For keyset pagination
@@ -1537,6 +1594,7 @@ SQL;
continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset);
}
Minz_Log::error('SQL error ' . __METHOD__ . json_encode($info));
+ Minz_Log::error('SQL error ' . __METHOD__ . json_encode($sql));
return false;
}
}
@@ -1546,18 +1604,22 @@ SQL;
* @param int $id category/feed/tag ID
* @param numeric-string $id_min
* @param numeric-string $id_max
- * @param 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'lastUserModified'|'length' $sort
+ * @param 'id'|'c.name'|'date'|'f.name'|'lastUserModified'|'length'|'link'|'rand'|'title' $sort
* @param 'ASC'|'DESC' $order
* @param numeric-string $continuation_id
* @param list<string|int> $continuation_values
+ * @param 'id'|'date'|'link'|'title' $secondary_sort
+ * @param 'ASC'|'DESC' $secondary_sort_order
* @return Traversable<FreshRSS_Entry>
* @throws FreshRSS_EntriesGetter_Exception
*/
public function listWhere(string $type = 'a', int $id = 0, int $state = FreshRSS_Entry::STATE_ALL, ?FreshRSS_BooleanSearch $filters = null,
string $id_min = '0', string $id_max = '0', string $sort = 'id', string $order = 'DESC',
- string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0): Traversable {
+ string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0,
+ string $secondary_sort = 'id', string $secondary_sort_order = 'DESC'): Traversable {
$stm = $this->listWhereRaw($type, $id, $state, $filters, id_min: $id_min, id_max: $id_max, sort: $sort, order: $order,
- continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset);
+ continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset,
+ secondary_sort: $secondary_sort, secondary_sort_order: $secondary_sort_order);
if ($stm !== false) {
while (is_array($row = $stm->fetch(PDO::FETCH_ASSOC))) {
/** @var array{'id':string,'id_feed':int,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,
@@ -1618,14 +1680,18 @@ SQL;
* @param 'ASC'|'DESC' $order
* @param numeric-string $continuation_id
* @param list<string|int> $continuation_values
+ * @param 'id'|'date'|'link'|'title' $secondary_sort
+ * @param 'ASC'|'DESC' $secondary_sort_order
* @return list<numeric-string>|null
* @throws FreshRSS_EntriesGetter_Exception
*/
public function listIdsWhere(string $type = 'a', int $id = 0, int $state = FreshRSS_Entry::STATE_ALL, ?FreshRSS_BooleanSearch $filters = null,
string $id_min = '0', string $id_max = '0', string $order = 'DESC',
- string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0): ?array {
+ string $continuation_id = '0', array $continuation_values = [], int $limit = 1, int $offset = 0,
+ string $secondary_sort = 'id', string $secondary_sort_order = 'DESC'): ?array {
[$values, $sql] = $this->sqlListWhere($type, $id, $state, $filters, id_min: $id_min, id_max: $id_max, order: $order,
- continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset);
+ continuation_id: $continuation_id, continuation_values: $continuation_values, limit: $limit, offset: $offset,
+ secondary_sort: $secondary_sort, secondary_sort_order: $secondary_sort_order);
$stm = $this->pdo->prepare($sql);
if ($stm !== false && $stm->execute($values)) {
/** @var list<int|numeric-string> $res */
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 6a995fef0..acbe11fe9 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -537,6 +537,13 @@ class FreshRSS_Feed extends Minz_Model {
$this->nbEntries = $value;
}
+ public function defaultSort(): ?string {
+ return $this->attributeString('defaultSort');
+ }
+ public function defaultOrder(): ?string {
+ return $this->attributeString('defaultOrder');
+ }
+
/**
* @throws Minz_FileNotExistException
* @throws FreshRSS_Feed_Exception
diff --git a/app/Models/UserConfiguration.php b/app/Models/UserConfiguration.php
index d12316141..d6a0be027 100644
--- a/app/Models/UserConfiguration.php
+++ b/app/Models/UserConfiguration.php
@@ -56,7 +56,9 @@ declare(strict_types=1);
* @property bool $show_nav_buttons
* @property 'big'|'small'|'none' $mark_read_button
* @property 'ASC'|'DESC' $sort_order
- * @property 'id'|'c.name'|'date'|'f.name'|'link'|'title'|'rand'|'length' $sort
+ * @property 'id'|'c.name'|'date'|'f.name'|'length'|'link'|'rand'|'title' $sort
+ * @property 'ASC'|'DESC' $secondary_sort_order
+ * @property 'id'|'date'|'link'|'title' $secondary_sort
* @property array<int,array<string,string>> $sharing
* @property array<string,string> $shortcuts
* @property bool $sides_close_article
diff --git a/app/i18n/cs/conf.php b/app/i18n/cs/conf.php
index 140e03cb9..4af5e04bc 100644
--- a/app/i18n/cs/conf.php
+++ b/app/i18n/cs/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Použije se také na popisky',
'sides_close_article' => 'Kliknutí mimo oblast textu článku zavře článek',
- 'sort' => array(
- '_' => 'Pořadí řazení',
- 'newer_first' => 'Nejdříve nejnovější',
- 'older_first' => 'Nejdříve nejstarší',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/cs/index.php b/app/i18n/cs/index.php
index 0a5689157..37fe885e3 100644
--- a/app/i18n/cs/index.php
+++ b/app/i18n/cs/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Označit kanál jako přečtený',
'mark_selection_unread' => 'Označit výběr jako nepřečtený',
'mylabels' => 'Mé popisky',
- 'newer_first' => 'Nejdříve novější',
'non-starred' => 'Zobrazit neoblíbené',
'normal_view' => 'Normální zobrazení',
- 'older_first' => 'Nejdříve nejstarší',
'queries' => 'Uživatelské dotazy',
'read' => 'Zobrazit přečtené',
'reader_view' => 'Zobrazení pro čtení',
'rss_view' => 'Kanál RSS',
'search_short' => 'Hledat',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php
index 3f57416f4..03c20f823 100644
--- a/app/i18n/de/conf.php
+++ b/app/i18n/de/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Auch auf Labels anwenden',
'sides_close_article' => 'Klick außerhalb des Artikel-Textes schließt den Artikel',
- 'sort' => array(
- '_' => 'Sortierreihenfolge',
- 'newer_first' => 'Neuere zuerst',
- 'older_first' => 'Ältere zuerst',
- ),
'star' => array(
'when' => 'Markiere einen Artikel als Favoriten…',
),
diff --git a/app/i18n/de/index.php b/app/i18n/de/index.php
index fc16db974..5afc83e7d 100644
--- a/app/i18n/de/index.php
+++ b/app/i18n/de/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Feed als gelesen markieren',
'mark_selection_unread' => 'Auswahl als ungelesen markieren',
'mylabels' => 'Meine Labels',
- 'newer_first' => 'Neuere zuerst',
'non-starred' => 'Nicht-Favoriten zeigen',
'normal_view' => 'Normale Ansicht',
- 'older_first' => 'Ältere zuerst',
'queries' => 'Benutzerabfragen',
'read' => 'Gelesene zeigen',
'reader_view' => 'Lese-Ansicht',
'rss_view' => 'RSS-Feed',
'search_short' => 'Suchen',
'sort' => array(
- '_' => 'Sortierkriterien',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Kategorie, Feed-Titel A→Z',
'name_desc' => 'Kategorie, Feed-Titel Z→A',
),
'date_asc' => 'Veröffentlichungsdatum 1→9',
'date_desc' => 'Veröffentlichungsdatum 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed-Titel A→Z',
'name_desc' => 'Feed-Titel Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // IGNORE
'link_desc' => 'Link Z→A', // IGNORE
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Zufällige Reihenfolge',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Titel A→Z',
'title_desc' => 'Titel Z→A',
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/el/conf.php b/app/i18n/el/conf.php
index 0d1ba6620..4ca9415d2 100644
--- a/app/i18n/el/conf.php
+++ b/app/i18n/el/conf.php
@@ -294,11 +294,6 @@ return array(
),
'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 order', // TODO
- 'newer_first' => 'Newest first', // TODO
- 'older_first' => 'Oldest first', // TODO
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/el/index.php b/app/i18n/el/index.php
index 0134d40ea..443d4bed4 100644
--- a/app/i18n/el/index.php
+++ b/app/i18n/el/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Mark feed as read', // TODO
'mark_selection_unread' => 'Mark selection as unread', // TODO
'mylabels' => 'My labels', // TODO
- 'newer_first' => 'Newer first', // TODO
'non-starred' => 'Show non-favourites', // TODO
'normal_view' => 'Normal view', // TODO
- 'older_first' => 'Oldest first', // TODO
'queries' => 'User queries', // TODO
'read' => 'Show read', // TODO
'reader_view' => 'Reading view', // TODO
'rss_view' => 'RSS feed', // TODO
'search_short' => 'Search', // TODO
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/en-US/conf.php b/app/i18n/en-US/conf.php
index 99272f190..1fcdad486 100644
--- a/app/i18n/en-US/conf.php
+++ b/app/i18n/en-US/conf.php
@@ -294,11 +294,6 @@ return array(
),
'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 order', // IGNORE
- 'newer_first' => 'Newest first', // IGNORE
- 'older_first' => 'Oldest first', // IGNORE
- ),
'star' => array(
'when' => 'Mark an article as favorite…',
),
diff --git a/app/i18n/en-US/index.php b/app/i18n/en-US/index.php
index 7d05d4f21..6b9d24b05 100644
--- a/app/i18n/en-US/index.php
+++ b/app/i18n/en-US/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Mark feed as read', // IGNORE
'mark_selection_unread' => 'Mark selection as unread', // IGNORE
'mylabels' => 'My labels', // IGNORE
- 'newer_first' => 'Newer first', // IGNORE
'non-starred' => 'Show non-favorites',
'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
'sort' => array(
- '_' => 'Sorting criteria', // IGNORE
+ 'asc' => 'Ascending', // IGNORE
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // IGNORE
'name_desc' => 'Category, feed titles Z→A', // IGNORE
),
'date_asc' => 'Publication date 1→9', // IGNORE
'date_desc' => 'Publication date 9→1', // IGNORE
+ 'desc' => 'Descending', // IGNORE
'f' => array(
'name_asc' => 'Feed title A→Z', // IGNORE
'name_desc' => 'Feed title Z→A', // IGNORE
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // IGNORE
'link_asc' => 'Link A→Z', // IGNORE
'link_desc' => 'Link Z→A', // IGNORE
+ 'primary' => array(
+ '_' => 'Sorting criterion', // IGNORE
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // IGNORE
+ ),
'rand' => 'Random order', // IGNORE
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // IGNORE
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // IGNORE
+ ),
'title_asc' => 'Title A→Z', // IGNORE
'title_desc' => 'Title Z→A', // IGNORE
'user_modified_asc' => 'User modified 1→9', // IGNORE
diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php
index 76428bd67..87acd07ba 100644
--- a/app/i18n/en/admin.php
+++ b/app/i18n/en/admin.php
@@ -31,7 +31,7 @@ return array(
'empty_list' => 'There are no installed extensions',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.',
'enabled' => 'Enabled',
- 'is_compatible' => 'Is compatible', // TODO
+ 'is_compatible' => 'Is compatible',
'latest' => 'Installed',
'name' => 'Name',
'no_configure_view' => 'This extension cannot be configured.',
diff --git a/app/i18n/en/api.php b/app/i18n/en/api.php
index f630eb1be..1350a0bde 100644
--- a/app/i18n/en/api.php
+++ b/app/i18n/en/api.php
@@ -14,10 +14,10 @@ return array(
'information' => array(
'address' => 'Your API address:',
'output' => array(
- 'encoding-support' => '⚠️ WARN: no <code>%2F</code> support, some clients might not work!', // TODO
- 'invalid-configuration' => '⚠️ WARN: Probable invalid base URL in ./data/config.php', // TODO
- 'pass' => '✔️ PASS', // TODO
- 'unknown-error' => '❌ ', // TODO
+ 'encoding-support' => '⚠️ WARN: no <code>%2F</code> support, some clients might not work!',
+ 'invalid-configuration' => '⚠️ WARN: Probable invalid base URL in ./data/config.php',
+ 'pass' => '✔️ PASS',
+ 'unknown-error' => '❌ ',
),
'test' => array(
'fever' => 'Fever API configuration test:',
diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php
index bfc32ec3a..c85a5e0c2 100644
--- a/app/i18n/en/conf.php
+++ b/app/i18n/en/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Applies also on labels',
'sides_close_article' => 'Clicking outside of article text area closes the article',
- 'sort' => array(
- '_' => 'Sort order',
- 'newer_first' => 'Newest first',
- 'older_first' => 'Oldest first',
- ),
'star' => array(
'when' => 'Mark an article as favourite…',
),
diff --git a/app/i18n/en/index.php b/app/i18n/en/index.php
index fed6491f7..0506854fa 100644
--- a/app/i18n/en/index.php
+++ b/app/i18n/en/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Mark feed as read',
'mark_selection_unread' => 'Mark selection as unread',
'mylabels' => 'My labels',
- 'newer_first' => 'Newer first',
'non-starred' => 'Show non-favourites',
'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',
'sort' => array(
- '_' => 'Sorting criteria',
+ 'asc' => 'Ascending',
'c' => array(
'name_asc' => 'Category, feed titles A→Z',
'name_desc' => 'Category, feed titles Z→A',
),
'date_asc' => 'Publication date 1→9',
'date_desc' => 'Publication date 9→1',
+ 'desc' => 'Descending',
'f' => array(
'name_asc' => 'Feed title A→Z',
'name_desc' => 'Feed title Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1',
'link_asc' => 'Link A→Z',
'link_desc' => 'Link Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion',
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance',
+ ),
'rand' => 'Random order',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion',
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles',
+ ),
'title_asc' => 'Title A→Z',
'title_desc' => 'Title Z→A',
'user_modified_asc' => 'User modified 1→9',
diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php
index 7560dc90c..0d930534b 100644
--- a/app/i18n/en/sub.php
+++ b/app/i18n/en/sub.php
@@ -211,7 +211,7 @@ return array(
'priority' => array(
'_' => 'Visibility',
'category' => 'Show in its category',
- 'feed' => 'Show in its feed', // TODO
+ 'feed' => 'Show in its feed',
'hidden' => 'Do not show',
'important' => 'Show in important feeds',
'main_stream' => 'Show in main stream',
diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php
index 13c991008..5a2924b9a 100644
--- a/app/i18n/es/conf.php
+++ b/app/i18n/es/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Se aplica también en las etiquetas',
'sides_close_article' => 'Pinchar fuera del área de texto del artículo lo cerrará',
- 'sort' => array(
- '_' => 'Orden',
- 'newer_first' => 'Nuevos primero',
- 'older_first' => 'Antiguos primero',
- ),
'star' => array(
'when' => 'Marca un artículo como favorito…',
),
diff --git a/app/i18n/es/index.php b/app/i18n/es/index.php
index 916f463c7..678aa9ff5 100644
--- a/app/i18n/es/index.php
+++ b/app/i18n/es/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Marcar fuente como leída',
'mark_selection_unread' => 'Marcar la selección como no leída',
'mylabels' => 'Mis etiquetas',
- 'newer_first' => 'Nuevos primero',
'non-starred' => 'Mostrar todos menos los favoritos',
'normal_view' => 'Vista normal',
- 'older_first' => 'Más antiguos primero',
'queries' => 'Búsquedas de usuario',
'read' => 'Mostrar solo los leídos',
'reader_view' => 'Vista de lectura',
'rss_view' => 'Fuente RSS',
'search_short' => 'Buscar',
'sort' => array(
- '_' => 'Criterios de ordenación',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Categoría, títulos de fuentes A→Z',
'name_desc' => 'Categoría, títulos de fuentes Z→A',
),
'date_asc' => 'Fecha de publicación 1→9',
'date_desc' => 'Fecha de publicación 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Título de fuente A→Z',
'name_desc' => 'Título de fuente Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Longitud de contenido 9→1',
'link_asc' => 'Enlace A→Z',
'link_desc' => 'Enlace Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Orden aleatorio',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Título A→Z',
'title_desc' => 'Título Z→A',
'user_modified_asc' => 'Modificado por usuario 1→9',
diff --git a/app/i18n/fa/conf.php b/app/i18n/fa/conf.php
index 28ed5039d..934fc5642 100644
--- a/app/i18n/fa/conf.php
+++ b/app/i18n/fa/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => ' روی برچسب ها نیز اعمال می شود',
'sides_close_article' => ' با کلیک کردن خارج از ناحیه متن مقاله',
- 'sort' => array(
- '_' => ' ترتیب مرتب سازی',
- 'newer_first' => ' ابتدا جدیدترین',
- 'older_first' => ' اول قدیمی ترین',
- ),
'star' => array(
'when' => 'یک مطلب را به عنوان مورد علاقه علامت‌گذاری کن...',
),
diff --git a/app/i18n/fa/index.php b/app/i18n/fa/index.php
index 1ad29523b..c538d4117 100644
--- a/app/i18n/fa/index.php
+++ b/app/i18n/fa/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => ' فید را به عنوان خوانده شده علامت گذاری کنید',
'mark_selection_unread' => ' انتخاب را به عنوان خوانده نشده علامت گذاری کنید',
'mylabels' => ' برچسب های من',
- 'newer_first' => ' ابتدا جدیدتر',
'non-starred' => ' موارد غیر مورد علاقه را نشان دهید',
'normal_view' => ' نمای عادی',
- 'older_first' => ' اول مسن ترین',
'queries' => ' پرس و جوهای کاربر',
'read' => ' نمایش خوانده شده',
'reader_view' => ' مشاهده خواندن',
'rss_view' => ' خوراک RSS',
'search_short' => ' جستجو',
'sort' => array(
- '_' => 'معیارهای مرتب‌سازی',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'دسته بندی، عناوین فید A→Z',
'name_desc' => 'دسته بندی، عناوین فید Z→A',
),
'date_asc' => 'تاریخ انتشار ۱→۹',
'date_desc' => 'تاریخ انتشار ۹→۱',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'عنوان فید A→Z',
'name_desc' => 'عنوان فید Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'لینک A→Z',
'link_desc' => 'لینک Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'ترتیب تصادفی',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'عنوانA→Z',
'title_desc' => 'عنوان Z→A',
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/fi/conf.php b/app/i18n/fi/conf.php
index 790e0a92b..e0e35ff00 100644
--- a/app/i18n/fi/conf.php
+++ b/app/i18n/fi/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Koskee myös merkintöjä',
'sides_close_article' => 'Artikkeli sulkeutuu napsauttamalla sen ulkopuolelle',
- 'sort' => array(
- '_' => 'Lajittelujärjestys',
- 'newer_first' => 'Uusimmat ensin',
- 'older_first' => 'Vanhimmat ensin',
- ),
'star' => array(
'when' => 'Merkitse artikkeli suosikiksi…',
),
diff --git a/app/i18n/fi/index.php b/app/i18n/fi/index.php
index f09b5ffc5..1805f864e 100644
--- a/app/i18n/fi/index.php
+++ b/app/i18n/fi/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Merkitse syöte luetuksi',
'mark_selection_unread' => 'Merkitse valitut lukemattomiksi',
'mylabels' => 'Omat tunnisteet',
- 'newer_first' => 'Uusin ensin',
'non-starred' => 'Näytä muut kuin suosikit',
'normal_view' => 'Tavallinen näkymä',
- 'older_first' => 'Vanhin ensin',
'queries' => 'Käyttäjän tekemät kyselyt',
'read' => 'Näytä luetut',
'reader_view' => 'Lukunäkymä',
'rss_view' => 'RSS-syöte',
'search_short' => 'Haku',
'sort' => array(
- '_' => 'Lajitteluehdot',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Luokka, syötteiden otsikot A→Ö',
'name_desc' => 'Luokka, syötteiden otsikot Ö→A',
),
'date_asc' => 'Julkaisupäivä 1→9',
'date_desc' => 'Julkaisupäivä 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Syötteen otsikko A→Ö',
'name_desc' => 'Syötteen otsikko Ö→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Linkki A→Ö',
'link_desc' => 'Linkki Ö→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Satunnainen järjestys',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Otsikko A→Ö',
'title_desc' => 'Otsikko Ö→A',
'user_modified_asc' => 'Käyttäjä muokannut 1→9',
diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php
index e43ee3fd0..551309069 100644
--- a/app/i18n/fr/conf.php
+++ b/app/i18n/fr/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'S’applique aussi aux étiquettes',
'sides_close_article' => 'Cliquer hors de la zone de texte ferme l’article',
- 'sort' => array(
- '_' => 'Ordre de tri',
- 'newer_first' => 'Plus récents en premier',
- 'older_first' => 'Plus anciens en premier',
- ),
'star' => array(
'when' => 'Marquer un article comme favori…',
),
diff --git a/app/i18n/fr/index.php b/app/i18n/fr/index.php
index 83faedddb..a4d8829d0 100644
--- a/app/i18n/fr/index.php
+++ b/app/i18n/fr/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Marquer le flux comme lu',
'mark_selection_unread' => 'Marquer la sélection comme non-lue',
'mylabels' => 'Mes étiquettes',
- 'newer_first' => 'Plus récents en premier',
'non-starred' => 'Afficher les non-favoris',
'normal_view' => 'Vue normale',
- 'older_first' => 'Plus anciens en premier',
'queries' => 'Filtres utilisateurs',
'read' => 'Afficher les lus',
'reader_view' => 'Vue lecture',
'rss_view' => 'Flux RSS',
'search_short' => 'Rechercher',
'sort' => array(
- '_' => 'Critère de tri',
+ 'asc' => 'Ascendant',
'c' => array(
'name_asc' => 'Catégorie, flux (titres) A→Z',
'name_desc' => 'Catégorie, flux (titres) Z→A',
),
'date_asc' => 'Date de publication 1→9',
'date_desc' => 'Date de publication 9→1',
+ 'desc' => 'Descendant',
'f' => array(
'name_asc' => 'Flux (titre) A→Z',
'name_desc' => 'Flux (titre) Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Longueur du contenu 9→1',
'link_asc' => 'Lien A→Z',
'link_desc' => 'Lien Z→A',
+ 'primary' => array(
+ '_' => 'Critère de tri',
+ 'help' => 'Le tri par date de <em>réception</em> est recommandé dans la plupart des cas, pour une meilleure cohérence et performance',
+ ),
'rand' => 'Ordre aléatoire',
+ 'secondary' => array(
+ '_' => 'Critère de tri secondaire',
+ 'help' => 'Seulemement pertinent lorsque le critère de tri principal est sur les titres des catégories ou des flux',
+ ),
'title_asc' => 'Titre A→Z',
'title_desc' => 'Titre Z→A',
'user_modified_asc' => 'Modifié par l’utilisateur 1→9',
diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php
index 7f66859c3..38c5ee52e 100644
--- a/app/i18n/he/conf.php
+++ b/app/i18n/he/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Applies also on labels', // TODO
'sides_close_article' => 'Clicking outside of article text area closes the article', // TODO
- 'sort' => array(
- '_' => 'סדר המיון',
- 'newer_first' => 'חדשים בראש',
- 'older_first' => 'ישנים יותר בראש',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/he/index.php b/app/i18n/he/index.php
index ed7aa038d..f5d4e15ef 100644
--- a/app/i18n/he/index.php
+++ b/app/i18n/he/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'סימון הזנה כנקראה',
'mark_selection_unread' => 'Mark selection as unread', // TODO
'mylabels' => 'My labels', // TODO
- 'newer_first' => 'חדשים בראש',
'non-starred' => 'הצגת הכל פרט למועדפים',
'normal_view' => 'תצוגה רגילה',
- 'older_first' => 'ישנים יותר בראש',
'queries' => 'שאילתות',
'read' => 'הצגת נקראו בלבד',
'reader_view' => 'תצוגת קריאה',
'rss_view' => 'הזנת RSS',
'search_short' => 'חיפוש',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/hu/conf.php b/app/i18n/hu/conf.php
index b1b9ee2a0..24f53112e 100644
--- a/app/i18n/hu/conf.php
+++ b/app/i18n/hu/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'A címkékre is vonatkozik',
'sides_close_article' => 'A cikk szövegrészén kívüli kattintás bezárja a cikket',
- 'sort' => array(
- '_' => 'Rendezési sorrend',
- 'newer_first' => 'Újabb elöl',
- 'older_first' => 'Régebbi elöl',
- ),
'star' => array(
'when' => 'Cikk megjelölése kedvencnek…',
),
diff --git a/app/i18n/hu/index.php b/app/i18n/hu/index.php
index 8c90e36ba..c7a025af6 100644
--- a/app/i18n/hu/index.php
+++ b/app/i18n/hu/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Hírforrás megjelölése olvasottként',
'mark_selection_unread' => 'Kijelöltek olvasatlanná tétele',
'mylabels' => 'Címkék',
- 'newer_first' => 'Újabbak elöl',
'non-starred' => 'Nem kedvencek megjelenítése',
'normal_view' => 'Normál nézet',
- 'older_first' => 'Régebbiek elöl',
'queries' => 'Felhasználói lekérdezések',
'read' => 'Olvasottak megjelenítése',
'reader_view' => 'Olvasó nézet',
'rss_view' => 'RSS hírforrás',
'search_short' => 'Keresés',
'sort' => array(
- '_' => 'Rendezési sorrend',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Kategória, feed címek A→Z',
'name_desc' => 'Kategória, feed címek Z→A',
),
'date_asc' => 'Kiadás dátuma 1→9',
'date_desc' => 'Kiadás dátuma 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed cím A→Z',
'name_desc' => 'Feed cím Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Tartalom hossza 9→1',
'link_asc' => 'Link A→Z', // IGNORE
'link_desc' => 'Link Z→A', // IGNORE
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Véletlen sorrend',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Cím A→Z',
'title_desc' => 'Cím Z→A',
'user_modified_asc' => 'Felhasználói módosítás 1→9',
diff --git a/app/i18n/id/conf.php b/app/i18n/id/conf.php
index 3c3a9a281..9c9704645 100644
--- a/app/i18n/id/conf.php
+++ b/app/i18n/id/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Berlaku juga pada label',
'sides_close_article' => 'Klik di luar area teks artikel untuk menutup artikel',
- 'sort' => array(
- '_' => 'Kriteria pengurutan',
- 'newer_first' => 'Terbaru dulu',
- 'older_first' => 'Terlama dulu',
- ),
'star' => array(
'when' => 'Tandai artikel sebagai favorit…',
),
diff --git a/app/i18n/id/index.php b/app/i18n/id/index.php
index bcca45c0c..5c6297d43 100644
--- a/app/i18n/id/index.php
+++ b/app/i18n/id/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Tandai umpan sebagai sudah dibaca',
'mark_selection_unread' => 'Tandai yang dipilih sebagai belum dibaca',
'mylabels' => 'Label Saya',
- 'newer_first' => 'Yang terbaru dulu',
'non-starred' => 'Tampilkan yang tidak difavoritkan',
'normal_view' => 'Tampilan Normal',
- 'older_first' => 'Yang terlama dulu',
'queries' => 'Pencarian pengguna',
'read' => 'Tampilkan yang sudah dibaca',
'reader_view' => 'Tampilan Membaca',
'rss_view' => 'Umpan RSS',
'search_short' => 'Cari',
'sort' => array(
- '_' => 'Kriteria pengurutan',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Tanggal publikasi 1→9',
'date_desc' => 'Tanggal publikasi 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Tautan A→Z',
'link_desc' => 'Tautan Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Acak',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Judul A→Z',
'title_desc' => 'Judul Z→A',
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php
index feb4c98a6..386730528 100644
--- a/app/i18n/it/conf.php
+++ b/app/i18n/it/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Si applica anche alle etichette',
'sides_close_article' => 'Cliccare fuori dall’area di testo dell’articolo chiude l’articolo',
- 'sort' => array(
- '_' => 'Ordinamento',
- 'newer_first' => 'Prima i più recenti',
- 'older_first' => 'Prima i più vecchi',
- ),
'star' => array(
'when' => 'Segna un articolo come preferito…',
),
diff --git a/app/i18n/it/index.php b/app/i18n/it/index.php
index 45c501cc5..9940a563d 100644
--- a/app/i18n/it/index.php
+++ b/app/i18n/it/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Segna il feed come letto',
'mark_selection_unread' => 'Segna i selezionati come non letti',
'mylabels' => 'Le mie etichette',
- 'newer_first' => 'Mostra prima i recenti',
'non-starred' => 'Escludi preferiti',
'normal_view' => 'Vista elenco',
- 'older_first' => 'Ordina per meno recenti',
'queries' => 'Chiavi di ricerca',
'read' => 'Mostra solo letti',
'reader_view' => 'Modalità di lettura',
'rss_view' => 'Feed RSS',
'search_short' => 'Cerca',
'sort' => array(
- '_' => 'Ordina per',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Categoria, titolo del feed A→Z',
'name_desc' => 'Categoria, titolo del feed Z→A',
),
'date_asc' => 'Data di pubblicazione 1→9',
'date_desc' => 'Data di pubblicazione 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Titolo del feed A→Z',
'name_desc' => 'Titolo del feed Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Lunghezza contenuto 9→1',
'link_asc' => 'Link A→Z', // IGNORE
'link_desc' => 'Link Z→A', // IGNORE
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Ordine casuale',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Titolo A→Z',
'title_desc' => 'Titolo Z→A',
'user_modified_asc' => 'Modificato dall’utente 1→9',
diff --git a/app/i18n/ja/conf.php b/app/i18n/ja/conf.php
index a0e523786..b68776fb1 100644
--- a/app/i18n/ja/conf.php
+++ b/app/i18n/ja/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'ラベルも適用する',
'sides_close_article' => '記事の外をクリックすると記事を閉じるようにする',
- 'sort' => array(
- '_' => '順序',
- 'newer_first' => '最新のものを先頭にする',
- 'older_first' => '最古のものを先頭にする',
- ),
'star' => array(
'when' => '記事をお気に入りに登録する。',
),
diff --git a/app/i18n/ja/index.php b/app/i18n/ja/index.php
index a44283c72..d05087ae0 100644
--- a/app/i18n/ja/index.php
+++ b/app/i18n/ja/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'フィードを既読にする',
'mark_selection_unread' => '選択した記事を未読にする',
'mylabels' => 'ラベル',
- 'newer_first' => '最新の記事を先頭にする',
'non-starred' => 'お気に入りに登録されてない記事を表示する',
'normal_view' => 'ノーマルビュー',
- 'older_first' => '最古の記事を先頭にする',
'queries' => 'ユーザークエリ',
'read' => '既読の記事を表示する',
'reader_view' => 'リーディングビュー',
'rss_view' => 'RSSフィード',
'search_short' => '検索',
'sort' => array(
- '_' => '並べ替え',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => '公開日順 1→9',
'date_desc' => '公開日順 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'リンクURL順 A→Z',
'link_desc' => 'リンクURL順 Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'ランダムに並べる',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'タイトル順 A→Z',
'title_desc' => 'タイトル順 Z→A',
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/ko/conf.php b/app/i18n/ko/conf.php
index b26c72112..2d791b5df 100644
--- a/app/i18n/ko/conf.php
+++ b/app/i18n/ko/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => '라벨에도 적용하기',
'sides_close_article' => '글 영역 바깥을 클릭하면 글 접기',
- 'sort' => array(
- '_' => '정렬 순서',
- 'newer_first' => '최근 글 먼저',
- 'older_first' => '오래된 글 먼저',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/ko/index.php b/app/i18n/ko/index.php
index f9b272b58..af0ee3539 100644
--- a/app/i18n/ko/index.php
+++ b/app/i18n/ko/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => '피드를 읽음으로 표시',
'mark_selection_unread' => '선택된 글을 읽지 않음으로 표시',
'mylabels' => '내 라벨',
- 'newer_first' => '최근 글 먼저',
'non-starred' => '즐겨찾기를 제외하고 표시',
'normal_view' => '일반 모드',
- 'older_first' => '오래된 글 먼저',
'queries' => '사용자 쿼리',
'read' => '읽은 글만 표시',
'reader_view' => '읽기 모드',
'rss_view' => 'RSS 피드',
'search_short' => '검색',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/lv/conf.php b/app/i18n/lv/conf.php
index f6c14d4ce..13320a560 100644
--- a/app/i18n/lv/conf.php
+++ b/app/i18n/lv/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Attiecas arī uz birkām',
'sides_close_article' => 'Spiežot ārpus raksta teksta apgabala, raksts tiek aizvērts',
- 'sort' => array(
- '_' => 'Kārtošanas kārtība',
- 'newer_first' => 'Sākumā jaunākos',
- 'older_first' => 'Sākumā vecākos',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/lv/index.php b/app/i18n/lv/index.php
index fcc506ecb..490272076 100644
--- a/app/i18n/lv/index.php
+++ b/app/i18n/lv/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Atzīmēt barotni kā izlasītu',
'mark_selection_unread' => 'Atzīmēt izvēlni kā izlasītu',
'mylabels' => 'Manas birkas',
- 'newer_first' => 'Sākumā jaunākos',
'non-starred' => 'Rādīt neiecienītākos',
'normal_view' => 'Parastais skats',
- 'older_first' => 'Sākumā vecākos',
'queries' => 'Lietotāja pieprasījumi',
'read' => 'Rādīt izlasītos',
'reader_view' => 'Lasīšanas skats',
'rss_view' => 'RSS barotne',
'search_short' => 'Meklēt',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php
index b18210bf3..b1f6c8c8e 100644
--- a/app/i18n/nl/conf.php
+++ b/app/i18n/nl/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Ook toepassen op labels',
'sides_close_article' => 'Sluit het artikel door buiten de artikeltekst te klikken',
- 'sort' => array(
- '_' => 'Sorteer volgorde',
- 'newer_first' => 'Nieuwste eerst',
- 'older_first' => 'Oudste eerst',
- ),
'star' => array(
'when' => 'Markeer een artikel als favoriet…',
),
diff --git a/app/i18n/nl/index.php b/app/i18n/nl/index.php
index cb07f06a6..a66a3660c 100644
--- a/app/i18n/nl/index.php
+++ b/app/i18n/nl/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Markeer feed als gelezen',
'mark_selection_unread' => 'Markeer selectie als ongelezen',
'mylabels' => 'Mijn labels',
- 'newer_first' => 'Nieuwste eerst',
'non-starred' => 'Niet-favorieten tonen',
'normal_view' => 'Normale weergave',
- 'older_first' => 'Oudste eerst',
'queries' => 'Gebruikers queries',
'read' => 'Gelezen tonen',
'reader_view' => 'Leesmodus',
'rss_view' => 'RSS-feed',
'search_short' => 'Zoeken',
'sort' => array(
- '_' => 'Sorteercriteria',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Categorie, feedtitels A→Z',
'name_desc' => 'Categorie, feedtitels Z→A',
),
'date_asc' => 'Publicatiedatum 1→9',
'date_desc' => 'Publicatiedatum 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feedtitel A→Z',
'name_desc' => 'Feedtitel Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Lengte van inhoud 9→1',
'link_asc' => 'Link A→Z', // IGNORE
'link_desc' => 'Link Z→A', // IGNORE
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Willekeurige volgorde',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Titel A→Z',
'title_desc' => 'Titel Z→A',
'user_modified_asc' => 'Aangepast door gebruiker 1→9',
diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php
index 16bd0e33f..86f82eef6 100644
--- a/app/i18n/oc/conf.php
+++ b/app/i18n/oc/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Aplicar tanben a las etiquetas',
'sides_close_article' => 'Clicar fòra de la zòna de tèxte tampa l’article',
- 'sort' => array(
- '_' => 'Òrdre de tria',
- 'newer_first' => 'Mai recents en primièr',
- 'older_first' => 'Mai ancians en primièr',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/oc/index.php b/app/i18n/oc/index.php
index 56d71543e..ad1a9efb8 100644
--- a/app/i18n/oc/index.php
+++ b/app/i18n/oc/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Marcar lo flux coma legit',
'mark_selection_unread' => 'Marcar la seleccion coma pas legida',
'mylabels' => 'Mas etiquetas',
- 'newer_first' => 'Mai recents en primièr',
'non-starred' => 'Mostrar los pas favorits',
'normal_view' => 'Vista normala',
- 'older_first' => 'Mai ancians en primièr',
'queries' => 'Filtres utilizaire',
'read' => 'Mostrar los legits',
'reader_view' => 'Vista lectura',
'rss_view' => 'Flux RSS',
'search_short' => 'Recercar',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/pl/conf.php b/app/i18n/pl/conf.php
index e45a9cb84..4cd587576 100644
--- a/app/i18n/pl/conf.php
+++ b/app/i18n/pl/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Stosuje się również do etykiet',
'sides_close_article' => 'Kliknięcie poza zawartością wiadomości zamyka widok wiadomości',
- 'sort' => array(
- '_' => 'Porządek sortowania',
- 'newer_first' => 'Najpierw najnowsze',
- 'older_first' => 'Najpierw najstarsze',
- ),
'star' => array(
'when' => 'Oznacz artykuł jako ulubiony…',
),
diff --git a/app/i18n/pl/index.php b/app/i18n/pl/index.php
index 66e80b0a7..1c9a29a15 100644
--- a/app/i18n/pl/index.php
+++ b/app/i18n/pl/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Oznacz kanał jako przeczytany',
'mark_selection_unread' => 'Oznacz wiadomości jako nieprzeczytane',
'mylabels' => 'Własne etykiety',
- 'newer_first' => 'Najpierw najnowsze',
'non-starred' => 'Pokaż wiadomości, które nie są ulubione',
'normal_view' => 'Widok normalny',
- 'older_first' => 'Najpierw najstarsze',
'queries' => 'Zapisane zapytania',
'read' => 'Pokaż przeczytane',
'reader_view' => 'Widok czytania',
'rss_view' => 'Kanał RSS',
'search_short' => 'Szukaj',
'sort' => array(
- '_' => 'Kryteria sortowania',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Tytuł kategorii i kanału A→Z',
'name_desc' => 'Tytuł kategorii i kanału Z→A',
),
'date_asc' => 'Data publikacji 1→9',
'date_desc' => 'Data publikacji 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Tytuł kanału A→Z',
'name_desc' => 'Tytuł kanału Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Długość zawartości 9→1',
'link_asc' => 'Odnośnik A→Z',
'link_desc' => 'Odnośnik Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Losowa kolejność',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Tytuł A→Z',
'title_desc' => 'Tytuł Z→A',
'user_modified_asc' => 'Zmodyfikowane przez użytkownika 1→9',
diff --git a/app/i18n/pt-BR/conf.php b/app/i18n/pt-BR/conf.php
index 92fdb167d..a141f7ffa 100644
--- a/app/i18n/pt-BR/conf.php
+++ b/app/i18n/pt-BR/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Aplicar também nas tags',
'sides_close_article' => 'Clicando fora da área do texto do artigo fecha o mesmo',
- 'sort' => array(
- '_' => 'Ordem de visualização',
- 'newer_first' => 'Novos primeiro',
- 'older_first' => 'Antigos primeiro',
- ),
'star' => array(
'when' => 'Marque um artigo como favorito…',
),
diff --git a/app/i18n/pt-BR/index.php b/app/i18n/pt-BR/index.php
index 9b67ca450..57cc4ea74 100644
--- a/app/i18n/pt-BR/index.php
+++ b/app/i18n/pt-BR/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Marcar feed com lido',
'mark_selection_unread' => 'Marcar seleção como não lida',
'mylabels' => 'Minhas etiquetas',
- 'newer_first' => 'Novos primeiro',
'non-starred' => 'Mostrar itens que não são favoritos',
'normal_view' => 'visualização normal',
- 'older_first' => 'Antigos primeiro',
'queries' => 'Queries do usuário',
'read' => 'Mostrar leitura',
'reader_view' => 'Visualização de leitura',
'rss_view' => 'Feed RSS',
'search_short' => 'Buscar',
'sort' => array(
- '_' => 'Critérios de ordenação',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Categoria, títulos dos feeds A→Z',
'name_desc' => 'Categoria, títulos dos feeds Z→A',
),
'date_asc' => 'Data de publicação 1→9',
'date_desc' => 'Data de publicação 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Título do feed A→Z',
'name_desc' => 'Título do feed Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Comprimento do conteúdo 9→1',
'link_asc' => 'Link A→Z', // IGNORE
'link_desc' => 'Link Z→A', // IGNORE
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Ordem aleatória',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Título A→Z',
'title_desc' => 'Título Z→A',
'user_modified_asc' => 'Modificado pelo usuário 1→9',
diff --git a/app/i18n/pt-PT/conf.php b/app/i18n/pt-PT/conf.php
index a4f4e4a5c..32f2016db 100644
--- a/app/i18n/pt-PT/conf.php
+++ b/app/i18n/pt-PT/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Aplicar também nas tags',
'sides_close_article' => 'Clicando fora da área do texto do artigo fecha o mesmo',
- 'sort' => array(
- '_' => 'Ordem de visualização',
- 'newer_first' => 'Novos primeiro',
- 'older_first' => 'Antigos primeiro',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/pt-PT/index.php b/app/i18n/pt-PT/index.php
index e2746eebe..1f0e187d5 100644
--- a/app/i18n/pt-PT/index.php
+++ b/app/i18n/pt-PT/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Marcar feed com lido',
'mark_selection_unread' => 'Marcar seleção como não lida',
'mylabels' => 'Minhas etiquetas',
- 'newer_first' => 'Novos primeiro',
'non-starred' => 'Mostrar todos, exceto favoritos',
'normal_view' => 'visualização normal',
- 'older_first' => 'Antigos primeiro',
'queries' => 'Queries do utilizador',
'read' => 'Mostrar apenas lidos',
'reader_view' => 'Visualização de leitura',
'rss_view' => 'Feed RSS',
'search_short' => 'Pesquisar',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php
index 82dce384f..8179ce307 100644
--- a/app/i18n/ru/conf.php
+++ b/app/i18n/ru/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Также относится к меткам',
'sides_close_article' => 'Нажатия мышью за пределами текста статьи закрывают статью',
- 'sort' => array(
- '_' => 'Порядок сортировки',
- 'newer_first' => 'Сначала новые',
- 'older_first' => 'Сначала старые',
- ),
'star' => array(
'when' => 'Отмечать статью избранной…',
),
diff --git a/app/i18n/ru/index.php b/app/i18n/ru/index.php
index 9b8982b3a..66145969e 100644
--- a/app/i18n/ru/index.php
+++ b/app/i18n/ru/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Отметить ленту прочитанной',
'mark_selection_unread' => 'Отметить выделение прочитанным',
'mylabels' => 'Мои метки',
- 'newer_first' => 'Сначала новые',
'non-starred' => 'Показать неизбранное',
'normal_view' => 'Обычный вид',
- 'older_first' => 'Сначала старые',
'queries' => 'Запросы',
'read' => 'Показать прочитанное',
'reader_view' => 'Вид для чтения',
'rss_view' => 'RSS-лента',
'search_short' => 'Поиск',
'sort' => array(
- '_' => 'Критерии сортировки',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Категории, названия лент А→Я',
'name_desc' => 'Категории, названия лент Я→А',
),
'date_asc' => 'Дата публикации 1→9',
'date_desc' => 'Дата публикации 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Названия лент А→Я',
'name_desc' => 'Названия лент Я→А',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Длина контента 9→1',
'link_asc' => 'Ссылка А→Я',
'link_desc' => 'Ссылка Я→А',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Случайный порядок',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Заголовок А→Я',
'title_desc' => 'Заголовок Я→А',
'user_modified_asc' => 'Изменено пользователем 1→9',
diff --git a/app/i18n/sk/conf.php b/app/i18n/sk/conf.php
index 27e669067..07e38c428 100644
--- a/app/i18n/sk/conf.php
+++ b/app/i18n/sk/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Týka sa aj štítkov',
'sides_close_article' => 'Po kliknutí mimo textu článku sa článok zatvorí',
- 'sort' => array(
- '_' => 'Poradie',
- 'newer_first' => 'Novšie hore',
- 'older_first' => 'Staršie hore',
- ),
'star' => array(
'when' => 'Mark an article as favourite…', // TODO
),
diff --git a/app/i18n/sk/index.php b/app/i18n/sk/index.php
index da3236938..3c82111d1 100644
--- a/app/i18n/sk/index.php
+++ b/app/i18n/sk/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Označiť kanál ako prečítaný',
'mark_selection_unread' => 'Označiť označené ako prečítané',
'mylabels' => 'Moje nálepky',
- 'newer_first' => 'Novšie hore',
'non-starred' => 'Zobraziť všetko okrem obľúbených',
'normal_view' => 'Základné zobrazenie',
- 'older_first' => 'Staršie hore',
'queries' => 'Používateľské dopyty',
'read' => 'Zobraziť prečítané',
'reader_view' => 'Zobrazenie na čítanie',
'rss_view' => 'RSS kanál',
'search_short' => 'Hľadať',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php
index 8e50ff93d..d5ab74f83 100644
--- a/app/i18n/tr/conf.php
+++ b/app/i18n/tr/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Etiketler için de geçerlidir',
'sides_close_article' => 'Makale metin alanının dışına tıklayınca makaleyi kapat',
- 'sort' => array(
- '_' => 'Sıralama düzeni',
- 'newer_first' => 'Önce yeniler',
- 'older_first' => 'Önce eskiler',
- ),
'star' => array(
'when' => 'Bir makaleyi favori olarak işaretle…',
),
diff --git a/app/i18n/tr/index.php b/app/i18n/tr/index.php
index ea1ba9e15..dd00a83f2 100644
--- a/app/i18n/tr/index.php
+++ b/app/i18n/tr/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Beslemeyi okundu olarak işaretle',
'mark_selection_unread' => 'Seçimi okunmadı olarak işaretle',
'mylabels' => 'Etiketlerim',
- 'newer_first' => 'Önce yeniler',
'non-starred' => 'Favori olmayanları göster',
'normal_view' => 'Normal görünüm',
- 'older_first' => 'Önce eskiler',
'queries' => 'Kullanıcı sorguları',
'read' => 'Okunanları göster',
'reader_view' => 'Okuma görünümü',
'rss_view' => 'RSS beslemesi',
'search_short' => 'Ara',
'sort' => array(
- '_' => 'Sıralama kriteri',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Yayın tarihi 1→9',
'date_desc' => 'Yayın tarihi 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Bağlantı A→Z',
'link_desc' => 'Bağlantı Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Rastgele sıralama',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Başlık A→Z',
'title_desc' => 'Başlık Z→A',
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/uk/conf.php b/app/i18n/uk/conf.php
index 91c4ce61f..ee41e2d47 100644
--- a/app/i18n/uk/conf.php
+++ b/app/i18n/uk/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => 'Впливає також на мітки',
'sides_close_article' => 'Натиск за межами тексту статті закриває статтю',
- 'sort' => array(
- '_' => 'Порядок',
- 'newer_first' => 'Спершу новіші',
- 'older_first' => 'Спершу старіші',
- ),
'star' => array(
'when' => 'Вподобати статтю…',
),
diff --git a/app/i18n/uk/index.php b/app/i18n/uk/index.php
index 03f5fc459..c12b8da28 100644
--- a/app/i18n/uk/index.php
+++ b/app/i18n/uk/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => 'Позначити стрічку прочитаною',
'mark_selection_unread' => 'Позначити вибрані непрочитаними',
'mylabels' => 'Мої мітки',
- 'newer_first' => 'Спершу новіші',
'non-starred' => 'Показати невподобані',
'normal_view' => 'Звичайний показ',
- 'older_first' => 'Спершу старіші',
'queries' => 'Користувацькі запити',
'read' => 'Показати прочитані',
'reader_view' => 'Читацький показ',
'rss_view' => 'RSS-стрічка',
'search_short' => 'Пошук',
'sort' => array(
- '_' => 'Критерії впорядкування',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Заголовки категорії та стрічки А→Я',
'name_desc' => 'Заголовки категорії та стрічки Я→А',
),
'date_asc' => 'Дата оприлюднення 1→9',
'date_desc' => 'Дата оприлюднення 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Назва стрічки A→Z',
'name_desc' => 'Назва стрічки Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Посилання А→Я',
'link_desc' => 'Посилання Я→А',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Довільний порядок',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Заголовок А→Я',
'title_desc' => 'Заголовок Я→А',
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/i18n/zh-CN/conf.php b/app/i18n/zh-CN/conf.php
index 9832be6dc..e67e9ab31 100644
--- a/app/i18n/zh-CN/conf.php
+++ b/app/i18n/zh-CN/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => '同样适用于标签',
'sides_close_article' => '点击文章文本区域外关闭文章',
- 'sort' => array(
- '_' => '排列顺序',
- 'newer_first' => '由新至旧',
- 'older_first' => '由旧至新',
- ),
'star' => array(
'when' => '将文章标记为收藏时…',
),
diff --git a/app/i18n/zh-CN/index.php b/app/i18n/zh-CN/index.php
index d228043d5..906d78f83 100644
--- a/app/i18n/zh-CN/index.php
+++ b/app/i18n/zh-CN/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => '此订阅源设为已读',
'mark_selection_unread' => '将筛选结果标记为未读',
'mylabels' => '我的标签',
- 'newer_first' => '由新至旧',
'non-starred' => '显示未收藏',
'normal_view' => '普通视图',
- 'older_first' => '由旧至新',
'queries' => '自定义查询',
'read' => '显示已读',
'reader_view' => '阅读视图',
'rss_view' => '订阅源',
'search_short' => '搜索',
'sort' => array(
- '_' => '排序标准',
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => '分类、订阅源标题 A→Z',
'name_desc' => '分类、订阅源标题 Z→A',
),
'date_asc' => '发布日期 1→9',
'date_desc' => '发布日期 9→1',
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => '订阅源标题 A→Z',
'name_desc' => '订阅源标题 Z→A',
@@ -104,7 +103,15 @@ return array(
'length_desc' => '内容长度 9→1',
'link_asc' => '链接 A→Z',
'link_desc' => '链接 Z→A',
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => '随机顺序',
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => '标题 A→Z',
'title_desc' => '标题 Z→A',
'user_modified_asc' => '用户修改 1→9',
diff --git a/app/i18n/zh-TW/conf.php b/app/i18n/zh-TW/conf.php
index 636f8c024..9a8a70a26 100644
--- a/app/i18n/zh-TW/conf.php
+++ b/app/i18n/zh-TW/conf.php
@@ -294,11 +294,6 @@ return array(
),
'show_fav_unread_help' => '同樣適用於標籤',
'sides_close_article' => '點擊文章區域外以關閉',
- 'sort' => array(
- '_' => '排列順序',
- 'newer_first' => '由新至舊',
- 'older_first' => '由舊至新',
- ),
'star' => array(
'when' => '標記一篇文章為最愛…',
),
diff --git a/app/i18n/zh-TW/index.php b/app/i18n/zh-TW/index.php
index f62519ec3..9b2529b76 100644
--- a/app/i18n/zh-TW/index.php
+++ b/app/i18n/zh-TW/index.php
@@ -77,23 +77,22 @@ return array(
'mark_feed_read' => '此訂閱源設為已讀',
'mark_selection_unread' => '選中設為已讀',
'mylabels' => '我的標籤',
- 'newer_first' => '由新至舊',
'non-starred' => '顯示未收藏',
'normal_view' => '普通視圖',
- 'older_first' => '由舊至新',
'queries' => '自定義查詢',
'read' => '顯示已讀',
'reader_view' => '閱讀視圖',
'rss_view' => '訂閱源',
'search_short' => '搜尋',
'sort' => array(
- '_' => 'Sorting criteria', // TODO
+ 'asc' => 'Ascending', // TODO
'c' => array(
'name_asc' => 'Category, feed titles A→Z', // TODO
'name_desc' => 'Category, feed titles Z→A', // TODO
),
'date_asc' => 'Publication date 1→9', // TODO
'date_desc' => 'Publication date 9→1', // TODO
+ 'desc' => 'Descending', // TODO
'f' => array(
'name_asc' => 'Feed title A→Z', // TODO
'name_desc' => 'Feed title Z→A', // TODO
@@ -104,7 +103,15 @@ return array(
'length_desc' => 'Content length 9→1', // TODO
'link_asc' => 'Link A→Z', // TODO
'link_desc' => 'Link Z→A', // TODO
+ 'primary' => array(
+ '_' => 'Sorting criterion', // TODO
+ 'help' => 'Sorting by <em>received</em> date is recommended in most cases, for consistency and performance', // TODO
+ ),
'rand' => 'Random order', // TODO
+ 'secondary' => array(
+ '_' => 'Secondary sorting criterion', // TODO
+ 'help' => 'Only relevant when the primary sorting criterion is categories or feeds titles', // TODO
+ ),
'title_asc' => 'Title A→Z', // TODO
'title_desc' => 'Title Z→A', // TODO
'user_modified_asc' => 'User modified 1→9', // TODO
diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml
index debc06611..f168f8d65 100644
--- a/app/layout/nav_menu.phtml
+++ b/app/layout/nav_menu.phtml
@@ -227,17 +227,17 @@
<?php
if (FreshRSS_Context::$order === 'ASC') {
$icon = 'sort-up';
- $title = _t('index.menu.older_first');
+ $title = _t('index.menu.sort.asc');
} else {
$icon = 'sort-down';
- $title = _t('index.menu.newer_first');
+ $title = _t('index.menu.sort.desc');
}
$url_order = Minz_Request::currentRequest();
?>
<div id="nav_menu_sort" class="group">
<div class="dropdown">
<div id="dropdown-sort" class="dropdown-target"></div>
- <a id="toggle-order" class="dropdown-toggle btn" href="#dropdown-sort" title="<?= _t('index.menu.sort') ?>"><?= _i($icon) ?></a>
+ <a id="toggle-order" class="dropdown-toggle btn" href="#dropdown-sort" title="<?= _t('index.menu.sort.primary') ?>"><?= _i($icon) ?></a>
<ul class="dropdown-menu" role="radiogroup">
<li class="item" role="radio" aria-checked="<?= FreshRSS_Context::$order === 'DESC' && FreshRSS_Context::$sort === 'id' ? 'true' : 'false' ?>">
<a href="<?= Minz_Url::display($url_order, amend: ['params' => ['sort' => 'id', 'order' => 'DESC']]) ?>"><?= _t('index.menu.sort.id_desc') ?></a></li>
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml
index 31daa7984..36cc27c0a 100644
--- a/app/views/configure/reading.phtml
+++ b/app/views/configure/reading.phtml
@@ -74,16 +74,59 @@
</div>
</div>
+ <?php
+ $userSort = FreshRSS_Context::userConf()->sort;
+ $userSortOrder = FreshRSS_Context::userConf()->sort_order;
+ $userSortCombined = $userSort === 'rand' ? 'rand' : $userSort . '_' . strtolower($userSortOrder ?? 'desc');
+ ?>
<div class="form-group">
- <label class="group-name" for="sort_order"><?= _t('conf.reading.sort') ?></label>
- <div class="group-controls">
- <select name="sort_order" id="sort_order">
- <option value="DESC"<?= FreshRSS_Context::userConf()->sort_order === 'DESC' ? ' selected="selected"' : '' ?>><?= _t('conf.reading.sort.newer_first') ?></option>
- <option value="ASC"<?= FreshRSS_Context::userConf()->sort_order === 'ASC' ? ' selected="selected"' : '' ?>><?= _t('conf.reading.sort.older_first') ?></option>
+ <label class="group-name" for="primary_sort"><?= _t('index.menu.sort.primary') ?></label>
+ <div class="group-controls">
+ <select name="primary_sort" id="primary_sort">
+ <option value="id_desc" <?= $userSortCombined === 'id_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_desc') ?></option>
+ <option value="date_desc" <?= $userSortCombined === 'date_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_desc') ?></option>
+ <option value="length_desc" <?= $userSortCombined === 'length_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.length_desc') ?></option>
+ <option value="link_desc" <?= $userSortCombined === 'link_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_desc') ?></option>
+ <option value="title_desc" <?= $userSortCombined === 'title_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_desc') ?></option>
+ <option value="f.name_desc" <?= $userSortCombined === 'f.name_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.f.name_desc') ?></option>
+ <option value="c.name_desc" <?= $userSortCombined === 'c.name_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.c.name_desc') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="rand" <?= $userSortCombined === 'rand' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.rand') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="id_asc" <?= $userSortCombined === 'id_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_asc') ?></option>
+ <option value="date_asc" <?= $userSortCombined === 'date_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_asc') ?></option>
+ <option value="length_asc" <?= $userSortCombined === 'length_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.length_asc') ?></option>
+ <option value="link_asc" <?= $userSortCombined === 'link_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_asc') ?></option>
+ <option value="title_asc" <?= $userSortCombined === 'title_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_asc') ?></option>
+ <option value="f.name_asc" <?= $userSortCombined === 'f.name_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.f.name_asc') ?></option>
+ <option value="c.name_asc" <?= $userSortCombined === 'c.name_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.c.name_asc') ?></option>
</select>
+ <p class="help"><?= _i('help') ?> <?= _t('index.menu.sort.primary.help') ?></p>
</div>
</div>
+ <?php
+ $userSecondarySort = FreshRSS_Context::userConf()->secondary_sort;
+ $userSecondarySortOrder = FreshRSS_Context::userConf()->secondary_sort_order;
+ $userSecondarySortCombined = $userSecondarySort === 'rand' ? 'rand' : $userSecondarySort . '_' . strtolower($userSecondarySortOrder ?? 'desc');
+ ?>
+ <div class="form-group">
+ <label class="group-name" for="secondary_sort"><?= _t('index.menu.sort.secondary') ?></label>
+ <div class="group-controls">
+ <select name="secondary_sort" id="secondary_sort">
+ <option value="id_desc" <?= $userSecondarySortCombined === 'id_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_desc') ?></option>
+ <option value="date_desc" <?= $userSecondarySortCombined === 'date_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_desc') ?></option>
+ <option value="link_desc" <?= $userSecondarySortCombined === 'link_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_desc') ?></option>
+ <option value="title_desc" <?= $userSecondarySortCombined === 'title_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_desc') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="id_asc" <?= $userSecondarySortCombined === 'id_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_asc') ?></option>
+ <option value="date_asc" <?= $userSecondarySortCombined === 'date_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_asc') ?></option>
+ <option value="link_asc" <?= $userSecondarySortCombined === 'link_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_asc') ?></option>
+ <option value="title_asc" <?= $userSecondarySortCombined === 'title_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_asc') ?></option>
+ </select>
+ <p class="help"><?= _i('help') ?> <?= _t('index.menu.sort.secondary.help') ?></p>
+ </div>
+ </div>
</fieldset>
<fieldset>
diff --git a/app/views/helpers/category/update.phtml b/app/views/helpers/category/update.phtml
index b8e86662e..6b4df34e5 100644
--- a/app/views/helpers/category/update.phtml
+++ b/app/views/helpers/category/update.phtml
@@ -36,6 +36,37 @@
</div>
</div>
+ <?php
+ $categoryDefaultSort = $this->category->defaultSort();
+ $categoryDefaultOrder = $this->category->defaultOrder();
+ $categoryDefaultSortOrder = $categoryDefaultSort !== null
+ ? ($categoryDefaultSort === 'rand' ? 'rand' : $categoryDefaultSort . '_' . strtolower($categoryDefaultOrder ?? 'desc'))
+ : '';
+ ?>
+ <div class="form-group">
+ <label class="group-name" for="defaultSortOrder"><?= _t('index.menu.sort.primary') ?></label>
+ <div class="group-controls">
+ <select name="defaultSortOrder" id="defaultSortOrderCategory" class="w50">
+ <option value=""></option>
+ <option value="id_desc" <?= $categoryDefaultSortOrder === 'id_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_desc') ?></option>
+ <option value="date_desc" <?= $categoryDefaultSortOrder === 'date_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_desc') ?></option>
+ <option value="length_desc" <?= $categoryDefaultSortOrder === 'length_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.length_desc') ?></option>
+ <option value="link_desc" <?= $categoryDefaultSortOrder === 'link_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_desc') ?></option>
+ <option value="title_desc" <?= $categoryDefaultSortOrder === 'title_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_desc') ?></option>
+ <option value="f.name_desc" <?= $categoryDefaultSortOrder === 'f.name_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.f.name_desc') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="rand" <?= $categoryDefaultSortOrder === 'rand' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.rand') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="id_asc" <?= $categoryDefaultSortOrder === 'id_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_asc') ?></option>
+ <option value="date_asc" <?= $categoryDefaultSortOrder === 'date_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_asc') ?></option>
+ <option value="length_asc" <?= $categoryDefaultSortOrder === 'length_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.length_asc') ?></option>
+ <option value="link_asc" <?= $categoryDefaultSortOrder === 'link_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_asc') ?></option>
+ <option value="title_asc" <?= $categoryDefaultSortOrder === 'title_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_asc') ?></option>
+ <option value="f.name_asc" <?= $categoryDefaultSortOrder === 'f.name_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.f.name_asc') ?></option>
+ </select>
+ </div>
+ </div>
+
<div class="form-group form-actions">
<div class="group-controls">
<button type="submit" class="btn btn-important"><?= _t('gen.action.submit') ?></button>
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml
index 001b88c1f..394c536a3 100644
--- a/app/views/helpers/feed/update.phtml
+++ b/app/views/helpers/feed/update.phtml
@@ -130,6 +130,36 @@
</div>
</div>
+
+ <?php
+ $feedDefaultSort = $this->feed->defaultSort();
+ $feedDefaultOrder = $this->feed->defaultOrder();
+ $feedDefaultSortOrder = $feedDefaultSort !== null
+ ? ($feedDefaultSort === 'rand' ? 'rand' : $feedDefaultSort . '_' . strtolower($feedDefaultOrder ?? 'desc'))
+ : '';
+ ?>
+ <div class="form-group">
+ <label class="group-name" for="defaultSortOrder"><?= _t('index.menu.sort.primary') ?></label>
+ <div class="group-controls">
+ <select name="defaultSortOrder" id="defaultSortOrderFeed" class="w50">
+ <option value=""></option>
+ <option value="id_desc" <?= $feedDefaultSortOrder === 'id_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_desc') ?></option>
+ <option value="date_desc" <?= $feedDefaultSortOrder === 'date_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_desc') ?></option>
+ <option value="length_desc" <?= $feedDefaultSortOrder === 'length_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.length_desc') ?></option>
+ <option value="link_desc" <?= $feedDefaultSortOrder === 'link_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_desc') ?></option>
+ <option value="title_desc" <?= $feedDefaultSortOrder === 'title_desc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_desc') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="rand" <?= $feedDefaultSortOrder === 'rand' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.rand') ?></option>
+ <option disabled="disabled">────────────────</option>
+ <option value="id_asc" <?= $feedDefaultSortOrder === 'id_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.id_asc') ?></option>
+ <option value="date_asc" <?= $feedDefaultSortOrder === 'date_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.date_asc') ?></option>
+ <option value="length_asc" <?= $feedDefaultSortOrder === 'length_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.length_asc') ?></option>
+ <option value="link_asc" <?= $feedDefaultSortOrder === 'link_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.link_asc') ?></option>
+ <option value="title_asc" <?= $feedDefaultSortOrder === 'title_asc' ? 'selected="selected"' : '' ?>><?= _t('index.menu.sort.title_asc') ?></option>
+ </select>
+ </div>
+ </div>
+
<div class="form-group">
<label class="group-name" for="unicityCriteria"><?= _t('sub.feed.unicityCriteria') ?></label>
<?php