Jamstack 已经在网站世界中存在多年。 静态站点生成器 (SSG)——其内容通常直接存在于 GitHub 仓库中——是这个故事的重要组成部分。 这开辟了让贡献者可以 打开 Pull Request 来添加、更改或编辑内容的想法。 非常有用!
这方面的例子包括
为什么选择静态站点方案?
当我们需要构建像这样的基于内容的网站时,通常会考虑使用什么数据库。 将内容保存在数据库中是一个久经考验的好主意。 但它并不是唯一的方法! SSG 可以成为一个不错的替代方案,因为……
- 它们廉价且易于部署。 SSG 通常是免费的,因此非常适合 MVP 或概念验证。
- 它们具有极高的安全性。 由于网站通常只包含静态文件,因此浏览器无法通过任何途径进行攻击。
- 您随时可以扩展。 您当前的托管服务可以轻松处理。
对于内容网站,我们还有另一个优势。 网站本身的内容可以以静态文件的形式保存在仓库中。 这意味着可以通过 GitHub 上的 Pull Request 添加和更新内容,例如。 即使对于非技术人员,它也为 Netlify CMS 和 开放创作 等概念打开了大门,允许社区贡献。
但是,让我们走超低端路线,拥抱仅使用基本 HTML 的内容 Pull Request 的想法。
挑战
人们如何以一种清晰直观的方式贡献添加或更新资源并非易事。 人们需要了解如何分叉您的仓库、如何在何处添加内容、内容格式标准、必填字段以及各种其他信息。 他们甚至可能需要在本地“启动”网站以确保内容看起来正确。
认真想帮助我们网站的人有时会退却,因为贡献的过程存在技术障碍和学习曲线——这很遗憾。
<form>
您知道任何人都可以做什么吗? 使用一个 就像普通网站一样,人们提交内容最简单的方式是填写一个表单,并用他们想要的内容提交它。
如果我们可以创建一种方式,让用户通过一个简单的 HTML <form>
(专门用于获取我们需要的特定内容)来为我们的网站贡献内容呢? 但是,如果表单不是发布到数据库,而是通过 Pull Request 发布到我们的静态站点生成器呢? 有个技巧!
技巧:使用查询参数创建 GitHub Pull Request
这里有一个鲜为人知的技巧:我们可以通过向特殊的 GitHub URL 添加查询参数来预填充针对我们仓库的 Pull Request。 这直接来自 GitHub 文档本身。
让我们反向分析一下。
如果我们知道可以预填充链接,那么我们需要生成该链接。 我们正在努力使其变得简单易懂。 为了生成这个包含动态数据的链接,我们将使用一点 JavaScript。
那么,我们如何在用户提交表单之后生成这个链接呢?
演示时间!
让我们以 CSS-Tricks 的 Serverless 网站 为例。 目前,添加新资源的唯一方法是分叉 GitHub 上的仓库并添加一个新的 Markdown 文件。 但是,让我们看看如何使用表单而不是通过这些步骤来完成它。
Serverless 网站本身有许多类别(例如 表单),我们可以为这些类别做出贡献。 为了简单起见,让我们关注 “资源”类别。 人们可以从此处添加与 Serverless 或 Jamstack 相关的文章。

所有资源文件都位于仓库中的 此文件夹 中。

仅从那里随机选择一个 文件 来探索其结构……
---
title: "How to deploy a custom domain with the Amplify Console"
url: "https://read.acloud.guru/how-to-deploy-a-custom-domain-with-the-amplify-console-a884b6a3c0fc"
author: "Nader Dabit"
tags: ["hosting", "amplify"]
---
In this tutorial, we’ll learn how to add a custom domain to an Amplify Console deployment in just a couple of minutes.
仔细查看内容后,我们的表单必须包含以下列
- 标题
- URL
- 作者
- 标签
- 链接的片段或描述。
因此,让我们为所有这些字段构建一个 HTML 表单
<div class="columns container my-2">
<div class="column is-half is-offset-one-quarter">
<h1 class="title">Contribute to Serverless Resources</h1>
<div class="field">
<label class="label" for="title">Title</label>
<div class="control">
<input id="title" name="title" class="input" type="text">
</div>
</div>
<div class="field">
<label class="label" for="url">URL</label>
<div class="control">
<input id="url" name="url" class="input" type="url">
</div>
</div>
<div class="field">
<label class="label" for="author">Author</label>
<div class="control">
<input id="author" class="input" type="text" name="author">
</div>
</div>
<div class="field">
<label class="label" for="tags">Tags (comma separated)</label>
<div class="control">
<input id="tags" class="input" type="text" name="tags">
</div>
</div>
<div class="field">
<label class="label" for="description">Description</label>
<div class="control">
<textarea id="description" class="textarea" name="description"></textarea>
</div>
</div>
<!-- Prepare the JavaScript function for later -->
<div class="control">
<button onclick="validateSubmission();" class="button is-link is-fullwidth">Submit</button>
</div>
</div>
</div>
我使用的是 Bulma 进行样式设置,因此这里使用的类名来自 Bulma。
现在,我们编写一个 JavaScript 函数,将用户的输入转换为友好的 URL,我们可以将其组合为 GitHub 查询参数来进行 Pull Request。 以下是步骤
- 获取用户有关他们想要添加的内容的输入
- 从所有这些内容生成一个字符串
- 对字符串进行编码,以使其以人类可读的方式进行格式化
- 将编码后的字符串附加到指向 GitHub 新 Pull Request 页面完整 URL 的链接
这里是代码笔
按下提交按钮后,用户将被直接带到 GitHub,并会为该新文件在正确的位置打开一个 Pull Request。

快速说明:用户仍然需要一个 GitHub 帐户才能做出贡献。 但这仍然比了解如何分叉仓库并从该分叉中创建 Pull Request 容易得多。
此方法的其他优势
好吧,首先,这是一个位于我们网站上的表单。 我们可以根据自己的喜好进行样式设置。 这种控制能力总是很受欢迎的。
其次,由于我们已经编写了 JavaScript,因此我们可以使用相同的基本思想与其他服务或 API 交互,以便首先处理输入。 例如,如果我们需要来自网站的信息(如标题、元描述或 favicon),我们可以通过提供 URL 来获取此信息。
更进一步
让我们玩一下上面第二点。 我们可以通过从用户提供的 URL 获取信息来预填充我们的表单,而不是让他们手动输入。
考虑到这一点,我们现在只要求用户输入两个信息(而不是四个)——仅 URL 和标签。
这是如何工作的? 我们可以使用 JavaScript 从网站获取元信息,只需拥有 URL 即可。 有许多 API 可以从网站获取信息,但您可能会用到我为这个项目构建的 API。 尝试访问任何类似这样的 URL
https://metadata-api.vercel.app/api?url=https://css-tricks.org.cn
上面的演示使用它作为 API,根据用户提供的 URL 预填充数据。对用户来说更方便!
总结
你可以把它看作是任何静态网站生成器的最小 CMS。你只需要自定义表单并更新预填充的查询参数以匹配你需要的格式。
你会如何使用这种方式?我们在开头看到的四个网站就是一个很好的例子。但在很多其他情况下,你可能需要对用户提交的内容做些处理,而这可能是一种低开销的解决方法。
如果我想在组织的仓库中创建拉取请求,它就不起作用。请指教。