Gatsby Starter博客:如何在支持Twitter卡的情况下将标题图像添加到帖子中

2020年12月30日10:41:27 发表评论 41 次浏览

本文概述

如果你像我, 你曾经盖茨比入门博客来启动你的个人博客, 进行一些自定义, 然后一起使用。

以markdown的形式添加新帖子很棒。但这也意味着你很少有理由看一下代码。因此, 当我决定将标题图片添加到我的帖子中并支持Twitter卡, 我感到迷茫。

我的要求是能够在帖子中添加带有标题的大标题图像, 如下所示:

在适用于Java的DynamoDB增强客户端中使用异构项目集合

使用Java SDK处理异构项目集合可能很棘手。在这里, 我们了解如何使用适用于Java的AWS开发工具包v2的增强客户端来处理它们。

Gatsby Starter博客:如何在支持Twitter卡的情况下将标题图像添加到帖子中1

大卫·阿古德

Gatsby Starter博客:如何在支持Twitter卡的情况下将标题图像添加到帖子中2

此外, 包含该帖子链接的推文应"扩展"为Twitter的大图片摘要卡, 像这样:

最后, 对于未指定图片的帖子, 默认图片应使用Twitter的摘要卡。这是我将网站徽标用作默认图片的样子:

注意:Twitter的文档指出, 网站徽标不应用于卡片图片(请参见推特:图片部分这里)。我将由你来决定像我在此处使用固定图像作为后备广告是否有意义。

入门

这是我将指导你完成的五个高级步骤。我将尝试深入解释所有内容, 并在此过程中提供指向其他资源的链接。这样, 你将积累对盖茨比的知识, 可以从中汲取知识来解决后面的更复杂的步骤。

  1. 添加文档元数据标签
  2. 使用GraphQL的源默认图像
  3. 使用GraphQL的特定源图像后属性
  4. 将标题图像添加到博客文章模板
  5. 向Post的Frontmatter添加新属性

我们将用于完成此任务的工具都是现成的盖茨比入门博客!

  • 反应头盔-用于搜索引擎优化用于向文档头添加元标记以支持Twitter Cards和其他组件的组件打开图标签
  • 盖茨比源文件系统-一个"用于从本地文件系统向Gatsby应用程序中获取数据的插件", 在我们这里是图片
  • 盖茨比图片-" React组件经过专门设计, 可与Gatsby的GraphQL查询无缝协作。它结合了盖茨比的原生图像处理具有先进的图像加载技术的功能, 可轻松, 完全优化你网站的图像加载。盖茨比图像用途gatsby-plugin-sharp为其图像转换提供动力。"
  • 盖茨比插件Sharp-"展示了一些基于夏普图像处理库"。我们使用它来调整图像大小。

如何添加文档元数据标签

首先, 我们将连接HTML元数据标签, 该标签可由Twitter和任何其他了解以下内容的平台或工具读取打开图例如Google, Facebook和WhatsApp。

在此处了解有关文档元数据的更多信息:脑子里有什么? HTML中的元数据.

打开搜索引擎优化组件中src / components / seo.js。首先要注意的是反应头盔, 并且已经有很多Open Graph和Twitter元标记, 例如og:title, twitter:描述。它甚至有一个推特:卡标记, 其值为"摘要", 可启用基本的Twitter摘要卡(无图片):

