多语言无头 WordPress
在本演练教程中,您将学习如何使用 Next.js、Next.js 国际化路由、Polylang、WPGraphQL 和 WPGraphQL Polylang 扩展创建具有多语言功能的无头 WordPress 站点。本教程假设您对 Node.js、React/Next.js 及其数据获取方法和路由、WPGraphQL、Apollo Client 和 WordPress 有基本的了解。
先决条件
-
Node.js 和 npm 已安装
-
代码编辑器(我用的是Visual Studio Code)
-
已安装的 WordPress 主机(WP Engine是我的首选)或带有Local的免费演示环境。
-
AGithub存储库和帐户
在本教程结束时,您将能够:
-
使用 Polylang 插件及其 WPGraphQL 扩展
-
Next.js 中理解和使用国际化路由
-
创建一个包含多语言帖子内容的主页
-
创建具有多语言帖子详细内容的单个帖子详细信息页面
Polylang WordPress 插件
Polylang WordPress 插件为您的 WordPress 内容启用多种语言的多语言站点功能。这很有价值,因为这使您可以创建针对说不同语言的用户本地化的内容和页面。有专业版。对于本教程,我们将使用免费版本。让我们安装 Polylang 插件并快速介绍它是如何工作的
传统上使用。
登录到您的 WP 管理员并安装 Polylang/WPGraphQL 扩展
登录到您的 WP 管理员。从Plugins > Add new菜单中,搜索 WPGraphQL,安装它,然后搜索 Polylang。它将是填充在 WordPress 插件目录中的第一个插件。安装并激活插件。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--Q5N_nq_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/vf8hasxkujmfb69902dn.png)
检查漂亮的永久链接设置
本教程中的所有代码都是围绕为您的永久链接设置选择帖子名称选项而设置的。要修改此设置,请在 WP Admin 仪表板中打开Settings > Permalinks菜单。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--SIj5erit--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/im5arg7whpt3mb7lzbt5.png)
激活插件后,您将在侧面菜单上看到一个名为Languages的新项目。导航到Languages > Settings > URL修改。单击选项“在漂亮的永久链接中设置语言,隐藏默认语言的 URL 语言信息,在漂亮的永久链接中删除 /language/。”这三个设置允许我们:
-
将我们的语言 URL 设置为该语言的目录而不是子域
-
隐藏了我们默认语言的 URL,因此它不会被该默认语言的代码预先设置
-
删除永久链接中的语言,因此链接中没有语言的整个字符串
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--tr5L25R6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/ok7icz3931ffvtdua9je.png)
安装 Polylang WPGraphQL 扩展
接下来,我们需要在 GraphQL 模式中为我们的帖子公开 Polylang 的语言和翻译。在此处转到 Polylang github 存储库页面的 WPGraphQL:https://github.com/valu-digital/wp-graphql-polylang
完成后,单击绿色代码按钮并转到下拉列表的底部并下载 zip 文件。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--MCBocd73--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/jjo1mbdiicklp0apg2zj.png)
现在回到你的 WP 管理员。从插件 > 添加新菜单,转到顶部的上传插件按钮。单击它,它将弹出一个choose file框。单击它并选择您从 WPGraphQL Polylang 存储库下载的 zip 文件。您现在可以激活并安装它。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--6Q9JcWM8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/z26fndax61knvl807eip.png)
Posts/Post Polylang 语言功能
下一步是开始用英语和西班牙语填充一些数据。导航到菜单中的发布。当您进入帖子编辑页面时,您现在将看到一面美国和墨西哥国旗。这是工作中的 Polylang 插件。它将单个帖子类型与您添加到其中的翻译联系在一起。在这种情况下,英语和西班牙语。我有点像《星球大战》的书呆子,因此是《星球大战》的内容,但你可以使用任何你喜欢的内容。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--W-einQLm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/rhidmnm8ph2ia1pcjd1r.png)
单击编辑器界面后,您可以在右侧菜单中看到Languages的选项。单击该选项然后单击铅笔图标,它可以让您在英语和西班牙语版本之间切换。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--dVziWnyW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/5urh00mze7dy9aormai0.png)
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--rcVpQxFg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/ooweoygpqcnbvwja8rv0.png)
这就是您以传统方法为 WordPress 设置 polylang 插件的方式。当您访问您的网站时,您会看到浏览器的翻译器,您可以在英语和西班牙语之间来回切换。你可以使用任何你想要的翻译器,但必应翻译器是我最喜欢和最可靠的
为翻译的帖子构建我们的 GraphQL 查询
现在我们有了帖子数据,并使用 WPGraphQL 及其扩展通过 GraphQL 层扩展了 WordPress 和 Polylang 数据模式,让我们构建查询以从 WordPress 中获取多语言帖子数据。
在您的 WP Admin 中,转到 GraphiQL IDE 并使用查询编辑器,创建此处显示的查询:
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--nyidrOse--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/4j9kgduck7j6gq4aipgq.png)
query posts($language: LanguageCodeFilterEnum!) {
posts(where: { language: $language }) {
edges {
node {
id
excerpt
title
slug
language {
code
locale
}
}
}
}
generalSettings {
title
description
}
}
进入全屏模式 退出全屏模式
Polylang 插件和WPGraphQL扩展允许$language作为变量并要求LanguageCodeFilterEnum!是所需的值。当您在作曲家中将语言变量查询为object并点击播放 (➡️) 时,它将为您提供该语言的所有帖子。将其更改为"ES"以获取西班牙语翻译。上火了!!🥳
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--s1u93sbk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/wqnr6tnrxsf6wwdi3k78.png)
获取克隆并在本地运行的 Next JS Headless WP Starter
由于这不是关于 React 和 Next.js 基础的基础教程,我已经为您构建了一个演示站点,它利用 Next.js 及其与 SSG、Apollo 客户端、Next.js 国际化路由和动态路由的数据获取功能。转到您的终端并使用以下 shell 命令克隆存储库:
git clone git@github.com:Fran-A-Dev/nextjs- polylangwpgql.git
克隆后,运行 npm install 并打开文件。我的 Next.js 启动器中的文件结构有一个 components 文件夹 pages 文件夹、lib 文件夹、public 文件夹和一个 styles 文件夹。我已经为这个启动器搭建了脚手架,包括静态站点生成数据获取方法、Apollo 客户端实例、动态发布页面路由和 Next.js 国际化路由。
Next.js 国际化路由
现在您已经克隆了初始站点,让我们从 Next.js 上的国际化路由开始分解前端的内容。当您在使用 Headless WordPress 并且有使用不同语言访问您的网站的用户时,将您的内容国际化对于获得出色的用户体验至关重要。
我们开始本教程学习如何以传统方式将 WordPress 中的内容国际化并与 WPGraphQL 解耦。在下一节中,我们将把它与我们的前端连接起来,并探索它的国际化特性。使用 Next.js 进行国际化有许多不同的方法。在我们的教程中,我们将使用路由器和链接从 WordPress 切换翻译的内容。
Next.js 通过具有属性 i18n 的配置对象,可以无缝且轻松地设置国际化,并且在该对象中,您可以使用所需的默认语言环境及其翻译定义您的键,该键是语言环境。 Locale 是用于定义语言的语法,是用于定义位置和语言的标准化格式的 UTS 标识符。在这种情况下,英语是默认的,西班牙语是翻译的。导航到项目根目录下的 next.config.js 文件以查看代码。
module.exports = {
reactStrictMode: true,
i18n: {
locales: ["en", "es"],
defaultLocale: "en",
},
};
进入全屏模式 退出全屏模式
配置它允许 Next.js 知道我们的应用程序中有哪些可用的语言环境以及每个页面在呈现时。
链接以在语言之间进行过滤
需要设置一个链接,我们可以单击以在帖子的语言之间进行过滤。进入项目中的components/Navbar.js。您应该在文件中看到以下代码:
import Link from "next/link";
import { useRouter } from "next/router";
import styles from "../components/Navbar.module.css"
export default function Navbar() {
const { locale: activeLocale, locales, asPath } = useRouter();
const availableLocales = locales.filter((locale) => locale !== activeLocale);
return (
<div className="container">
<nav>
<ul>
<li>
<Link href="/">
<a className={styles.home}>Home</a>
</Link>
</li>
</ul>
<ul>
{availableLocales.map((locale) => {
return (
<li key={locale}>
<Link href={asPath} locale={locale}>
<a className={styles.toggle}>{locale.toUpperCase()}</a>
</Link>
</li>
);
})}
</ul>
</nav>
</div>
);
}
进入全屏模式 退出全屏模式
让我们分解这个文件并解释 Next.js 在这里做什么。首先,我们需要编写一种方法来列出所有可用的语言环境、用户当前处于活动状态的语言环境以及该语言环境的实际路径。我通过使用解构的useRouter挂钩和在文件顶部导入的next/router来执行此操作:
import { useRouter } from "next/router";
组件顶部并解构以提取我的应用程序中支持的所有语言环境常量变量:
const { locale: activeLocale, locales, asPath } = useRouter();
上面看到的语言环境变量都是我的语言环境,用户在查看页面时将使用的实际活动语言环境以及反映他们所在语言环境的路径。下一步是只向用户显示未激活的区域设置,以便用户知道除了页面上的当前默认设置之外,他们可以链接到哪些区域设置。
为此,我创建了一个常量并将其命名为availableLocales。我将其设置为等于语言环境,并通过该语言环境数组进行过滤。通过该区域设置数组进行过滤,我们仅返回不等于活动区域的区域设置。
const availableLocales = locales.filter((locale) => locale !== activeLocale);
现在完成了,我需要将它传递到我的链接列表中的 return 语句中,以使其成为带有 next/link 的实际链接,以显示一个可点击的链接,该链接将作为我们在具有正确路径的两个不同语言环境之间切换显示在这些行中:
<li>
<Link href="/">
<a className={styles.home}>Home</a>
</Link>
</li>
</ul>
<ul>
{availableLocales.map((locale) => {
return (
<li key={locale}>
<Link href={asPath} locale={locale}>
<a className={styles.toggle}>{locale.toUpperCase()}</a>
</Link>
</li>
进入全屏模式 退出全屏模式
更细致地分解这一点,在<ul>中,我使用可用的语言环境常量并通过它映射返回<li>列表项,并在内部将<a>标记中的值替换为语言环境作为值,并使字母大写。
这里发生的事情是我添加了一个新的 locale 属性,并将其设置为等于 locale 以将语言环境从英语更改为西班牙语,反之亦然。然后,我们必须传递它应该导航到的与用户当前所在位置相关的链接。因此,我们使用解构后的 useRouter 挂钩中的 asPath 变量,并在 href 中将其设置为等于 asPath。现在已经设置好了,用户可以单击导航栏中的链接以切换回正确的语言及其路径。
完成这个Navbar.js文件后,我将组件包装在pages >_app.js文件中,这样我的整个应用程序就可以跨页面访问它。
Apollo 客户端/GraphQL 设置
这个项目确实使用了 apollo 和 GraphQL。在这个演示中,我选择只使用 apollo-client.js 文件创建一个 lib 文件夹来创建一个 apollo 实例。我也没有使用 .env.local 这是一个 Next.js 约定不显示环境变量并允许 Next 检测这些。在这个演示的例子中,我直接将该端点放入函数中
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--ZNmbB3wL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/7f1mpjzxbn5vp8v213z9.png)
添加我们的 GraphQL 查询
在上一节中,我们启用了 Next.js 国际化功能,并在导航栏中添加了一个链接,允许用户切换网站上可用的区域设置或语言。最后,我们需要将我们在 WordPress 管理员中使用 WPGraphQL 进行的查询添加到我们的前端。
主页上的多语种帖子
还记得我们在本演练教程开始时使用语言变量进行的 GraphQL 查询吗?转到pages/index.js/文件,在这里我们看到它在底部被我们的getStaticProps函数查询:
export async function getStaticProps({ locale }) {
const apolloClient = getApolloClient();
const language = locale.toUpperCase();
const data = await apolloClient.query({
query: gql`
query posts($language: LanguageCodeFilterEnum!) {
posts(where: { language: $language }) {
edges {
node {
id
excerpt
title
slug
language {
code
locale
}
}
}
}
generalSettings {
title
description
}
}
`,
variables: {
language,
},
});
进入全屏模式 退出全屏模式
您可以通过上面的代码片段看到我们正在查询所有帖子及其与默认英语设置相关的不同语言。我们正在使用 Apollo 客户端作为客户端帮助来获取此数据,同时设置常量const language = locale.toUpperCase();以提供和调用我们在导航栏中创建的过滤器。
WPGraphQL/Polylang Single Post查询
我们现在已经建立了我们的项目,我们的主页显示了我们所有的帖子,可以单击导航栏顶部的链接并在英语和西班牙语之间切换路径。
我们需要做的下一件事是在 WP Admin 中的 GraphiQL IDE 中创建一个查询,以获取单个帖子及其翻译。回到我们的查询编写器,创建一个如下所示的查询:
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--jWUoYgIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/fn6h2f6zxe59wp6kiywb.png)
此查询要求单个帖子类型,变量为 slug,我们想要获取的字段以及可用的翻译和语言为变量。当您通过 slug 和语言查询变量并在 GraphiQL IDE 中按 play 时,您将通过其 slug 及其可用的翻译版本返回您想要的单个帖子。
动态路由页面和单张贴查询
在我们的 Next.js 前端并设置我们刚刚为单个帖子显示的查询。这将允许用户点击他们想在主页上看到的帖子,动态地将他们路由到该帖子的详细信息页面。当他们在帖子详细信息页面上时,用户可以继续在英语和西班牙语之间进行过滤。
导航回 Next.js 项目并转到pages/posts/ [postsSlug].js.文件底部的getStaticProps内,您将看到我们的查询:
export async function getStaticProps({params, locale}) {
const { postSlug } = params;
const language = locale.toUpperCase();
const apolloClient = getApolloClient();
const data = await apolloClient.query({
query: gql`
query PostBySlug($slug: String!, $language: LanguageCodeEnum!) {
generalSettings {
title
}
postBy(slug: $slug) {
id
content
title
slug
translation(language: $language) {
id
slug
content
title
language {
locale
slug
}
}
}
}
进入全屏模式 退出全屏模式
这类似于我们的主页查询。不同之处在于,我们现在要求一个帖子,其中包含我们的动态路由页面和指向该特定帖子详细信息页面的路径。显示时,我们将看到我们要求的单个帖子的特定字段,并且能够在其语言翻译上来回切换。
接下来,让我们关注我们的getStaticPaths函数,我们可以在我们的应用程序上使用我们预构建的页面静态预构建静态路径,因为我们对每个页面的详细信息都有动态路由。
export async function getStaticPaths({ locales }) {
const apolloClient = getApolloClient();
const data = await apolloClient.query({
query: gql`
{
posts(first: 10000) {
edges {
node {
id
title
slug
}
}
}
}
`,
});
进入全屏模式 退出全屏模式
我解构了语言环境的上下文,因此我可以拥有所有语言环境变量。
现在我们在这里只为现有的默认路由创建所有路径。
const paths = posts.map(({ slug }) => {
return {
params: {
postSlug: slug,
},
};
});
进入全屏模式 退出全屏模式
我们需要做的是有一种方法可以为我们现有的路径添加语言环境。这是在这里完成的:
return {
paths: [...paths,
...paths.flatMap((path) => {
return locales.map((locale) => {
return {
...path,
locale,
};
进入全屏模式 退出全屏模式
在 return 语句中,我打开了一个数组,我正在展开已经存在的默认路由路径。这里的技巧是展开另一个路径实例,然后我使用 flatMap 方法深入到具有语言环境的另一个级别的数组。flatMap方法类似于 map 方法,但它允许您展平具有顶级数组的数组,在本例中为默认路径并将它们展平到顶级数组中。
然后对于每个路径,它返回一个新的映射语句,通过语言环境进行映射,并将路径和语言环境一起返回。
本地运行demo
我们快完成了。你现在要做的就是去你的终端,运行npm run dev并在localhost:3000.上启动你的浏览器
您应该在浏览器上看到此内容,导航栏显示可用的区域设置和未使用的语言,即西班牙语:
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--zcunHWeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/bhamw5xuchy2eazgb61q.png)
现在单击链接,它应该会翻译,您应该会看到显示相同的帖子及其西班牙语翻译:
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--mzbM70Gp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/uof21nbu033fqwp656eh.png)
单击显示的西班牙语帖子之一,它将带您到该帖子的详细信息页面及其路径。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--reX7a4Vh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/ci0ox5nrb93z5p7vopw0.png)
最后,再次单击导航栏顶部的 EN 链接顶部的链接,将此帖子详细信息页面切换为其默认的英文版本:
[
](https://res.cloudinary.com/practicaldev/image/fetch/s--b1ri0I2h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/et7lwgrob5lv01285fx3.png)
完成!!兴奋! 🎉
我们完成了这个演练教程!果酱!通过本教程,我们希望您消除在您的网站和应用程序上添加多语言功能的重要性,利用 WPGraphQL 等工具及其所有扩展,如 Polylang、Next.js 国际化路由以及 Next.js 基本功能。
这只是接近多语言无头 WordPress 的一种方式。我很想听听您的想法以及您自己的方法和构建。在我们的Discord中联系我!
这里又是一个演示,所以你可以跟着做,把它变成你自己的,如果你喜欢的话,可以在我的GitHub上添加它。
点击这里如果你想看现场直播!如果您正在寻找无头 WordPress 托管,我的网站位于Atlas 平台上。
更多推荐

所有评论(0)