如何从WordPress迁移到无头CMS

467 阅读24分钟

WordPress是世界上使用最多的网站建设者;几乎一半的网络都使用WordPress来创建他们的网站。这是有道理的,因为它允许你快速创建网站,并有一个丰富的插件的生态系统来帮助你扩展你的网站。

但技术在不断发展,有越来越多的选择使创建网站更容易。此外,它们给我们提供了提高网站性能的可能性,并对应用程序有更多的控制和安全。

最初的WordPress架构是单片式的,所以用户界面和数据访问结合在同一个平台上。

自从WordPress引入REST API后,它可以以无头方式使用,允许开发者将其作为后端使用,而将前端放在不同的项目中。

在这种解耦方式中,模型和控制器被捆绑在WordPress一侧,处理数据操作和数据库交互。同时,前端只通过一个HTTP客户端与REST API进行交互。

但这也有一些缺点,你仍然需要配置和更新WordPress,使其安全,并且在开发新功能时依赖于他们的技术。

SmashingMag上的相关阅读

对于那些刚刚开始进入无头世界的人来说,这些文章将帮助你了解它背后的来龙去脉,以及为什么大家都开始迁移。

但为什么要迁移到无头CMS?

考虑到这篇文章将展示如何从WordPress迁移到无头CMS,WordPress可能是你目前的设置。

无头CMS将给我们自由,让我们只关注前端项目,能够选择我们熟悉的技术,以及我们的数据结构。最后,它负责内容管理和内容交付,这样我们就可以负责渲染部分。

"无头CMS是一个系统,它提供与内容管理系统(CMS)相同的功能,并提供更多的功能,所有这些都通过API暴露出来"。

这种类型的设置对于拥有多个网站并希望降低成本或简化流程的公司特别有用。无头架构允许这些公司将内容管理集中在一个管理界面,提供将被公司不同网页所消耗的API。

无头架构的另一个常见用途是创建一个代表公司品牌的前端项目。这样一来,公司推出的所有产品都会有相同的外观和感觉,但每个产品都有自己的内容,在同一个管理面板中管理。

这个例子很容易在会议网站上看到,如JSWorld ConferenceVueJS Amsterdam,由于来自同一个创建者,前端项目是相同的,只是内容有所变化。

与WordPress这样的CMS不同,在无头CMS中,你有一个已经配置和维护的管理面板,有时还为你托管。要开始创建内容,你只需要创建一个账户,登录,你将能够创建、编辑、复制和删除你的内容,管理用户,翻译内容,并使用出版工作流程,以及其他事项。

无头CMS将使你团队中的人更容易理解工作流程,无论他们是内容创作者还是营销人员,如果你不是唯一会编辑内容的人,就应该记住这一点。

值得注意的是,一些无头CMS,不仅专注于为你提供WordPress等CMS已经提供的服务。它还提供图像CDN等服务**,以便在运行中调整图像大小或重新格式化**,或通过S3备份提供额外的安全性。

有了这样的设置,不仅会给你带来自由、安全和舒适,而且还能在没有第三方服务的情况下提高你的应用程序的性能。只需通过HTTP客户端连接你的前端项目并获得组件和数据,你就可以开始运行了。

无头程序的好处以及何时有意义

WordPress的架构往往不能提供我们在做网站时有时需要的可能性,特别是当涉及到优化性能时,这是我们的网站在谷歌等搜索引擎中排名时最重要的一点,特别是现在Web Vitals已经开始运行了。

但是很明显,如果我们有一个只有我们自己工作的个人网站,那么就没有必要把它迁移到无头设置。但是,如果有更多的人参与该项目(不仅仅是开发人员,还有内容创作者或营销团队),那么我们就应该考虑采用无头CMS。

无头CMS如何帮助我们提高网站的性能和前端项目的质量?

  • 通过允许你以一种完全独立于你编辑内容的平台的方式来开发前端

    你所选择的技术是你自己的选择,如果你想把你的项目升级到最新的前端框架,你就不会依赖后端,可以这样做,而不必重新考虑迁移。

  • 允许你创建多平台的项目,而不必依赖不同的管理面板。

    最后,如果对于一个应用程序,你需要一个比主网站更短的描述,你总是可以利用一个新的 "short_description "字段,只需在该特定应用程序的前端表示。

  • 它的目的是使开发更容易,简化创建网站的过程,以及扩展它。

    通过让前端完全隔离,我们可以在不修改内容结构的情况下改变我们整个应用程序的视觉外观

  • 始终提供服务,使我们能够优化我们的资产和提供给我们的响应速度。 最终,我们所有的数据都将通过CDN网络交付。

