xaoxuu / hexo-theme-stellar

内置文档系统的简约商务风Hexo主题,支持大量的标签组件和动态数据组件。
https://xaoxuu.com/wiki/stellar/
MIT License
1.27k stars 316 forks source link

相关文章 不显示 cover 图片,设置 `related_posts.auto_cover: true` 时会发生报错。 #28

Closed hermitlsr closed 3 years ago

hermitlsr commented 3 years ago

问题描述

我一开始没有设置 front-matter.cover ,使用 related_posts 时默认选择了文章的第一个图片。但当我设置了 cover: 时,其显示的图片仍然时文章的第一个图片,而非 cover 的图片。我重装了 hexo-related-popular-posts,但是没有效果。 而当我尝试通过设置 related_posts.auto_cover: true ,来避免其使用第一个图片,会发生如下报错:

ERROR TypeError: D:\myBlog\hermitlsr-stellar\themes\stellar\layout\post.ejs:25
    23| </article>
    24| <%- partial('_partial/main/article/read_next') %>
 >> 25| <%- partial('_partial/main/article/related_posts') %>
    26| <%- partial('_partial/plugins/comments/layout') %>
    27|

D:\myBlog\hermitlsr-stellar\themes\stellar\layout\_partial\main\article\related_posts.ejs:16
    14| }
    15| %>
 >> 16| <%- layoutDiv() %>
    17|

Cannot read property 'length' of undefined
    at generateHTML (D:\myBlog\hermitlsr-stellar\themes\stellar\scripts\helpers\related_posts.js:45:43)
    at Object.<anonymous> (D:\myBlog\hermitlsr-stellar\themes\stellar\scripts\helpers\related_posts.js:77:19)
    at layoutDiv (D:\myBlog\hermitlsr-stellar\themes\stellar\layout\_partial\main\article\related_posts.ejs:15:11)
    at eval (D:\myBlog\hermitlsr-stellar\themes\stellar\layout\_partial\main\article\related_posts.ejs:28:17)
    at related_posts (D:\myBlog\hermitlsr-stellar\node_modules\ejs\lib\ejs.js:682:17)
    at _View._compiledSync (D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\theme\view.js:132:24)
    at _View.renderSync (D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\theme\view.js:59:25)
    at Object.partial (D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\plugins\helper\partial.js:34:15)
    at eval (D:\myBlog\hermitlsr-stellar\themes\stellar\layout\post.ejs:51:17)
    at post (D:\myBlog\hermitlsr-stellar\node_modules\ejs\lib\ejs.js:682:17)
    at _View._compiled (D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\theme\view.js:136:50)
    at _View.render (D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\theme\view.js:39:17)
    at D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\hexo\index.js:64:21
    at tryCatcher (D:\myBlog\hermitlsr-stellar\node_modules\bluebird\js\release\util.js:16:23)
    at D:\myBlog\hermitlsr-stellar\node_modules\bluebird\js\release\method.js:15:34
    at RouteStream._read (D:\myBlog\hermitlsr-stellar\node_modules\hexo\lib\hexo\router.js:47:5)
    at RouteStream.Readable.read (internal/streams/readable.js:481:10)
    at resume_ (internal/streams/readable.js:977:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  path: 'D:\\myBlog\\hermitlsr-stellar\\themes\\stellar\\layout\\post.ejs'
}

可复现

下载您网站的源码,并通过 git 方式安装 stellar,使用您的网站源码进行本地测试也是这种效果,但是看您的网站和本地情况不一样: 1629805590384.png 当设置 related_posts.auto_cover: true 时,也会出现同样的报错。

xaoxuu commented 3 years ago

默认就是true呀 https://github.com/xaoxuu/hexo-theme-stellar/blob/3fc6632a833ea96211c62e09ab856ab9df60494a/_config.yml#L77

hermitlsr commented 3 years ago

@xaoxuu 我确认了下的确是这样,因为我测试的时候把这部分复制到 _config.stellar.yml 中了,在其中更改的 true 或者 false 。我使用您的源站重新测试了一次还是会出现报错。该报错不影响站点的构建,会正常生成 http://localhost:4000,可访问非文章页的其他页面,访问文章页时就会出现上述报错。上述报错会出现在构建网站时,和构建完成后点击文章时。 前面提到的可复现的图片情况应该是 auto_cover: false 时的情况。

出现报错的配置如下:

# _config.stellar.yml
  related_posts:
    enable: true
