使用 Jekyll 进行内容建模
已发表: 2022-03-10这并不是一个全新的主题,但最近我有理由重新审视我团队工作中的内容建模技能。 我们的经验已经达到了我们练习方式的局限性开始变得清晰的地步。 我们最常见的问题是人们倾向于将自己和他们的心智模型与选择的平台及其约定联系起来。
我们没有教人们如何建模内容,而是教他们如何在 Drupal 中建模内容,或者如何在 WordPress 中建模内容。 但我更希望我们从关注用户的最大利益出发,不管内容最终会出现在哪个平台上。
关于 SmashingMag 的进一步阅读:
- 使用 Jekyll 和 GitHub 页面构建博客
- 为什么静态网站生成器是下一件大事
- 静态网站生成器评测:Jekyll、Middleman、Roots、Hugo
- 自动化风格指南驱动的开发
这条思路让我想起了一个我已经有点痴迷的想法,那就是当我们必须创建一个工件来将某些想法传达给客户时,当这个工件尽可能接近时,这个过程几乎总是会变得更好可能是实际网站,而不是网站图片或充满图表的 PDF。
因此,我最终问自己一个问题:是否有一种工具可以帮助人们以与平台无关的方式快速建模内容,同时构建一个非常适合与客户或团队交流意图的工件?
内容建模的高级理论
在我们进入 Jekyll 之前,让我们转移一下注意力。 我相信您可以从内容建模讨论中删除所有约定和特定于平台的语言,并将其定义为一个三部分系统:
- 核心思想是一个对象:在一个站点上保持在一起的一些内容单元。 例如,一篇博客文章或一个人将是网站上的一个对象。
- 对象具有定义它们的属性。 一篇博文可以有标题、内容主体、作者。 一个人可以有名字、照片、简历。
- 对象具有确定它们在站点上的最终位置的关系,并且布局具有定义使用对象的哪些属性以及在何处使用的逻辑。 我们的示例博客文章对象连接到一个人对象,因为它的作者是一个人。 我们在帖子页面上输出作者的姓名和他们个人资料的链接,我们在他们的个人资料页面上输出他们的完整简历。
我想创建一个尊重我概述的高级想法的系统,但允许团队自由地创建他们认为合适的属性和关系,而不必担心特定于某些平台的想法。 相反,他们可以专注于根据最适合用户的内容来定义内容。 事实证明,Jekyll 具有使这成为可能的功能。
进入杰基尔
Jekyll 是一个静态博客框架。 在您前往评论部分之前,是的,我知道将其视为一个平台是正确的。 然而,它比 Drupal 或 WordPress 有一些优势。
Jekyll 非常重视简单性。 它没有数据库,而是依赖于平面文件和一些能够生成普通旧 HTML 的 Liquid 模板标签。 Liquid 是有限的、简单的并且非常易于人类阅读。 我发现我可以向某人展示一个由一些 Liquid 标签构建的模板,只要他们对前端代码有一点经验,他们就可以理解模板在做什么。
这样做的好处是我们不必向某人展示如何让数据库运行,如何将他们的模板连接到它,如何配置他们的 CMS 的管理区域以使用他们的模板,等等。 相反,我们可以安装 Jekyll 并教授如何启动服务器。 如果用户使用的是 Mac,则很有可能这是一个两分钟的过程,在我们第一次尝试时才有效。
Jekyll 也不会强迫用户接受很多约定。 您可以自由创建您喜欢的文件结构和资产管道,建立您自己的文件之间的关系,并以您最喜欢的方式编写标记。 它拥有的少数约定很容易重新配置以适合您的风格。
使用集合创建和包含对象
虽然它仍然被认为是一个实验性功能,但 Jekyll 有一个叫做集合的东西,它可以让我们创建我所描述的系统。
基本上,您创建一个文件夹并以您正在创建的对象类型命名它。 然后将文件添加到该文件夹,每个文件代表该集合中的一个对象。 拥有对象后,您可以在每个文件的开头使用 YAML 为它们创建属性。 YAML 是一种语法,允许您定义轻松存储信息的键/值对。
这个系统的好处在于它非常简单。 一切都是人类可读的,并且以新用户易于学习的方式运行。 与其创建大量关于某人应如何在最终系统中创建内容和关系的文档,您只需创建它即可。 设计师可以看到对象及其属性是什么,以便他们可以规划他们的设计系统。 前端开发人员有一个功能强大的网站来构建他们的标记和 CSS。
因为他们没有被迫使用特定的系统或约定,所以他们可以只使用他们喜欢的系统或项目最终平台的约定。 在将模板和逻辑转移到他们决定使用的任何 CMS 中时,后端开发人员可以轻松确定设计人员的意图,因为它已经为他们编写好了。
让我们用对象和关系构建一个简单的站点
如果我们想尝试一下这个想法,我们需要建立一个简单的 Jekyll 站点,然后构建我们的对象和关系。 如果您想查看最终产品,可以从这个 GitHub 存储库中获取。 (注意:您必须使用终端来完成其中的一些操作,但我保证这是非常基本的用法。)
安装 Jekyll
如果你在 Mac 上,这很容易。 Ruby 已经安装好了,你只需要安装 Jekyll。 打开终端并输入:
gem install jekyll
这将安装 Jekyll Ruby gem 及其依赖项。 一旦它完成运行,就是这样:你有 Jekyll。
设置您的网站
现在我们需要启动一个 Jekyll 脚手架。 我将所有 Web 项目存储在我的 Mac 上名为Sites的文件夹中,位于主文件夹中。 所以首先我需要导航到它:
cd ~/Sites
然后我可以使用以下命令生成一个包含正确文件和结构的文件夹:
jekyll new my-new-site
您可以将“my-new-site”替换为您想要的项目名称。 您将得到一个具有该名称的文件夹,以及其中的所有正确文件。
弹出打开 Finder 并导航到您的新文件夹以查看里面的内容。 您应该看到如下内容:
![一个 Mac OS X Finder 窗口,显示初始 Jekyll 文件脚手架。 A Mac OS X Finder window showing the initial Jekyll file scaffold.](/uploads/article/1299/byzQgXCLvh2hXgij.png)
由于我们不需要 Jekyll 提供的所有东西,我们将首先删除一些文件和文件夹。 让我们折腾/_includes 、 /_posts 、 /_sass 、 about.md和feed.xml 。
配置
现在我们将设置站点范围的配置。 打开_config.yml 。 里面有很多介绍性的东西。 我将删除它并用我喜欢的配置替换它。 这是该项目的新配置:
permalink: pretty collections: projects people
我这样做是为了让我的 URL 看起来像/path/to/file/而不是/path/to/file.html这只是个人喜好。 我还建立了两个集合:项目和人员。 必须将任何新集合添加到配置文件中。
现在我可以在我的项目中为这些集合创建文件夹:
![一个 Mac OS X Finder 窗口,显示添加到项目文件夹的集合文件夹。 A Mac OS X Finder window showing collection folders added to the project folder.](/uploads/article/1299/CHDFluqvDyXu97Yo.png)
文件夹名称必须以_ (下划线)字符开头,以便 Jekyll 知道如何处理它们。
制作一些对象
我们将制造的第一批物品将是我们的员工。 我们将使用 Markdown 来创建这些文件,这样它们会很好而且干净,但仍然会生成正确的语义 HTML。 你可以看到我已经为美国历史上的人物制作了一些文件(这可能与我一个月以来一直在不停地听汉密尔顿的事实有关,也可能无关):
![Mac OS X Finder 窗口显示添加到人员集合中的每个人员对象的文件。 A Mac OS X Finder window showing the files for each person object added to the people collection.](/uploads/article/1299/QcGcRyDJzOiue2Us.png)
我们将为一个人放入文件中的属性将是:
--- object-id: first-name: last-name: job: listing-priority: wikipedia-url: ---
稍后我们将使用object-id
来专门引用这些对象中的任何一个。 我们将拆分名字和姓氏,以便我们可以选择在不同的地方使用哪种组合(如果您的系统要求这样做),我们将使用job
来定义它们的作用。 (我避免使用“标题”,因为它已经是 Jekyll 中的页面默认具有的变量。)我还包括一个用于列出优先级的属性,这将允许我根据突发奇想对每个人进行排序,但你也可以按一些内置方法,如字母或数字。 最后,我们有一个字段用于链接到此人的 Wikipedia 页面。
所有这些都包含在顶部和底部的三个连字符之间,以将其定义为 YAML 前端。 每个 bio 的内容都在 YAML 之后,可以是任意数量和结构的 HTML(但我们将使用 Markdown 格式来保持一切整洁)。
一个完全填充的人员对象如下所示(为清楚起见,内容被截断):
--- object-id: alexander-hamilton first-name: Alexander last-name: Hamilton job: 1st United States Secretary of the Treasury listing-priority: 1 wikipedia-url: https://en.wikipedia.org/wiki/Alexander_Hamilton --- Alexander Hamilton (January 11, 1755 or 1757 – July 12, 1804) was...
这是一个项目对象(为清楚起见,内容被截断):
![](https://s.stat888.com/img/bg.png)
--- object-id: united-states-coast-guard title: United States Coast Guard featured: true featured-priority: 2 listing-priority: 1 architect-id: alexander-hamilton wikipedia-url: https://en.wikipedia.org/wiki/United_States_Coast_Guard --- The United States Coast Guard (USCG) is...
这个有一些不同之处。 我设置了一个featured
属性。 如果一个项目被推荐,那么它就会被列在主页上。 所有项目都将列在项目页面上。 我们还为每个展示位置设置了首选排序顺序。 我们已经包含了对创建项目的人的id
的引用,因此我们以后可以直接引用它们。
从我们的对象生成页面
通过更改我的_config.yml文件,我可以为每个对象创建页面。
permalink: pretty collections: projects: output: true people: output: true
在每个集合上设置output: true
会导致为其中的每个对象生成一个页面。 但是因为我们的对象在它们的文件中没有内容,所以它们目前不输出任何数据,这意味着我们只会得到空页面。 让我们构建一个布局模板来为我们做这件事。
该文件将位于_layouts文件夹中。 但首先,我们需要处理一个default.html文件。 这将包含在我们所有 HTML 文件中一致的任何标记。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>{{ page.title }}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/css/styles.css" /> </head> <body> <header role="banner"> ... </header> <div role="main"> <div class="container"> {{ content }} </div> </div> <footer role="contentinfo"> ... </footer> </body> </html>
您会注意到一个如下所示的 Liquid 标签: {{ content }}
。 Jekyll 渲染到页面中的每个文件都需要为其指定一个模板。 指定模板后,该文件中的内容将呈现到布局模板中{{ content }}
标记的位置。 现在我们不必重复将出现在每一页上的内容。
接下来,我们将为我们的人员对象构建一个独特的布局模板。 看起来像这样:
--- layout: default --- <header class="intro person-header"> <h1>{{ page.first-name }} {{ page.last-name }}</h1> <h2>{{ page.job }}</h2> </header> <div class="person-body"> {{ page.content }} <a href="{{ page.wikipedia-url }}">Read more about {{ page.first-name }} {{ page.last-name }} on Wikipedia</a> </div>
此文件指定将其代码插入到默认布局模板中,然后从人员对象文件中的数据填充其标记。
最后一步是确保每个 person 对象都指定它使用person.html布局文件。 通常,我们只需将其插入到个人文件中的 YAML 中,如下所示:
--- object-id: first-name: last-name: job: listing-priority: wikipedia-url: layout: person ---
但我更喜欢让我的目标文件中的数据只包含与内容模型相关的属性。 幸运的是,我可以更改我的_config.yml文件来为我处理这个问题:
exclude: - README.md permalink: pretty collections: projects: output: true people: output: true defaults: - scope: type: projects values: layout: project - scope: type: people values: layout: person
现在我的站点知道项目集合中的任何对象都应该使用项目布局模板,并且人员集合中的任何对象都应该使用人员布局。 这有助于我保持我的内容对象整洁。
在列表页面上显示对象
无论我们是否选择为我们的对象输出页面,我们都可以将它们列出并按不同的参数排序。 以下是我们在页面上列出所有项目的方式:
--- layout: default title: Projects --- <header class="intro"> <h1>{{ page.title }}</h1> </header> <div class="case-studies-body"> <ul class="listing"> {% assign projects = site.projects | sort: 'listing-priority' %} {% for project in projects %} <li> <h2><a href="{{ project.url }}">{{ project.title }}</a></h2> {{ project.content }} </li> {% endfor %} </ul> </div>
我们所做的是创建一个<ul>
来将我们的列表放入其中。 然后,我们在页面上创建了一个名为projects
的变量,并将我们所有的项目对象分配给它,并按照我们在每个项目中创建的listing-priority
变量对它们进行排序。 最后,对于我们的projects
变量中的每个项目,我们输出一个<li>
,其中包含来自每个文件中的属性的数据。 这为我们提供了一个高度可控的项目对象列表,其中包含指向其独特页面的链接。
在主页上,我们将只显示我们的特色项目,而不是显示所有项目:
<ul class="listing"> {% assign projects = site.projects | where: "featured", "true" | sort: 'featured-priority' %} {% for project in projects %} <li> <h3>{{ project.title }}</h3> <a href="{{ project.url }}">Learn about {{ project.title }}</a> </li> {% endfor %} </ul>
任何将featured
属性设置为true
的项目对象都将呈现到此页面上,并且它们将按照我们为特色项目设置的特殊优先级排序进行排序。
这些是关于如何输出和排序对象的非常简单的示例,但它们展示了我们可以创建的用于组织内容的不同功能。
链接到特定对象
我们要构建的最后一个功能是链接到特定对象。 如果您将作者链接到博客文章或类似内容,您可能想要这样做。 在我们的例子中,我们将把一个人附加到他们通常关联的项目中。 如果您还记得,我们的项目对象有一个architect-id
属性,我们的每个人都有一个object-id
属性。 我们可以使用这些属性将正确的人附加到特定项目。
这是我们的项目布局模板:
--- layout: default --- {% assign architect = site.people | where: "object-id", page.architect-id | first %} <header class="intro project-header"> <h1>{{ page.title }}</h1> <p>Architected by: <a href="{{ architect.url }}">{{ architect.first-name }} {{ architect.last-name }}</a></p> </header> <div class="project-body"> {{ page.content }} <a href="{{ page.wikipedia-url }}">Read more about {{ page.title }} on Wikipedia</a> </div>
第 4 行创建了一个名为architect
的变量,并在我们所有的人员对象中搜索任何object-id
与项目中的architect-id
属性相匹配的对象。 我们应该分配object-id
以便只返回一个结果,但是为了确保我们只得到一个答案并引用它而不是我们的一项列表,我们必须设置| first
| first
在我们的{% assign %}
Liquid 标签的末尾。 这绕过了 Jekyll 的限制,即集合中的对象一开始就没有唯一的 ID。 还有另一个称为data的功能确实允许唯一的 ID,但它不容易输出页面或使我们能够对对象进行排序; 解决集合的限制是获得我们想要的功能的一种更简单、更干净的方法。
现在该页面有一个代表该项目架构师的唯一对象,我们可以使用架构师的名字和他们的 Wikipedia 页面的 URL 等内容来调用它的属性。 瞧! 通过唯一 ID 轻松链接到对象。
包起来
通过更详细地研究 Jekyll 文档,可以建立一些很棒的进一步特性,但我们这里有一个好的内容建模原型的基础知识:定义不同类型对象的能力,附加到这些对象的属性,以及允许我们从任何地方调用特定对象的 ID。 我们还获得了高度灵活的逻辑,用于在各个地方模板化和输出我们的对象。 最重要的是,整个系统简单易读,并在必要时输出纯 HTML 以供其他地方使用。
出于交流目的,我们现在有一个独立于平台的可点击原型(一个真实的网站),它将比带有一堆图表的 PDF 更好地定义系统。 当我们学习新事物并需要适应时,我们可以随时改变我们的内容模型。 我们可以让设计人员和开发人员进入系统来建立他们的模式和前端架构,因为它可以接受他们想要使用的任何标记和 CSS。 我们甚至可以通过 GitHub GUI 或允许使用可视化编辑器(如 Prose.io、GitHub Pages、CloudCannon 或 Netlify)的托管平台来设置内容编辑器。
而且这些都没有将一个人与学习特定平台的工作方式联系起来,而是让他们能够从专注于用户而不是技术的概念层面工作。