Closed SineObama closed 5 months ago
related PR: #5119
https://github.com/hexojs/hexo/blob/ea4f63cd2a7a6712acb8a15fc36692d8ef52a64b/lib/hexo/index.ts#L299
I guess I can run this code once by myself to solve the problem for now.
I tried to run this code in after_post_render
filter and it works. Should I use some other methods?
Does it need to be discussed whether this is a problem?
Here is my solution code, but I'm not entirely know how it works. When I use only the after_post_render
filter, it ran into the problem again at the second generation.
hexo.extend.filter.register('after_post_render', filterSiteTag);
hexo.locals.set('tags', reloadTag);
let _filterSiteTagOnce = false;
function filterSiteTag(data) {
if (!_filterSiteTagOnce) {
_filterSiteTagOnce = true;
this.locals.set('tags', reloadTag);
}
return data;
}
function reloadTag() {
const logger = hexo.log;
// Ignore tags with zero posts
const model = hexo.database.model('Tag');
const filtered = model.filter(tag => tag.length);
logger.info('Tag size: ' + model.length + ' -> ' + filtered.length);
return filtered;
}
I've run into a similar problem when I tried to remove posts dynamically in filters.
Here's some code to demonstrate it:
// FILE: scripts/test.js
hexo.extend.filter.register("before_generate", function () {
this._bindLocals();
// Delete the "hello-world" post which has the "removed" tag.
const posts = this.locals.get("posts");
this.locals.set("posts", posts.filter((post) => post.slug !== "hello-world"));
// The "removed" tag should contain zero posts now, since there is no post tagged with "removed".
const tags = this.locals.get("tags");
const removedTag = tags.findOne({ name: "removed" });
// The behavior in Hexo 7.0:
console.log(removedTag.length); // 1
// Which equals to:
console.log(this.database.model('PostTag').find({ tag_id: removedTag._id }).length); // 1
// The behavior in Hexo 6.3:
console.log(removedTag.posts.length); // 0
// To workaround it, undoing the change introduced in #5119 could help:
// this.locals.set("tags", () => {
// return this.database.model("Tag").filter((tag) => {
// return tag.posts.length;
// });
// });
});
I would like to know if this is working as intended or not. Should we use some other methods to manipulate posts/tags/categories in filters?
I guess 5119 is necessary, it does reduce traversal. Maybe hexo needs a better way to deal with idle tags and categories. For example, when the number of articles in a label or category become 0, delete them. Or, filter labels or categories when they no longer change.
Or, announce to users that if they want to use accurate tags and categories list, they should filter the list.
However, revert is a temporary solution, too.
Check List
hexo version
to check)Expected behavior
I need to change the posts' tags with my own filter. I find out the
setTags
method when using hexo 6.3.0 and it always works before I upgrade to hexo 7.0.This is an example code:
In this case, some of the tags are removed completely from my website. I expect those tags to disappear.
I test this problem in my repo branch.
Actual behavior
The tag list remain the removed tags and I can not jump into the tag's page(the page was not generated).
How to reproduce?
simply a post with tag and run with the example filter code above (using the
setTags
method to remove tag(s) in before_post_render filter).Is the problem still there under
Safe mode
?this is a plugin usage problem, and I disabled my theme and my other plugins, I just using the example code, the problem still there.
Your Node.js & npm version
Your Hexo and Plugin version
Your
package.json
Others
No response