#_config.yml
  related_posts:
    enable: false
    max_count: 5
    auto_cover: true # 如果没有封面就根据 tags 作为关键词搜索封面,开了此项将不会自动从文章中提取首张图片作为封面了。

package.json

{
  "name": "hexo-site",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "c": "hexo clean",
    "s": "hexo clean && hexo server",
    "g": "hexo clean && hexo generate",
    "d": "hexo deploy"
  },
  "hexo": {
    "version": "5.4.0"
  },
  "dependencies": {
    "hexo": "^5.4.0",
    "hexo-all-minifier": "^0.5.7",
    "hexo-autonofollow": "^1.0.1",
    "hexo-deployer-git": "^3.0.0",
    "hexo-generator-archive": "^1.0.0",
    "hexo-generator-category": "^1.0.0",
    "hexo-generator-index": "^2.0.0",
    "hexo-generator-seo-friendly-sitemap": "^0.2.1",
    "hexo-generator-tag": "^1.0.0",
    "hexo-related-popular-posts": "^5.0.1",
    "hexo-renderer-ejs": "^1.0.0",
    "hexo-renderer-marked": "^4.0.0",
    "hexo-renderer-stylus": "^2.0.1",
    "hexo-server": "^2.0.0"
  }
}

具体过程时下载您的源站压缩包,解压后使用 npm i命令下载必要插件,再使用 git 下载主题。

再次提一下报错内容:

Unhandled rejection TypeError: C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\themes\stellar\layout\post.ejs:25
    23| </article>
    24| <%- partial('_partial/main/article/read_next') %>
 >> 25| <%- partial('_partial/main/article/related_posts') %>
    26| <%- partial('_partial/plugins/comments/layout') %>
    27|

C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\themes\stellar\layout\_partial\main\article\related_posts.ejs:16
    14| }
    15| %>
 >> 16| <%- layoutDiv() %>
    17|

Cannot read property 'length' of undefined
    at generateHTML (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\themes\stellar\scripts\helpers\related_posts.js:45:43)
    at Object.<anonymous> (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\themes\stellar\scripts\helpers\related_posts.js:77:19)
    at layoutDiv (eval at compile (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\ejs\lib\ejs.js:618:12), <anonymous>:14:11)
    at eval (eval at compile (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\ejs\lib\ejs.js:618:12), <anonymous>:27:17)
    at returnedFn (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\ejs\lib\ejs.js:653:17)
    at _View._compiledSync (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\theme\view.js:132:24)
    at _View.renderSync (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\theme\view.js:59:25)
    at Object.partial (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\plugins\helper\partial.js:34:15)
    at eval (eval at compile (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\ejs\lib\ejs.js:618:12), <anonymous>:50:17)
    at returnedFn (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\ejs\lib\ejs.js:653:17)
    at _View._compiled (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\theme\view.js:136:50)
    at _View.render (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\theme\view.js:39:17)
    at C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\hexo\index.js:64:21
    at tryCatcher (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\bluebird\js\release\util.js:16:23)
    at C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\bluebird\js\release\method.js:15:34
    at RouteStream._read (C:\Users\HermitLee\Downloads\xaoxuu.github.io-main\node_modules\hexo\lib\hexo\router.js:47:5)
    at RouteStream.Readable.read (internal/streams/readable.js:481:10)
    at resume_ (internal/streams/readable.js:977:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)
xaoxuu commented 3 years ago

我的网站是有CI根据源码生成的,我本地跑起来没问题,CI生成的也没问题,你下载下来跑的有问题,说明还是你改了什么东西改出问题了。

源码原封不动跑起来就没问题呀:

image

xaoxuu commented 3 years ago

看报错信息是文章没有标签导致的,你是不是把文章换成了你的就报错了?我刚提交了个版本,修复了没有tags导致报错的问题,你更新一下看看。

xaoxuu commented 3 years ago

你贴的截图的情况只有:

同时满足才会出现。 (也有可能是文章路径格式问题导致我没有匹配到文章对其封面进行替换,使用了插件默认的图片)

相关文章封面的优先级是:

  1. 文章中的 cover ,无论配置是否开启了自动封面。
  2. 如果文章中没有 cover,如果开启了自动封面,则会根据 tags 作为关键词搜索封面。
  3. 如果文章中既没有 cover 又没有 tags;或者没有 cover 且配置没开启自动封面,那么会显示文章中的第一个图片,如果文章中没有任何图片,则显示占位图。
hermitlsr commented 3 years ago

@xaoxuu 按照新的修改 3fc6632 ,报错修复了。

