在降价中添加后备图像

Adding a fallback images in markdown

我一直在用 .webp 替换我现有的网站图片。在 HTML 中,添加后备支持相对容易,例如不支持 .webp 的情况。但是,我正在努力寻找降价的等价物?

HTML

<img src="img.webp" />

HTML 具有后备支持

<picture>
  <source srcset="img.webp" type="image/webp">
  <source srcset="img.jpg" type="image/jpeg"> 
  <source srcset="img.png" type="image/png"> 
</picture> 

例如

降价

![](img.webp)

带后备支持的 Markdown

![](img.webp,img.png)

不确定这是否有效,但您可以尝试一下:

[![my image](img.webp)](image_url)

我认为没有像 markdown 中那样的后备图像规范,但是如果您使用 markdown-it(这是 Eleventy 中的默认 markdown 解析器),您可以添加自定义插件来扩展句法。您也可以只将 HTML 放在您的 markdown 中,或者如果您使用的是 Eleventy,您甚至可以在您的 markdown 中使用短代码。

使用简码

您可以定义custom shortcodes in Eleventy and then use them in your markdown。这可能比设置 markdown-it 插件更容易和更灵活,但缺点是将非 markdown 内容放入 markdown。

使用 markdown-it 插件

如果您已经有了要使用的预生成图像,您可能想使用类似 markdown-it-picture 的东西并修改它以设置 type 属性,或者通过解析文件扩展名或更改媒体 query/title 点以接受 type。您需要将代码复制到项目中的新文件中,进行修改,然后像这样注册它:

// .eleventy.js
module.exports = function(eleventyConfig) {
  const mdPicture = require('/path/to/plugin.js')
  const md = require('markdown-it')()
  md.use(mdPicture)
  eleventyConfig.setLibrary('md', md)
  // ...
};

eleventy-image

或者,如果您还没有生成图像并希望在第 11 步构建步骤中生成它们,您可以使用 eleventy-image (Docs). This Twitter thread 关于创建自定义 markdown-it 渲染器的讨论,我已将其修改为与下面的 eleventy-image 一起使用。

// you might want to put this in another file
// such as ./utils/markdown.js

// responsive images with 11ty image
// this overrides the default image renderer
// titles are also used for size setting (optional)
//
// ![alt text](/path/to/img.png '(max-width: 768px) 100vw, 768px')

const md = require('markdown-it')();
const Image = require('@11ty/eleventy-img')

md.renderer.rules.image = function (tokens, idx, options, env, self) {
  const token = tokens[idx]
  let imgSrc = token.attrGet('src')
  const imgAlt = token.content

  // you can modify the default sizes, or omit
  const imgSize = token.attrGet('title') || '(max-width: 768px) 100vw, 768px'

  const widths = [250, 426, 580, 768] // choose your own widths, or [null] to disable resize
  const imgOpts = {
    widths: widths
      .concat(widths.map((w) => w * 2)) // generate 2x sizes for retina displays
      .filter((v, i, s) => s.indexOf(v) === i), // dedupe widths
    formats: ['webp', 'jpeg'], // choose your own formats (see docs)
    urlPath: '/assets/img/', // src path in HTML output
    outputDir: './_site/assets/img/' // where the generated images will go
  }

  // generate the images
  // see https://www.11ty.dev/docs/plugins/image/#synchronous-usage
  Image(imgSrc, imgOpts)

  const metadata = Image.statsSync(imgSrc, imgOpts)

  return Image.generateHTML(metadata, {
    alt: imgAlt,
    sizes: imgSize,
    loading: 'lazy',
    decoding: 'async'
  })
}

// in your .eleventy.js
module.exports = function(eleventyConfig) {
  // you may need to `require` the file with
  // your markdown config with the custom renderer
  // const md = require('./utils/markdown.js')
  eleventyConfig.setLibrary('md', md)
  // ...
};

此渲染器会自动生成不同尺寸的图像,以及不同的格式,然后在您的 HTML 中输出 <picture> 标签。由于 markdown-it 不能很好地与 async 函数一起使用,我们使用 syncronous pattern of eleventy-image. More information about configuration can be found in the docs.

您可能需要注意的一件事是,您的 markdown 中的图像路径应该是图像在您网站源中的位置,不是 最终发布的 URL。例如,我的图像可能位于 src/images/img.png,但发布在 https://example.com/images/img.png。降价应该是 ![alt text](src/images/img.png) 而不是 ![alt text](/images/img.png)。您还可以在渲染器函数中进行额外的解析。