内容交付网络(CDN),是一个由代理服务器及其数据中心组成的地理分布网络。其目的是通过在空间上相对于最终用户分布服务,提供高可用性和性能

如果我们担心它将如何与我们的品牌或公司的结构一起工作呢?

  • 除了支持跨平台的应用外,它还允许我们保持品牌的一致性

    将前端作为一个基础项目,并在无头CMS中拥有多个空间,可以使你的产品之间保持一致,并使扩展性更容易,因为我们有更少的代码需要维护。

  • 虽然不是所有的无头CMS都有这样的好处,但我们正在迁移到的无头CMS,Storyblok,有一个可视化编辑器,它允许在团队之间创建独立性。 编辑或内容创建者可以访问面板来编辑现有的内容或创建新的内容,能够在发布前看到预览的效果。因此,他们不必让开发团队参与这个过程,可以更有效地完成他们的工作。

  • 它还简化了内容管理,允许你设置自己的内容工作流程。 你可以定义一段内容在发布前必须经过的阶段,只有当它成功通过这个过程时,它才会被发布。

与传统CMS相比,无头CMS如何节省时间?

  • 负责维护平台的安全,并代表您更新平台。 每当有一个错误或用户需要一个新的功能时,您的无头CMS背后的团队将为您开发,您只需开始使用它即可
  • 不断为您改善用户体验(UX)和设计(UI),使内容创作者和开发者在创建新字段、组件或页面时感到舒适。 但不仅仅是在视觉方面,他们还将着眼于改善数据库的性能,因此您可以立即获得您的内容,忘记所有的工作。
单片机与无头机
特点单片机无头式
架构耦合:连接后端和前端解耦:独立的前端项目
技术你必须使用项目开发的那一种技术自由选择你的前端技术
跨平台每次只限于一个前端可与任何前端项目连接
内容工作流程有限制性自定义
安全和更新你负责它为你打理

在看到无头设置能给我们的项目和从事该项目工作的人带来的好处后,我想现在是时候看看我们需要采取哪些步骤来迁移我们的项目了。

使用无头程序时需要注意的事项

正如我们已经提到的,无头CMS允许内容创建者和开发者之间的关注点完全分离。这样一来(在无头CMS中),开发人员专注于创建内容结构,这将在前端项目中得到体现,而编辑将负责使用组件并在管理面板中填充内容。

我们可以在无头CMS中创建的内容类型

1.条目或模板的类型

类似于WordPress中的自定义帖子类型,但在数据类型和编辑器方面有更多的自由和可扩展性。

当你在你的仪表板上创建一个新的内容条目时,你希望能够根据情况选择什么类型。例如,如果你有一个带博客的网站,你会希望有几种类型的模板,一种用于有列表或动态内容的页面,称为_"页面_",一种用于每个博客条目_"帖子_"。

根据你所选择的无头CMS,其名称会有所不同,但概念是相同的。在Storyblok中,这些类型的实体被称为_内容类型_。"内容类型 "定义了内容条目的类型,可以容纳你的内容条目的基本字段。默认情况下,我们有一个 "页面 "内容类型。

2.可重复使用的组件

在无头CMS中,除了内容类型外,你还可以创建嵌套组件,并在内容类型和其他组件之间重复使用。在Storyblok中,这种类型的组件--你可能已经从它的名字中注意到--被称为Blok

要在一个_内容类型_(如页面)中使用它们,你需要在块类型的模式中创建一个字段。这个字段允许你在添加内容时向你的页面添加嵌套组件。

但是,原则上,在迁移过程中,我们将不需要这样的组件。它只是让你灵活地创建健壮和动态的应用程序,而不必让开发人员参与。

