Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin issue: Tags removed by setTags in before_post_render filter still exists in the tag list but the page is not generated #5380

Closed
5 tasks done
SineObama opened this issue Dec 10, 2023 · 4 comments · Fixed by #5388
Labels
bug Something isn't working

Comments

@SineObama
Copy link

SineObama commented Dec 10, 2023

Check List

  • I have already read Docs page & Troubleshooting page.
  • I have already searched existing issues and they are not help to me.
  • I examined error or warning messages and it's difficult to solve.
  • I am using the latest version of Hexo. (run hexo version to check)
  • My Node.js is matched the required version.

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:

hexo.extend.filter.register('before_post_render', function (data) {
    if (!data.tags || !data.categories) {
        return data;
    }

    data.setTags([]);

    return data;
});

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

v18.18.0
10.2.4

Your Hexo and Plugin version

hexo-site@0.0.0 D:\workspace\hexoProject\blog
+-- hexo-filter-nofollow@2.0.2
+-- hexo-generator-archive@2.0.0
+-- hexo-generator-category@2.0.0
+-- hexo-generator-feed@3.0.0
+-- hexo-generator-index@3.0.0
+-- hexo-generator-search@2.4.3
+-- hexo-generator-sitemap@3.0.1
+-- hexo-generator-tag@2.0.0
+-- hexo-renderer-ejs@2.0.0
+-- hexo-renderer-marked@6.2.0
+-- hexo-renderer-pug@3.0.0
+-- hexo-renderer-stylus@3.0.0
+-- hexo-server@3.0.0
+-- hexo-theme-butterfly@4.11.0
+-- hexo-theme-landscape@1.0.0
+-- hexo-wordcount@6.0.1
`-- hexo@7.0.0

Your package.json

{
  "name": "hexo-site",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "build": "hexo generate",
    "clean": "hexo clean",
    "deploy": "hexo deploy",
    "server": "hexo server"
  },
  "hexo": {
    "version": "7.0.0"
  },
  "dependencies": {
    "hexo": "^7.0.0",
    "hexo-filter-nofollow": "^2.0.2",
    "hexo-generator-archive": "^2.0.0",
    "hexo-generator-category": "^2.0.0",
    "hexo-generator-feed": "^3.0.0",
    "hexo-generator-index": "^3.0.0",
    "hexo-generator-search": "^2.4.3",
    "hexo-generator-sitemap": "^3.0.1",
    "hexo-generator-tag": "^2.0.0",
    "hexo-renderer-ejs": "^2.0.0",
    "hexo-renderer-marked": "^6.2.0",
    "hexo-renderer-pug": "^3.0.0",
    "hexo-renderer-stylus": "^3.0.0",
    "hexo-server": "^3.0.0",
    "hexo-theme-butterfly": "^4.11.0",
    "hexo-theme-landscape": "^1.0.0",
    "hexo-wordcount": "^6.0.1"
  }
}

Others

No response

@D-Sketon
Copy link
Member

D-Sketon commented Dec 10, 2023

related PR: #5119

locals.set('tags', () => db.model('Tag'));

hexo/lib/hexo/index.js

Lines 208 to 212 in ca51e15

locals.set('tags', () => {
// Ignore tags with zero posts
return db.model('Tag').filter(tag => tag.length);
});

@SineObama
Copy link
Author

SineObama commented Dec 10, 2023

related PR: #5119

locals.set('tags', () => db.model('Tag'));

hexo/lib/hexo/index.js

Lines 208 to 212 in ca51e15

locals.set('tags', () => {
// Ignore tags with zero posts
return db.model('Tag').filter(tag => tag.length);
});

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;
}

@prinsss
Copy link

prinsss commented Dec 16, 2023

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?

@uiolee uiolee added the bug Something isn't working label Dec 28, 2023
@uiolee
Copy link
Member

uiolee commented Dec 28, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants