Gutenberg 是WordPress的默认编辑器。该编辑器可以通过拖放界面使用文本、图像、视频和其他网站元素的离散块来制作和设计内容。这种方法增强了 WordPress 的灵活性和设计能力。
使用 REST API 获取古腾堡(Gutenberg)内容
要以编程方式与 WordPress 网站交互并检索古腾堡块中结构化的内容,可以使用 WordPress REST API 或WPGraphQL 插件。这些工具能够让你以 JSON 格式获取 WordPress 内容。
要通过 REST API 启用 JSON 数据访问,请将 WordPress 永久链接设置调整为远离“Plain”。这样,就能通过一种特定格式的网址来访问 API 了,如下所示:
https://yoursite.com/wp-json/wp/v2
通过向此 URL 发出 API 请求,可以用编程方式检索各种信息并在 WordPress 网站上执行操作。例如,你可以通过向以下地址发送 GET 请求来获取帖子列表:
https://yoursite.com/wp-json/wp/v2/posts
会返回一个 JSON 对象,其中包含有关 WordPress 网站上的帖子的信息,包括标题、内容、作者详细信息等。
将古腾堡(Gutenberg)块解析为 HTML
当从使用古腾堡编辑器的 WordPress 网站检索帖子时,数据库中存储的内容可以混合使用 HTML 和 JSON 元数据来描述各种块类型,例如引用和图库:
<!-- wp:quote {"className":"inspirational-quote","style":{"typography":{"fontSize":"large"}}} -->
<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>“The journey of a thousand miles begins with one step.”</p><cite>Lao Tzu</cite></blockquote>
<!-- /wp:quote -->
<!-- wp:gallery {"ids":[34,35],"columns":2,"linkTo":"none","sizeSlug":"medium","className":"custom-gallery"} -->
<ul class="wp-block-gallery columns-2 is-cropped custom-gallery"><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="A breathtaking view of the mountains" class="wp-image-34"/></figure></li><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serene lakeside at dawn" class="wp-image-35"/></figure></li></ul>
<!-- /wp:gallery -->
该代码段展示了两个 Gutenberg 块:引用和图库。每个区块都有封装在 HTML 注释中的 JSON 元数据。元数据定义了类名、样式等属性,以及与区块展示相关的其他配置。
当你通过 WordPress REST API 或 WPGraphQL 获取这些区块时,WordPress 会对其进行处理,将 HTML 和 JSON 元数据的组合转换为完全呈现的 HTML 元素,你可以直接将其整合到网页中。上述区块转换后的 HTML 显示如下:
<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>“The journey of a thousand miles begins with one step.”</p><cite>Lao Tzu</cite></blockquote>
<ul class="wp-block-gallery columns-2 is-cropped custom-gallery">
<li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="A breathtaking view of the mountains" class="wp-image-34" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
<li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serene lakeside at dawn" class="wp-image-35" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
</ul>
对于使用 Next.js 等 JavaScript 框架构建解耦或应用程序的开发人员来说,这提供了一种简单的方法来显示内容,即使用属性将 HTML 直接注入到页面中dangerouslySetInnerHTML
以呈现标记。
<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />
Parse Gutenberg 块内容进入 Next.js 静态站点
我们将 WordPress 内容提取到 Next.js 项目中,然后将 Gutenberg 块解析为 HTML。
1.首先设置一个从 WordPress 网站获取帖子的函数。打开 项目中的 src/page.js文件并将其内容替换为以下代码片段:
const getWpPosts = async () => {
const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
const posts = await res.json();
return posts;
};
此异步函数对 WordPress REST API 执行 API 请求。它获取你网站上的所有可用帖子并将它们作为数组返回。
2.接下来,让我们通过将帖子记录到控制台并呈现基本问候语,在简单的 Next.js 页面组件中利用获取的帖子:
const page = async () => {
const posts = await getWpPosts();
console.log(posts);
return (
<div>
<h1>Hello World</h1>
</div>
);
};
export default page;
当你使用运行项目时npm run dev
,它会显示“Hello World”消息并将获取的帖子记录到终端。
[
{
"_links" : {
"about" : [...],
"author" : [...],
"collection" : [...],
"curies" : [...],
"predecessor-version" : [...],
"replies" : [...],
"self" : [...],
"version-history" : [...],
"wp:attachment" : [...],
"wp:term" : [...]
},
"author" : 1,
"categories" : [...],
"comment_status" : "open",
"content" : {
"protected" : false,
"rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate.</p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"148\" src=\"https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg\" alt=\"\" class=\"wp-image-14\"/></figure>\n\n\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and danger. From the comforting glow of a hearth to the destructive fury of wildfires, fire’s dual nature reminds us of our fragile relationship with the elements.</p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380\" alt=\"\"/></figure>\n\n\n\n<p>You can check out other articles on our blog:</p>\n\n\n\n<ul>\n<li><a href=\"https://yoursite.com/?p=6\">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Act 3</a></li>\n</ul>\n"
},
"date" : "2024-02-27T12:08:30",
"date_gmt" : "2024-02-27T12:08:30",
"excerpt" : {
"protected" : false,
"rendered" : "<p>Fire, a primal force, captivates with its flickering flames, evoking both awe and caution. Its dance symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate. In ancient times, fire was a beacon of light and warmth, […]</p>\n"
},
"featured_media" : 0,
"format" : "standard",
"guid" : {
"rendered" : "https://yoursite.com/?p=13"
},
"id" : 13,
"link" : "https://yoursite.com/?p=13",
"meta" : {
"footnotes" : ""
},
"modified" : "2024-02-29T16:45:36",
"modified_gmt" : "2024-02-29T16:45:36",
"ping_status" : "open",
"slug" : "fire-fire",
"status" : "publish",
"sticky" : false,
"tags" : [],
"template" : "",
"title" : {
"rendered" : "Fire"
},
"type" : "post"
},
},
...
]
表示各个古腾堡帖子数据的 JSON 对象包括各种字段,其中内容和摘录字段作为解析为 HTML 字符串的古腾堡块返回。
3.在 Next.js 中正确渲染此 HTML 内容,我们使用dangerouslySetInnerHTML
属性:
const page = async () => {
const posts = await getWpPosts();
return (
<>
<h1> Headless Blog </h1>
<div>
{posts.map((post) => (
<Link href={'/blog/' + post.id} key={post.id}>
<h2>
{post.title.rendered} <span>-></span>
</h2>
<div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
</Link>
))}
</div>
</>
);
};
export default page;
在更新的组件中,我们映射获取的帖子数组以生成帖子摘录列表。每个摘录都包含在一个Link
用于导航的组件中,显示帖子标题及其内容片段。
该dangerouslySetInnerHTML
属性用于解析和呈现excerpt.rendered
字段中包含的 HTML 内容。
4.接下来,在应用程序目录 中创建文件blog/[id]/page.js 。可以使用文件夹来定义路线。因此,通过创建博客 文件夹,可以定义博客 路线。可以将其与动态路由结合起来 ,为每个帖子生成路径。
5.每个帖子都有一个 ID。可以使用此 ID/blog/{post_id}
在应用程序中生成其唯一的路径。添加以下代码:
import Link from 'next/link';
export async function generateStaticParams() {
const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
const posts = await res.json();
return posts.map((post) => {
return {
params: {
id: post.id.toString(),
},
};
});
}
export async function getPost(id) {
const response = await fetch('https://yoursite.com/wp-json/wp/v2/posts/' + id);
const post = await response.json();
return post;
}
该generateStaticParams()
函数根据每个帖子返回的相应 ID 在构建时静态生成路径。该getPost()
函数使用传递的 ID 从 REST API 获取帖子的古腾堡数据。
前面的部分显示了从帖子的 REST API 返回的已解析古腾堡数据示例。目前,我们只关心该content.rendered
领域:
[
{
...
"content": {
"rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate.</p>\n\n\n\n<figure> class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"148\" src=\"https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg\" alt=\"\" class=\"wp-image-14\"/></figure>\n\n\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and danger. From the comforting glow of a hearth to the destructive fury of wildfires, fire’s dual nature reminds us of our fragile relationship with the elements.</p>\n\n\n\n<figure> class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380\" alt=\"\"/></figure>\n\n\n\n<p>You can check out other articles on our blog:</p>\n\n\n\n<ul>\n<li><a> href=\"https://yoursite.com/?p=6\">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a> href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a> href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Act 3</a></li>\n</ul>\n"
},
...
}
]
该字段包含帖子的原始 HTML。它可以直接使用dangerouslySetInnerHTML
像这样的属性来渲染<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />
。
6.接下来,可以通过解析内部链接和调整图像大小来处理数据。安装该html-react-parser
包以简化解析标签的过程:
npm install html-react-parser --save
7.将以下代码添加到blog/[id]/page.js 文件中:
import parse, { domToReact } from "html-react-parser";
/*
* We use a regular expression (pattern) to match the specific URL you want to replace.
* The (\d+) part captures the numeric ID after ?p=.
* Then, we use the replacement string 'data-internal-link="true" href="/blog/$1"',
* where $1 is a placeholder for the captured ID.
*/
export function fixInternalLinks(html_string) {
const pattern = /href="https:\/\/yoursite.com\/\?p=(\d+)"/g;
const replacement = 'data-internal-link="true" href="/blog/$1"';
return html_string.replace(pattern, replacement);
}
export function parseHtml(html) {
// Replace 2+ sequences of '\n' with a single '<br />' tag
const _content = html.replace(/\n{2,}/g, '<br />');
const content = fixInternalLinks(_content);
const options = {
replace: ({ name, attribs, children }) => {
// Convert internal links to Next.js Link components.
const isInternalLink =
name === "a" && attribs["data-internal-link"] === "true";
if (isInternalLink) {
return (
<Link href={attribs.href} {...attribs}>
{domToReact(children, options)}
</Link>
);
} else if (name === "img") {
attribs["width"] = "250";
attribs["height"] = "150";
return (
<img {...attribs}/>
);
}
},
};
return parse(content, options);
}
该fixInternalLinks()
函数使用正则表达式从 HTML 字符串中查找 WordPress 网站中帖子的链接。在原始 HTML 中,可以看到该帖子包含一个List
标签,其中包含指向网站上其他帖子的链接,并将这些链接替换为指向静态网站中的路径的内部链接。
该parseHTML()
函数找到多个多余换行符序列,n
并用标签替换它们<br />
。它还查找内部链接并将锚标记转换为链接标记。然后,该函数使用标签属性调整图像大小。
8.要为每个动态路径生成主 UI,请添加以下代码:
export default async function Post({ params }) {
const post = await getPost(params.id);
const content = parseHtml(post.content.rendered);
return (
<>
<h1>
{post.title.rendered}
</h1>
<div>{content}</div>
</>
);
}
从古腾堡数据解析原始 HTML 后,代码返回表示页面格式化 UI 的 JSX。
最后,运行项目时,主页将显示 WordPress 上的帖子列表。此外,当你单击各个帖子时,将看到解析后的古腾堡内容正确呈现。
暂无评论内容