使用 Google Sheets 和 Eleventy 创建可编辑网站

Avatar of David Atanda
David Atanda

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

还记得 Tabletop.js 吗?我们刚刚在这篇文章中讨论过它,内容与本文完全相同:构建可编辑的网站。它是一个将 Google Sheet 转换为 API 的工具,开发人员可以在构建网站时使用它获取数据。在上一篇文章中,我们在客户端使用了该 API,这意味着 JavaScript 需要在每个页面浏览时运行,访问该 URL 获取数据并构建页面。在某些情况下,这可能没问题,但我们可以做得更好。让我们在构建步骤期间访问 API,以便内容直接构建到 HTML 中。这将更快且更具弹性。

情况

作为开发人员,您可能不得不与一些客户合作,他们不断要求您对内容进行无尽的修改,有时甚至在网站构建几个月后。这可能会令人沮丧,因为它会不断拖延您的进度,阻止您进行更有成效的工作。

我们将让他们自己使用他们可能已经熟悉的工具更新内容:Google Sheets。

一个新工具

在上一篇文章中,我们介绍了使用 Google Sheets 和 Tabletop.js 的概念。现在让我们向其中引入一个新工具:Eleventy

我们将使用 Eleventy(一个静态网站生成器),因为我们希望网站被渲染为纯静态网站,而无需在客户端 JavaScript 中发送网站的所有内部工作。我们将在构建时从 API 中提取内容,并让 Eleventy 创建一个最小化的 index.html 文件,然后将其推送到服务器以供生产网站使用。通过静态化,这可以让页面加载速度更快,并且出于安全原因也更好。

电子表格

我们将使用我构建的一个演示,以及它的代码库和Google Sheet来演示如何在您自己的项目中复制类似的内容。首先,我们需要一个 Google Sheet 作为我们的数据存储。

打开一个新的电子表格,并在列中输入您自己的值,就像我的一样。每列的第一个单元格是稍后在 JavaScript 中使用的引用,第二个单元格是实际显示的内容。

在第一列中,“header”是引用名称,“Please edit me!”是第一列中的实际内容。

接下来,我们将数据发布到 Web 上,方法是在菜单栏中单击“文件”→“发布到 Web”。

将提供一个链接,但对我们来说在技术上毫无用处,因此我们可以忽略它。重要的是电子表格(及其数据)现在可以公开访问,以便我们为应用程序获取它。

请注意,在我们继续的过程中,我们将需要从其 URL 中获取电子表格的唯一 ID。

需要 Node 才能继续,所以请确保已安装。如果您想跳过安装此工作所有依赖项的过程,您可以fork 或下载我的代码库并运行

npm install

接下来运行此命令——我稍后会解释它为什么重要

npm run seed

然后在本地运行它

npm run dev

好了,让我们进入src/site/_data/prod/sheet.js。在这里,我们将从 Google Sheet 中提取数据,然后将其转换为易于使用的对象,最后将 JavaScript 对象转换回 JSON 格式。JSON 在本地存储以供开发使用,因此我们不必每次都访问 API。

以下是我们想要放入其中的代码。再次提醒,请确保将变量sheetID更改为您自己电子表格的唯一 ID。


module.exports = () => {
  return new Promise((resolve, reject) => {
    console.log(`Requesting content from ${googleSheetUrl}`);
    axios.get(googleSheetUrl)
      .then(response => {
        // massage the data from the Google Sheets API into
        // a shape that will more convenient for us in our SSG.
        var data = {
          "content": []
        };
        response.data.feed.entry.forEach(item => {
          data.content.push({
            "header": item.gsx$header.$t,
            "header2": item.gsx$header2.$t,
            "body": item.gsx$body.$t,
            "body2": item.gsx$body2.$t,
            "body3":  item.gsx$body3.$t,
            "body4": item.gsx$body4.$t,
            "body5": item.gsx$body5.$t,
            "body6":  item.gsx$body6.$t,
            "body7": item.gsx$body7.$t,
            "body8": item.gsx$body8.$t,
            "body9":  item.gsx$body9.$t,
            "body10": item.gsx$body10.$t,
            "body11": item.gsx$body11.$t,
            "body12":  item.gsx$body12.$t,
            "body13": item.gsx$body13.$t,
            "body14": item.gsx$body14.$t,
            "body15":  item.gsx$body15.$t,
            "body16": item.gsx$body16.$t,
            "body17": item.gsx$body17.$t,
            
          })
        });
        // stash the data locally for developing without
        // needing to hit the API each time.
        seed(JSON.stringify(data), `${__dirname}/../dev/sheet.json`);
        // resolve the promise and return the data
        resolve(data);
      })
      // uh-oh. Handle any errrors we might encounter
      .catch(error => {
        console.log('Error :', error);
        reject(error);
      });
  })
}

module.exports中,有一个 promise 将解析我们的数据或在必要时抛出错误。您会注意到我正在使用axios从电子表格中获取数据。我喜欢它通过自动拒绝 promise 来处理状态错误代码,不像Fetch那样需要手动监控错误代码。

我在其中创建了一个data对象,其中包含一个content数组。您可以根据电子表格的外观自由更改对象的结构。

我们正在使用forEach()方法循环遍历每个电子表格列,同时将其与我们想要分配给它的相应名称关联,并将所有这些内容推送到数据对象中作为内容。

还记得前面提到的seed命令吗?我们使用 seed 通过JSON.stringify将数据对象中的内容转换为 JSON,然后将其发送到src/site/_data/dev/sheet.json

是的!现在我们有了可以使用任何模板引擎(如Nunjucks)来操作的数据格式。但是,我们在这个项目中专注于内容,因此我们将使用 index.md 模板格式来传递项目中存储的数据。

例如,以下是如何通过 for 循环语句提取 item.header 的示例

<div class="listing">
{%- for item in sheet.content -%}
  <h1>{{ item.header }} </h1>
{%- endfor -%}
</div>

如果您使用的是 Nunjucks 或任何其他模板引擎,则需要相应地提取数据。

最后,让我们构建它

npm run build

请注意,您需要在项目中创建一个dist文件夹,构建过程可以将编译后的资产发送到该文件夹。

但这还不是全部!如果我们要编辑 Google Sheet,我们不会在网站上看到任何更新。这就是Zapier发挥作用的地方。我们可以“zap” Google Sheet 和 Netlify,以便对 Google Sheet 的更新触发 Netlify 的部署。

假设您已设置并运行了 Zapier 帐户,我们可以通过授予 Google 和 Netlify 彼此通信的权限,然后添加触发器来创建 zap。

我们正在寻找的配方是什么?我们将 Google Sheets 连接到 Netlify,以便当“新行或更新的行”出现时,Netlify 开始部署。这确实是一种设置后即可忘记的方案。

太好了,就是这样!我们有一个高性能的静态网站,它从 Google Sheets 获取数据,并在对电子表格进行更新时自动部署。