diff --git a/website/docs/joinus/advanced/advanced-feed.md b/website/docs/joinus/advanced/advanced-feed.md index 6631084e4..c3d7877ec 100644 --- a/website/docs/joinus/advanced/advanced-feed.md +++ b/website/docs/joinus/advanced/advanced-feed.md @@ -6,7 +6,7 @@ sidebar_position: 1 This guide is intended for advanced users who want to know how to create an RSS feed in detail. If you're new to creating RSS feeds, we recommend reading [Create Your Own RSSHub Route](/joinus/new-rss/start-code) first. -Once you have collected the data you want to include in your RSS feed, you can pass it to `ctx.state.data`. RSSHub's middleware [`template.js`](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/template.js) will then process the data and render the RSS output in the required format (which is RSS 2.0 by default). In addition to the fields mentioned in [Create your own RSSHub route](/joinus/new-rss/start-code), you can customize your RSS feed further using the following fields. +Once you have collected the data you want to include in your RSS feed, you can pass it to `ctx.set('data', obj)`. RSSHub's middleware [`template.js`](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/template.js) will then process the data and render the RSS output in the required format (which is RSS 2.0 by default). In addition to the fields mentioned in [Create your own RSSHub route](/joinus/new-rss/start-code), you can customize your RSS feed further using the following fields. It's important to note that not all fields are applicable to all output formats since RSSHub supports multiple output formats. The table below shows which fields are compatible with different output formats. We use the following symbols to denote compatibility: `A` for Atom, `J` for JSON Feed, `R` for RSS 2.0. @@ -72,7 +72,7 @@ RSSHub allows you to create BitTorrent/Magnet feeds, which can be useful for tri Here's an example of how to create a BitTorrent/Magnet feed: ```js -ctx.state.data = { +ctx.set('data', { item: [ { enclosure_url: '', // This should be the Magnet URI @@ -80,7 +80,7 @@ ctx.state.data = { enclosure_type: 'application/x-bittorrent', // This field should be fixed to 'application/x-bittorrent' }, ], -}; +}); ``` By including these fields in your RSS feed, you'll be able to create BitTorrent/Magnet feeds that can be automatically downloaded by compatible downloaders. @@ -100,13 +100,13 @@ By setting the `supportBT` attribute to `"1"`, you'll be able to update your doc RSSHub supports creating journal feeds that can replace `item.link` with a Sci-hub link if users provide the [common parameter](/parameter#sci-hub-link) `scihub`. To create a journal feed, you'll need to include an **additional** field in your RSS feed: ```js -ctx.state.data = { +ctx.set('data', { item: [ { doi: '', // This should be the DOI of the item (e.g., '10.47366/sabia.v5n1a3') }, ], -}; +}); ``` By including this `doi` field in your RSS feed, you'll be able to create journal feeds that are compatible with RSSHub's Sci-hub functionality. @@ -126,7 +126,7 @@ By setting the `supportSciHub` attribute to `"1"`, the documentation for your ro RSSHub supports creating podcast feeds that can be used with many podcast players' subscription formats. To create a podcast feed, you'll need to include several **additional** fields in your RSS feed: ```js -ctx.state.data = { +ctx.set('data', { itunes_author: '', // This field is **required** and should specify the podcast author's name itunes_category: '', // This field specifies the channel category image: '', // This field specifies the channel's cover image or album art @@ -139,7 +139,7 @@ ctx.state.data = { enclosure_type: '', // This field specifies the MIME type of the audio file (common types are 'audio/mpeg' for .mp3, 'audio/x-m4a' for .m4a, and 'video/mp4' for .mp4) }, ], -}; +}); ``` By including these fields in your RSS feed, you'll be able to create podcast feeds that are compatible with many podcast players. @@ -168,7 +168,7 @@ RSSHub supports creating [Media RSS](https://www.rssboard.org/media-rss) feeds t Here's an example of how to create a [Media RSS](https://www.rssboard.org/media-rss) feed: ```js -ctx.state.data = { +ctx.set('data', { item: [ { media: { @@ -185,7 +185,7 @@ ctx.state.data = { }, }, ], -}; +}); ``` By including these fields in your RSS feed, you'll be able to create [Media RSS](https://www.rssboard.org/media-rss) feeds that are compatible with many [Media RSS](https://www.rssboard.org/media-rss) software subscription formats. @@ -197,7 +197,7 @@ RSSHub supports creating Atom feeds that include interactions like upvotes, down Here's an example of how to create an Atom feed with interactions: ```js -ctx.state.data = { +ctx.set('data', { item: [ { upvotes: 0, // This should be the number of upvotes for this item @@ -205,7 +205,7 @@ ctx.state.data = { comments: 0, // This should be the number of comments for this item }, ], -}; +}); ``` By including these fields in your Atom feed, you'll be able to create Atom feeds with interactions that are compatible with many Atom feed readers. diff --git a/website/docs/joinus/advanced/debug.md b/website/docs/joinus/advanced/debug.md index b48ac718f..26b8e8f88 100644 --- a/website/docs/joinus/advanced/debug.md +++ b/website/docs/joinus/advanced/debug.md @@ -8,28 +8,28 @@ When debugging your code, you can use more than just `console.log` or attaching Note: The following methods are only effective when the instance is running with `debugInfo=true`. -## Using `ctx.state.json` +## Using `ctx.set('json', obj)` -To pass a custom object to ctx.state.json for debugging, follow these steps: +To pass a custom object to `ctx.set('json', obj)` for debugging, follow these steps: 1. Create your custom object. -2. Assign your object to `ctx.state.json`. +2. Pass your object to `ctx.set('json', obj)`. 3. Access the corresponding route + `.debug.json` to view your object. For example, if you want to debug the route `/furstar/characters/:lang?`, you can access the URL: `/furstar/characters/en.debug.json` -Here's an example of how to use `ctx.state.json` taken from [furstar/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar/index.js) +Here's an example of how to use `ctx.set('json', obj)` taken from [furstar/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar/index.js) ```js const info = utils.fetchAllCharacters(res.data, base); -ctx.state.json = { +ctx.set('json', { info, -}; +}); ``` -In the example above, we're passing the `info` object to `ctx.state.json`, which we can then access using the corresponding route + `.debug.json`. +In the example above, we're passing the `info` object to `ctx.set('json', obj)`, which we can then access using the corresponding route + `.debug.json`. ## debug.html -In order to quickly test if the `description` in `ctx.state.data` is correct, you can use the `.debug.html` file suffix to obtain the HTML of the corresponding entry. The link can be directly opened in the browser to preview the rendering result. +In order to quickly test if the `description` in `ctx.set('data', obj)` is correct, you can use the `.debug.html` file suffix to obtain the HTML of the corresponding entry. The link can be directly opened in the browser to preview the rendering result. -Usage: Access the corresponding route + `.{index}.debug.html`, where `{index}` is the item number (starting from 0) in your `ctx.state.data.item`. And the data corresponds to the `ctx.state.data.item[index].description` information will be returned as route result. +Usage: Access the corresponding route + `.{index}.debug.html`, where `{index}` is the item number (starting from 0) in your `data.item`. And the data corresponds to the `data.item[index].description` information will be returned as route result. diff --git a/website/docs/joinus/advanced/pub-date.md b/website/docs/joinus/advanced/pub-date.md index 3700df49f..d0f919612 100644 --- a/website/docs/joinus/advanced/pub-date.md +++ b/website/docs/joinus/advanced/pub-date.md @@ -29,7 +29,7 @@ We recommend using [day.js](https://github.com/iamkun/dayjs) for date processing The RSSHub utility class includes a wrapper for [day.js](https://github.com/iamkun/dayjs) that allows you to easily parse date strings and obtain a [Date Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) in most cases. ```js -const { parseDate } = require('@/utils/parse-date'); +import { parseDate } from '@/utils/parse-date'; const pubDate = parseDate('2020/12/30'); // OR @@ -45,7 +45,7 @@ You can refer to the [day.js documentation](https://day.js.org/docs/en/parse/str If you need to parse a relative date, use `parseRelativeDate`. ```js -const { parseRelativeDate } = require('@/utils/parse-date'); +import { parseRelativeDate } from '@/utils/parse-date'; const pubDate = parseRelativeDate('2 days ago'); const pubDate = parseRelativeDate('day before yesterday 15:36'); @@ -58,7 +58,7 @@ When parsing dates from websites, it's important to consider time zones. Some we To manually specify the time zone in your code, use the following code: ```js -const timezone = require('@/utils/timezone'); +import timezone from '@/utils/timezone'; const pubDate = timezone(parseDate('2020/12/30 13:00'), +1); ``` diff --git a/website/docs/joinus/advanced/script-standard.md b/website/docs/joinus/advanced/script-standard.md index b1d6a9031..1ee6d8c19 100644 --- a/website/docs/joinus/advanced/script-standard.md +++ b/website/docs/joinus/advanced/script-standard.md @@ -100,20 +100,20 @@ RSSHub appends the name of all route namespace folders in front of the actual ro ### Registering a Route -To register a route, the `router.js` file should export a method that provides a `@koa/router` object when initializing the route. +To register a route, the `router.js` file should export a method that provides a Hoho route handler. ### Maintainer List The `maintainer.js` file should export an object that provides maintainer information related to the route, including: -- Key: Corresponding path in the `@koa/router` object +- Key: Corresponding route path - Value: Array of string, including all maintainers' GitHub ID. To generate a list of maintainers, use the following command: `pnpm run build:maintainer`, which will create the list under `assets/build/`. :::danger -The path in the `@koa/router` object should be the same as the `path` in the corresponding documentation before the namespace appended in front of it. +The path should be the same as the `path` in the corresponding documentation before the namespace appended in front of it. ::: @@ -151,8 +151,8 @@ Here's an example taken from the [furstar](https://github.com/DIYgod/RSSHub/blob ``` ```js -const path = require('path'); -const { art } = require('@/utils/render'); +import * as path from 'node:path'; +import { art } from '@/utils/render'; const renderAuthor = (author) => art(path.join(__dirname, 'templates/author.art'), author); ``` diff --git a/website/docs/joinus/advanced/use-cache.md b/website/docs/joinus/advanced/use-cache.md index 751b062d8..ff2e12521 100644 --- a/website/docs/joinus/advanced/use-cache.md +++ b/website/docs/joinus/advanced/use-cache.md @@ -4,18 +4,20 @@ sidebar_position: 3 # Using Cache -All routes have a cache that expires after a short duration. You can change how long the cache lasts by modifying the `CACHE_EXPIRE` value in the `lib/config.js` file using environment variables. However, for interfaces that have less frequently updated content, it's better to specify a longer cache expiration time using `CACHE_CONTENT_EXPIRE` instead. +RSSHub have a cache module that expires after a short duration. You can change how long the cache lasts by modifying the `CACHE_EXPIRE` value in the `lib/config.js` file using environment variables. However, for interfaces that have less frequently updated content, it's better to specify a longer cache expiration time using `CACHE_CONTENT_EXPIRE` instead. For example, to retrieve the full text of the first comment for each issue, you can make a request to `${baseUrl}/${user}/${repo}/issues/${id}`, since this data is unavailable through `${baseUrl}/${user}/${repo}/issues`. It's recommended to store this data in the cache to avoid making repeated requests to the server. Here's an example of how you can use the cache to retrieve the data: ```js + import cache from '@/utils/cache'; + const items = await Promise.all( list.map((item) => - ctx.cache.tryGet(item.link, async () => { + cache.tryGet(item.link, async () => { const { data: response } = await got(item.link); - const $ = cheerio.load(response); + const $ = load(response); item.description = $('.comment-body').first().html(); @@ -25,7 +27,7 @@ Here's an example of how you can use the cache to retrieve the data: ); ``` -The above code snippet from [Create Your Own RSSHub Route](/joinus/new-rss/start-code#better-reading-experience) shows how to use the cache to get the full text of the first comment of each issue. `ctx.cache.tryGet()` is used to determine if the data is already available within the cache. If it's not, the code retrieves the data and stores it in the cache. +The above code snippet from [Create Your Own RSSHub Route](/joinus/new-rss/start-code#better-reading-experience) shows how to use the cache to get the full text of the first comment of each issue. `cache.tryGet()` is used to determine if the data is already available within the cache. If it's not, the code retrieves the data and stores it in the cache. The object returned from the previous statement will be reused, and an extra `description` property will be added to it. The returned cache for each `item.link` will be `{ title, link, pubDate, author, category, description }`. The next time the same path is requested, this processed cache will be used instead of making a request to the server and recomputing the data. @@ -35,7 +37,7 @@ Any assignments to variables that are declared outside of the `tryGet()` functio ```js let x = '1'; - const z = await ctx.cache.tryGet('cache:key', async () => { + const z = await cache.tryGet('cache:key', async () => { x = '2'; const y = '3'; return y; @@ -48,7 +50,7 @@ Any assignments to variables that are declared outside of the `tryGet()` functio ## API -### ctx.cache.tryGet(key, getValueFunc [, maxAge [, refresh ]]) +### cache.tryGet(key, getValueFunc [, maxAge [, refresh ]]) #### Parameters @@ -65,13 +67,13 @@ Any assignments to variables that are declared outside of the `tryGet()` functio :::tip -Below are advanced methods for using cache. You should use `ctx.cache.tryGet()` most of the time. +Below are advanced methods for using cache. You should use `cache.tryGet()` most of the time. -Note that you need to use `JSON.parse()` when retrieving the cache using `ctx.cache.get()`. +Note that you need to use `JSON.parse()` when retrieving the cache using `cache.get()`. ::: -### ctx.cache.get(key [, refresh ]) +### cache.get(key [, refresh ]) #### Parameters @@ -80,7 +82,7 @@ Note that you need to use `JSON.parse()` when retrieving the cache using `ctx.ca | key | `string` | *(Required)* The key used to retrieve the cache. You can use `:` as a separator to create a hierarchy. | | refresh | `boolean` | *(Optional)* Whether to renew the cache expiration time when the cache is hit. `true` by default. | -### ctx.cache.set(key, value [, maxAge ]) +### cache.set(key, value [, maxAge ]) #### Parameters diff --git a/website/docs/joinus/new-rss/before-start.md b/website/docs/joinus/new-rss/before-start.md index 462534ced..1244b57d2 100644 --- a/website/docs/joinus/new-rss/before-start.md +++ b/website/docs/joinus/new-rss/before-start.md @@ -98,7 +98,7 @@ For example, if you are creating an RSS feed for [GitHub Repo Issues](/routes/pr ```js module.exports = (router) => { // highlight-next-line - router.get('/issue/:user/:repo?', require('./issue')); + router.get('/issue/:user/:repo?', './issue'); }; ``` @@ -108,26 +108,22 @@ module.exports = (router) => { ```js module.exports = function (router) { // highlight-next-line - router.get('/issue/:user/:repo?', require('./issue')); + router.get('/issue/:user/:repo?', './issue'); }; ``` -When registering your new RSS route in `router.js`, you can define the route path and specify the corresponding function to be executed. In the code above, the `router.get()` method is used to specify the HTTP method and the path of the new RSS route. The first parameter of `router.get()` is the route path using [path-to-regexp](https://github.com/pillarjs/path-to-regexp) syntax. The second parameter is the exported function from your new RSS rule, `issue.js`. Note that you can omit the `.js` extension. +When registering your new RSS route in `router.js`, you can define the route path and specify the corresponding function to be executed. In the code above, the `router.get()` method is used to specify the HTTP method and the path of the new RSS route. The first parameter of `router.get()` is the route path using [Hono routing](https://hono.dev/api/routing) syntax. The second parameter is the relative path of your new RSS rule, `issue.js`. Note that you can omit the `.js` extension. In the example above, `issue` is an exact match, `:user` is a required parameter, and `:repo?` is an optional parameter. The `?` after `:repo` means that the parameter is optional. If the user does not enter repo, it will fall back to whatever is specified in your code (in this case, `RSSHub`). -Once you have defined the route path, you can retrieve the value of the parameters from the `ctx.params` object. For example, if the user visits `/github/issue/DIYgod/RSSHub`, you can get the value of `user` and `repo` from `ctx.params.user` and `ctx.params.repo`, respectively. For example, if an user visits `/github/issue/DIYgod/RSSHub`, `ctx.params.user` and `ctx.params.repo` which will be `DIYgod` and `RSSHub`. - -**Note that the type of the value will be either `String` or `undefined`**. - -You can use the `*` or `+` symbols to match the rest of the path, like `/some/path/:variable*`. Note that `*` and `+` mean "zero or more" and "one or more", respectively. You can also use patterns like `/some/path/:variable(\\d+)?` or even RegExp. +Once you have defined the route path, you can retrieve the value of the parameters from the [`ctx.req.param()`](https://hono.dev/api/request#param) function. For example, if the user visits `/github/issue/DIYgod/RSSHub`, you can get the value of `user` and `repo` from `ctx.req.param('user')` and `ctx.req.param('repo')`, respectively. For example, if an user visits `/github/issue/DIYgod/RSSHub`, `ctx.req.param('user')` and `ctx.req.param('repo')` which will be `DIYgod` and `RSSHub`. :::tip -For more advanced usage of `router`, see the [@koa/router API Reference](https://github.com/koajs/router/blob/master/API.md). +For more advanced usage of `router`, see the [Hono Routing API Reference](https://hono.dev/api/routing). ::: diff --git a/website/docs/joinus/new-rss/start-code.md b/website/docs/joinus/new-rss/start-code.md index 525c3cfea..12f934734 100644 --- a/website/docs/joinus/new-rss/start-code.md +++ b/website/docs/joinus/new-rss/start-code.md @@ -28,15 +28,15 @@ Here's the basic code to get you started: ```js // Import the necessary modules -const got = require('@/utils/got'); // a customised got -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; // a customised got +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { // Your logic here - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -53,11 +53,11 @@ As mentioned earlier, we need to retrieve the GitHub username and repository nam ```js module.exports = async (ctx) => { // highlight-next-line - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -67,13 +67,13 @@ module.exports = async (ctx) => { ```js module.exports = async (ctx) => { // highlight-start - const user = ctx.params.user; - const repo = ctx.params.repo ?? 'RSSHub'; + const user = ctx.req.param('user'); + const repo = ctx.req.param('repo') ?? 'RSSHub'; // highlight-end - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -91,7 +91,7 @@ After we have the user input, we can use it to make a request to the API. In mos ```js module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-start // Send an HTTP GET request to the API // and destruct the data object returned by the request @@ -104,14 +104,14 @@ module.exports = async (ctx) => { }, searchParams: { // This allows users to set the number of feed items they want - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); // highlight-end - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -120,8 +120,8 @@ module.exports = async (ctx) => { ```js module.exports = async (ctx) => { - const user = ctx.params.user; - const repo = ctx.params.repo ?? 'RSSHub'; + const user = ctx.req.param('user'); + const repo = ctx.req.param('repo') ?? 'RSSHub'; // highlight-start // Send an HTTP GET request to the API const response = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { @@ -129,16 +129,16 @@ module.exports = async (ctx) => { accept: 'application/vnd.github.html+json', }, searchParams: { - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); // response.data is the data object returned by the above request const data = response.data; // highlight-end - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -149,7 +149,7 @@ module.exports = async (ctx) => { Once we have retrieved the data from the API, we need to process it further to generate an RSS feed that conforms to the RSS specification. Specifically, we need to extract the channel title, channel link, item title, item link, item description, and item publication date. -To do this, we can assign the relevant data to the `ctx.state.data` object, and RSSHub's middleware will take care of the rest. +To do this, we can assign the relevant data to the `ctx.set('data', obj)` object, and RSSHub's middleware will take care of the rest. Here is the final code that you should have: @@ -157,18 +157,18 @@ Here is the final code that you should have: ```js -const got = require('@/utils/got'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { accept: 'application/vnd.github.html+json', }, searchParams: { - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); @@ -191,14 +191,14 @@ module.exports = async (ctx) => { // highlight-end // highlight-start - ctx.state.data = { + ctx.set('data', { // channel title title: `${user}/${repo} issues`, // channel link link: `https://github.com/${user}/${repo}/issues`, // each feed item item: items, - }; + }); // highlight-end }; ``` @@ -207,23 +207,23 @@ module.exports = async (ctx) => { ```js -const got = require('@/utils/got'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { accept: 'application/vnd.github.html+json', }, searchParams: { - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); // highlight-start - ctx.state.data = { + ctx.set('data', { // channel title title: `${user}/${repo} issues`, // channel link @@ -243,7 +243,7 @@ module.exports = async (ctx) => { // item category, if available category: item.labels.map((label) => label.name), })); - }; + }); // highlight-end }; ``` @@ -261,16 +261,16 @@ Here's the basic code to get you started: ```js // Require necessary modules -const got = require('@/utils/got'); // a customised got -const cheerio = require('cheerio'); // an HTML parser with a jQuery-like API -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; // a customised got +import { load } from 'cheerio'; // an HTML parser with a jQuery-like API +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { // Your logic here - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -286,12 +286,12 @@ As mentioned before, we want users to enter a GitHub username and a repository n module.exports = async (ctx) => { // highlight-start // Retrieve user and repository name from the URL parameters - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-end - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -305,12 +305,12 @@ To begin, we'll make an HTTP GET request to the API and load the HTML response i ```js const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // Note that the ".data" property contains the full HTML source of the target page returned by the request // highlight-start const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); // highlight-end ``` @@ -341,30 +341,30 @@ Next, we'll use Cheerio selectors to select the relevant HTML elements, parse th }); // highlight-end - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); ``` ### Outputting the RSS Once we have the data from the web page, we need to further process it to generate RSS in accordance with the RSS specification. Mainly, we need the channel title, channel link, item title, item link, item description, and item publication date. -Assign them to the `ctx.state.data` object, and RSSHub's middleware will take care of the rest. +Pass them to the `ctx.set('data', obj)` object, and RSSHub's middleware will take care of the rest. Here's an example code: ```js -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); const items = $('div.js-navigation-container .flex-auto') .toArray() @@ -384,14 +384,14 @@ module.exports = async (ctx) => { }); // highlight-start - ctx.state.data = { + ctx.set('data', { // channel title title: `${user}/${repo} issues`, // channel link link: `${baseUrl}/${user}/${repo}/issues`, // each feed item item: items, - }; + }); // highlight-end }; ``` @@ -403,16 +403,16 @@ The previous code provides only part of the information for each feed item. To p Here's the updated code: ```js -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); // highlight-next-line const list = $('div.js-navigation-container .flex-auto') @@ -435,9 +435,9 @@ module.exports = async (ctx) => { // highlight-start const items = await Promise.all( list.map((item) => - ctx.cache.tryGet(item.link, async () => { + cache.tryGet(item.link, async () => { const { data: response } = await got(item.link); - const $ = cheerio.load(response); + const $ = load(response); // Select the first element with the class name 'comment-body' item.description = $('.comment-body').first().html(); @@ -450,12 +450,12 @@ module.exports = async (ctx) => { ); // highlight-end - ctx.state.data = { + ctx.set('data', { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, // highlight-next-line item: items, - }; + }); }; ``` @@ -486,10 +486,10 @@ Here's some basic code to get you started: ```js // Import necessary modules -const buildData = require('@/utils/common-config'); +import buildData from '@/utils/common-config'; module.exports = async (ctx) => { - ctx.state.data = await buildData({ + ctx.set('data', await buildData({ link: '', // The RSS source link url: '', // The data source link // Variables can be used here, such as %xxx% will be parsed into @@ -498,20 +498,20 @@ module.exports = async (ctx) => { params: { title: '', // Additional title }, - }); + })); }; ``` Our RSS feed currently lacks content. The `item` must be set to add the content. Here's an example: ```js -const buildData = require('@/utils/common-config'); +import buildData from '@/utils/common-config'; module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const link = `https://github.com/${user}/${repo}/issues`; - ctx.state.data = await buildData({ + ctx.set('data', await buildData({ link, url: link, title: `${user}/${repo} issues`, // you can also use $('head title').text() @@ -529,7 +529,7 @@ module.exports = async (ctx) => { pubDate: `parseDate($('relative-time').attr('datetime'))`, }, // highlight-end - }); + })); }; ``` @@ -540,17 +540,17 @@ You'll notice that the code is similar to the [Obtaining data from the webpage]( To get the full article of each issue, you need to add a few more lines of code. Here is an example: ```js -const buildData = require('@/utils/common-config'); +import buildData from '@/utils/common-config'; // highlight-start -const got = require('@/utils/got'); -const cheerio = require('cheerio'); +import got from '@/utils/got'; +import { load } from 'cheerio'; // highlight-end module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const link = `https://github.com/${user}/${repo}/issues`; - ctx.state.data = await buildData({ + const data = await buildData({ link, url: link, title: `${user}/${repo} issues`, @@ -568,15 +568,17 @@ module.exports = async (ctx) => { // highlight-start await Promise.all( - ctx.state.data.item.map((item) => - ctx.cache.tryGet(item.link, async () => { + data.item.map((item) => + cache.tryGet(item.link, async () => { const { data: resonse } = await got(item.link); - const $ = cheerio.load(resonse); + const $ = load(resonse); item.description = $('.comment-body').first().html(); return item; }) ) ); + + ctx.set('data', data); // highlight-end }; ``` @@ -593,16 +595,16 @@ To get started with puppeteer, create a new file in your code editor and save it ```js // Require some useful modules -const cheerio = require('cheerio'); // an HTML parser with a jQuery-like API -const { parseDate } = require('@/utils/parse-date'); -const logger = require('@/utils/logger'); +import { load } from 'cheerio'; // an HTML parser with a jQuery-like API +import { parseDate } from '@/utils/parse-date'; +import logger from '@/utils/logger'; module.exports = async (ctx) => { // Your logic here - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); }; ``` @@ -614,17 +616,18 @@ Now, we will be using `puppeteer` instead of `got` to retrieve data from the web ```js -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); -const logger = require('@/utils/logger'); +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import logger from '@/utils/logger'; +import puppeteer from '@/utils/puppeteer'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-start // require puppeteer utility class and initialise a browser instance - const browser = await require('@/utils/puppeteer')(); + const browser = await puppeteer(); // open a new tab const page = await browser.newPage(); // intercept all requests @@ -650,7 +653,7 @@ module.exports = async (ctx) => { page.close(); // highlight-end - const $ = cheerio.load(response); + const $ = load(response); // const item = ...; @@ -659,9 +662,9 @@ module.exports = async (ctx) => { browser.close(); // highlight-end - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); } ``` @@ -669,21 +672,21 @@ module.exports = async (ctx) => { ```js -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-next-line const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); - ctx.state.data = { + ctx.set('data', { // Your RSS output here - }; + }); } ``` @@ -695,15 +698,16 @@ module.exports = async (ctx) => { Retrieving the full articles of each issue using a new browser page is similar to the [previous section](#better-reading-experience). We can use the following code: ```js -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); -const logger = require('@/utils/logger'); +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import logger from '@/utils/logger'; +import puppeteer from '@/utils/puppeteer'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); - const browser = await require('@/utils/puppeteer')(); + const browser = await puppeteer(); const page = await browser.newPage(); await page.setRequestInterception(true); page.on('request', (request) => { @@ -718,7 +722,7 @@ module.exports = async (ctx) => { const response = await page.content(); page.close(); - const $ = cheerio.load(response); + const $ = load(response); const list = $('div.js-navigation-container .flex-auto') .toArray() @@ -739,7 +743,7 @@ module.exports = async (ctx) => { const items = await Promise.all( list.map((item) => - ctx.cache.tryGet(item.link, async () => { + cache.tryGet(item.link, async () => { // highlight-start // reuse the browser instance and open a new tab const page = await browser.newPage(); @@ -758,7 +762,7 @@ module.exports = async (ctx) => { page.close(); // highlight-end - const $ = cheerio.load(response); + const $ = load(response); item.description = $('.comment-body').first().html(); @@ -772,11 +776,11 @@ module.exports = async (ctx) => { browser.close(); // highlight-end - ctx.state.data = { + ctx.set('data', { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, item: items, - }; + }); }; ``` diff --git a/website/docs/parameter.md b/website/docs/parameter.md index f044ff71d..cd6ee0c4a 100644 --- a/website/docs/parameter.md +++ b/website/docs/parameter.md @@ -149,7 +149,7 @@ E.g. ### debug.json -If the RSSHub instance is running with `debugInfo=true` enabled, suffixing a route with `.debug.json` will result in the value of `ctx.state.json` being returned. +If the RSSHub instance is running with `debugInfo=true` enabled, suffixing a route with `.debug.json` will result in the value of `ctx.set('json', obj)` being returned. This feature aims to facilitate debugging or developing customized features. A route developer has the freedom to determine whether to adopt it or not, without any format requirement. @@ -159,7 +159,7 @@ For example: ### debug.html -By adding `.{index}.debug.html` (where `{index}` is a number starting from 0) at the end of the route and running the instance with `debugInfo=true`, RSSHub will return the content set in the plugin's `ctx.state.data.item[index].description`. You can access this page with a browser to quickly view the extracted information. +By adding `.{index}.debug.html` (where `{index}` is a number starting from 0) at the end of the route and running the instance with `debugInfo=true`, RSSHub will return the content set in the plugin's `data.item[index].description`. You can access this page with a browser to quickly view the extracted information. Example: diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md index 8ff29c93c..4b1b82edb 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/advanced-feed.md @@ -6,7 +6,7 @@ sidebar_position: 1 本指南面向希望深入了解如何制作 RSS 订阅源的高级用户。如果您是第一次制作 RSS 订阅源,我们建议先阅读 [制作自己的 RSSHub 路由](/zh/joinus/new-rss/start-code)。 -一旦您获取了要包含在您的 RSS 订阅源中的数据,就可以将其传递给 `ctx.state.data`。然后RSSHub的中间件 [`template.js`](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/template.js) 将处理数据并以所需的格式呈现 RSS 输出(默认为RSS 2.0)。除了 [制作自己的 RSSHub 路由](/zh/joinus/new-rss/start-code) 中提到的字段外,您还可以使用以下字段进一步自定义 RSS 订阅源。 +一旦您获取了要包含在您的 RSS 订阅源中的数据,就可以将其传递给 `ctx.set('data', obj)`。然后RSSHub的中间件 [`template.js`](https://github.com/DIYgod/RSSHub/blob/master/lib/middleware/template.js) 将处理数据并以所需的格式呈现 RSS 输出(默认为RSS 2.0)。除了 [制作自己的 RSSHub 路由](/zh/joinus/new-rss/start-code) 中提到的字段外,您还可以使用以下字段进一步自定义 RSS 订阅源。 需要注意的是,并非所有字段都适用于所有的输出格式,因为 RSSHub 支持多种输出格式。下表显示了不同输出格式兼容的字段。我们使用以下符号表示兼容性:`A` 表示 Atom,`J` 表示 JSON Feed,`R` 表示 RSS 2.0。 @@ -72,7 +72,7 @@ RSSHub 支持制作 BitTorrent/磁力订阅源,这将帮助你的 RSS 订阅 以下是制作 BitTorrent/磁力订阅源的示例: ```js -ctx.state.data = { +ctx.set('data', { item: [ { enclosure_url: '', // 磁力链接 @@ -80,7 +80,7 @@ ctx.state.data = { enclosure_type: 'application/x-bittorrent', // 应固定为 'application/x-bittorrent' }, ], -}; +}); ``` 在 RSS 源中包含这些字段,您将能够制作被 BitTorrent 客户端识别并自动下载的 BitTorrent/磁力订阅源。 @@ -100,13 +100,13 @@ ctx.state.data = { RSSHub支持制作期刊订阅源。如果用户提供 [通用参数](/zh/parameter#输出-sci-hub-链接) `scihub`,则可以将 `item.link` 替换为 Sci-hub 链接。要制作期刊订阅源,您需要在您的 RSS 源中包含一个附加字段: ```js -ctx.state.data = { +ctx.set('data', { item: [ { doi: '', // 条目的 DOI(例如,'10.47366/sabia.v5n1a3') }, ], -}; +}); ``` 通过在 RSS 源中包含 `doi` 字段,您将能够制作与 RSSHub 的 Sci-hub 功能兼容的期刊订阅源。 @@ -126,7 +126,7 @@ ctx.state.data = { RSSHub 支持制作与播客播放器订阅格式兼容的播客订阅源。要制作播客订阅源,您需要在RSS源中包含几个附加字段: ```js -ctx.state.data = { +ctx.set('data', { itunes_author: '', // **必需**,应为主播名称 itunes_category: '', // 播客分类 image: '', // 专辑封面,作为播客源时**必填** @@ -139,7 +139,7 @@ ctx.state.data = { enclosure_type: '', // 音频文件 MIME 类型(常见类型 .mp3 是 'audio/mpeg',.m4a 是 'audio/x-m4a',.mp4 是 'video/mp4') }, ], -}; +}); ``` 通过在 RSS 源中包含这些字段,您将能够制作与播客播放器兼容的播客订阅源。 @@ -168,7 +168,7 @@ RSSHub支持制作与 [Media RSS](https://www.rssboard.org/media-rss) 格式兼 以下是制作媒体订阅源的示例: ```js -ctx.state.data = { +ctx.set('data', { item: [ { media: { @@ -185,7 +185,7 @@ ctx.state.data = { }, }, ], -}; +}); ``` 通过在 RSS 源中包含这些字段,您将能够制作与 [Media RSS](https://www.rssboard.org/media-rss) 格式兼容的媒体订阅源。 @@ -197,7 +197,7 @@ RSSHub支持制作包含互动,如点赞、反对和评论的 Atom 订阅源 以下是制作带有互动的 Atom 订阅源的示例: ```js -ctx.state.data = { +ctx.set('data', { item: [ { upvotes: 0, // 条目的点赞数 @@ -205,7 +205,7 @@ ctx.state.data = { comments: 0, // 条目的评论数 }, ], -}; +}); ``` 通过在 Atom 源中包含这些字段,您将能够制作包含互动的 Atom 订阅源,这些源与支持 Atom 订阅源的阅读器兼容。 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/debug.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/debug.md index 7c713c0ac..be4434193 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/debug.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/debug.md @@ -8,28 +8,28 @@ sidebar_position: 5 注意:需要实例运行在 `debugInfo=true` 的情况下以下方式才有效 -## 使用 `ctx.state.json` +## 使用 `ctx.set('json', obj)` -要将自定义对象传递给 ctx.state.json 进行调试,请跟随以下步骤: +要将自定义对象传递给 `ctx.set('json', obj)` 进行调试,请跟随以下步骤: 1. 创建自定义对象。 -2. 将对象传递给 `ctx.state.json`。 +2. 将对象传递给 `ctx.set('json', obj)`。 3. 访问相应的路由 + `.debug.json` 来查看您的对象。例如,如果您想调试 `/furstar/characters/en`,您可以访问 URL:`/furstar/characters/en.debug.json`。 -以下是来自 [furstar/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar/index.js) 的使用 `ctx.state.json` 的示例: +以下是来自 [furstar/index.js](https://github.com/DIYgod/RSSHub/blob/master/lib/v2/furstar/index.js) 的使用 `ctx.set('json', obj)` 的示例: ```js const info = utils.fetchAllCharacters(res.data, base); -ctx.state.json = { +ctx.set('json', { info, -}; +}); ``` -在上面的示例中,我们将 `info` 对象传递给 `ctx.state.json`,然后可以使用相应的路由 + `.debug.json` 来访问它。 +在上面的示例中,我们将 `info` 对象传递给 `ctx.set('json', obj)`,然后可以使用相应的路由 + `.debug.json` 来访问它。 ## debug.html -为了快速测试 `ctx.state.data` 中的 description 是否正确,你可以利用 `debug.html` 机制来获取相关条目的 HTML,该链接可以直接在浏览器中打开以预览渲染结果。 +为了快速测试 `ctx.set('data', obj)` 中的 description 是否正确,你可以利用 `debug.html` 机制来获取相关条目的 HTML,该链接可以直接在浏览器中打开以预览渲染结果。 -使用方式:访问相应的路由 + `.{index}.debug.html`,其中 `{index}` 为你的 `ctx.state.data.item` 中的项目序号(从 0 开始),即返回对应路由结果中的 `ctx.state.data.item[index].description` 信息。 +使用方式:访问相应的路由 + `.{index}.debug.html`,其中 `{index}` 为你的 `data.item` 中的项目序号(从 0 开始),即返回对应路由结果中的 `data.item[index].description` 信息。 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md index cf31ad71b..6e4434d6e 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/pub-date.md @@ -29,7 +29,7 @@ sidebar_position: 4 RSSHub 工具类包括了一个 [day.js](https://github.com/iamkun/dayjs) 的包装函数,它允许你直接解析日期字符串并在大多数情况下获得一个 [Date 对象](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)。 ```js -const { parseDate } = require('@/utils/parse-date'); +import { parseDate } from '@/utils/parse-date'; const pubDate = parseDate('2020/12/30'); // 或 @@ -45,7 +45,7 @@ const pubDate = parseDate('2020/12/30', 'YYYY/MM/DD'); 如果你需要解析相对日期,请使用 `parseRelativeDate`。 ```js -const { parseRelativeDate } = require('@/utils/parse-date'); +import { parseRelativeDate } from '@/utils/parse-date'; const pubDate = parseRelativeDate('2天前'); const pubDate = parseRelativeDate('前天 15:36'); @@ -58,7 +58,7 @@ const pubDate = parseRelativeDate('前天 15:36'); 要在代码中手动指定时区,可以使用以下代码: ```js -const timezone = require('@/utils/timezone'); +import timezone from '@/utils/timezone'; const pubDate = timezone(parseDate('2020/12/30 13:00'), +1); ``` diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md index 6b23e9fe4..dc44f2ddc 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/script-standard.md @@ -98,20 +98,20 @@ RSSHub 会将所有路由命名空间的文件夹名附加到路由前面。路 ### 注册路由 -`router.js` 文件应导出一个方法,提供在初始化路由时使用的 `@koa/router` 对象。 +`router.js` 文件应导出一个方法,提供一个 Hoho route handler。 ### 维护者列表 `maintainer.js` 文件应导出一个对象,提供与路由相关的维护者信息,包括: -- 键: `@koa/router` 对象中对应的路由 +- 键: 对应的路由 - 值:一个字符串数组,包括所有维护者的 GitHub ID。 要生成维护者列表,可使用以下命令:`pnpm run build:maintainer`,它将在 `assets/build/` 目录下一份维护者列表。 :::danger -在 `@koa/router` 对象中的路由应该与相应的文档中添加命名空间前的 `path` 一致。 +路由应该与相应的文档中添加命名空间前的 `path` 一致。 ::: @@ -151,8 +151,8 @@ RSSHub 会将所有路由命名空间的文件夹名附加到路由前面。路 ``` ```js -const path = require('path'); -const { art } = require('@/utils/render'); +import * as path from 'node:path'; +import { art } from '@/utils/render'; const renderAuthor = (author) => art(path.join(__dirname, 'templates/author.art'), author); ``` diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md index 4731745fa..2ec83b60c 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/advanced/use-cache.md @@ -4,18 +4,20 @@ sidebar_position: 3 # 使用缓存 -所有路由都有一个缓存,该缓存在短时间后过期。您可以通过环境变量来修改 `lib/config.js` 文件中的 `CACHE_EXPIRE` 值使用来更改缓存的持续时间。然而,对于那些内容更新较少的接口,最好是使用 `CACHE_CONTENT_EXPIRE` 来指定较长的缓存过期时间。 +RSSHub 有一个缓存模块,该缓存在短时间后过期。您可以通过环境变量来修改 `lib/config.js` 文件中的 `CACHE_EXPIRE` 值使用来更改缓存的持续时间。然而,对于那些内容更新较少的接口,最好是使用 `CACHE_CONTENT_EXPIRE` 来指定较长的缓存过期时间。 例如,为了获取每个 GitHub Issue 的第一个评论的正文,您可以向 `${baseUrl}/${user}/${repo}/issues/${id}` 发出请求,因为 `${baseUrl}/${user}/${repo}/issues` 无法提供此数据。推荐将此数据存储在缓存中,以避免重复向服务器发出请求。 以下是如何使用缓存获取数据的示例代码: ```js + import cache from '@/utils/cache'; + const items = await Promise.all( list.map((item) => - ctx.cache.tryGet(item.link, async () => { + cache.tryGet(item.link, async () => { const { data: response } = await got(item.link); - const $ = cheerio.load(response); + const $ = load(response); item.description = $('.comment-body').first().html(); @@ -25,7 +27,7 @@ sidebar_position: 3 ); ``` -以上代码片段来自 [制作自己的 RSSHub 路由](/zh/joinus/new-rss/start-code),展示了如何使用缓存获取每个问题的第一个评论的全文。使用 `ctx.cache.tryGet()` 来确定数据是否已经在缓存中。如果不在,则代码会获取数据并将其存储在缓存中。 +以上代码片段来自 [制作自己的 RSSHub 路由](/zh/joinus/new-rss/start-code),展示了如何使用缓存获取每个问题的第一个评论的全文。使用 `cache.tryGet()` 来确定数据是否已经在缓存中。如果不在,则代码会获取数据并将其存储在缓存中。 上一个语句返回的对象将被重复使用,并且会添加一个额外的 `description` 属性。每个 `item.link` 的返回缓存将是`{ title, link, pubDate, author, category, description }`。下一次请求相同路由时,将直接返回处理过后的缓存而不是向服务器发出请求并重新计算数据。 @@ -34,8 +36,10 @@ sidebar_position: 3 在 `tryGet()` 函数之外声明的变量的任何赋值都不会在缓存命中的情况下被处理。例如,以下代码将无法按预期工作: ```js + import cache from '@/utils/cache'; + let x = '1'; - const z = await ctx.cache.tryGet('cache:key', async () => { + const z = await cache.tryGet('cache:key', async () => { x = '2'; const y = '3'; return y; @@ -48,7 +52,7 @@ sidebar_position: 3 ## API -### ctx.cache.tryGet(key, getValueFunc \[, maxAge \[, refresh ]]) +### cache.tryGet(key, getValueFunc \[, maxAge \[, refresh ]]) #### 参数 @@ -65,13 +69,13 @@ sidebar_position: 3 :::tip -以下是使用缓存的高级方法。大多数情况下,您应使用 `ctx.cache.tryGet()`。 +以下是使用缓存的高级方法。大多数情况下,您应使用 `cache.tryGet()`。 -请注意,当使用 `ctx.cache.get()` 获取缓存时,您需要使用 `JSON.parse()`。 +请注意,当使用 `cache.get()` 获取缓存时,您需要使用 `JSON.parse()`。 ::: -### ctx.cache.get(key \[, refresh ]) +### cache.get(key \[, refresh ]) #### 参数 @@ -80,7 +84,7 @@ sidebar_position: 3 | key | `string` | *(必填)* 用于检索缓存的键。您可以使用 `:` 作为分隔符创建层次结构。 | | refresh | `boolean` | *(可选)* 是否在缓存命中时更新缓存过期时间。默认为`true`。 | -### ctx.cache.set(key, value \[, maxAge ]) +### cache.set(key, value \[, maxAge ]) #### 参数 diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md index f18586846..70c57771f 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/before-start.md @@ -98,7 +98,7 @@ npm run dev ```js module.exports = (router) => { // highlight-next-line - router.get('/issue/:user/:repo?', require('./issue')); + router.get('/issue/:user/:repo?', './issue'); }; ``` @@ -108,26 +108,22 @@ module.exports = (router) => { ```js module.exports = function (router) { // highlight-next-line - router.get('/issue/:user/:repo?', require('./issue')); + router.get('/issue/:user/:repo?', './issue'); }; ``` -在 `router.js` 中注册您的新 RSS 路由时,您可以定义路由路径并指定要执行的相应函数。在上面的代码中,`router.get()` 方法用于指定新的 RSS 路由的 HTTP 方法和路径。`router.get()` 的第一个参数是使用 [path-to-regexp](https://github.com/pillarjs/path-to-regexp) 语法的路由路径。第二个参数是您新的 RSS 规则 `issue.js` 中导出的函数。您可以省略 `.js` 扩展名。 +在 `router.js` 中注册您的新 RSS 路由时,您可以定义路由路径并指定要执行的相应函数。在上面的代码中,`router.get()` 方法用于指定新的 RSS 路由的 HTTP 方法和路径。`router.get()` 的第一个参数是使用 [Hono 路由](https://hono.dev/api/routing) 语法的路由路径。第二个参数是您新的 RSS 规则 `issue.js` 的相对路径。您可以省略 `.js` 扩展名。 在上面的示例中,`issue` 是一个精确匹配,`:user` 是一个必需参数,`:repo?` 是一个可选参数。`?` 在 `:repo` 之后表示该参数是可选的。如果用户没有输入仓库名,则会返回到您代码中指定的内容(这里是 `RSSHub`)。 -一旦您定义了路由路径,您可以从 `ctx.params` 对象中获取参数的值。例如,如果用户访问了 `/github/issue/DIYgod/RSSHub`,您可以分别从 `ctx.params.user` 和 `ctx.params.repo` 中获取 `user` 和 `repo` 的值。例如,如果用户访问了 `/github/issue/DIYgod/RSSHub`,则 `ctx.params.user` 和 `ctx.params.repo` 将分别为 `DIYgod` 和 `RSSHub`。 - -**请注意,值的类型将是 String 或 undefined。** - -您可以使用 `*` 或 `+` 符号来匹配路径的其余部分,例如 `/some/path/:variable*`。请注意,`*` 和 `+` 分别意味着“零个或多个”和“一个或多个”。您还可以使用模式,例如 `/some/path/:variable(\\d+)?`,甚至是正则表达式。 +一旦您定义了路由路径,您可以从 [`ctx.req.param()`](https://hono.dev/api/request#param) 方法中获取参数的值。例如,如果用户访问了 `/github/issue/DIYgod/RSSHub`,您可以分别从 `ctx.req.param('user')` 和 `ctx.req.param('repo')` 中获取 `user` 和 `repo` 的值。例如,如果用户访问了 `/github/issue/DIYgod/RSSHub`,则 `ctx.req.param('user')` 和 `ctx.req.param('repo')` 将分别为 `DIYgod` 和 `RSSHub`。 :::tip -有关 `router` 的更高级用法,请参阅 [@koa/router API 参考文档](https://github.com/koajs/router/blob/master/API.md)。 +有关 `router` 的更高级用法,请参阅 [Hono Routing API 参考文档](https://hono.dev/api/routing)。 ::: diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md index ff1334426..abb4023ba 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md @@ -28,15 +28,15 @@ sidebar_position: 3 ```js // 导入所需模组 -const got = require('@/utils/got'); // 自订的 got -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; // 自订的 got +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { // 在此处编写您的逻辑 - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -53,11 +53,11 @@ module.exports = async (ctx) => { ```js module.exports = async (ctx) => { // highlight-next-line - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -67,13 +67,13 @@ module.exports = async (ctx) => { ```js module.exports = async (ctx) => { // highlight-start - const user = ctx.params.user; - const repo = ctx.params.repo ?? 'RSSHub'; + const user = ctx.req.param('user'); + const repo = ctx.req.param('repo') ?? 'RSSHub'; // highlight-end - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -91,7 +91,7 @@ module.exports = async (ctx) => { ```js module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-start // 发送 HTTP GET 请求到 API 并解构返回的数据对象 const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { @@ -102,14 +102,14 @@ module.exports = async (ctx) => { }, searchParams: { // 这允许用户设置条数限制 - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); // highlight-end - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -118,8 +118,8 @@ module.exports = async (ctx) => { ```js module.exports = async (ctx) => { - const user = ctx.params.user; - const repo = ctx.params.repo ?? 'RSSHub'; + const user = ctx.req.param('user'); + const repo = ctx.req.param('repo') ?? 'RSSHub'; // highlight-start // 发送 HTTP GET 请求到 API const response = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { @@ -127,16 +127,16 @@ module.exports = async (ctx) => { accept: 'application/vnd.github.html+json', }, searchParams: { - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); // response.data 是上述请求返回的数据对象 const data = response.data; // highlight-end - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -147,7 +147,7 @@ module.exports = async (ctx) => { 一旦我们从 API 获取到数据,我们需要进一步处理它以生成符合 RSS 规范的 RSS 源。具体来说,我们需要提取源标题、源链接、文章标题、文章链接、文章正文和文章发布日期。 -为此,我们可以将相关数据赋值给 `ctx.state.data` 对象,RSSHub 的中间件将处理其余部分。 +为此,我们可以将相关数据传给 `ctx.set('data', obj)`,RSSHub 的中间件将处理其余部分。 以下是应有的最终代码: @@ -155,18 +155,18 @@ module.exports = async (ctx) => { ```js -const got = require('@/utils/got'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { accept: 'application/vnd.github.html+json', }, searchParams: { - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); @@ -188,14 +188,14 @@ module.exports = async (ctx) => { })); // highlight-start - ctx.state.data = { + ctx.set('data', { // 源标题 title: `${user}/${repo} issues`, // 源链接 link: `https://github.com/${user}/${repo}/issues`, // 源文章 item: items, - }; + }); // highlight-end }; ``` @@ -204,23 +204,23 @@ module.exports = async (ctx) => { ```js -const got = require('@/utils/got'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data } = await got(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { accept: 'application/vnd.github.html+json', }, searchParams: { - per_page: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30, + per_page: ctx.req.query('limit') ? parseInt(ctx.req.query('limit'), 10) : 30, }, }); // highlight-start - ctx.state.data = { + ctx.set('data', { // 源标题 title: `${user}/${repo} issues`, // 源链接 @@ -240,7 +240,7 @@ module.exports = async (ctx) => { // 如果有的话,文章分类 category: item.labels.map((label) => label.name), })); - }; + }); // highlight-end }; ``` @@ -258,16 +258,16 @@ module.exports = async (ctx) => { ```js // 导入必要的模组 -const got = require('@/utils/got'); // 自订的 got -const cheerio = require('cheerio'); // 可以使用类似 jQuery 的 API HTML 解析器 -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; // 自订的 got +import { load } from 'cheerio'; // 可以使用类似 jQuery 的 API HTML 解析器 +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { // 在此处编写您的逻辑 - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -283,12 +283,12 @@ module.exports = async (ctx) => { module.exports = async (ctx) => { // highlight-start // 从 URL 参数中获取用户名和仓库名称 - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-end - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -302,12 +302,12 @@ module.exports = async (ctx) => { ```js const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // 注意,".data" 属性包含了请求返回的目标页面的完整 HTML 源代码 // highlight-start const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); // highlight-end ``` @@ -338,30 +338,30 @@ module.exports = async (ctx) => { }); // highlight-end - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); ``` ### 生成 RSS 源 一旦我们从 API 获取到数据,我们需要进一步处理它以生成符合 RSS 规范的 RSS 源。具体来说,我们需要提取源标题、源链接、文章标题、文章链接、文章正文和文章发布日期。 -为此,我们可以将相关数据赋值给 `ctx.state.data` 对象,RSSHub 的中间件将处理其余部分。 +为此,我们可以将相关数据传给 `ctx.set('data', obj)`,RSSHub 的中间件将处理其余部分。 以下是应有的最终代码: ```js -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); const items = $('div.js-navigation-container .flex-auto') .toArray() @@ -381,14 +381,14 @@ module.exports = async (ctx) => { }); // highlight-start - ctx.state.data = { + ctx.set('data', { // 源标题 title: `${user}/${repo} issues`, // 源链接 link: `${baseUrl}/${user}/${repo}/issues`, // 源文章 item: items, - }; + }); // highlight-end }; ``` @@ -400,16 +400,16 @@ module.exports = async (ctx) => { 以下是更新后的代码: ```js -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); // highlight-next-line const list = $('div.js-navigation-container .flex-auto') @@ -432,9 +432,9 @@ module.exports = async (ctx) => { // highlight-start const items = await Promise.all( list.map((item) => - ctx.cache.tryGet(item.link, async () => { + cache.tryGet(item.link, async () => { const { data: response } = await got(item.link); - const $ = cheerio.load(response); + const $ = load(response); // 选择类名为“comment-body”的第一个元素 item.description = $('.comment-body').first().html(); @@ -447,12 +447,12 @@ module.exports = async (ctx) => { ); // highlight-end - ctx.state.data = { + ctx.set('data', { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, // highlight-next-line item: items, - }; + }); }; ``` @@ -483,10 +483,10 @@ module.exports = async (ctx) => { ```js // 导入所需模组 -const buildData = require('@/utils/common-config'); +import buildData from '@/utils/common-config'; module.exports = async (ctx) => { - ctx.state.data = await buildData({ + ctx.set('data', await buildData({ link: '', // RSS 来源链接 url: '', // 数据来源链接 // 此处可以使用变量 @@ -495,20 +495,20 @@ module.exports = async (ctx) => { params: { title: '', // 标题变量 }, - }); + })); }; ``` 我们的 RSS 订阅源目前缺少内容。必须设置 `item` 才能添加内容。以下是一个示例: ```js -const buildData = require('@/utils/common-config'); +import buildData from '@/utils/common-config'; module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const link = `https://github.com/${user}/${repo}/issues`; - ctx.state.data = await buildData({ + ctx.set('data', await buildData({ link, url: link, title: `${user}/${repo} issues`, // 也可以使用 $('head title').text() @@ -526,7 +526,7 @@ module.exports = async (ctx) => { pubDate: `parseDate($('relative-time').attr('datetime'))`, }, // highlight-end - }); + })); }; ``` @@ -537,17 +537,17 @@ module.exports = async (ctx) => { 要获取每个 GitHub Issue 的正文,你需要添加一些代码。以下是一个示例: ```js -const buildData = require('@/utils/common-config'); +import buildData from '@/utils/common-config'; // highlight-start -const got = require('@/utils/got'); -const cheerio = require('cheerio'); +import got from '@/utils/got'; +import { load } from 'cheerio'; // highlight-end module.exports = async (ctx) => { - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); const link = `https://github.com/${user}/${repo}/issues`; - ctx.state.data = await buildData({ + const data = await buildData({ link, url: link, title: `${user}/${repo} issues`, @@ -565,15 +565,17 @@ module.exports = async (ctx) => { // highlight-start await Promise.all( - ctx.state.data.item.map((item) => - ctx.cache.tryGet(item.link, async () => { + data.item.map((item) => + cache.tryGet(item.link, async () => { const { data: resonse } = await got(item.link); - const $ = cheerio.load(resonse); + const $ = load(resonse); item.description = $('.comment-body').first().html(); return item; }) ) ); + + ctx.set('data', data); // highlight-end }; ``` @@ -590,16 +592,16 @@ module.exports = async (ctx) => { ```js // 导入所需模组 -const cheerio = require('cheerio'); // 可以使用类似 jQuery 的 API HTML 解析器 -const { parseDate } = require('@/utils/parse-date'); -const logger = require('@/utils/logger'); +import { load } from 'cheerio'; // 可以使用类似 jQuery 的 API HTML 解析器 +import { parseDate } from '@/utils/parse-date'; +import logger from '@/utils/logger'; module.exports = async (ctx) => { // 在此处编写您的逻辑 - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); }; ``` @@ -611,17 +613,18 @@ module.exports = async (ctx) => { ```js -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); -const logger = require('@/utils/logger'); +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import logger from '@/utils/logger'; +import puppeteer from '@/utils/puppeteer'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-start // 导入 puppeteer 工具类并初始化浏览器实例 - const browser = await require('@/utils/puppeteer')(); + const browser = await puppeteer(); // 打开一个新标签页 const page = await browser.newPage(); // 拦截所有请求 @@ -647,7 +650,7 @@ module.exports = async (ctx) => { page.close(); // highlight-end - const $ = cheerio.load(response); + const $ = load(response); // const item = ...; @@ -656,9 +659,9 @@ module.exports = async (ctx) => { browser.close(); // highlight-end - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); } ``` @@ -666,21 +669,21 @@ module.exports = async (ctx) => { ```js -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); // highlight-next-line const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); - const $ = cheerio.load(response); + const $ = load(response); - ctx.state.data = { + ctx.set('data', { // 在此处输出您的 RSS - }; + }); } ``` @@ -692,15 +695,16 @@ module.exports = async (ctx) => { 使用浏览器新标签页获取每个 GitHub Issue 的正文,类似于 [上一节](#tong-guo-got-cong-html-huo-qu-shu-ju-geng-hao-de-yue-du-ti-yan)。我们可以使用以下代码: ```js -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); -const logger = require('@/utils/logger'); +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import logger from '@/utils/logger'; +import puppeteer from '@/utils/puppeteer'; module.exports = async (ctx) => { const baseUrl = 'https://github.com'; - const { user, repo = 'RSSHub' } = ctx.params; + const { user, repo = 'RSSHub' } = ctx.req.param(); - const browser = await require('@/utils/puppeteer')(); + const browser = await puppeteer(); const page = await browser.newPage(); await page.setRequestInterception(true); page.on('request', (request) => { @@ -715,7 +719,7 @@ module.exports = async (ctx) => { const response = await page.content(); page.close(); - const $ = cheerio.load(response); + const $ = load(response); const list = $('div.js-navigation-container .flex-auto') .toArray() @@ -736,7 +740,7 @@ module.exports = async (ctx) => { const items = await Promise.all( list.map((item) => - ctx.cache.tryGet(item.link, async () => { + cache.tryGet(item.link, async () => { // highlight-start // 重用浏览器实例并打开新标签页 const page = await browser.newPage(); @@ -755,7 +759,7 @@ module.exports = async (ctx) => { page.close(); // highlight-end - const $ = cheerio.load(response); + const $ = load(response); item.description = $('.comment-body').first().html(); @@ -769,11 +773,11 @@ module.exports = async (ctx) => { browser.close(); // highlight-end - ctx.state.data = { + ctx.set('data', { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, item: items, - }; + }); }; ``` diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md index c5dc06288..cecd70cb9 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/parameter.md @@ -171,7 +171,7 @@ RSSHub 同时支持 RSS 2.0、Atom、JSON Feed 和 RSS3 UMS 输出格式,在 ### debug.json -在路由末尾添加 `.debug.json`且实例运行在`debugInfo=true`的情况下,RSShub 将会返回插件设置在`ctx.state.json`的内容 +在路由末尾添加 `.debug.json`且实例运行在`debugInfo=true`的情况下,RSShub 将会返回插件设置在 `ctx.set('json', obj)` 的内容 这功能皆在方便开发者调试问题,方便用户自行开发需要的功能。插件作者可以酌情考虑使用,没有格式要求。 @@ -181,7 +181,7 @@ RSSHub 同时支持 RSS 2.0、Atom、JSON Feed 和 RSS3 UMS 输出格式,在 ### debug.html -在路由末尾添加 `.{index}.debug.html` (`{index}` 为数字,为从 0 开始的下标)且实例运行在 `debugInfo=true` 的情况下,RSShub 将会返回插件设置在 `ctx.state.data.item[index].description` 的内容,你可用浏览器访问该页面来快速查看提取的信息的展示结果。 +在路由末尾添加 `.{index}.debug.html` (`{index}` 为数字,为从 0 开始的下标)且实例运行在 `debugInfo=true` 的情况下,RSShub 将会返回插件设置在 `data.item[index].description` 的内容,你可用浏览器访问该页面来快速查看提取的信息的展示结果。 举例: