对于这个博客的重新设计,我创建了自动生成的Twitter标题卡。因此,每当人们在社交媒体上分享我的东西时,他们会收到一张漂亮的卡片,告诉他们文章的标题和发布日期。
而人们应该在社交媒体上分享这些文章,不是吗?

我使用Eleventy作为这个网页的静态网站生成器,感谢他们的分页功能,为每篇文章创建Twitter卡片只需要很少的投资。
Eleventy的分页功能#。
Eleventy的一个重要功能是集合。Eleventy试图从你的源文件中收集所有可解析的文件到一个大的集合中,你有可能将这一大堆的数据集中到不同的组。其中一个是帖子,这适用于我所有的博客文章。
在很多情况下,你想把你的集合作为一个整体或在几个页面上浏览。Eleventy的分页功能正是让你做到这一点。它获取一组数据,并根据页面大小将其切分。这可以在前面的内容中定义。
---
pagination:
data: collections.posts
size: 10
alias: pagedPosts
---
在上面的例子中,我从帖子集合中创建了每个有10个项目的页面,将信息存储在一个名为pagedPosts 的数组中。我们在这个数组上循环,在模板中显示内容。有效地创建了一个分页概览。
分页来重新映射你的集合#
那么,我们如何为我们的预告使用分页呢?诀窍在于分页的大小。如果我们把分页大小设置为1会发生什么?我们为帖子集合中的每个条目得到一个页面。这样,我们就把博客的全部内容重新映射到一个新的输出中。
这可以是另一个HTML或XML页面,或JSON,或在我们的例子中。一个SVG。
---
pagination:
data: collections.posts
size: 1
alias: post
permalink: /teasers/{{ pagination.items[0].permalink | slug }}.svg
eleventyExcludeFromCollections: true
---
上面的代码
- 将分页大小设置为1,有效地为每篇文章创建另一个页面
- 将帖子存储在变量
post,这样我们就可以在模板中访问它。 - 将其内容重新映射到一个新的输出URL。一个原始帖子的固定链接,但有一个svg结尾。注意:我只是通过自己设置每个固定链接来做到这一点。这可以进一步自动化。
- 通过
eleventyExcludeFromCollections: true,我确保新创建的页面会被添加到整个集合列表中。
这就是基本的设置。现在来看看模板的内容
创建一个SVG#
我为这个网站所做的是用Sketch创建一个SVG。一个简单的,只有一点文字的。我尝试了系统字体,因为一旦我在SVG或PNG中渲染这个,我不确定我有哪些字体可用。我使用了一些基于真实博客文章的假文本,然后复制了模板中的SVG代码。
---
pagination:
data: collections.posts
size: 1
alias: post
permalink: /teasers/{{ pagination.items[0].permalink | slug }}.svg
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1452px"
height="843px" viewBox="0 0 1452 843"
version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- here come the contents -->
</svg>
我搜索了一下为什么要设置文字的部分,并删除了所有现有的行。我把它改成了一个循环,在这个循环中,我把文章的标题拆开,这样每一行都有合适的字符数。
<text id="text"
fill="url(#linearGradient-3)"
font-family="Arial, Helvetica, sans-serif"
font-size="100" font-weight="bold" line-spacing="101">
{% for line in post.data.title | splitlines %}
<tspan x="81" y="{{247 + loop.index0 * 141}}">{{line}}</tspan>
{% endfor %}
</text>
根据我设置的字体大小,我将y坐标设置为一个偏移量(在这种情况下是247),加上当前行的索引和一个带行高的字体大小(141)。
splitlines 是我在我的 配置文件中创建的一个过滤器。.eleventy.js
config.addFilter('splitlines', function(input) {
const parts = input.split(' ') /* 1 */
/* 2 */
const lines = parts.reduce(function(prev, current) {
/* 3 */
if(!prev.length) {
return [current]
}
/* 4 */
let lastOne = prev[prev.length - 1]
if(lastOne.length + current.length > 18) {
return [...prev, current]
}
prev[prev.length - 1] = lastOne + ' ' + current
return prev
}, [])
return lines
})
我是这样做的。
- 我将标题按每个词拆开
- 遍历所有单词
- 如果数组是空的,我就用第一个词创建一个数组
- 对于每一个后续的单词,我都会检查单词的串联是否超过了我设想的每一行的字符数(本例中为18)。
- 如果是空的,我就把新词添加到下一行
- 否则,我在一行中串联单词
我也对帖子的日期做了一些类似的处理。
这就为我正在写的每篇博文提供了一个SVG。
创建一个PNG#
最后一件事是为每个SVG创建一个PNG。我还没能通过Eleventy做到这一点。所以我求助于Gulp。这其实是故意的,因为我想通过最大限度的并行化来节省时间。
这是我的Gulpfile.js 。我只需要一个插件。
const gulp = require('gulp');
const svg2png = require('gulp-svg2png');
gulp.task('default', function() {
return gulp
.src('./dist/teasers/*.svg')
.pipe(svg2png())
.pipe(gulp.dest('./dist/teasers/'));
})
请注意,这是很重的资源。取决于你的网站有多大,你可能想逐步进行,或者把结果储存在某个地方,而不是每次构建运行都创建这个。
至于这个网站。Eleventy在不到2秒的时间内完成了HTML+SVG的构建。在Vercel上转换PNG还需要20秒。这仍然比一个 "Hello world "风格的Gatsby网站快。所以我认为每次都这样做是合理的 😉
设置元标签#
最后,但不是最不重要的,我在每篇博客文章的元信息中添加了结果。
{% set imgPath = permalink | slug %}
<meta property="og:image"
content="https://fettblog.eu/teasers/{{ imgPath }}.png">
<meta property="og:image:secure_url"
content="https://fettblog.eu/teasers/{{ imgPath }}.png">
<meta name="twitter:image"
content="https://fettblog.eu/teasers/{{ imgPath }}.png">