例如,当营销团队的成员想在 "关于我们 "页面上添加一个新的英雄时,如果英雄组件是以嵌套方式创建的,并且页面上有一个Blocks字段,那么营销人员就可以添加英雄,而不必让开发人员参与。

渲染来自无头CMS的数据

当我们在无头CMS面板中定义内容结构时,我们必须考虑哪种框架来创建我们的前端项目,以及我们将使用哪种HTTP客户端。

在选择框架时,我们必须考虑到几个因素。

我的团队和我是否熟悉这项技术?

它是否允许我以我的项目所需要的渲染类型来渲染我的内容?

它是否有插件或模块来促进与我使用的无头CMS的整合?

在大多数情况下,一个静态网站就足够了,而且永远是最经济和高性能的答案。所以,你只需要为你熟悉的技术寻找一个静态网站生成器,例如,Vue的_Nuxt_或React库的_Next_。

将这两件事联系起来,无头CMS和静态网站生成器被认为是一套专注于提供最高性能、安全和最低成本的网络开发最佳实践。这种架构也被称为Jamstack。它是一个旨在使网络更快、更安全、更容易扩展的架构。它建立在许多开发者喜爱的工具和工作流程上,这些工具和工作流程带来了最大的生产力。

通过使用新潮的框架,你将确保与你将要使用的无头CMS的集成指南,而且大多数框架已经有一个模块或包,允许你从API中获取信息,并在许多情况下扩展它。

你唯一要做的是定义你的组件的结构,即你如何在你的无头CMS中构建数据结构,并使内容发布过程自动化。例如,使用无头CMS为您提供的Webhooks,您将能够在内容发布后通过其构建钩子在您最喜欢的主机上启动构建过程。

你需要的时间量

与任何迁移一样,所需的时间总是与你的项目的复杂性成正比。如果我们谈论的是一个普通的WordPress网站,你将只需要迁移你定义的或默认的帖子类型,如页面、帖子和类别,以及它们的内容。

另一方面,如果你用多个插件来定制你的项目,你将不得不通过前端项目或使用你的无头CMS所提供的插件来开发它们。例如,如果我们有SEO意识,因此在WordPress上利用Yoast SEO,我们将有Storyblok中的Field-Type SEO插件来帮助我们过渡,但我们仍然要在前端开发我们的网站地图,有指南帮助我们

最后,所有的开发负担将落在前端项目上,因为设置无头CMS不会花费那么多时间。

但是,让我们停止谈论,让我们看一看吧

将我们的内容从WordPress迁移到Storyblok的步骤

迁移将包括四个步骤,从在我们新的无头CMS Storyblok中创建一个空间到在我们的前端项目中表示迁移的内容,我们将在下面看到详细的步骤,其中我将留给你资源,使你的迁移更容易。

让我们开始吧!

1.在Storyblok中创建一个空间

为了在Storyblok创建一个空间,你首先需要有一个账户。要做到这一点,你需要选择最适合你的计划。

进入定价页面,从最适合你的需求的计划开始,或尝试免费计划进行测试。

创建你的帐户,你将能够访问面板。

选择 "创建一个新空间",让我们开始吧!

空间是一个内容存储库。可以把它看作是保存与一个项目有关的所有内容的地方。每个空间都有自己的组件、数据源、资产、环境、域、合作者和权限。

花一些时间来探索左侧边栏的各个部分。从浏览以下内容开始。

  • 内容,这将是存储内容的文件夹,营销团队将在这里花费大部分时间。
  • 资产,所有的图片将存储在这里,然后你可以通过CDN服务获得这些图片,并进行优化和任何尺寸。
  • 组件,你将在这里创建_内容类型_和_嵌套组件_。
  • 设置,这部分你将能够配置你的空间数据以及你的应用程序的语言,你希望你的内容在发布前遵循的工作流程,用户权限,等等。比方说,这个区域将是与项目的IT团队有关的区域。

如果你仍然想在潜入迁移之前探索仪表盘上的每一个选项,我建议看一下Storyblok的《理解用户界面》。

现在你对Storyblok生态系统有了一定的了解,是时候定义我们的应用程序的内容是什么样子了。

2.定义模型

为了将WordPress的内容迁移到Storyblok,下一步是通过在Storyblok空间中创建Post Types来创建定义WP数据结构的模式。