但是目前的问题是无论是否开启 auto_cover,显示的图片都是文章的第一张图片而非 cover 图片。这个情况在我的站点和下载的您的站点的本地测试上都存在,并且对于我的站点发布后也没有得到解决。另,在文章内没有图片时会正确出现默认图片。

由于我的图片托管在其他平台上并开启了防盗链,于是我使用由 jsdelivr 加速的 GitHub 上的图片进行测试,仍然会出现第一张图片而非 cover 图片,排除了防盗链影响图片显示的问题。

问题截图:

我站点上的效果: image

下载的您站点上的效果: image

测试的环境:

image

xaoxuu commented 3 years ago

发一下你的两个配置文件

xaoxuu commented 3 years ago

image

我的源码就是 true 啊,为什么要修改,你修改成什么了?

hermitlsr commented 3 years ago

@xaoxuu 我是测试了 auto_cover: falseauto_cover: true 两种情况。 配置文件就是: image 你的源站只改动了主题配置文件里的 auto_cover,他们 truefalse 的结果一样,都是显示第一张图片。

我的站点是在 _config.stellar.yml 里面改的:

  related_posts:
    enable: true
    max_count: 5
    auto_cover: true # 如果没有封面就根据 tags 作为关键词搜索封面,开了此项将不会自动从文章中提取首张图片作为封面了。

我为什么要改动 auto_cover: 我的站点一开始设置的是 auto_cover: false, 发现只会出现文章的第一张图片,然后我设置为 true 之后就会显示之前的报错。现在报错的问题解决了,我就在我的站点和你的源站测试了 auto_cover 开启和不开启两种状态的效果,发现两种状态结果是一样的,在有设置 cover 的前提下:

xaoxuu commented 3 years ago

发一下你的两个配置文件吧,源文件打包上传

hermitlsr commented 3 years ago

@xaoxuu config.zip

xaoxuu commented 3 years ago

我需要看你改了什么,主题里面那个没动的不用发,发你自己的

xaoxuu commented 3 years ago

博客根目录的那两个

xaoxuu commented 3 years ago

你能像 GitHub Action 一样任何代码都不改,直接跑我的源码吗?

hermitlsr commented 3 years ago

测试的你的源站的: config.zip 我自己的: config.zip

xaoxuu commented 3 years ago

你能像 GitHub Action 一样任何代码都不改,直接跑我的源码吗?

hermitlsr commented 3 years ago

你能像 GitHub Action 一样任何代码都不改,直接跑我的源码吗?

我没配置过 Github Action, 我用你的代码配置试一下。

xaoxuu commented 3 years ago

我用你的配置跑不起来,估计跟这部分设置有关:

permalink: :year-:month-:day/:abbrlink.html   #permalink: :year-:month-:day-:title/
abbrlink:
    alg: crc32   #算法: crc16(default) and crc32
    rep: hex     #进制: dec(default) and hex
permalink_defaults:
hermitlsr commented 3 years ago

我用你的配置跑不起来,估计跟这部分设置有关:

permalink: :year-:month-:day/:abbrlink.html   #permalink: :year-:month-:day-:title/
abbrlink:
    alg: crc32   #算法: crc16(default) and crc32
    rep: hex     #进制: dec(default) and hex
permalink_defaults:

这个是使用了 hexo-abbrlink 这个插件,用于生成博客文章的永久链接的。

xaoxuu commented 3 years ago

把这个插件去了试试

hermitlsr commented 3 years ago

去掉之后还是不行,应该不是这个的问题。我之前用你的代码测试的时候,没有这个插件也是一样的。

xaoxuu commented 3 years ago

刚我试了下装了这个插件也没问题。

hermitlsr commented 3 years ago

会不会是使用了 GitHub Action 的缘故,我是直接运行的

xaoxuu commented 3 years ago

GitHub Action 就是拉我的源码在全新的环境中原封不动跑起来生成静态文件的,GitHub Action 运行的结果是最准确的、可在任何电脑上重现的。

xaoxuu commented 3 years ago

你看看别人的就没问题: https://www.cayzlh.com/

hermitlsr commented 3 years ago

我也很奇怪,我现在配置一下 github action 试一下看看

hermitlsr commented 3 years ago

