使用 WordPress 作为无头 CMS 构建 Astro 网站
本文原发于OpenReplay博客
大家好!
我确定您听说过 WordPress,您可能喜欢也可能不喜欢它。在本文中,我将向您展示如何将 WordPress 用作下一个项目的无头 CMS,从而仅利用它的优点。
作为前端,我们将使用新的流行静态站点生成器 Astro。
让我们深入了解一下我们正在使用的细节。
什么是Astro?
Astro 是一个静态站点生成器 (SSG),这意味着它可以输出静态 HTML 网站。
您可能想知道,好吧,但我们为什么需要它呢? SSG 非常出色,因为它输出静态 HTML,这反过来意味着您的网站将非常快速。没有什么比纯 HTML 网站更快的了。
我们经常需要在我们的网站上使用动态零件和组件。这就是 SSG 派上用场的地方。
Astro 是一个相当新的孩子,但非常强大且充满潜力。以下是使用 Astro 的一些好处:
-
SEO 专注于开箱即用
-
BYOF(自带框架)方法,带上你喜欢工作的任何框架,Astro 让它工作
-
部分水化,使组件在正确的时间渲染
-
大量内置支持
-
路由非常扩展
-
活跃社区
如果您问我,这些只是 Astro 非常出色的部分原因。但是,如果您想知道 Astro 与其他工具的比较,请查看他们设置的惊人的文档。
什么是无头 CMS?
现在我们已经解释了前端部分,让我们花点时间来看看究竟什么是无头 CMS。
我相信您已经听说过 WordPress,这是一个臃肿且使用良好的 CMS 系统。 WordPress 是一个绝对的软件包怪物,允许人们在几乎没有开发经验的情况下管理他们的网站。
开发社区通常不喜欢 WordPress,因为它有点过于臃肿。这意味着网站速度很慢,而且充满了我们不需要的东西。
这就是 WordPress 作为无头系统的用武之地。无头系统意味着您可以使用 WordPress 的整个后端系统,但不必使用前端输出。
相反,我们使用 API 来查询我们的数据并在其他系统中使用它。在我们的例子中,这将是一个 Astro 前端。
对于 API 系统,我们将使用 GraphQL 作为查询语言,但在下面的步骤中会详细介绍。
将 WordPress 设置为无头 CMS
在我们继续之前,让我们设置 WordPress,特别是将其设置为无头 CMS。
在本地机器上设置 WordPress 的最简单方法是使用 docker 映像。
如果您没有安装 Docker Desktop,请遵循 Docker 网站上的本指南。
接下来,创建一个新文件夹并导航到它:
mkdir wordpress && cd wordpress
然后创建一个docker-compose.yml文件并填写以下详细信息:
version: '3.9'
services:
db:
image: mariadb
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped
ports:
- 3307:3306
environment:
MYSQL_ROOT_PASSWORD: rootpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- '8000:80'
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
然后我们可以通过运行以下命令来处理我们的 docker 镜像:
docker-compose up
启动后,您应该在 Docker 桌面客户端中看到以下内容。

下一步是访问我们的 WordPress 安装并按照安装步骤进行操作。
您可以在http://localhost:8000/上找到您的 WordPress 安装,并且应该受到 WordPress 安装指南的欢迎。

要将其设置为 Headless CMS,我们需要安装WP GraphQL插件。

按照插件的安装指南进行操作。安装后,我们甚至可以使用这个出色的 GraphQL 编辑器来测试我们的查询。

我们在以下 URL 获得了一个可用的 GraphQL 端点:http://localhost:8000/graphql。
当您在 WordPress 部分时,创建一些演示页面。接下来是时候设置我们的 Astro 项目了。
设置 Astro 项目
请创建一个新文件夹并导航到它。
mkdir astro-wordpress && cd astro-wordpress
然后我们可以通过运行以下命令来安装 Astro:
npm init astro
您可以选择开始模板开始使用。接下来,运行npm install以安装所有依赖项并通过运行npm start启动您的 Astro 项目。
您现在可以在http://localhost:3000/访问您的前端。