让我们从_页面_和_帖子_(任何WP网站中的主要帖子类型)开始,我们在Storyblok中称之为pagepost

在WP中,_页面_的模式包含以下字段:标题lug特色 图片日期_和_内容

注意:_要想看到一个帖子类型中包含的所有字段,请到WP REST API模式参考中_的模式。

你需要知道的是,默认情况下,Storyblok中的任何内容类型都会有一些已经为你定义好的字段,如_名称_、Slug标签、首次发布_日期_等。

这些字段可以用来从WP迁移内容。你只需要通过在页面内容类型中添加_feature_image_和_内容_来扩展它。

进入你空间中的组件部分,点击默认创建的page ,删除_正文字_段,并添加_feature_image_为Assets > Images ,_内容_为Rich-text

一旦page 模式准备好了,我们就进入post 。对于帖子内容类型,有必要包括更多的信息,如_feature_image_、excelpt、_content,以及与其他类型如_Authors_或_Categories 的关系

由于_作者_和_类别_也将有他们自己的内容,请到侧边栏的内容部分,创建几个名为_作者_和_类别_的文件夹。

每个文件夹都必须有一个默认的内容类型关联。要做到这一点,在组件部分,创建_作者_和_类别_作为新的内容类型,然后通过点击文件夹右边的三个点,选择设置,将内容类型相对于每个文件夹关联起来。

这样,在帖子内容类型中,你可以添加一个带有源故事的_单选项_或_多选项_字段,并指向为每个字段创建的文件夹。

  • 作者
    这指定了他们所在的文件夹authors/
  • 类别
    这指定了它们所在的文件夹categories/

注意如果你想知道更多关于这种关系的信息,请看文章《作者和文章的关系

现在你已经看到了如何创建几个内容类型和如何创建它们之间的关系,你将不得不按照同样的步骤来定义其余的模型。

添加一个内容类型。全局

你会问自己,我的所有页面将共享的内容是什么?像导航菜单、页脚和其他通用元素?

别担心,Storyblok已经考虑到了这一点,并为我们提供了一个简单的指南来动态地定义我们的全局元素。它向我们展示了如何创建一个_全局_内容类型以及如何在内容部分使用它。

3.迁移内容

现在是时候开始迁移你所存储的内容了。要访问WP内容,你需要访问REST JSON API。访问路径/wp-json ,如果项目已经部署,或者如果是本地的?rest_route=/

如果这两个路径都不行,请检查你的页面HTML,在头部有一个rel="https://api.w.org/" 的链接,如WP发现指南所示,并获得正确的链接。

<link rel="https://api.w.org/" href="https://localhost/your-site/index.php?rest_route=/">

为了在迁移过程中帮助我们,Storyblok的开发人员为我们提供了一个插件,这将为我们节省大量的工作。这个插件叫做wordpress-importer,在它上面,可以在Storyblok中为要迁移的WP帖子类型定义相应的内容类型,它将会把它推送到我们的空间,并为我们把图片迁移到资产部分。

注意使用这个脚本需要节点≥14.0.0,因为它使用的是可选链

创建迁移脚本

首先要做的是克隆版本库。然后,使用npm installyarn 安装 NPM 包,并在项目的根目录下创建一个文件,名为_migrateWPtoStoryblok.js_。为了运行该脚本,你需要在package.json中添加一个脚本来运行它。

"migrate": "node ./migrateWPtoStoryblok.js"

一旦一切准备就绪,就可以按照README规范开始定义脚本了。而且,正如你所看到的,接下来需要的是找到Space_idOAuth 令牌来连接到Storyblok空间。

  • Space_id 在侧边栏的_设置_部分,只要你点击它,你就会在右边看到它。
  • 要生成OAuth 代币,你需要到侧边栏的顶部,点击Storyblok标志旁边的小箭头,然后进入_我的账户_。如果我们向下滚动,我们将看到_个人访问令_牌部分,生成一个,并复制它。

当你获得这两个秘密后,你可以把它们和你项目的JSON API的URL一起添加到脚本的开头。

import { Wp2Storyblok } from './index.js'

const wp2storyblok = new Wp2Storyblok('https://your-domain.com/wp-json', {
  token: 'storyblok-oauth-token', // My Account > Personal access tokens
  space_id: 'space-id', // Settings
})

