aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2022-08-18 12:10:55 +0200
committerGravatar GitHub <noreply@github.com> 2022-08-18 12:10:55 +0200
commit1603c10bbab61b4a84380c8a9d5aa77536a4f1c7 (patch)
tree36ee76291c8e877d7421641ae7a38570ff65f8ce /app
parent4f111c5b305078a641d13ac41ce7d798e3cc19ce (diff)
XPath ability to define the UID manually (#4507)
* XPath ability to define the UID manually * Fix error in i18n
Diffstat (limited to 'app')
-rwxr-xr-xapp/Controllers/feedController.php1
-rw-r--r--app/Controllers/subscriptionController.php1
-rw-r--r--app/Models/Feed.php9
-rw-r--r--app/Services/ImportService.php1
-rw-r--r--app/i18n/cz/sub.php6
-rw-r--r--app/i18n/de/sub.php6
-rw-r--r--app/i18n/en-us/sub.php6
-rw-r--r--app/i18n/en/sub.php6
-rwxr-xr-xapp/i18n/es/sub.php6
-rw-r--r--app/i18n/fr/sub.php4
-rw-r--r--app/i18n/he/sub.php6
-rw-r--r--app/i18n/it/sub.php6
-rw-r--r--app/i18n/ja/sub.php6
-rw-r--r--app/i18n/ko/sub.php6
-rw-r--r--app/i18n/nl/sub.php6
-rw-r--r--app/i18n/oc/sub.php6
-rw-r--r--app/i18n/pl/sub.php6
-rw-r--r--app/i18n/pt-br/sub.php6
-rw-r--r--app/i18n/ru/sub.php4
-rw-r--r--app/i18n/sk/sub.php6
-rw-r--r--app/i18n/tr/sub.php6
-rw-r--r--app/i18n/zh-cn/sub.php4
-rw-r--r--app/views/helpers/export/opml.phtml1
-rw-r--r--app/views/helpers/feed/update.phtml8
-rw-r--r--app/views/subscription/add.phtml7
25 files changed, 114 insertions, 16 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index c016d3584..95bca33eb 100755
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -198,6 +198,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
if (Minz_Request::param('xPathItemTimestamp', '') != '') $xPathSettings['itemTimestamp'] = Minz_Request::param('xPathItemTimestamp', '', true);
if (Minz_Request::param('xPathItemThumbnail', '') != '') $xPathSettings['itemThumbnail'] = Minz_Request::param('xPathItemThumbnail', '', true);
if (Minz_Request::param('xPathItemCategories', '') != '') $xPathSettings['itemCategories'] = Minz_Request::param('xPathItemCategories', '', true);
+ if (Minz_Request::param('xPathItemUid', '') != '') $xPathSettings['itemUid'] = Minz_Request::param('xPathItemUid', '', true);
if (!empty($xPathSettings)) {
$attributes['xpath'] = $xPathSettings;
}
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index 9e4eab8e2..bbefc2d68 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -204,6 +204,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
if (Minz_Request::param('xPathItemTimestamp', '') != '') $xPathSettings['itemTimestamp'] = Minz_Request::param('xPathItemTimestamp', '', true);
if (Minz_Request::param('xPathItemThumbnail', '') != '') $xPathSettings['itemThumbnail'] = Minz_Request::param('xPathItemThumbnail', '', true);
if (Minz_Request::param('xPathItemCategories', '') != '') $xPathSettings['itemCategories'] = Minz_Request::param('xPathItemCategories', '', true);
+ if (Minz_Request::param('xPathItemUid', '') != '') $xPathSettings['itemUid'] = Minz_Request::param('xPathItemUid', '', true);
if (!empty($xPathSettings)) {
$feed->_attributes('xpath', $xPathSettings);
}
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 4de61167b..710f8b557 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -611,6 +611,7 @@ class FreshRSS_Feed extends Minz_Model {
$xPathItemTimestamp = $xPathSettings['itemTimestamp'] ?? '';
$xPathItemThumbnail = $xPathSettings['itemThumbnail'] ?? '';
$xPathItemCategories = $xPathSettings['itemCategories'] ?? '';
+ $xPathItemUid = $xPathSettings['itemUid'] ?? '';
if ($xPathItem == '') {
return null;
}
@@ -657,8 +658,14 @@ class FreshRSS_Feed extends Minz_Model {
}
}
}
- if ($item['title'] . $item['content'] . $item['link'] != '') {
+ if ($xPathItemUid != '') {
+ $item['guid'] = @$xpath->evaluate('normalize-space(' . $xPathItemUid . ')', $node);
+ }
+ if (empty($item['guid'])) {
$item['guid'] = 'urn:sha1:' . sha1($item['title'] . $item['content'] . $item['link']);
+ }
+
+ if ($item['title'] . $item['content'] . $item['link'] != '') {
$item = Minz_Helper::htmlspecialchars_utf8($item);
$view->entries[] = FreshRSS_Entry::fromArray($item);
}
diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php
index e09da1f15..780dcbd07 100644
--- a/app/Services/ImportService.php
+++ b/app/Services/ImportService.php
@@ -179,6 +179,7 @@ class FreshRSS_Import_Service {
case 'xPathItemTimestamp': $xPathSettings['itemTimestamp'] = $value['value']; break;
case 'xPathItemThumbnail': $xPathSettings['itemThumbnail'] = $value['value']; break;
case 'xPathItemCategories': $xPathSettings['itemCategories'] = $value['value']; break;
+ case 'xPathItemUid': $xPathSettings['itemUid'] = $value['value']; break;
}
}
}
diff --git a/app/i18n/cz/sub.php b/app/i18n/cz/sub.php
index 7867055c7..6cacf3e8b 100644
--- a/app/i18n/cz/sub.php
+++ b/app/i18n/cz/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php
index ff4f11ca3..c8a0c7961 100644
--- a/app/i18n/de/sub.php
+++ b/app/i18n/de/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/en-us/sub.php b/app/i18n/en-us/sub.php
index de5fd9340..648fdec9a 100644
--- a/app/i18n/en-us/sub.php
+++ b/app/i18n/en-us/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // IGNORE
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // IGNORE
),
- 'item_categories' => 'items tags', // IGNORE
+ 'item_categories' => 'item tags', // IGNORE
'item_content' => array(
'_' => 'item content', // IGNORE
'help' => 'Example to take the full item: <code>.</code>', // IGNORE
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // IGNORE
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // IGNORE
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // IGNORE
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // IGNORE
'help' => 'Example: <code>descendant::a/@href</code>', // IGNORE
diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php
index 9cc9c61bf..202d89b3c 100644
--- a/app/i18n/en/sub.php
+++ b/app/i18n/en/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author',
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>',
),
- 'item_categories' => 'items tags',
+ 'item_categories' => 'item tags',
'item_content' => array(
'_' => 'item content',
'help' => 'Example to take the full item: <code>.</code>',
@@ -104,6 +104,10 @@ return array(
'_' => 'item title',
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>',
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)',
'help' => 'Example: <code>descendant::a/@href</code>',
diff --git a/app/i18n/es/sub.php b/app/i18n/es/sub.php
index 90e853f9a..dcf72697f 100755
--- a/app/i18n/es/sub.php
+++ b/app/i18n/es/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php
index 379bd6296..3faf379c2 100644
--- a/app/i18n/fr/sub.php
+++ b/app/i18n/fr/sub.php
@@ -104,6 +104,10 @@ return array(
'_' => 'titre de l’article',
'help' => 'Utiliser en particulier l’<a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">axe XPath</a> <code>descendant::</code> comme <code>descendant::h2</code>',
),
+ 'item_uid' => array(
+ '_' => 'identifiant unique de l’article',
+ 'help' => 'Optionnel. Exemple : <code>descendant::div/@data-uri</code>',
+ ),
'item_uri' => array(
'_' => 'lien (URL) de l’article',
'help' => 'Exemple : <code>descendant::a/@href</code>',
diff --git a/app/i18n/he/sub.php b/app/i18n/he/sub.php
index bcb540e6b..0d9f2ea96 100644
--- a/app/i18n/he/sub.php
+++ b/app/i18n/he/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/it/sub.php b/app/i18n/it/sub.php
index 1a3875892..c9f4823f0 100644
--- a/app/i18n/it/sub.php
+++ b/app/i18n/it/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/ja/sub.php b/app/i18n/ja/sub.php
index 6ea8fc375..9973e5bec 100644
--- a/app/i18n/ja/sub.php
+++ b/app/i18n/ja/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/ko/sub.php b/app/i18n/ko/sub.php
index 77e72aa0f..edb97842b 100644
--- a/app/i18n/ko/sub.php
+++ b/app/i18n/ko/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/nl/sub.php b/app/i18n/nl/sub.php
index b5442ea0e..b8585bcbb 100644
--- a/app/i18n/nl/sub.php
+++ b/app/i18n/nl/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/oc/sub.php b/app/i18n/oc/sub.php
index 68f9e1f88..28b0de33b 100644
--- a/app/i18n/oc/sub.php
+++ b/app/i18n/oc/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/pl/sub.php b/app/i18n/pl/sub.php
index 07cc07286..603fe8f4a 100644
--- a/app/i18n/pl/sub.php
+++ b/app/i18n/pl/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/pt-br/sub.php b/app/i18n/pt-br/sub.php
index 87b9b635b..82ae085ef 100644
--- a/app/i18n/pt-br/sub.php
+++ b/app/i18n/pt-br/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/ru/sub.php b/app/i18n/ru/sub.php
index dc0cf8eda..9bc64f05d 100644
--- a/app/i18n/ru/sub.php
+++ b/app/i18n/ru/sub.php
@@ -104,6 +104,10 @@ return array(
'_' => 'заголовка элемента',
'help' => 'Используйте, в частности, <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">ось XPath</a> <code>descendant::</code>, наподобие <code>descendant::h2</code>',
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'ссылки элемента (URL)',
'help' => 'Пример: <code>descendant::a/@href</code>',
diff --git a/app/i18n/sk/sub.php b/app/i18n/sk/sub.php
index 6660ff573..58999e5f3 100644
--- a/app/i18n/sk/sub.php
+++ b/app/i18n/sk/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/tr/sub.php b/app/i18n/tr/sub.php
index 34169aac3..e0af10d12 100644
--- a/app/i18n/tr/sub.php
+++ b/app/i18n/tr/sub.php
@@ -87,7 +87,7 @@ return array(
'_' => 'item author', // TODO
'help' => 'Can also be a static string. Example: <code>"Anonymous"</code>', // TODO
),
- 'item_categories' => 'items tags', // TODO
+ 'item_categories' => 'item tags', // TODO
'item_content' => array(
'_' => 'item content', // TODO
'help' => 'Example to take the full item: <code>.</code>', // TODO
@@ -104,6 +104,10 @@ return array(
'_' => 'item title', // TODO
'help' => 'Use in particular the <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath axis</a> <code>descendant::</code> like <code>descendant::h2</code>', // TODO
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => 'item link (URL)', // TODO
'help' => 'Example: <code>descendant::a/@href</code>', // TODO
diff --git a/app/i18n/zh-cn/sub.php b/app/i18n/zh-cn/sub.php
index 7ede19a3d..10211b99e 100644
--- a/app/i18n/zh-cn/sub.php
+++ b/app/i18n/zh-cn/sub.php
@@ -104,6 +104,10 @@ return array(
'_' => '文章标题',
'help' => '特别是用 <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath 轴</a> <code>descendant::</code> 像 <code>descendant::h2</code>',
),
+ 'item_uid' => array(
+ '_' => 'item unique ID', // TODO
+ 'help' => 'Optional. Example: <code>descendant::div/@data-uri</code>', // TODO
+ ),
'item_uri' => array(
'_' => '文章链接 (URL)',
'help' => '例: <code>descendant::a/@href</code>',
diff --git a/app/views/helpers/export/opml.phtml b/app/views/helpers/export/opml.phtml
index c401b05bd..677bb03b5 100644
--- a/app/views/helpers/export/opml.phtml
+++ b/app/views/helpers/export/opml.phtml
@@ -28,6 +28,7 @@ function feedsToOutlines($feeds, $excludeMutedFeeds = false): array {
$outline['frss:xPathItemTimestamp'] = ['namespace' => FreshRSS_Export_Service::FRSS_NAMESPACE, 'value' => $xPathSettings['itemTimestamp'] ?? null];
$outline['frss:xPathItemThumbnail'] = ['namespace' => FreshRSS_Export_Service::FRSS_NAMESPACE, 'value' => $xPathSettings['itemThumbnail'] ?? null];
$outline['frss:xPathItemCategories'] = ['namespace' => FreshRSS_Export_Service::FRSS_NAMESPACE, 'value' => $xPathSettings['itemCategories'] ?? null];
+ $outline['frss:xPathItemUid'] = ['namespace' => FreshRSS_Export_Service::FRSS_NAMESPACE, 'value' => $xPathSettings['itemUid'] ?? null];
}
if (!empty($feed->filtersAction('read'))) {
$filters = '';
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml
index 0e4a34a76..02dcb29e6 100644
--- a/app/views/helpers/feed/update.phtml
+++ b/app/views/helpers/feed/update.phtml
@@ -475,6 +475,14 @@
data-leave-validation="<?= $xpath['itemCategories'] ?? '' ?>"><?= $xpath['itemCategories'] ?? '' ?></textarea>
</div>
</div>
+ <div class="form-group">
+ <label class="group-name" for="xPathItemUid"><small><?= _t('sub.feed.kind.html_xpath.relative') ?></small><br />
+ <?= _t('sub.feed.kind.html_xpath.item_uid') ?></label>
+ <div class="group-controls">
+ <textarea class="valid-xpath w100" name="xPathItemUid" id="xPathItemUid" rows="2" cols="64" spellcheck="false"
+ data-leave-validation="<?= $xpath['itemUid'] ?? '' ?>"><?= $xpath['itemUid'] ?? '' ?></textarea>
+ </div>
+ </div>
</fieldset>
<div class="form-group form-actions">
<div class="group-controls">
diff --git a/app/views/subscription/add.phtml b/app/views/subscription/add.phtml
index 5aadc350b..41ee04fb7 100644
--- a/app/views/subscription/add.phtml
+++ b/app/views/subscription/add.phtml
@@ -147,6 +147,13 @@
<textarea class="valid-xpath" name="xPathItemCategories" id="xPathItemCategories" rows="2" cols="64" spellcheck="false"></textarea>
</div>
</div>
+ <div class="form-group">
+ <label class="group-name" for="xPathItemUid"><small><?= _t('sub.feed.kind.html_xpath.relative') ?></small><br />
+ <?= _t('sub.feed.kind.html_xpath.item_uid') ?></label>
+ <div class="group-controls">
+ <textarea class="valid-xpath" name="xPathItemUid" id="xPathItemUid" rows="2" cols="64" spellcheck="false"></textarea>
+ </div>
+ </div>
</fieldset>
</details>