添加 Tailwind CSS 作为我们的样式框架
是的,在我们继续加载 WordPress 数据之前,让我们安装 TailwindCSS,因为它可以让我们更轻松地为网站设计样式。
在 Astro 项目中安装 Tailwind 非常简单。让我们一步一步来看看需要发生什么。
- 安装顺风:
npm install --D tailwindcss
- 创建
tailwind.config.js文件
module.exports = {
mode: 'jit',
purge: ['./public/**/*.html', './src/**/*.{astro,js,jsx,svelte,ts,tsx,vue}'],
};
- 在您的
astro.config.mjs文件中启用顺风配置。
export default {
devOptions: {
tailwindConfig: './tailwind.config.js',
}
};
最后,我们需要在src目录下创建一个styles文件夹。在其中创建一个global.css文件并添加以下内容:
@tailwind base;
@tailwind components;
@tailwind utilities;
要在我们的页面中使用这种样式,我们需要像这样加载它:
<link rel="stylesheet" type="text/css" href={Astro.resolve('../styles/global.css')} />
安装 Tailwind 排版插件
鉴于我们的内容来自 WordPress,我们可以利用Tailwind Typography 插件不必手动设置样式。
运行以下命令安装插件:
npm install @tailwindcss/typography
然后打开你的tailwind.config.js文件并添加插件:
module.exports = {
mode: 'jit',
purge: ['./public/**/*.html', './src/**/*.{astro,js,jsx,svelte,ts,tsx,vue}'],
plugins: [require('@tailwindcss/typography')],
};
就是这样!我们现在可以使用 Tailwind 及其出色的排版插件。
创建 .env 文件
由于我们的端点可能会因环境而异,所以让我们安装dotenv包。
npm install --D dotenv
然后我们可以创建一个包含 WordPress graphQL 端点的.env文件。
WP_URL=http://localhost:8000/graphql
在 Astro 中创建 API 调用
好的,我们已经设置好 WordPress,并启动并运行了基本的 Astro 网站。是时候将这两者结合起来了。
在src目录下创建一个lib文件夹,并创建一个名为api.js的文件。
该文件将包含我们对 WordPress GraphQL API 端点的 API 调用。
我们需要在这个文件中做的第一件事是加载我们的环境。
import dotenv from 'dotenv';
dotenv.config();
const API_URL = process.env.WP_URL;
然后我们需要创建一个基本的fetchAPI调用来执行我们的 GraphQL 查询。这个通用调用将处理 URL 和实际发布。
async function fetchAPI(query, { variables } = {}) {
const headers = { 'Content-Type': 'application/json' };
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables }),
});
const json = await res.json();
if (json.errors) {
console.log(json.errors);
throw new Error('Failed to fetch API');
}
return json.data;
}
然后让我们创建一个函数,该函数可以获取我们所有有 slug 的 WordPress 页面。
export async function getAllPagesWithSlugs() {
const data = await fetchAPI(`
{
pages(first: 10000) {
edges {
node {
slug
}
}
}
}
`);
return data?.pages;
}
如您所见,我们将一个 GraphQL 查询传递给我们的fetchAPI函数,并返回我们获得的所有页面。
请记住,您可以在 WordPress 插件 GraphQL 查看器中试用这些 GraphQL 查询。
看到上面的查询只会给我们每个页面的 slug。我们可以继续创建一个详细的调用,该调用可以根据其 slug 检索页面的内容。
export async function getPageBySlug(slug) {
const data = await fetchAPI(`
{
page(id: "${slug}", idType: URI) {
title
content
}
}
`);
return data?.page;
}
在 Astro 中渲染 WordPress 页面
现在我们已经设置了这些功能,我们需要在我们的前端 Astro 项目中动态创建这些页面。
还记得 Astro 是如何输出静态 HTML 的吗?这意味着我们需要一种方法来检索这些页面并动态构建这些页面。
幸运的是,Astro 可以为我们做到这一点!
要创建动态页面,我们必须在pages目录中创建一个名为[slug].astro的文件。
由于这是一个 Astro 文件,它分为两部分,代码和 HTML。代码包含在 frontmatter(三行)中,如下所示:
---
Code
---
<html>
<h1>HTML</h1>
</html>
让我们首先从 API 文件中导入我们需要的两个函数。
---
import { getAllPagesWithSlugs, getPageBySlug } from '../lib/api';
---
然后Astro自带了一个getStaticPaths功能,可以让我们创建动态页面。
在这个函数中,我们可以像这样包装我们所有的页面:
export async function getStaticPaths() {
const pagesWithSlugs = await getAllPagesWithSlugs();
}
然后,我们可以将它们映射为我们的每个 WordPress 页面返回一个 slugged 页面。
export async function getStaticPaths() {
const pagesWithSlugs = await getAllPagesWithSlugs();
return pagesWithSlugs.edges.map(({ node }) => {
return {
params: { slug: node.slug },
};
});
}
您可以看到文件名必须与那里的参数匹配,因为我们有[slug]作为文件名。参数也必须是slug。
然后我们需要做的最后一件事是根据 slug 获取当前页面。
const { slug } = Astro.request.params;
const page = await getPageBySlug(slug);
然后我们可以移动到 HTML 部分来渲染页面!
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{page.title}</title>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" type="text/css" href={Astro.resolve('../styles/global.css')} />
</head>
<body>
<div class="flex flex-col p-10">
<div class="mb-5 text-4xl font-bold">{page.title}</div>
<article class="prose lg:prose-xl">
{page.content}
</article>
</div>
</body>
</html>
您现在应该能够访问您的任何蛞蝓。例如,让我们看看我的隐私政策页面。