因为我配置 Github Action 有问题,我又做了新的测试。大概把问题定位到,关于元素 p 的部分,我的理解是 p 应该是相关文章的 post,但是这个代码在我这里应该没有对应到 post,或者说没有起到作用。我把这部分代码注释掉或者保留都是文章出现第一张图片,也就是 list.img 。 所有测试的前提是,所有的文章都有 cover, related_posts.enable: trueauto_cover: true

    var p = posts.filter(function(p) {
      return root + p.path == list.path;
    });
    if (p && p.length > 0) {
      p = p.data[0];
    }
    if (p) {
      if (p.cover) {
        if (p.cover.includes('/')) {
          list.img = p.cover;
        } else {
          list.img = 'https://source.unsplash.com/1280x640/?' + p.cover;
        }
      } else if (cfg.auto_cover && p.tags && p.tags.length > 0) {
        var params = '';
        p.tags.reverse().forEach((tag, i) => {
          if (i > 0) {
            params += ',';
          }
          params += tag.name;
        });
        list.img = 'https://source.unsplash.com/1280x640/?' + params;
      }
    }

之后我进一步测试:

  1. 直接给 list.img 传一张图片进去,结果发现没有出现 img 元素,没有图片显示。 测试的代码:具体可见 : 测试1
    if (p) {
      if (p.cover) {
        if (p.cover.includes('/')) {
    -         list.img = p.cover
    +          list.img = 'https://cdn.jsdelivr.net/gh/cdn-x/xaoxuu@1.0.1/blog/2021-0102a@1x.svg';
    +          el += '<div class="img">'
    +         el += '<img src="' + list.img + '" />';
    +          el += '</div>';}}}

测试结果: image

  1. 将 p.cover 在最后再赋一次值给 list.img,结果发现出现 img 元素,但图片链接为未定义(http://localhost:500/2021-08-28/undefined),文章内没有图片的会正确显示默认图片

测试的代码:具体可见 : 测试2

    if (hexo.theme.config.default.cover) {
      el += '<div class="img">'
      if (list.img && list.img != "") {
+        list.img = p.cover
        el += '<img src="' + list.img + '" />';
      } else {
        el += '<img src="' + hexo.theme.config.default.cover + '" />';
      }
      el += '</div>';
    }

测试的结果: image

  1. 注释掉其他部分,按 1. 测试 else if (cfg.auto_cover && p.tags && p.tags.length > 0) 这一部分,结果也没有出现 img 元素。

经过以上测试我推断问题应该出现在 p 元素上,它没有正确提取到 post。建议大大不用 github action ,在本地跑一跑试试。

xaoxuu commented 3 years ago

image

我一开始回复你的时候就是本地跑的。。。

xaoxuu commented 3 years ago

现在情况是:

你再研究研究为什么同样的代码在你电脑上就拿不到封面吧,我是没辙了。。。

hermitlsr commented 3 years ago

我设置了自动发布到 github page 的 Github Action 。生成的页面也还是有问题,我也没辙了,就挺迷惑的。我现在写了一个随机图片代替这个东西。 在 related_posts.js 中设置:

    if (hexo.theme.config.default.cover) {
      var imgurl;
      el += '<div class="img">'
      if( cfg.selfimg && cfg.selfimg.length > 0 ){
        imgurl = cfg.selfimg[Math.floor(Math.random() * cfg.selfimg.length )]
        el += '<img src="' + imgurl + '" />';
      }else if (list.img && list.img != "") {
        el += '<img src="' + list.img + '" />';
      }else{
        el += '<img src="' + hexo.theme.config.default.cover + '" />';
      }
      el += '</div>';
    }

主题文件夹下:

  related_posts:
    enable: true
    max_count: 5
    auto_cover: true # 如果没有封面就根据 tags 作为关键词搜索封面,开了此项将不会自动从文章中提取首张图片作为封面了。
    selfimg:
      - 

可以设置多张图片,随机选取作为封面。算是暂时解决吧。

ps:related_posts.ejs 里的 maxCount 设置成定值了,我提了 pr ,或者下次更新改一下。

hermitlsr commented 3 years ago

得,我今天 GitHub Page 和 腾讯云 都用 GitHub Action 自动部署结果就没问题了。但是,我把用 GitHub Action 推送的那个 public 下载下来在本地 hexo s 就有问题。总之就是很迷。上面那个随机图片就算我自己搞得一个新特性吧。

xaoxuu commented 1 year ago
image

相关文章的封面去掉了,彻底解决问题。(🤪)

hermitlsr commented 1 year ago

没想到还记得这个 issue,这样更节省版面,看起来也舒服。 之前把这块和文章的 cover,banner 弄了个随机封面,找时间修修补补。