【问题标题】:Create an Eleventy collection from SVG folder从 SVG 文件夹创建一个 Eleventy 集合
【发布时间】:2021-04-27 00:06:06
【问题描述】:

大家好, 我创建了一个小的 SVG 图标集,并希望使用 Eleventy 将它们全部显示在一个页面上的一个文件夹中。但同时,我需要 SVG 代码,因为用户应该能够快速将 SVG 代码复制到剪贴板。有一些用于 SVG 内容放置的插件,但我不能将它们与 110 个集合结合使用。

我能够使用eleventy-plugin-svg-contents 将 SVG 代码放入 110 页。但由于图标集将包含 200 多个图标,我真的不想单独复制和粘贴它们。


此外,我已经设法将文件夹中的所有 SVG 文件添加到集合中,但由于它应该是矢量图标集,我无法使用图像文件。

{% for icon in collections.iconGallery %}
  <figure>
    <img class="m-2 w-6 h-6" src="{{ icon }}" alt="" />
  </figure>
{% endfor %}

我想实现以下目标:

  • 将所有 SVG 图标文件放在一个文件夹中
  • 创建该文件夹中所有 SVG 文件的集合
  • 显示渲染的 SVG 内容(无 &lt;img&gt; 标签)
  • 显示名称(不带扩展名的文件名)和 SVG 代码

出于测试目的,我将提供三个图标作为 SVG 代码示例:

<!-- annotation.svg -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7 8H17M7 12H12M16.8284 17H19C20.1046 17 21 16.1046 21 15V6C21 4.89543 20.1046 4 19 4H5C3.89543 4 3 4.89543 3 6V15C3 16.1046 3.89543 17 5 17H7.17157C7.70201 17 8.21071 17.2107 8.58579 17.5858L10.5858 19.5858C11.3668 20.3668 12.6332 20.3668 13.4142 19.5858L15.4142 17.5858C15.7893 17.2107 16.298 17 16.8284 17Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>

<!-- briefcase.svg -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M8 7H5C3.89543 7 3 7.89543 3 9V13M8 7V5C8 3.89543 8.89543 3 10 3H14C15.1046 3 16 3.89543 16 5V7M8 7H16M16 7H19C20.1046 7 21 7.89543 21 9V13M3 13V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19V13M3 13H8M21 13H16M8 13H16M8 13V15M8 13V11M16 13V11M16 13V15" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>

<!-- calendar.svg -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M4 9V19C4 20.1046 4.89543 21 6 21H18C19.1046 21 20 20.1046 20 19V9M4 9V7C4 5.89543 4.89543 5 6 5H8M4 9H20M20 9V7C20 5.89543 19.1046 5 18 5H16M16 5V3M16 5H8M8 3V5" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>

我希望我的问题足够清楚,如果您有任何问题,请在 cmets 中告诉我。 提前感谢大家。

【问题讨论】:

  • 您能否详细说明您是如何创建iconGallery 集合的?我认为有几种选择可以达到您想要的结果。我会使用 JavaScript 数据文件而不是集合,但听起来你已经完成了一半......

标签: svg eleventy


【解决方案1】:

我建议使用JavaScript data files 的替代方法。由于您可以通过 Node 完全访问文件系统,因此您只需手动将文件夹解析为包含您需要的所有信息的数组,包括 SVG 源代码。

又快又脏,可能需要一些调整:

// _data/icons.js
const fg = require('fast-glob');
const path = require('path');
const fs = require('fs');

module.exports = function() {
    return new Promise(async (resolve, reject) => {
        const iconFolder = path.resolve(__dirname, '../path/to/your/icon/folder/');
        const svgIcons = await fg('**/*.svg', { cwd: iconFolder };
        const iconData = await Promise.all(svgIcons.map(async (name) => {
            const nameWithoutExtension = path.parse(name).name;
            const source = fs.readFileSync(path.resolve(iconFolder, name), { encoding: 'utf8' });
            const sourceWithClass = source.replace('<svg', '<svg class="my-custom-class"');
            return { name, source, sourceWithClass, nameWithoutExtension };
        }));
        resolve(iconData);
    });
};

此数据文件返回一个对象数组,其中包含图标文件夹中每个 SVG 图标的名称(或相对于图标基本文件夹的路径,如果有子目录)和来源。然后你可以在你的模板中遍历它并相应地显示名称和来源。

请注意,上面的示例使用fast-glob,当然您也可以使用fs 手动遍历文件夹中的文件。

使用集合应该也可以做到这一点,因为您现在可以将所需的任何数据结构放入集合中。

访问数据

Eleventy automatically parses data file 并使它们可用于您的模板。因此,您可以在任何模板中访问这样的图标数据(以 Nunjucks 语法为例):

{% for icon in icons %}
    <figure>
        {# output the svg source code including the added class. the safe filter is necessary to prevent nunjucks from escaping the SVG code  #}
        {{ icon.sourceWithClass | safe }}
        {# output the file name (excluding the extension) #}
        <figcaption>{{ icon.nameWithoutExtension }}</figcaption>
    </figure>
{% endfor %}

请注意,用于访问数据的变量名称(此处为:icons)取决于数据文件的名称。详情请见documentation

【讨论】:

  • 看起来不错。如何在 HTML 页面上添加这些内容?
  • @GerritHalfmann 我已经用如何访问模板中的数据的示例更新了答案!
  • 在我的十一构建中,我得到了这个错误:Unhandled rejection in promise ([object Promise]): (more in DEBUG output) &gt; Callback must be a function. Received { encoding: 'utf8' }
  • @GerritHalfmann 我已经用关于您的后续问题的示例更新了上面的代码。但是您可以在为每个图标返回的对象中添加您想要的任何数据,因此您可以使用常规 JavaScript 字符串函数(例如:String.prototype.replace 用于添加类)或 NodeJS 实用方法(例如:path.parse 用于获取不带扩展名的文件名)将数据修改为您需要的格式。
  • 太棒了,非常感谢。我在这里实现了所有这些:majesticons.com 再次感谢!
猜你喜欢
  • 2017-02-22
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
相关资源
最近更新 更多