在 Astro 中加载主 WordPress 菜单
我们拥有这些页面非常酷,但是我们不能告诉用户输入他们想要访问的 URL。
因此,让我们在 WordPress 中创建一个主菜单并使用它!
首先,前往您的 WordPress 管理面板并找到Appearance>Menu部分。
添加新菜单。你可以给它任何你想要的名字。但是,对于显示位置,请选择Primary menu。

然后,您可以继续向此菜单添加一些页面。
接下来我们需要做的是在我们的前端项目的lib/api.js文件中查询这个菜单。
export async function getPrimaryMenu() {
const data = await fetchAPI(`
{
menus(where: {location: PRIMARY}) {
nodes {
menuItems {
edges {
node {
path
label
connectedNode {
node {
... on Page {
isPostsPage
slug
}
}
}
}
}
}
}
}
}
`);
return data?.menus?.nodes[0];
}
要使用它,让我们创建一个可以重用的新组件。请记住,这是 Astro 带给我们的力量之一。
在components目录中创建一个Header.astro文件。在那里,让我们首先进入代码部分。
---
import { getPrimaryMenu } from '../lib/api';
const { menuItems } = await getPrimaryMenu();
---
这将检索我们刚刚定义的主菜单中的所有菜单项。
接下来是 HTML 部分:
<nav class="flex flex-wrap items-center justify-between p-6 bg-blue-500 shadow-lg">
<a href="/" class="cursor-pointer p-4 ml-2 text-white">AstroPress</a>
<ul class="flex items-center justify-end flex-grow">
{menuItems.edges.map((item) =>
<li key={item.node.path}>
<a href={item.node.connectedNode.node.slug} class={`cursor-pointer p-4 ml-2 text-white`}>
{item.node.label}
</a>
</li>
)}
</ul>
</nav>
要使用这个组件并查看它的运行情况,让我们打开[slug].astro文件并将其导入我们的代码部分。
---
import Header from '../components/Header.astro';
---
然后我们可以通过在我们的 body 标签中添加以下代码在我们的 HTML 部分中使用它。
<body>
<Header />
<!-- Other code -->
</body>
如果我们刷新我们的项目,我们有一个超级酷的菜单!

结论
今天,我们学习了如何将 WordPress 设置为无头 CMS,以及如何通过 Astro 网站中的 GraphQL 端点加载它。
对我来说,这带来了两个世界中最好的。
WordPress 作为一个成熟的 CMS 系统,我们不想从头开始重建。而作为 SSG 的 Astro 为我们输出最快的网站!
从这里开始,选项无穷无尽,因为您可以从 WordPress 中检索帖子、自定义元素等。
有兴趣的可以在GitHub上找到完整代码。或者在这里查看示例网站。
感谢您的阅读,让我们连接起来!
感谢您阅读我的博客。随时订阅我的电子邮件通讯并联系Facebook或Twitter
更多推荐
所有评论(0)