hexo
hexo copied to clipboard
"before_post_render", "after_post_render" executed on non-article page
Check List
Please check followings before submitting a new issue.
- [x] I have already read Docs page & Troubleshooting page
- [x] I have already searched existing issues and they are not help to me
- [x] I examined error or warning messages and it's difficult to solve
- [x] Using the latest version of Hexo (run
hexo version
to check) - [x] Node.js is higher than minimum required version
Expected behavior
before_post_render
and after_post_render
should only executed on posts and pages.
Actual behavior
Non-article files (like css) being processed by before_post_render
& after_post_render
well.
Is the problem still there under "Safe mode"?
Yes.
Other Information
Add following content to scripts/test.js
:
hexo.on('generateBefore', () => {
hexo.model('Page').toArray().forEach(i => console.log(i.path));
})
And non-article paths will show up.
https://github.com/hexojs/site/pull/1506
cc @curbengh
See also https://github.com/hexojs/hexo/issues/1591 https://github.com/hexojs/hexo/issues/2675
A possible reason is that all the js and css files in the source folder are judged as pages https://github.com/hexojs/hexo/blob/6437ff51869faf1add5cbb1f5411586b61a93fbf/lib/plugins/processor/asset.js#L118-L124
Interesting:
$ hexo list page
The list
command is also affected.
https://github.com/hexojs/hexo/blob/b7d15b95cb7e48b855f9d4c72bc24078b7b7a505/lib/plugins/processor/asset.js#L114-L120
renderable is defined in the pattern, maybe we can add some default value for skip_render
maybe we can add some default value for skip_render
Tested working. I add a test css in source/css/test.css
.
skip_render:
- '**.css'
// should not show css
hexo.on('generateBefore', () => {
hexo.model('Page').toArray().forEach(i => console.log(i.path));
})
hexo.extend.filter.register('before_post_render', function(data){
if (data.source.endsWith('.md') === false) console.log(data.content.substring(0, 50))
return data;
});
hexo.extend.filter.register('after_post_render', function(data){
if (data.source.endsWith('.md') === false) console.log(data.content.substring(0, 50))
return data;
});
after_render:css
still works:
// should show css
hexo.extend.filter.register('after_render:css', function(str, data){
console.log(str.substring(0, 50))
console.log(data.path)
return str
});
This approach is not practical, every non-post patterns (**.js
, **.css
, **.styl
, etc) have to be added. Another approach is to include _posts/**
only.
https://github.com/hexojs/hexo/blob/b7d15b95cb7e48b855f9d4c72bc24078b7b7a505/lib/hexo/post.js#L245-L249
I tried:
return promise.then(content => {
data.content = content;
// Run "before_post_render" filters
if (data.source && data.source.startsWith('_posts/')) return ctx.execFilter('before_post_render', data, { context: ctx });
return
}).then(() => {
Then I realised backtick_code_block.js is a before_post_render
filter, so if I use that workaround, "backtick_code_block.js" wouldn't execute on page (files outside of "posts/" folder).
To ensure "backtick_code_block.js" still works, we may need a new filter "before_render".
hexo.post.render(source, data);
Looking at the docs, I notice source
is optional, so it seems before/after_post_render was never designed to be limited to _posts/
folder only. If that's the case, we can mention in the docs (https://github.com/hexojs/site/pull/1506).
This issue has been automatically marked as stale because lack of recent activity. It will be closed if no further activity occurs. Thank you for your contributions.