十一分钟内达到十一分之一
目录
什么是十一?
为什么是十一?
创建一个新项目
添加内容
运行和建设
HTML模板
在内容文件中使用模板
为您的网站提供数据
收藏
过滤器
插件和工具
添加 CSS 和 JS 工具链
示例项目
资源
谢谢👩💻
图片来自11ty.dev
我想分享一下我最初是如何开始使用这项技术的,以及我个人的看法。
目录
什么是十一?
Eleventy是一款流行的静态网站生成器。它可以根据您提供的输入文件创建静态网站。Eleventy 需要的输入文件包括内容文件、HTML 模板文件和数据文件,本文将详细介绍这些文件。
它支持多种数据文件格式、内容文件格式和 HTML 模板引擎,您可以将它们结合使用。在本文中,我将Markdown文件与Nunjucks模板结合使用。
为什么是十一?
市面上有很多静态网站生成器,你可能会想知道它与其他生成器相比有哪些优势。我真正喜欢 Eleventy 的原因主要有以下几点:
- 它基于 Node.js 构建。
- 它只做一件事,而且做得很好:从内容和模板创建标记
- 它对客户端 JS+CSS 工具链完全不持任何立场:自带工具链即可。
- 无需具备Angular/React/Vue知识。
- 它采用 HTML 优先的设计方法,这使得它非常适合渐进增强。
- 易于扩展,并可与 npm 包结合使用
- 类似于 Jekyll,但基于 Node.js
- 通过数据文件夹可以轻松模拟数据。
创建一个新项目
mkdir my-awesome-site
cd my-awesome-site
git config --global init.defaultBranch main
npm init -y
npm i @11ty/eleventy -D
初始化您的存储库
此外,如果您正在使用 Git,请运行git init并提供以下命令:.gitignore
node_modules
.DS_Store
Thumbs.db
# Eleventy output folder
public
配置
配置是通过一个名为 `.javascript.js` 的单个 JavaScript 文件完成的.eleventy.js。提供配置是可选的。
我个人偏好同时提供src输入文件夹和public输出文件夹。此外,我还会指定一些在构建时会被复制到输出文件夹的文件夹。这些文件夹在启动开发服务器时也会被 Eleventy 自动监控。
module.exports = (config) => {
// specify folders to be copied to the output folder
config.addPassthroughCopy('./src/js/');
config.addPassthroughCopy('./src/css/');
return {
markdownTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
dir: {
input: 'src', // default: '.'
output: 'public' // default: '_site'
}
}
};
添加内容
创建一个 Markdown 文件,并按如下方式命名:src/index.md
---
title: "Hello world"
---
# Hello World
Welcome to my awesome {{title}} site!
Markdown 和前置信息
Markdown 文件可以选择性地提供一个元数据块,该块以三个连字符---开头和结尾。您可以在此块中以YAML格式指定元数据。
从内容到路径
对于每个 Markdown 内容文件,eleventy 都会创建一个文件夹,其中包含一个index.html用于生成友好 URL 的文件夹:
index.md --> /
about.md --> /about/
faq.md --> /faq/
blog/hello-world.md --> /blog/hello-world/
运行和建设
最后,我们可以开始向文件中添加启动和构建任务了package.json:
{
"scripts": {
"start": "eleventy --serve",
"build": "eleventy"
}
}
npm start-> 启动开发服务器npm run build-> 搭建您的网站npx serve public-> 测试你的构建
开发服务器使用了browsersync一种能够自动跟踪更改并更新 DOM 的技术。此外,如果您在多个浏览器中打开页面,事件将保持同步,这对于跨浏览器测试非常有用。
HTML模板
要定义 HTML 结构和布局,可以使用 HTML 模板。Eleventy 提供了多种模板引擎。在本例中,我使用的是Nunjucks模板引擎。
支持的其他模板格式有.html,,,,,。.liquid.hbs.ejs.haml.pug
一般方法是先创建一个基础 html 文件,然后
根据需要在此基础上构建其他几个结构。
添加src/_includes/base.njk文件
<!DOCTYPE html>
<html lang="en">
<head><title>{{ title }}</title></head>
<body>
<main>
{% block main %}
{{ content | safe }}
{% endblock %}
</main>
</body>
</html>
通过{% block %}{% endblock %}语法,您可以向模板中添加多个插槽,以便在扩展模板时使用这些插槽。
该content变量是一个保留变量,其中包含当前内容文件的内容主体。
该| safe指令是一个内置过滤器,它告诉模板引擎你要插入的内容是安全的。这样,HTML 标签就不会被转换为包含HTML 实体的纯文本。这允许你在内容中使用 HTML。
在内容文件中使用模板
在 Markdown 文件的 front matter 中,指定你想要使用的布局:
layout: base
扩展您的模板
在你的文件旁边base.njk,创建一个article.njk文件:
{% extends "base.njk" %}
{% block main %}
<article class="article">
{{ content | safe }}
</article>
{% endblock %}
Nunjucks 的文档中也有一个关于继承的章节:https://mozilla.github.io/nunjucks/templating.html#template-inheritance
包括
您可以在 njk 或 markdown 文件中的任何位置包含部分布局:
{% include "header.njk" %}
为您的网站提供数据
有几种方法可以提供可在模板或内容文件中使用的数据:
- 文件特定:在 Markdown 的 front matter 中
- 文件夹特定操作:向内容文件夹添加 JSON 文件
- 全球
_data目录:全球可用 _data支持.js,,文件.yaml.json
_data例子
假设您想要构建一个导航,并从 JSON 文件中提供所有 URL 条目:
src/_data/nav.json
[
{"title": "Home", "url": "/"},
{"title": "Blog", "url": "/blog/"}
]
然后,您可以创建一个部分 html 代码片段,并将其包含在您的主模板中,例如:src/_includes/nav.njk
<nav>
<ul>
{% for link in nav %}
<li>
<a href="{{ link.url }}">{{ link.title }}</a>
</li>
{% endfor %}
</ul>
</nav>
_dataJavaScript 示例
_data/site.js
module.exports = {
name: 'My awesome site',
url: 'https://awesome.site/'
};
在内容中可以这样使用:{{ site.name }}
使用.js文件而不是纯 JSON 或 YAML 文件,可以更灵活地使用 Node.js 环境变量(例如,检查当前处于开发环境还是生产环境)。此外,还可以通过该文件进行 API 获取,例如,引入无头 CMS。
收藏
你可以给内容添加关键词标签,然后通过集合来遍历这些标签。
这对于自动生成目录或列出彼此相关的文章非常有用。
收藏示例
在你的 src 文件夹中,添加一个blog包含多个 Markdown 文件的文件夹。按照postsfront matter 中的方式给它们添加标签:
tags: posts
然后,在你的 Markdown 或包含文件中,你可以使用 for 循环遍历这些集合:
index.md:
# Blog
<ul>{% for post in collections.posts %}<li>
<a href="{{ post.url }}">
{{ post.date | date('YYYY-MM-DD') }}: {{ post.data.title }}
</a>
</li>{% endfor %}</ul>
过滤器
过滤器提供了一种进一步处理内容的方法。您可以使用管道符在内容和模板文件中使用这些过滤器。
添加自定义过滤器
您可以在.eleventy.js文件中添加多个过滤器,以便在文件中使用。您还可以使用第三方库。以下是一个尖叫过滤器和日期格式化过滤器的示例:
const moment = require('moment');
module.exports = (config) => {
config.addFilter('date', (date, format) => moment(date).format(format || 'YYYY-MM-DD'));
config.addFilter('scream', (str) => str.toUpperCase());
// ...additional config
return { ... }
};
然后,您可以在内容和模板文件中使用此过滤器,如下所示:
{{ content | scream | safe }}`
{{ page.date | date('YYYY-MM-DD') }}
使用过滤器处理包含文件
如果你想使用过滤器处理包含文件,可以使用 nunjucksset指令将包含文件存储到变量中。在我的个人网站上,我使用这种技术来动态压缩 WebGL 着色器代码:
{% set vertexShader %}
{% include 'shaders/vertex-shader.vs' %}
{% endset %}
{{ vertexShader | glslminify | safe }}
内置过滤器
- 您可以使用所有内置的 Nunjucks 过滤器。
safe– 内容可以安全插入,因此 html 特定字符不会转换为 html 实体(使用此功能注入 html 和脚本)。url– 指定前缀路径(对于部署到子目录(例如在 GitHub Pages 上)非常有用)。slug– 将字符串转换为 URL 友好的别名(例如转换My site为slugmy-site)。get*CollectionItem获取收藏集中的下一个或上一个项目
插件和工具
Eleventy 提供了一个丰富的插件生态系统,您可以为您的工作流程增添更多魔力✨ 🙌。
添加 CSS 和 JS 工具链
在本文中,我们使用了直通复制命令,并且直接使用了 CSS 和 JS,没有进行任何打包或进一步处理。我个人更喜欢使用 CSS 预处理器加上 ES 模块 JavaScript 文件。但这些方法在 IE11 等旧版浏览器中不受支持。使用渐进增强时,读取
内容并不需要 JavaScript。
接下来,我将演示我使用的方法(仅使用 CSS 转译器)以及使用 parcel 作为替代方法的完整 JS+CSS 工具链。
仅 CSS 转译器
在我的个人项目中,我使用了 sass 和 concurrently,在我的npm start脚本中启动两个并发运行的进程。
npm i sass concurrently -D
为了构建 CSS,我运行了一个命令,sass src/scss:src/css它会将所有 .scss 文件编译成 CSS:
{
"scripts": {
"start": "concurrently 'npm:watch-css' 'npm:serve-11ty'",
"build-11ty": "eleventy",
"serve-11ty": "eleventy --serve",
"build-css": "sass src/scss/:src/css/",
"watch-css": "sass src/scss/:src/css/ --watch",
"build": "npm run build-css -s && npm run build-11ty -s"
}
}
或者完整的 Javascript+CSS 工具链。
如果您想要一个完整的前端工具链来处理 JavaScript 和 CSS 的编译,一种方法是使用Parcel。
npm i parcel-bundler concurrently -D
echo src/dist >> .gitignore
echo .cache >> .gitignore
在开发模式下,我还使用concurrently并行启动 Eleventy 和 Parcel:
{
"scripts": {
"start": "concurrently 'npm:watch-bundle' 'npm:serve-11ty'",
"build": "npm run build-bundle -s && npm run build-11ty -s",
"watch-bundle": "parcel watch src/app/index.js -d src/dist",
"build-bundle": "parcel build src/app/index.js -d src/dist",
"serve-11ty": "eleventy --serve",
"build-11ty": "eleventy"
}
}
在 `<path>`中src/app,放入一个index.js文件。此外,将你选择的任何 CSS 导入语句放入其中:
import './scss/styles.scss';
console.log('Hello world');
最后,在 eleventy 配置中,将传递复制设置为将 parcel 输出复制到 eleventy 输出文件夹:
config.addPassthroughCopy('./src/dist/');
然后,Parcel 会在 dist 文件夹中创建 index.js 和 index.css 文件,您可以在 html 模板中像这样使用它们:
<!-- in your head tag -->
<link rel="stylesheet" href="/dist/index.css">
<!-- right before your closing </body> tag -->
<script src="/dist/index.js"></script>
示例项目
资源
- https://terabaud.github.io/eleventy-talk/ - 我关于 11ty 的演讲幻灯片(可作为本文的总结)
- https://11ty.dev/ - 官方网站
- https://11ty.rocks/ - Eleventy rocks
- https://piccalil.li/course/learn-eleventy-from-scratch - 深入课程