xu-song / hexo-auto-category

Generate categories automatically for each post in Hexo
https://blog.eson.org/pub/e2f6e239/
MIT License
98 stars 8 forks source link

join is not a function #19

Closed everburstSun closed 3 years ago

everburstSun commented 4 years ago

运行hexo g的时候提示tmpPost.categories.join is not a function,以下是输出,不懂js不会修,求助。

➜ BlogCollections hexo g && hexo s INFO Validating config INFO Start processing FATAL { err: TypeError: tmpPost.categories.join is not a function at Hexo.logic (/Users/simon/Documents/BlogCollections/node_modules/hexo-auto-category/lib/logic.js:33:55) at Hexo.tryCatcher (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/util.js:16:23) at Hexo. (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/method.js:15:34) at /Users/simon/Documents/BlogCollections/node_modules/hexo/lib/extend/filter.js:67:52 at tryCatcher (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/util.js:16:23) at Object.gotValue (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/reduce.js:166:18) at Object.gotAccum (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/reduce.js:155:25) at Object.tryCatcher (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:547:31) at Promise._settlePromise (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:604:18) at Promise._settlePromise0 (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:649:10) at Promise._settlePromises (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:729:18) at _drainQueueStep (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:93:12) at _drainQueue (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:86:9) at Async._drainQueues (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:15:14) at processImmediate (internal/timers.js:461:21) } Something's wrong. Maybe you can find the solution here: %s https://hexo.io/docs/troubleshooting.html

MebilyChen commented 3 years ago

运行hexo g的时候提示tmpPost.categories.join is not a function,以下是输出,不懂js不会修,求助。