// src/components/seo.js
const SEO = ({ description, lang, meta, title }) => { 
// Details omitted for brevity 
return ( 
    <Helmet 
        htmlAttributes={{ lang }} 
        title={title} 
        titleTemplate={`%s | ${site.siteMetadata.title}`} 
        meta={[ 
            { name: `description`, content: metaDescription, }, { property: `og:title`, content: title, }, { property: `og:description`, content: metaDescription, }, { property: `og:type`, content: `website`, }, { property: `twitter:card`, content: `summary`, }, { property: `twitter:creator`, content: site.siteMetadata.social.twitter, }, // ...

让我们更新此组件:

  1. 加imageUrl和imageAlt参数。这些将作为道具通过BlogPostTemplate组件, 我们将在后面看到。请注意, 我在道具名称中使用了" URL"来传达一个事实, 即该URL必须是完全限定的URL。 OG映像不支持相对路径!
  2. 构造默认的图片网址, defaultImageUrl。我写了一个很小的实用函数ConstructUrl, 以将基本URL与相对路径连接起来。我们会看到哪里data.ogImageDefault来自下一部分。
  3. 添加一个ogImageUrl变量imageSrcUrlprop, 或者, 如果未提供, 则默认为defaultImageUrl.
  4. 将对象添加到元数组传递给头盔零件:og:image, 推特:卡和推特:图片:alt

这里需要注意的几件事:

  1. Twitter确实有自己的推特:图片元标记, 但根据docs, 我们不需要同时添加og:image和推特:图片标签, 因为Twitter的解析器将退回到"打开图表"标签。
  2. 打开图指定元属性属性和内容而Twitter指定名称和内容, 分别。但是, Twitter文档再次声明其解析器将退回到"打开图"属性。这很好, 因为我们可以保持一致性, 并且不需要一堆具有必须保持同步的相同值的重复属性。
  3. 使用属性归因于元标签是任何非Open Graph标签, 例如描述必须使用名称属性。我鼓励你使用灯塔这将确定你的SEO的基本问题。
// util.js
export const constructUrl = (baseUrl, path) =>
  (!baseUrl || !path) ? null : `${baseUrl}${path}`;

// src/components/seo.js
// Step 1: Add props
const SEO = ({ description, lang, meta, title, imageUrl, imageAlt }) => { 
    
    const data = useStaticQuery(
        // This is explained next
    );
                                
    // Step 2: Construct default image URL
    // ogImageDefault is explained next
    const defaultImageUrl = constructUrl(data.site.siteMetadata.siteUrl, data.ogImageDefault?.childImageSharp?.fixed?.src)
    
    // Step 3: Add this
    const ogImageUrl = imageUrl || defaultImageUrl; 
    
    return ( 
        // Step 4: Add new meta objects
        <Helmet 
            htmlAttributes={{ lang }} 
            title={title} 
            titleTemplate={`%s | ${site.siteMetadata.title}`} 
            meta={[
                { property: `og:image`, content: ogImageUrl, }, // If a post has an image, use the larger card. 
                // Otherwise the default image is just 
                // a small logo, so use the smaller card.
                { property: `twitter:card`, content: imageUrl ? `summary_large_image` : `summary`, }, // Add image alt text
                // Falls back to default which describes the site logo
                { property: `twitter:image:alt`, content: imageAlt || "davidagood.com logo", }, // ...

如何使用GraphQL获取默认图像

这就是盖茨比(Gatsby)的文件系统和图像处理功能发挥作用的地方。下面是useStaticQuery从中调用GraphQL查询搜索引擎优化零件。我已经添加了ogImageDefault部分和siteUrl这是需要的ConstructUrl上面显示的电话。

// src/components/seo.js
const data = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
            description
            social {
              twitter
            }
            # Add this
            siteUrl
          }
        }
        # Add this
        ogImageDefault: file(relativePath: {eq: "icon.png"}) { 
          childImageSharp {
            fixed(height: 260, width: 260) {
              src
            }
          }
        }
      }
    `, );

GraphQL文件和图像处理查询介绍

顶级节点是ogImageDefault。这是一个GraphQL别名为了文件查询正在应用过滤器以查找相对路径等于的文件icon.png。我选择的名字ogImageDefault, 完全是任意的。

这里要了解的一件事是relativePath是相对的。换句话说, 这个档案在哪里icon.png?

首先让我告诉你文件相对于项目根目录的位置:./content/assets/icon.png。在查询中, 我没有指定任何相对路径, 只是文件名。那么盖茨比如何知道在哪里找到它?

输入gatsby源文件系统。如果你看gatsby-config.js你将看到一些这样的配置:

// gatsby-config.js 
module.exports = { 
    // siteMetadata: {...}, plugins: [ 
        // Other plugins omitted 
        { 
            resolve: `gatsby-source-filesystem`, options: { 
                path: `${__dirname}/content/blog`, name: `blog`, }, }, { 
            resolve: `gatsby-source-filesystem`, options: { 
                path: `${__dirname}/content/assets`, name: `assets`, }, }, // ...

这是将这些路径注册为"内容根"并为其命名。所以这个名字博客指./content/blog相对于项目根目录。和名字资产指./content/资产相对于项目根目录。你可以通过过滤在查询中使用这些名称sourceInstanceName:

# http://localhost:8000/___graphql 
{ 
    allFile(filter: {sourceInstanceName: {eq: "blog"}}) { 
        edges { 
            node { 
                absolutePath 
                publicURL 
                sourceInstanceName 
            } 
        } 
    } 
}

该查询的结果:

// Result of allFiles query with sourceInstanceName filter 
{ 
    "data": { 
        "allFile": { 
            "edges": [{ 
                "node": { 
                    "absolutePath": "/home/dgood/IdeaProjects/davidagood.com/content/blog/clean-code-and-architecture/index.md", "publicURL": "/static/40bb02d938c4faf7f977dd66c1a399d2/index.md", "sourceInstanceName": "blog" 
                } 
            }, // additional results...

回到ogImageDefault:relativePath我们提供的只是icon.png, 但文件实际上位于./content/assets/icon.png.

Gatsby能够解析该文件, 因为我们在以下位置配置了"内容根目录"./content/资产。我们可以指定sourceInstanceName消除关于此文件位于哪个"内容根"的任何歧义。

实际上, 如果多个"内容根"中存在相同的相对路径, 我不确定Gatsby的行为。

这将是一个深入了解盖茨比(Gatsby)源代码以了解其工作原理的好机会, 但我将留给你!

接下来:什么是childImageSharp? "子"是指这是一个子节点文件节点。 "图像"就像听起来一样。 "尖锐"是指尖锐图像处理工具和相应的Gatsby插件, gatsby-plugin-sharp, 从而启用这些图像处理功能。

固定意味着我们要将图像转换为固定大小的图像。我们通过传递如下参数来指定尺寸:固定(高度:260, 宽度:260)。有一些替代方法固定我们可以使用它, 我们将在下面看到其中之一。

最后, 我们只需要src属性用于"打开图"图像元标记。

如何使用GraphQL获取特定于后期的图像属性

从上面开始, 我们必须更新BlogPostTemplate组件通过imageUrl和imageAlt道具搜索引擎优化零件。同样, 我们使用ConstructUrl转换相对路径的工具, src, 转换为网址。我在下面解释这些道具价值的由来。

// util.js
export const constructUrl = (baseUrl, path) =>
  (!baseUrl || !path) ? null : `${baseUrl}${path}`;

// src/templates/blog-post.js
const BlogPostTemplate = ({ data, pageContext, location }) => { 
    // Details omitted for brevity
    return ( 
        <Layout location={location} title={data.site.siteMetadata.title}> 
            <SEO 
                title={data.markdownRemark.frontmatter.title} 
                description={data.markdownRemark.frontmatter.description || data.markdownRemark.excerpt} 
                imageUrl={
                    constructUrl(
                        data.site.siteMetadata.siteUrl, data.markdownRemark.frontmatter.image?.childImageSharp?.fixed?.src
                )} 
                imageAlt={data.markdownRemark.frontmatter.imageAlt} />
        // ...

提供图片替代文字非常简单:我们添加了imageAlt作为财产前题我们的一部分BlogPostTemplate组件的GraphQL查询。该查询被导出为GraphQL标记的模板。

导出常量的名称是任意的。就我而言const pageQuery.

此查询由Gatsby为我们执行, 并将结果传递给BlogPostTemplate组件中的数据支柱。

Gatsby文档中对此进行了解释:使用GraphQL查询页面中的数据.

为了获得实际图像, 我们使用childImageSharp再次, 但与我们上面看到的方式略有不同:

// src/templates/blog-post.js
export const pageQuery = graphql`
    query BlogPostBySlug($slug: String!) {
      site {
        siteMetadata {
          title
          siteUrl
        }
      }
      markdownRemark(fields: {slug: {eq: $slug}}) {
        id
        excerpt(pruneLength: 160)
        html
        frontmatter {
          title
          date(formatString: "MMMM DD, YYYY")
          description
          # Add this
          image {
            childImageSharp {
              fixed(height: 600, width: 1200) {
                src
              }
              fluid(maxWidth: 700, maxHeight: 500) {
                ...GatsbyImageSharpFluid
              }
            }
          }
          # Add these
          imageAlt
          imageTitleHtml
        }
      }
    }
`;

这里, 图片必须与我们打算在帖子的前题中设置的属性名称匹配。并且此属性的值必须是文件的路径相对于发布降价文件.

这类似于我们上面使用GraphQL别名和文件查询, 但此处是隐式的, 由盖茨比(Gatsby)在后台处理。

我们在参数中指定尺寸固定领域。选择尺寸时, 请确保你使用的任何图像至少与你在此处指定的尺寸一样大, 并使用来自docs:

此卡的图像支持2:1的长宽比, 最小尺寸为300x157或最大4096x4096像素

我们还添加了体液财产和GraphQL片段, ...盖茨比ImageSharpFluid, 它检索该节点上所有可用的属性, 而不必一一枚举。

Gatsby Image组件是设计用于这种方式为了提供使用的响应式图像体验HTML的本机自适应图像功能.

如何将标题图像添加到你的博客文章模板

随着GraphQL查询的更新以及Gatsby将结果传递到我们的组件后, 我们准备添加Gatsby Image导入以及用于标题图像和标题的JSX:

// src/templates/blog-post.js
import Image from "gatsby-image";

// Details omitted for brevity

{data.markdownRemark.frontmatter.image?.childImageSharp?.fluid &&
    <>
        <Image
            fluid={data.markdownRemark.frontmatter.image.childImageSharp.fluid}
            alt={data.markdownRemark.frontmatter.imageAlt} 
        />
        <div
            style={{
                textAlign: "center", fontSize: "14px", lineHeight: "28px", }}
            dangerouslySetInnerHTML={{ 
                __html: data.markdownRemark.frontmatter.imageTitleHtml 
            }} 
        />
    	<br/>
        <br/>
    </>
}

如果图片orimageAlt属性未设置在帖子的开头, 不会引起任何问题。这些属性将是null在帖子的数据道具, 例如data.markdownRemark.frontmatter.image和data.markdownRemark.frontmatter.imageAlt.

因此, 我使用了可选链接通过时imageUrl支撑搜索引擎优化零件:data.markdownRemark.frontmatter.image?.childImageSharp?.fixed?.src以及可选地添加标题图像组件树时:data.markdownRemark.frontmatter.image?.childImageSharp?.fluid.

如何向帖子的前题添加新属性

现在剩下的就是添加实际的图像文件, 通常在与我们要使用的markdown所在的目录中。然后我们添加图片, imageAlt和imageTitleHtml属性的位置。

我直接从中获取了建议的归因HTML不飞溅并用于imageTitleHtml.

请记住:在这种情况下, 图像路径是相对于后期降价文件的。

--- 
title: "Working with Heterogeneous Item Collections in the DynamoDB Enhanced Client for Java" 
date: "2020-12-07T01:51:34.815Z"
description: "Working with heterogeneous item collections with the Java SDKs can be tricky. Here we see how to handle 
them with the AWS SDK v2 for Java's Enhanced Client."
image: "./kevin-mueller-gGUiw8GNIFE-unsplash.jpg"
imageAlt: "Water droplets on black background"
imageTitleHtml: '<span>Photo by <a href="https://unsplash.com/@kevinmueller?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Kevin Mueller</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>'

--- 

// Markdown here...

总结

就是这样–你做到了!本文涵盖了很多概念。现在, 你应该能够在博客帖子中添加标题图像, 并在Twitter, Facebook, Google, WhatsApp等上获得基于Open Graph的出色预览体验。

你可以在GitHub上找到完整的代码:

  • 搜索引擎优化
  • BlogPostTemplate
  • 减价示例

实施并部署之后, 你可以使用Twitter卡验证器在实际发布链接之前测试行为。

碰巧的是, 即使验证程序显示卡正在运行, 我也确实遇到了卡未在推文中显示的一些问题。

在一种情况下, 我在回复中发布了一个推文, 但根本没有卡片, 只有原始链接。第二天, 我在推特上发布了相同的链接, 这次卡工作正常!

在另一种情况下, 我正在查看我的Twitter个人资料页面, 并且我的一些推文中都包含卡片, 但图像未显示。因此, 我打开了一个Chrome Incognito窗口, 并在该窗口中按预期显示了图像。

一盏木

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: