GatsbyJS 的新手,我需要帮助来检查 RSS 提要,但我迷路了!
我想在我的 gatsby 网站上查看另一个博客的 rss 提要,我想把这个博客的帖子取回我的 gatsby 网站。
有人可以告诉我是否需要安装:“gatsby source rss feed”(我认为)、“gatsby source rss”或“gatsby rss feed”(我认为不是它,dit 将他的 gatsby 帖子推送到另一个博客,我需要反过来)?
如果有人也可以告诉我如何声明 rss 的查询?在女巫文件夹中?
我的 gatsby-config.js:
const path = require("path")
const config = require("./data/siteConfig")
module.exports = {
siteMetadata: {
title: ``,
author: config.authorName,
description: config.siteDescription,
siteUrl: config.siteUrl,
...config,
},
pathPrefix: `/froggit.fr`,
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: "pages",
path: "content/pages",
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: "posts",
path: "content/posts",
//path: "src/page/blog",
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: "images",
path: "content/images",
},
},
{
resolve: `gatsby-plugin-page-creator`,
options: {
path: path.join(__dirname, `src`, `pages`),
},
},
{
resolve: `gatsby-plugin-page-creator`,
options: {
path: `${__dirname}/src/settings/pages`,
},
},
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: [`.mdx`, `.md`],
defaultLayouts: {
default: require.resolve("./src/templates/page.js"),
},
gatsbyRemarkPlugins: [
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 590,
linkImagesToOriginal: false,
withWebp: true,
},
},
{ resolve: "gatsby-remark-prismjs" },
{ resolve: "gatsby-remark-responsive-iframe" },
{ resolve: "gatsby-remark-copy-linked-files" },
{ resolve: "gatsby-remark-smartypants" },
{ resolve: "gatsby-remark-autolink-headers" },
],
},
},
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [`gatsby-remark-images`],
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-offline`,
`gatsby-plugin-styled-components`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: config.googleAnalyticsId,
},
},
{
resolve: `gatsby-source-rss-feed`,
options: {
url: `https://www.gatsbyjs.org/blog/rss.xml`,
name: `GatsbyBlog`,
parserOption: {
customFields: {
item: ['itunes:duration']
}
}
}
},
{
resolve: '@uptimeventures/gatsby-source-rss',
options: {
feeds: ['https://www.uptime.ventures/blog/rss.xml'],
},
},
{
resolve: 'gatsby-source-rss',
options: {
rssURL: 'https://lydra.fr/tag/froggit/feed/rss.xml'
}
},
{
resolve: `gatsby-plugin-feed`,
options: {
setup: (options) => ({
...options,
custom_namespaces: {
yournamespace: "https://lydra.fr/tag/froggit/feed/",
},
}),
feeds: [
{
serialize: ({
query: { allMarkdownRemark },
}) => {
return allMarkdownRemark.edges.map((edge) => {
return Object.assign(
{},
edge.node.frontmatter,
{
custom_elements: [
//{ "content:encoded": edge.node.html },
{ "yournamespace:yourcustomfield": edge.node.fields.someField },
],
}
);
});
},
},
],
},
},
{
resolve: 'gatsby-source-rss',
options: {
rssURL: 'https://blog.jordanrhea.com/rss.xml',
customFields: {
item: ['tags'],
},
},
},
*/
{
resolve: `gatsby-plugin-feed`,
options: {
query: `
{
site {
siteMetadata {
title
description
siteUrl
site_url: siteUrl
}
}
}
`,
feeds: [
{
serialize: ({ query: { site, allMarkdownRemark } }) => {
return allMarkdownRemark.edges.map(edge => {
return Object.assign({}, edge.node.frontmatter, {
description: edge.node.excerpt,
date: edge.node.frontmatter.date,
url: site.siteMetadata.siteUrl + edge.node.fields.slug,
guid: site.siteMetadata.siteUrl + edge.node.fields.slug,
custom_elements: [{ "content:encoded": edge.node.html }],
})
})
},
query: `
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] },
) {
edges {
node {
excerpt
html
fields { slug }
frontmatter {
title
date
}
}
}
}
}
`,
output: "/rss.xml",
title: "Your Site's RSS Feed",
},
],
},
},
{
resolve: `gatsby-source-podcast-rss-feed`,
options: {
feedURL: `https://lydra.fr/ea-2-le-podcasteur-erwan/rss`,
id: 'guid',
},
},
{
resolve: `@arshad/gatsby-theme-podcast-core`,
options: {
feedUrl: `https://blog.jordanrhea.com/rss.xml`,
podcast: {
name: `Name of Podcast`,
description: `Eligendi nisi nobis nisi voluptate. Corporis deserunt provident hic numquam. Veritatis vero necessitatibus adipisci cumque voluptate rerum at.`,
image: `content/images/podcast.jpg`,
social: [
{
name: `Apple Podcast`,
url: `https://itunes.apple.com`,
},
{
name: `Google Podcast`,
url: `https://podcasts.google.com`,
},
],
},
},
},
{
resolve: `gatsby-source-youtube`,
options: {
channelId: '<<Youtube channelID eg. UCK8sQmJBp8GCxrOtXWBpyEA >>',
apiKey: '<< Add your Youtube api key here>>',
maxVideos: 50 // Defaults to 50
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: config.siteTitle,
short_name: config.siteTitle,
start_url: config.pathPrefix,
background_color: config.background_color,
theme_color: config.theme_color,
display: config.display,
icon: "content/images/logo_froggit.png",
},
},
{
resolve: "gatsby-plugin-compile-es6-packages",
options: {
modules: ["gatsby-starter-morning-dew"],
},
},
],
}
在我的文件中:gatsby-node.js?我已经复制了一些代码来创建我的 rss 提要,但我不明白很多东西......
const { createFilePath } = require("gatsby-source-filesystem")
const { load, createFeed } = require('./internals')
async function sourceNodes({ boundActionCreators }, options = {}) {
const { createNode } = boundActionCreators
const { feeds = [] } = options
for (const f of feeds) {
const { rss } = await load(f)
if (rss && rss.channel) {
const sources = (Array.isArray(rss.channel)
? rss.channel : [rss.channel]
)
sources.forEach(f => createFeed(f, createNode))
}
}
return Promise.resolve()
}
module.exports = {
sourceNodes,
}
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions
const BlogPostTemplate = require.resolve("./src/templates/blog-post.js")
const BlogPostShareImage = require.resolve(
"./src/templates/blog-post-share-image.js"
)
const PageTemplate = require.resolve("./src/templates/page.js")
const PostsBytagTemplate = require.resolve("./src/templates/tags.js")
const ListPostsTemplate = require.resolve(
"./src/templates/list.js"
)
const allMarkdownQuery = await graphql(`
{
allMarkdown: allMdx(
sort: { fields: [frontmatter___date], order: DESC }
filter: { frontmatter: { published: { ne: false } } }
limit: 1000
) {
edges {
node {
fileAbsolutePath
frontmatter {
title
slug
tags
language
cover {
publicURL
}
unlisted
}
timeToRead
excerpt
}
}
}
}
`)
if (allMarkdownQuery.errors) {
reporter.panic(allMarkdownQuery.errors)
}
const postPerPageQuery = await graphql(`
{
site {
siteMetadata {
postsPerPage
}
}
}
`)
const markdownFiles = allMarkdownQuery.data.allMarkdown.edges
const posts = markdownFiles.filter(item =>
item.node.fileAbsolutePath.includes("/content/posts/")
)
actions.createPage({
path: '/blog',
component: require.resolve(`./src/templates/list.js`),
context: {},
})
const postsPerPage = postPerPageQuery.data.site.siteMetadata.postsPerPage
const nbPages = Math.ceil(listedPosts.length / postsPerPage)
Array.from({ length: nbPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/` : `/pages/${i + 1}`,
component: ListPostsTemplate,
context: {
limit: postsPerPage,
skip: i * postsPerPage,
currentPage: i + 1,
nbPages: nbPages,
},
})
posts.forEach((post, index, posts) => {
const previous = index === posts.length - 1 ? null : posts[index + 1].node
const next = index === 0 ? null : posts[index - 1].node
createPage({
path: post.node.frontmatter.slug,
component: BlogPostTemplate,
context: {
slug: post.node.frontmatter.slug,
previous,
next,
},
})
if (process.env.gatsby_executing_command.includes("develop")) {
createPage({
path: `${post.node.frontmatter.slug}/image_share`,
component: BlogPostShareImage,
context: {
slug: post.node.frontmatter.slug,
width: 440,
height: 220,
},
})
}
})
markdownFiles
.filter(item => item.node.fileAbsolutePath.includes("/content/pages/"))
.forEach(page => {
createPage({
path: page.node.frontmatter.slug,
component: PageTemplate,
context: {
slug: page.node.frontmatter.slug,
},
})
})
markdownFiles
.filter(item => item.node.frontmatter.tags !== null)
.reduce(
(acc, cur) => [...new Set([...acc, ...cur.node.frontmatter.tags])],
[]
)
.forEach(uniqTag => {
createPage({
path: `tags/${uniqTag}`,
component: PostsBytagTemplate,
context: {
tag: uniqTag,
},
})
})
}
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
}
}
const parser = require('rss-parser');
const crypto = require('crypto');
const createContentDigest = obj => crypto.createHash('md5').update(JSON.stringify(obj)).digest('hex');
function promisifiedParseURL(url) {
return new Promise((resolve, reject) => {
parser.parseURL(url, (err, data) => {
if (err) {
reject(err);
}
resolve(data.feed);
});
});
}
const createChildren = (entries, parentId, createNode) => {
const childIds = [];
entries.forEach(entry => {
childIds.push(entry.link);
const node = Object.assign({}, entry, {
id: entry.link,
title: entry.title,
link: entry.link,
description: entry.description,
parent: parentId,
children: []
});
node.internal = {
type: 'rssFeedItem',
contentDigest: createContentDigest(node)
};
createNode(node);
});
return childIds;
};
async function sourceNodes({ boundActionCreators }, { rssURL }) {
const { createNode } = boundActionCreators;
const data = await promisifiedParseURL(rssURL);
if (!data) {
return;
}
const { title, description, link, entries } = data;
const childrenIds = createChildren(entries, link, createNode);
const feedStory = {
id: link,
title,
description,
link,
parent: null,
children: childrenIds
};
feedStory.internal = { type: 'rssFeed', contentDigest: createContentDigest(feedStory) };
createNode(feedStory);
}
exports.sourceNodes = sourceNodes;
或者再次在我的模板的文件夹中?
非常感谢。