➜ BlogCollections hexo g && hexo s INFO Validating config INFO Start processing FATAL { err: TypeError: tmpPost.categories.join is not a function at Hexo.logic (/Users/simon/Documents/BlogCollections/node_modules/hexo-auto-category/lib/logic.js:33:55) at Hexo.tryCatcher (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/util.js:16:23) at Hexo. (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/method.js:15:34) at /Users/simon/Documents/BlogCollections/node_modules/hexo/lib/extend/filter.js:67:52 at tryCatcher (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/util.js:16:23) at Object.gotValue (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/reduce.js:166:18) at Object.gotAccum (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/reduce.js:155:25) at Object.tryCatcher (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:547:31) at Promise._settlePromise (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:604:18) at Promise._settlePromise0 (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:649:10) at Promise._settlePromises (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/promise.js:729:18) at _drainQueueStep (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:93:12) at _drainQueue (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:86:9) at Async._drainQueues (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (/Users/simon/Documents/BlogCollections/node_modules/bluebird/js/release/async.js:15:14) at processImmediate (internal/timers.js:461:21) } Something's wrong. Maybe you can find the solution here: %s https://hexo.io/docs/troubleshooting.html

我把logic.js里的tmpPost都替换成了tmpPost1,似乎可以运行,但不知道方法和效果对不对 等下,可能方法有问题。刚刚手动新建了文件夹,之前的分类都消失了,只剩下这一个。是我打开方式有问题吗Orz

xu-song commented 3 years ago

你打印 tmpPost 看看,比如

console.log("tmpPost的值是:");
console.log(tmpPost);

然后再hexo g试试?看看打印的什么日志

MebilyChen commented 3 years ago

你打印 tmpPost 看看

嗯嗯,我不太懂js,编程学得很浅,这句我不太懂啥意思(挠头)。不过我的分类数不多,现在新建了文件夹已经用起来了,挺好的。就是希望用hexo admin新建post的时候,填分类也能自动放在对应文件夹下,我现在生成的post是手动拖进去的,在hexo admin填完分类不会自动分类。 ...或者是我这边个人的问题?

xu-song commented 3 years ago

@MebilyChen hexo admin新建post的时候,填分类也能自动放在对应文件夹下

指的是 hexo new 命令吗?

目前不支持这功能

MebilyChen commented 3 years ago

hexo admin新建post的时候,填分类也能自动放在对应文件夹下

指的是 hexo new 命令吗?

目前不支持这功能

好的。就是用hexo admin插件新建post的时候,原理不太懂,可能差不多也是new的命令? QQ截图20210317152654 QQ截图20210317153037 感谢大大,辛苦了,改分类确实是大痛点

lorezyra commented 3 years ago

I'm seeing the same problem:

 $ hexo server  
INFO  Validating config
INFO  Start processing
FATAL {
  err: TypeError: tmpPost.categories.join is not a function
      at Hexo.logic (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/hexo-auto-category/lib/logic.js:33:55)
      at Hexo.tryCatcher (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/util.js:16:23)
      at Hexo.<anonymous> (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/method.js:15:34)
      at /Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/hexo/lib/extend/filter.js:67:52
      at tryCatcher (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/util.js:16:23)
      at Object.gotValue (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/reduce.js:166:18)
      at Object.gotAccum (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/reduce.js:155:25)
      at Object.tryCatcher (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/util.js:16:23)
      at Promise._settlePromiseFromHandler (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:547:31)
      at Promise._settlePromise (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:604:18)
      at Promise._settlePromise0 (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:649:10)
      at Promise._settlePromises (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:729:18)
      at _drainQueueStep (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:93:12)
      at _drainQueue (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:86:9)
      at Async._drainQueues (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:102:5)
      at Immediate.Async.drainQueues [as _onImmediate] (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:15:14)
      at processImmediate (node:internal/timers:464:21)
} Something's wrong. Maybe you can find the solution here: %s https://hexo.io/docs/troubleshooting.html

Here's my package.json config. Could I be missing any plugin?

{
  "name": "hexo-site",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "build": "hexo generate",
    "clean": "hexo clean",
    "deploy": "hexo deploy",
    "server": "hexo server"
  },
  "hexo": {
    "version": "5.4.0"
  },
  "dependencies": {
    "hexo": "^5.0.0",
    "hexo-auto-category": "^0.2.0",
    "hexo-deployer-git": "^3.0.0",
    "hexo-filter-github-emojis": "^3.0.4",
    "hexo-generator-archive": "^1.0.0",
    "hexo-generator-category": "^1.0.0",
    "hexo-generator-index": "^2.0.0",
    "hexo-generator-search": "^2.4.2",
    "hexo-generator-seo-friendly-sitemap": "^0.2.1",
    "hexo-generator-tag": "^1.0.0",
    "hexo-renderer-ejs": "^1.0.0",
    "hexo-renderer-marked": "^4.0.0",
    "hexo-renderer-stylus": "^2.0.0",
    "hexo-server": "^2.0.0",
    "hexo-tag-wikipedia": "^1.0.0",
    "hexo-theme-landscape": "^0.0.3",
    "hexo-wordcount": "^6.0.1"
  },
  "devDependencies": {
    "hexo-breadcrumb": "^1.0.2",
    "hexo-util": "^2.5.0"
  }
}
lorezyra commented 3 years ago

After adding the console output:

        var newCategories = categories.slice(1, 1 + Math.min(depth, categories.length - 2));
        // 3.2 prevents duplicate file changes
        console.log("tmpPost的值是:");
        console.log(tmpPost);
        if (tmpPost.categories && (tmpPost.categories.join("_") == newCategories.join("_"))) return data;
        tmpPost.categories = newCategories

I see the following output:

tmpPost的值是:
{
  title: 'Far far away, behind the word mountains',
  date: 2021-05-23T22:38:34.000Z,
  subtitle: 'lorem-ipsum',
  indexing: true,
  tags: [ 'lorem-ipsum', 'text generator' ],
  categories: 'fun',
  postImg: null,
  postImgAlt: null,
  postVideo: null,
  postVideoH: null,
  postVideoW: null,
  description: 'lorem-ipsum replacement text',
  comments: true,
  lang: 'en_US',
  home_posts_tag: true,
  sticky: 999,
  'header-img': '/img/header_img/lml_bg.jpg',
  _content: '\n' +
    'Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia.\n' +
    '\n' +
    'The Big Oxmox advised her not to do so, because there were thousands of bad Commas, wild Question Marks and devious Semikoli, but the Little Blind Text didn’t listen. She packed her seven versalia, put her initial into the belt and made herself on the way. When she reached the first hills of the Italic Mountains, she had a last view back on the skyline of her hometown Bookmarksgrove, the headline of Alphabet Village and the subline of her own road, the Line Lane. \n' +
    '\n' +
    'Pityful a rethoric question ran over her cheek, then she continued her way. On her way she met a copy. The copy warned the Little Blind Text, that where it came from it would have been rewritten a thousand times and everything that was left from its origin would be the word "and" and the Little Blind Text should turn around and return to its own, safe country. But nothing the copy said could convince her and so it didn’t take long until a few insidious Copy Writers ambushed her, made her drunk with Longe and Parole and dragged her into their agency, where they abused her for their projects again and again. \n' +
    'And if she hasn’t been rewritten, then they are still using her. \n' +
    '\n' +
    '*(Original author unknown)*\n' +
    '**Can be found in [text generators](https://www.blindtextgenerator.com/) for web designers**'
}
tmpPost的值是:
{
  title: 'littleBits earth day',
  comments: true,
  lang: 'en_US',
  description: '',
  toc: true,
  indexing: true,
  date: 2017-04-16T23:34:00.000Z,
  tags: [
    'migrated from twitter',
    'LittleBits',
    'Earth Day',
    'Climate Action',
    'Climate Change'
  ],
  categories: 'fun',
  postImg: null,
  postImgAlt: null,
  postVideo: null,
  postVideoH: null,
  postVideoW: null,
  _content: '## Cloud Swarm\n' +
    '{% blockquote @LoreZyra https://twitter.com/LoreZyra/status/854115881412042752 %}\n' +
    '#littleBitsearthday #climatechange #ClimateAction\n' +
    '{% endblockquote %}\n' +
    '![](C9pt3CfV0AAKhs1.jpeg)'
}

