如何使用WordPress、Next.js和GraphQL查询(WPGraphQL)创建一个无头CMS网站
在当前的网络世界中,建立一个网站可能会让人不知所措,尤其是在没有极端的建站知识的情况下。但是,如果有一个完善的、现成的内容管理系统,如WordPress,建立一个网站会更容易。
WordPress是一个开源的内容管理系统(CMS)。内容管理系统是一种在网络服务器上运行的软件,用于托管现成的和可定制的网站模板。这意味着你可以免费使用或修改WordPress建立一个成熟的网站。
作为一个CMS,它允许你管理网站的不同方面,如改变WordPress的外观,添加和修改内容,以及增强搜索引擎。
然而,由于WordPress对初学者友好,其后端技术是服务器端渲染(SSR)。这暗示你可能会遇到一些比其他技术(如Next.js)更高的性能开销。WordPress的内容是直接从服务器上提供的。
每一个请求都要经过服务器,请求提供必要的资源。由于有许多请求需要处理,当请求流量增加时,处理能力较弱的服务器会不堪重负。
Next.js等技术支持混合内容生成。他们同时支持静态网站生成的SSR和CSR。这意味着服务器端的内容是提前提供的。
Next.js使用静态渲染页面的生成器,使其提前加载。有了Next.js这样的卓越技术,你可以把它们与WordPress等CMS结合起来,以无头方式运行。这样,WordPress将运行一个无头的CMS。这将产生一个具有良好用户体验的高性能网站。
前提条件
以下先决条件将帮助你浏览本教程。
- 对[Next.js]的工作有基本了解。
- 充分了解[WordPress的工作原理]以及[如何使用它来建立网站]。
什么是无头CMS
在WordPress CMS中,后台(你管理内容的地方)和前台(向网站访问者显示内容的地方)被整合为一个整体系统。当WordPress作为一个无头CMS运行时,内容和内容展示都是解耦的。
这使得内容展示层变得灵活。你现在可以建立一个网站或一个移动应用程序来呈现原始的WordPress驱动的内容。后台和前端不再与CMS捆绑在一起。
你仍然有WordPress CMS用于内容创建,以及保存在数据库中的管理。唯一的区别是,内容呈现是通过应用编程接口(API)作为原始数据格式(如JSON)交付的。然后在网站、移动应用程序或任何其他渠道和设备中展示这些数据。
将WordPress作为无头CMS运行的原因
- 它使你能够在你想要的时候改变内容交付渠道,而无需重新编写内容。
- 由于内容是通过API以原始数据的形式交付的,你可以使用任何你希望的技术来展示这些数据。作为一个开发者,这使你能够专注于最重要的事情,例如为你的用户创造伟大的数字体验。
- API驱动的数据促进了全渠道架构。你创建WordPress的内容,并通过API来引导它。因此,内容在所有接触点上都会发光。
- 它创造了更有效、可扩展和更快的应用程序。后台和前台都与单片机CMS架构分离。如果WordPress支持的CMS有任何问题,渠道交付管道将不会受到影响。因此,交付渠道的性能不会受到影响。
在本指南中,我们将学习如何使用Next.js将WordPress作为无头CMS运行。
让我们深入了解一下。
添加一个帖子
首先,到你的远程WordPress网站管理仪表板去。
由于WordPress和Next.js是用来开发基于博客的网站,我们将使用这个方案,首先在WordPress管理中添加和发布一个帖子。
然后,从你的WordPress管理仪表板,导航到posts
,添加一个category
。在产生的页面的左窗格中,输入一个名称、slug和帖子类别的描述,然后点击按钮Add new category
。
下图显示了如何设置这些字段。
现在添加一个新的帖子。从管理仪表板,导航到左边的侧栏,点击posts
。在由此产生的右侧弹出窗口中,点击Add new
。
在出现的面板上,输入标题和一些假内容,如下所示。
WordPress博客中的每篇发表的文章都可以与一个特定的类别相关联。在右侧,点击Post
标签。
在Categories
菜单标签中,选中你在上一步创建的类别。
如果你想添加一个特色图片,你可以在Featured image
菜单标签中这样做。在Excerpt
菜单选项卡中,添加一个帖子的简短描述。
完成后,导航到右上角,点击Publish
,你的帖子就会上线。
这样,你就有一个帖子了。重复这个过程几次,以便有几个帖子可以查询。
安装WpGraphQL插件
WPGraphQL是一个免费的、开源的WordPress插件,为任何WordPress网站提供一个可扩展的GraphQL模式和API。我们将使用它来获取GraphQL模式,以帮助WordPress的API与Next.js通信。让我们继续安装这个插件。
从仪表板的左侧边栏,导航到插件。在右侧弹出的窗口中,点击Add new
。
在搜索栏中,搜索WpGraphQL
。
在下面的结果中点击Install now
。
一旦安装结束,确保激活该插件。
从GraphiQL IDE运行查询
在你的WordPress网站上安装该插件后,你将在左侧边栏的底部有一个GraphQL
标签。导航到它,在弹出的窗口中,点击GraphiQL IDE
。这将使你重定向到一个GraphQL操场,在那里你可以写你的查询。
为了查询我们已经发布的帖子,我们将使用以下GraphQL模式。
query postsQuery{
posts{
edges{
node{
title
categories{
edges{
node{
name
}
}
}
excerpt
slug
content
}
}
}
}
我们从上述查询中获取所有的帖子,每个查询都会得到帖子的标题、类别、摘要和内容。在左侧窗格中,粘贴上述查询。然后,通过点击播放按钮执行查询,如图所示。
设置Next.js环境
要设置Next.js环境,请遵循以下步骤。
- 通过运行以下命令,使用create-next-app创建一个简单的Next.js应用程序。
npx create-next-app cms-wordpress-app
- 将创建一个文件夹
cms-wordpress-app
,其中将包含开始处理Next.js项目的所有必要文件。使用Change Directory (cd)
命令,进入我们创建的项目文件夹cms-wordpress-app
。
cd cms-wordpress-app
- 为了测试一切是否正常,运行以下命令,启动Next.js开发服务器。
npm run dev
上面的命令将在3000端口启动开发服务器,并将其暴露在你的本地主机上。打开你的浏览器,访问http://localhost:3000
。一个Next.js的模板博客将在你的浏览器上提供。
使用GraphQL模式将WordPress API添加到Next.js中
如下图所示,在根目录下创建一个.env.local
文件和一个WORDPRESS_API_URL
。
WORDPRESS_API_URL=your_wordpress_api_url
要获得你的API_URL
。
- 进入你的WordPress管理页面。
- 在左边的侧栏,点击GraphQL。
- 在GraphQL端点下获得你的URL。
连接到WordPress CMS
为了连接到WordPress CMS,创建一个名为lib
的文件夹。在这个文件夹中,我们将处理从我们的应用程序到WordPress CMS的连接。
在pages
文件夹里有一个api.js
文件,我们将在这里实现与WordPress API通信的各种功能。
因此,在api.js
文件中,通过添加这一行,得到我们保存在env.local
文件中的API_URL
。
const API_URL = process.env.WORDPRESS_API_URL;
配置一个要调用的函数来发送请求给API,如下图所示。
async function fetchAPI(query, { variables } = {}) {
const headers = { 'Content-Type': 'application/json' }
if (process.env.WORDPRESS_AUTH_REFRESH_TOKEN) {
headers[
'Authorization'
] = `Bearer ${process.env.WORDPRESS_AUTH_REFRESH_TOKEN}`
}
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({
query,
variables,
}),
})
const json = await res.json()
if (json.errors) {
console.error(json.errors)
throw new Error('Failed to fetch API')
}
return json.data
}
上述函数将收到两个参数;要运行的查询和要与查询一起传递的变量。然后,我们将使用该查询从CMS中获取数据。
该请求将以POST方式使用Fetch发送。如果在运行查询时发生错误,将抛出一个消息,否则将返回数据。
取回所有WordPress的帖子
添加一个函数来获取所有的帖子,如下所示。
export async function getPosts(){
const data = await fetchAPI(
`query AllPosts {
posts(first: 20) {
edges {
node {
title
categories{
edges{
node{
name
}
}
}
excerpt
slug
author {
node {
name
firstName
lastName
}
}
}
}
}
}
`,
{
variables: {},
}
);
return data?.posts?.edges;
}
在上面的代码中,我们向WordPress API发送一个请求,以获取前20个帖子。
获取一个WordPress的帖子
同样地,我们可以添加一个函数来获取一个帖子,如下所示。
export async function getSinglePost(id){
const data = await fetchAPI(`
query getSinglePost($id:ID!){
post(id:$id){
title
categories{
edges{
node{
name
}
}
}
excerpt
content
slug
id
author {
node {
name
firstName
lastName
}
}
}
}
`,{id});
return data?.post;
}
在上面的函数中,我们收到了我们想要获取的帖子的ID,并将它与查询一起发送,以获取其具体数据。
为了在我们的应用程序中显示这些帖子,我们将利用getServerSideProps()方法。该方法将在每次请求中运行,以便从CMS中获取数据。
该方法将在主页上实现,在那里我们获取所有的帖子,并在一个特定的帖子页面上实现。
要在主页上实现这个方法,请按照以下步骤进行:pages/index.js
。
- 让我们导入
getPosts
函数。
import {getPosts} from "../lib/api";
- 在
Home
函数的下面,调用getServerSideProps()
,如下图所示。
export async function getServerSideProps(ctx){
let posts = await getPosts();
return {
props:{
posts
}
}
}
在上面的getServerSideProps()
中,我们正在调用getPosts()
函数来获取帖子,并在props
对象中返回它们。这些数据将被发送到组件中。我们必须得到它并通过它来显示帖子。
- 编辑
Home
函数,如下图所示。
export default function Home({posts}) {
return (
<div className={styles.container}>
<Head>
<title>CMS blog</title>
<meta name="description" content="CMS Wordpress with Next.js" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
{
posts.map((post,index) => (
<div key={index}>
<Link href={`/posts/${post.node.id}`}>
<a style={{color:'blue'}}>{post.node.title}</a>
</Link>
<div dangerouslySetInnerHTML={{__html:post.node.excerpt}} />
<p>By {post.node.author.node.name}</p>
</div>
))
}
</main>
<footer className={styles.footer}>
<p>Posts</p>
</footer>
</div>
)
}
在上述函数中。
- 我们正在获取从
getServerSideProps()
发送的帖子。 - 通过帖子的映射,为每个帖子显示标题、摘要和作者。标题是一个指向特定帖子页面的链接。
测试
为了测试,让我们使用以下命令确保开发服务器已经启动并运行。
npm run dev
在你的浏览器中,导航到http://localhost:3000
。你的帖子将根据你添加到WordPress博客的帖子来显示。
用单篇文章测试
要显示一个单一的帖子页面,请导航到pages
目录并创建posts
目录。在posts
目录内,创建[id].js
文件。
[] 标志着该ID将是动态的。
在[id].js
文件中,导入getSinglePost
函数。
import {getSinglePost} from "../../lib/api";
这个函数做两件事。
- 它获取从
getServerSideProps()
发送的帖子。 - 它通过帖子进行映射,为每个帖子显示标题、摘要和作者。标题是一个指向特定帖子页面的链接。
接下来,实现getServerSideProps()
,如下所示。
export async function getServerSideProps(ctx){
let {id} = ctx.params;
let post = await getSinglePost(id);
return {
props:{
post
}
}
}
从上面的代码块中,我们得到帖子的ID,根据该ID获取帖子,并将帖子发送到props对象内。下一步是为视图实现一个函数。
要做到这一点,从Next.js导入styles
模块和Head
包。
import Head from "next/head";
import styles from '../../styles/Home.module.css';
接下来,创建一个Post
函数,如下图所示。
export default function Post({post}) {
return (
<div className={styles.container}>
<Head>
<title>{post.title}</title>
</Head>
<main>
<div dangerouslySetInnerHTML={{__html:post.excerpt}} />
<br />
<br />
<div dangerouslySetInnerHTML={{__html:post.content}} />
</main>
</div>
)
}
在这里,我们得到传递的帖子,并通过显示其标题、摘录和内容,将其呈现在上述函数的视图中。你可以随意显示你想要的字段,但要确保它们在查询中。
为了测试这个,确保开发服务器正在运行,我们可以通过运行来启动它。
npm run dev
在你的浏览器中,导航到http://localhost:3000
。
要测试实现,请点击主页上的任何帖子的标题。你应该被重定向到一个单一的帖子页面。然后,点击后面的箭头,探索其他的帖子。
结论
我们已经成功地在WordPress中创建帖子,查询,并从Next.js应用程序中显示它们。要想获得有关各种技术和概念的更深入的知识,请查看参考资料部分列出的资源。