学习用Gatsby生成打开的图形图像。
当你在社交媒体上发布你的网站(或博客文章)的链接时,你希望它能吸引人们的注意。有效做到这一点的一种方法是提供打开图表协议元信息< >头
您的网站,包括提供og:映像
元标签提供URL的图像要显示。此外,鼓励您为每个URL提供自定义图像,如果您手动创建卡片图像,这可能是一个冗长的过程。
的目标是:
ogimage.
我们可以在Gatsby的静态graphhyql查询中查询的字段属性。
元标记在< >头
使用盔甲的博客帖子页面。以下是我想要为此帖子生成的开放图图像:
NPM.安装-D帆布灰度
我们将使用:
让我们创造一个generateOpenGraphImage ()
函数将接受:
Dest.
图象的路径。标题
的博客文章。日期
的博客文章。我们将创建一个1200x630的图像。第一步是注册一些自定义字体:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{const高度=630.;const宽度=1200;const填充=80;//添加字体registerFont('./fonts/roboto-regular.ttf'那{家庭:'roboto'});registerFont('./fonts/roboto-thin.ttf'那{家庭:'roboto'那风格:“薄”});};
在上面的代码中,我们正在使用registerfont()
函数要注册两个字体,两者都一样家庭
一个是瘦
风格。
接下来,让我们使用createCanvas ()
函数生成画布,然后访问访问背景
:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{//为了简洁,省略代码const帆布=Createcanvas.(宽度那高度);const背景=帆布。getContext('2d');};
接下来,我想包装博客帖子的标题文本。所以,我们将定义一个新的wraptext()
功能:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{//为了简洁,省略代码函数WrAptext.(背景那文本那X那y那行宽那line_height.){var.行='';var.段=文本。分裂('\ n');对于(var.一世=0.;一世<段。长度;一世++){var.话=段[一世]。分裂('');对于(var.N=0.;N<话。长度;N++){var.测试线=行+话[N]+'';var.指标=背景。measureText.(测试线);var.testWidth=指标。宽度;如果(testWidth>行宽&&N>0.){背景。fillText(行那X那y);行=话[N]+'';y+ =line_height.;}其他{行=测试线;}}背景。fillText(行那X那y);y+ =line_height.;行='';}返回y;}};
接下来,我们将用浅灰色填充整个画布,然后创建一个带有一些盒子阴影的白色卡片:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{//为了简洁,省略代码//浅灰色填充背景。填充='#f9f9fa';背景。填充(0.那0.那宽度那高度);//阴影:0 2px 2px 0 rgba(0,0,0,.14)背景。填充='#fff';背景。shadowoffsetx.=0.;背景。ShadowOffsety=2;背景。阴影博尔=2;背景。暗影色彩='RGBA(0,0,0,0.14)';背景。填充(40那40那宽度-填充那高度-填充);//阴影:0 3px 1px -2px rgba(0,0,0,.2)背景。填充='#fff';背景。shadowoffsetx.=0.;背景。ShadowOffsety=3.;背景。阴影博尔=-2;背景。暗影色彩='RGBA(0,0,0,0.2)';背景。填充(40那40那宽度-填充那高度-填充);//阴影:0 1px 5px 0 RGBA(0,0,0,.12);背景。填充='#fff';背景。shadowoffsetx.=0.;背景。ShadowOffsety=1;背景。阴影博尔=5.;背景。暗影色彩='rgba(0, 0, 0, 0.12)';背景。填充(40那40那宽度-填充那高度-填充);};
接下来,我们将添加博客文章的标题,然后添加包含文章日期和我的博客URL的副标题:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{//为了简洁,省略代码背景。字体='48pt roboto';背景。textAlign=“左”;背景。textBaseline='最佳';背景。填充='#000';consty=WrAptext.(背景那标题那填充那填充那600那填充);背景。填充=“# ff5722”;背景。填充(填充那y+填充那200那4.);const字幕=日期?`$ {日期}·//www.nxtmastery.com.`:'//www.nxtmastery.com';背景。字体='14pt roboto瘦';背景。textAlign=“左”;背景。textBaseline='底部';背景。填充='#000';背景。fillText(字幕那填充那高度-填充);const缓冲=帆布。toBuffer('图像/ jpeg'那{质量:1});FS.。writefilesync.(Dest.那缓冲);};
最后,我们将使用tobuffer()
画布的方法:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{//为了简洁,省略代码const缓冲=帆布。toBuffer('图像/ jpeg'那{质量:1});FS.。writefilesync.(Dest.那缓冲);};
以下是使用CANVAS生成打开图形图像的完整代码:
constgenerateOpenGraphImage=(Dest.那标题那日期)= >{const高度=630.;const宽度=1200;const填充=80;//添加字体registerFont('./fonts/roboto-regular.ttf'那{家庭:'roboto'});registerFont('./fonts/roboto-thin.ttf'那{家庭:'roboto'那风格:“薄”});const帆布=Createcanvas.(宽度那高度);const背景=帆布。getContext('2d');函数WrAptext.(背景那文本那X那y那行宽那line_height.){var.行='';var.段=文本。分裂('\ n');对于(var.一世=0.;一世<段。长度;一世++){var.话=段[一世]。分裂('');对于(var.N=0.;N<话。长度;N++){var.测试线=行+话[N]+'';var.指标=背景。measureText.(测试线);var.testWidth=指标。宽度;如果(testWidth>行宽&&N>0.){背景。fillText(行那X那y);行=话[N]+'';y+ =line_height.;}其他{行=测试线;}}背景。fillText(行那X那y);y+ =line_height.;行='';}返回y;}背景。填充='#f9f9fa';背景。填充(0.那0.那宽度那高度);// 0 2px 2px 0 rgba(0,0,0,.14)背景。填充='#fff';背景。shadowoffsetx.=0.;背景。ShadowOffsety=2;背景。阴影博尔=2;背景。暗影色彩='RGBA(0,0,0,0.14)';背景。填充(40那40那宽度-填充那高度-填充);// 0 3px 1px -2px rgba(0,0,0,.2)背景。填充='#fff';背景。shadowoffsetx.=0.;背景。ShadowOffsety=3.;背景。阴影博尔=-2;背景。暗影色彩='RGBA(0,0,0,0.2)';背景。填充(40那40那宽度-填充那高度-填充);// 0 1px 5px 0 rgba(0,0,0,.12);背景。填充='#fff';背景。shadowoffsetx.=0.;背景。ShadowOffsety=1;背景。阴影博尔=5.;背景。暗影色彩='rgba(0, 0, 0, 0.12)';背景。填充(40那40那宽度-填充那高度-填充);背景。字体='48pt roboto';背景。textAlign=“左”;背景。textBaseline='最佳';背景。填充='#000';consty=WrAptext.(背景那标题那填充那填充那600那填充);背景。填充=“# ff5722”;背景。填充(填充那y+填充那200那4.);const字幕=日期?`$ {日期}·//www.nxtmastery.com.`:'//www.nxtmastery.com';背景。字体='14pt roboto瘦';背景。textAlign=“左”;背景。textBaseline='底部';背景。填充='#000';背景。fillText(字幕那填充那高度-填充);const缓冲=帆布。toBuffer('图像/ jpeg'那{质量:1});FS.。writefilesync.(Dest.那缓冲);};
下一步是创建一个二进制,我们将作为构建管道的一部分执行。
我会创造一个新的生成
可执行文件:
MKDIR.箱光盘箱触摸BG.修改文件权限+ xBG.
节点可执行文件将调用我们的generateOpenGraphImage ()
功能:
#!!/usr/箱/env节点constFS.=要求('fs');const物=要求('灰质');const路径=要求('路径');constopenGraphImage=异步(src那Dest.)= >{const{generateOpenGraphImage那getfilesindirectory.}=要求('./utils.js');constSRCDIR.=路径。加入(__dirname.那'..'那src);constimagePath=路径。加入(__dirname.那'..'那Dest.);//检查目标目录是否存在如果(!!FS.。存在(imagePath)){FS.。mkdirsync.(imagePath);}const文件=等待getfilesindirectory.(SRCDIR.);等待诺言。所有(文件。过滤器(文件= >文件。匹配(/ ^\./)===.零)。地图(异步文件= >{const帖子=文件。分裂('。')。片(0.那-1)。加入('。');const图片=路径。加入(imagePath那帖子)+'.jpg';//检查图像文件是否已存在如果(FS.。存在(图片)){返回;}const啰嗦=物(FS.。readfilesync.(路径。加入(SRCDIR.那文件)));//检查frontmatter标题如果(!!啰嗦。数据。hasOwnProperty('标题')){返回;}const火柴=文件。匹配(/ ^ (\ d {4}) - ((\ d {2})) ((\ d {2})) /);const[日期]=火柴;过程。stdout.。写(`生成打开图形图像:$ {图片}\ n`);//获取新的横幅图像generateOpenGraphImage(图片那啰嗦。数据。标题那日期);}));};如果(要求。主要===.模块){(异步()= >{试一试{等待openGraphImage(“/ src /网页/职位。”那'./static/img/ogimages');}抓住(错误){控制台。错误(错误);过程。出口(1);}过程。出口(0.);})();}
让我们回顾一下节点脚本:
FS.
那大脑灰质
,路径
包。OpenGraphImage()
函数我们会执行。generateOpenGraphImage ()
功能以及一个getfilesindirectory.
帮手功能。该getFilesInDirectory ()
函数将使我们能够获得所有markdown post文件。在我的构造中,我有一个的帖子包含站点上所有博客文章的目录。文件
只有在尚不存在图像时,我们将要生成一个开放图图像。物()
从中的功能大脑灰质
包来解析markdown文件的内容,包括包含标题
的博客文章。匹配()
方法,并使用正则表达式获取帖子的日期。generateOpenGraphImage ()
函数,指定目标路径、标题和日期。ogimage.
节点字段接下来,我们将修改gatsby-node.js.添加新的文件ogimage.
领域:
const文档名称=createFilePath({节点那getNode那basePath:'帖子'});const火柴=文档名称。匹配(/ ^ \\/ ([\d]ams4} - [\d]} - [\d]}) - {1}(。+)\ / / / /);const[那日期那标题]=火柴;constogimage.=`/$ {日期}-$ {标题}.jpg.`;createNodeField({节点那名称:'ogimage'那价值:ogimage.});
接下来,我们将更新GraphQL静态查询以包含ogimage.
领域:
出口const页面=GraphQL.`查询PostTemplate($id: String!) {post: markdownRemark(frontmatter: {templateKey: {eq: "post"}} id: {eq: $id}) {fields {ogimage}}}}`;
og:映像
元标签最后一步是修改我们的模板,以指定具有我们为每个帖子生成的开放图图像的URL的适当元标记。我正在使用盔甲,所以我只需将标记添加到我的使用头盔的组件。
首先,我们将验证ogimage.
存在,因为我的组件用于网站上的所有页面和帖子。如果ogimage.
属性上不存在领域
对象,然后我们将使用默认图像:
出口默认({摘抄那领域那额外的}:道具)= >{让ogimage.;如果(领域&&领域。ogimage.){ogimage.=`/ img / ogimages$ {领域。ogimage.}`;}其他{ogimage.='/img/og-image.jpg';}
然后,我们将指定og:映像
元标签使用ogimage.
URL:
<头盔><超文本标记语言朗=“EN.“/><标题>{frontmatter & & frontmatter。标题吗?“$ {frontmatter。标题}| Brian F Love` : defaultTitle}标题><! - 简洁省略的代码 - ><荟萃属性=“og:type.“内容=“网站“/><荟萃属性=“og:映像“内容=“{'$ {siteurl} $ {ogimage}`}“/>头盔>
总之,虽然您可以在网站上的每个页面/帖子中手动创建开放图协议图像,但它也是方便的,因为这些自动生成了,特别是如果通过无头CMS生成的Gatsby网站内容。
您是否在帖子中注意到了拼写错误或遇到问题?让我在评论中知道。
嗨,我是布莱恩。我对类型名称,Angular和node.js感兴趣我嫁给了我最好的朋友邦妮,我住在波特兰和我滑雪(很多)。