正如前几节所述,Storyblok中的页面内容类型相当于WP_页面_中的帖子类型。在下面的代码块中,你会看到你需要分别指定的地方。

而且,一旦定义了Post Type和Content Type,就应该在schema_mapping 选项中指定WP中这个实体类型所使用的字段的名称和Storyblok中的对应名称。

import { Wp2Storyblok } from './index.js'

const wp2storyblok = new Wp2Storyblok('https://your-domain.com/wp-json', {
  // ... Secrets
  content_types: [
    {
      name: 'pages', // Post type in WP
      new_content_type: 'page', // Equivalent Content type in Storyblok
      folder: '', // OPTIONAL: To save all the content of the same type in a specific folder
      schema_mapping: {
        "title": "name", // "Field in WP": "Field in Storyblok"
      }
    }
  ]
})

注意为了使迁移工作正常进行,请确保permalinks是按条目名称选择的,而不是按简单的。否则,脚本将无法创建页面之间的父子关系。

schema_mapping ,你可以定义几种类型的字段,这些可以是。

  • 一个简单的字段,如title

  • 一个字段的属性,比如本例中的特征图片的URL。
    注意插件本身会通过links.wp:featuredmedia.0 中的相关URL负责将图片迁移到Storyblok空间中。

  • 一个字段被迁移到Storyblok的一个嵌套块中。

    想象一下,你想在Storyblok中创建一个组件来定义你的网站的富文本,以便所有使用它的帖子类型有相同的风格和选项。

    为此,你可以使用对象格式,在Storyblok模型中的_字_段属性下指定字段的名称,你想存储在该字段内的_组件_的名称,以及_组件内的字段_的名称,内容将被迁移。

import { Wp2Storyblok } from './index.js'

const wp2storyblok = new Wp2Storyblok('https://your-domain.com/wp-json', {
  // ... Secrets
  content_types: [
    {
      // ... Post type WP:Storyblok
      schema_mapping: {
        "title": "name", // "Field in WP": "Field in Storyblok"
        "_links.wp:featuredmedia.0": "content.preview_image", // Using the dot notation you can define subproperties.
        // Using nested blocks in Storyblok
        "content": {
          field: 'content.body_items', // Field name in Storyblok
          component: "rich-text", // Component name inside the above field
          component_field: "content" // Field name inside the component where you want to migrate the content
        }
      }
    }
  ]
})

wp2storyblok.migrate()
条目类型页面

现在你知道如何定义字段类型了,对于页面模式,它看起来就像下面的代码块。

该插件将处理页面之间的父子关系,在Storyblok中创建一个文件夹,放在父的lug下,并将父作为该文件夹的首页。

此外,如果内容字段包含 图片,该插件也将为你迁移它

{
  name: 'pages', // Name of the post type in WP
  new_content_type: 'page', // Name of the Content Type in Storyblok
  schema_mapping: {
    "date": "first_published_at",
    "title": "name",
    "slug": "slug",
    "_links.wp:featuredmedia.0": "content.featured_image",
    "content": "content.content",
  }
}

条目类型帖子

帖子有一个类似于页面的模式,但在这种情况下,要把它们存储在一个文件夹里,你必须在条目类型下面定义文件夹的名称。

{
  name: 'posts', // Post type name in WP
  new_content_type: 'post', // Content Type name in Storyblok
  folder: 'articles', // Destination folder name in Storyblok
  schema_mapping: {
    "date": "first_published_at",
    "title": "name",
    "slug": "slug",
    "_links.wp:featuredmedia.0": "content.featured_image",
    "excerpt": "content.excerpt",
    "content": "content.content",
  }
}
条目类型分类

而一旦定义了帖子的模式,为类别定义模式也是有意义的,这样它们就可以像上一节所述的那样被关联起来。

为了将包含它们的文件夹定义为类别,而不是类别,即它们的默认名称,你必须进入WordPress管理中的Permalinks选项,并将类别基础选项改为categories 。然后,帖子条目的多选项字段将是与相应类别有关系的字段。

注意这些步骤与迁移作者并将其链接到文章所要遵循的步骤相同。

{
  name: 'categories', // Name of the post type in WP
  new_content_type: 'category', // Name of the Content Type in Storyblok
  // By default will be contained by a folder called Category (change it in the Permalinks option in WP)
  schema_mapping: {
    "name": "name",
    "slug": "slug",
    "description": "content.description",
    "parent": "content.parent",
  }
}
完整的最终脚本

下面的代码将是由一个具有基本类型的WP项目迁移到我们创建的Storyblok空间的结果脚本。

import { Wp2Storyblok } from './index.js'

const wp2storyblok = new Wp2Storyblok('https://your-domain.com/wp-json', {
  token: '',
  space_id: 34234,
  content_types: [
    {
      name: 'pages', // Name of the post type in WP
      new_content_type: 'page', // Name of the Content Type in Storyblok
      schema_mapping: {
        "date": "first_published_at",
        "title": "name",
        "slug": "slug",
        "_links.wp:featuredmedia.0": "content.featured_image",
        "content": "content.content",
      }
    },
    {
      name: 'categories', // Name of the post type in WP
      new_content_type: 'category', // Name of the Content Type in Storyblok
      // By default will be contained by a folder called Category (change it in the Permalinks option in WP)
      schema_mapping: {
        "name": "name",
        "slug": "slug",
        "description": "content.description",
        "parent": "content.parent",
      }
    },
    // Add authors as categories.
    {
      name: 'posts', // Name of the post type in WP
      new_content_type: 'post', // Name of the Content Type in Storyblok
      folder: 'articles', // Name of the destination folder in Storyblok
      schema_mapping: {
        "date": "first_published_at",
        "title": "name",
        "slug": "slug",
        "_links.wp:featuredmedia.0": "content.featured_image",
        "excerpt": "content.excerpt",
        "content": "content.content",
      }
    }
    // More schemas...
  ]
})

wp2storyblok.migrate()

4.创建一个前端项目

现在,内容已经存储在Storyblok仪表盘中,现在是时候将前端项目连接到Storyblok。

无论你的框架或JS库是什么,Storyblok提供的JavaScript客户端将帮助你进行整合。此外,如果你使用的是一个特定的框架,你会发现其他的软件包将缓解这种情况,比如Nuxt的storyblok-nuxt 模块。

这个JavaScript API还包括Storyblok和你的前端应用程序之间的桥梁。该桥负责通过iframe与Storyblok进行通信,告诉编辑界面在用户点击时要打开哪个组件。

下面是你可以在Storyblok上找到的连接你的前端项目的教程列表。

注意:_如果你在其中没有找到你的技术,不要担心,在Storyblok网站上还有_很多其他的教程,在搜索引擎中搜索你的教程,如果你没有找到,我鼓励你联系他们,你会帮助更多的人

5.托管你的前端项目并自动部署

一旦你的项目准备投入生产,你选择了一个托管供应商,并链接你的存储库以方便部署,然后你问自己。

如果我在Storyblok上发布一个条目,我如何重新部署我的静态网站?

答案非常简单:通过使用Storyblok提供的webhooks和你的主机的构建钩子。

为了给你一个真实的例子,你可以在Netlify的部署部分创建构建钩子的URL;在构建钩子中为Storyblok创建的URL将在Storyblok空间的_设置_→_Webhooks_→_Story published & unpublished_领域中。

迁移过程中我们所使用的指南和工具

让我们回顾一下那些帮助迁移内容的链接,以及那些帮助理解REST API的功能和你要迁移的无头CMS的链接。

需要的WP REST API文档

REST API
模式

迁移到Storyblok

一般信息
文档
全局组件
与SEO相关
网络钩子和构建钩子
脚本和包

Jamstack

总结

阅读完这篇文章后,你就会明白为什么无头设置会改善你的项目,如何从你的WordPress项目迁移到Storyblok这样的无头CMS,以及如何继续改善和扩展你的项目。

正如你所看到的,无头设置的可能性是无限的。迁移后,你将有巨大的灵活性来扩展你的项目,提高其性能和SEO,提高开发团队的生产力,并保持在最新的趋势之上。

每个人都在开始迁移,而且有越来越多的内容和脚本使迁移变得更容易。你还在等什么来迁移你的WordPress呢?