diff --git a/docs/en/new-media.md b/docs/en/new-media.md
index 77822102a..17b61c616 100644
--- a/docs/en/new-media.md
+++ b/docs/en/new-media.md
@@ -739,6 +739,12 @@ Provides all of the Thrillist articles with the specified tag.
+## Tribal Football
+
+### Latest News
+
+
+
## VOA News
### Day in Photos
diff --git a/docs/new-media.md b/docs/new-media.md
index 3d3e51321..d2f089aca 100644
--- a/docs/new-media.md
+++ b/docs/new-media.md
@@ -1317,6 +1317,12 @@ Provides all of the Thrillist articles with the specified tag.
+## Tribal Football
+
+### Latest News
+
+
+
## Uwants
### 版塊
diff --git a/lib/v2/tribalfootball/latest.js b/lib/v2/tribalfootball/latest.js
new file mode 100644
index 000000000..9758d93c4
--- /dev/null
+++ b/lib/v2/tribalfootball/latest.js
@@ -0,0 +1,68 @@
+const got = require('@/utils/got');
+const { art } = require('@/utils/render');
+const path = require('path');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+
+const rssUrl = 'https://www.tribalfootball.com/rss/mediafed/general/rss.xml';
+
+module.exports = async (ctx) => {
+ const rss = await got(rssUrl);
+ const $ = cheerio.load(rss.data, { xmlMode: true });
+ const items = $('rss > channel > item')
+ .map((_, item) => {
+ const $item = $(item);
+ let link = $item.find('link').text();
+ link = new URL(link);
+ link.search = '';
+ link = link.href;
+ return {
+ title: $item.find('title').text(),
+ description: $item.find('description').text(),
+ link,
+ guid: $item.find('guid').text(),
+ pubDate: parseDate($item.find('pubDate').text()),
+ author: $item.find('dc\\:creator').text(),
+ _header_image: $item.find('enclosure').attr('url'),
+ };
+ })
+ .get();
+
+ await Promise.all(
+ items.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const response = await got(item.link);
+ const $ = cheerio.load(response.data);
+
+ const title = $('head > title').text().replace(' - Tribal Football', '');
+
+ let desc = $('.articleBody');
+ desc.find('.ad').remove();
+ //
AD
+ const ad = desc.find('p > br:first-child').next('i');
+ const adNextSpan = ad.next('span');
+ if (adNextSpan.length && !adNextSpan.text() && !adNextSpan.next().length) {
+ ad.parent().remove();
+ }
+ desc = desc.html();
+ desc = art(path.join(__dirname, 'templates/plus_header.art'), {
+ desc,
+ header_image: item._header_image,
+ });
+
+ item.title = title || item.title;
+ item.description = desc || item.description;
+ delete item._header_image;
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: 'Tribal Football - Latest',
+ description: 'Tribal Football - Football News, Soccer News, Transfers & Rumours',
+ link: 'https://www.tribalfootball.com/articles',
+ image: 'https://www.tribalfootball.com/images/tribal-logo-rss.png',
+ item: items,
+ };
+};
diff --git a/lib/v2/tribalfootball/maintainer.js b/lib/v2/tribalfootball/maintainer.js
new file mode 100644
index 000000000..01ddbc7de
--- /dev/null
+++ b/lib/v2/tribalfootball/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/': ['Rongronggg9'],
+};
diff --git a/lib/v2/tribalfootball/radar.js b/lib/v2/tribalfootball/radar.js
new file mode 100644
index 000000000..ddb76471d
--- /dev/null
+++ b/lib/v2/tribalfootball/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'tribalfootball.com': {
+ _name: 'Tribal Football',
+ '.': [
+ {
+ title: 'Latest News',
+ docs: 'https://docs.rsshub.app/new-media.html#tribal-football',
+ source: ['/'],
+ target: '/tribalfootball',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/tribalfootball/router.js b/lib/v2/tribalfootball/router.js
new file mode 100644
index 000000000..f8bf816f4
--- /dev/null
+++ b/lib/v2/tribalfootball/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/', require('./latest'));
+};
diff --git a/lib/v2/tribalfootball/templates/plus_header.art b/lib/v2/tribalfootball/templates/plus_header.art
new file mode 100644
index 000000000..dceaf5868
--- /dev/null
+++ b/lib/v2/tribalfootball/templates/plus_header.art
@@ -0,0 +1,6 @@
+{{ if header_image }}
+
+
+
+{{ /if }}
+{{@ desc }}