FATAL {
  err: TypeError: tmpPost.categories.join is not a function
      at Hexo.logic (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/hexo-auto-category/lib/logic.js:37:55)

So, tmpPost.categories object is definitely not null .

I'm running NodeJS

$> node -v  
v15.14.0

Any suggestions?

lorezyra commented 3 years ago

Okay, I think I see the problem...

code https://github.com/xu-song/hexo-auto-category/blob/master/lib/logic.js

I've created this debug code for logic.js to help see the problem:

'use strict';

var front = require('hexo-front-matter');
var fs = require('hexo-fs');
debugger;
let logic = function (data) {
    var log = this.log;

    if (data.layout != 'post')
        return data;
    if (!this.config.render_drafts && data.source.startsWith("_drafts/"))
        return data;

    var overwrite = true;
    if (this.config.auto_category.enable && overwrite) {
        let postStr;
        // 1. parse front matter
        var tmpPost = front.parse(data.raw);
        // 2. read old categories
        //
        // 3. generate categories from directory
        // var categories = data.slug.split('/');
        var categories = data.source.split('/');
        // 3.1 handle depth
        var depth = this.config.auto_category.depth || categories.length - 2;
        if (depth == 0) { // Uncategorized
            //tmpPost.categories = ["Uncategorized"];
            return data;
        }
        var newCategories = categories.slice(1, 1 + Math.min(depth, categories.length - 2));
        // 3.2 prevents duplicate file changes
        // console.log("tmpPost的值是:");
        // console.log(tmpPost);
        // console.log("\n\n");
        console.log("\t\t ==============================================\n title: ", tmpPost.title);
        console.log(" Date: ", tmpPost.date);
        // console.log(" categories.isArray: ", tmpPost.categories.isArray());

        /*
            - probably need to check out the front-matter across all the posts to see what's causing this join error
            - Start by removing all posts and add them back in one-by-one to find what kills this function.
            - If not the front-matter issue, then could be an issue with the join function itself. Buffer overload?
        */
        if (tmpPost.categories) {
            console.log(" tmpPost.categories(", typeof(tmpPost.categories), "): ", tmpPost.categories);
            console.log(" newCategories(", typeof(newCategories), "): ", newCategories);
            if (tmpPost.categories.join("_") == newCategories.join("_")) return data;
        } 
        tmpPost.categories = newCategories

        // 4. process post
        postStr = front.stringify(tmpPost);
        postStr = '---\n' + postStr;
        fs.writeFile(data.full_source, postStr, 'utf-8');
        log.i("Generated: categories %s for post [ %s ]", tmpPost.categories, categories[categories.length - 1]);
    }
    return data
}

module.exports = logic;

output

After moving most of my posts to another directory to make testing easier, I see this output:

 $ hexo gen
INFO  Validating config
INFO  Start processing
                 ==============================================
 title:  NikeService, Why doesn’t the app list English
 Date:  2021-02-08T06:39:00.000Z
 tmpPost.categories( string ):  work
 newCategories( object ):  [ 'work' ]
                 ==============================================
 title:  10 Questions You NEED to Ask During Your Tech Job Interview
 Date:  2018-07-22T09:42:00.000Z
 tmpPost.categories( string ):  work
 newCategories( object ):  [ 'work' ]
                 ==============================================
 title:  discover an idea so great
 Date:  2015-02-11T01:18:00.000Z
 tmpPost.categories( string ):  work
 newCategories( object ):  [ 'work' ]
FATAL {
  err: TypeError: tmpPost.categories.join is not a function
      at Hexo.logic (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/hexo-auto-category/lib/logic.js:52:36)
      at Hexo.tryCatcher (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/util.js:16:23)
      at Hexo.<anonymous> (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/method.js:15:34)
      at /Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/hexo/lib/extend/filter.js:67:52
      at tryCatcher (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/util.js:16:23)
      at Object.gotValue (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/reduce.js:166:18)
      at Object.gotAccum (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/reduce.js:155:25)
      at Object.tryCatcher (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/util.js:16:23)
      at Promise._settlePromiseFromHandler (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:547:31)
      at Promise._settlePromise (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:604:18)
      at Promise._settlePromise0 (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:649:10)
      at Promise._settlePromises (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/promise.js:729:18)
      at _drainQueueStep (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:93:12)
      at _drainQueue (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:86:9)
      at Async._drainQueues (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:102:5)
      at Immediate.Async.drainQueues [as _onImmediate] (/Users/lorezyra/Documents/blog.RichieBartlett.com/node_modules/bluebird/js/release/async.js:15:14)
      at processImmediate (node:internal/timers:464:21)
} Something's wrong. Maybe you can find the solution here: %s https://hexo.io/docs/troubleshooting.html

Conclusion

The reason we get the error err: TypeError: tmpPost.categories.join is not a function is because a string does NOT have the join() function. So, you must test for the type of tmpPost.categories before comparing with newCategories.

And... the reason tmpPost.categories is a string is because a new user of HEXO would not define their front-matter so that categories has a value or write it like this:

---
title: blank
date: 2021-05-29 01:33:18
comments:true
toc:false
tocOpen:true
indexing:false
swiper: false # 将改文章放入轮播图中
swiperImg: '/medias/1.jpg' # 该文章在轮播图中的图片,可以是本地目录下图片也可以是http://xxx图片
img: '/medias/1.jpg' # 该文章图片,可以是本地目录下图片也可以是http://xxx图片
top:false
geolocation: Japan
copyright: false
categories: 
- test
---

In this case, categories is an object.

However, I would simply write the front-matter on categories like this:

---
title: "blank"
date: 2021-05-29 01:33:18
categories: test
---

Or... like this:

---
title: "blank"
date: 2021-05-29 01:33:18
categories: 
---

This yields a STRING.

My expectation is for hexo-auto-category to fill it in for me based on the folder hierarchy.

lorezyra commented 3 years ago

Submitted https://github.com/xu-song/hexo-auto-category/pull/21

xu-song commented 3 years ago

Thanks for your contribution!

xu-song commented 3 years ago

New version has been released, you can update the package by

npm update hexo-auto-category