hexojs / hexo

A fast, simple & powerful blog framework, powered by Node.js.
https://hexo.io
MIT License
39.55k stars 4.86k forks source link

Any official way to insert HTML codes once per file? #3086

Closed xiazeyu closed 4 years ago

xiazeyu commented 6 years ago

Environment Info

Node version(node -v): v9.7.1

Hexo and Plugin version(npm ls --depth 0): hexo@3.6.0

For feature request

Our plugin wants to inject some HTML codes into every pages once:

<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/shizuku.model.json"}});</script></body>

Our current code is to use hexo.extend.filter.register('after_render:html', (str, data) and (/<\/body>/gi.test(htmlContent)) or s.replace(/<\/head>/, tag + '</head>') to inject it into HTML: https://github.com/MoePlayer/hexo-tag-dplayer/blob/master/index.js#L64 https://github.com/EYHN/hexo-helper-live2d/blob/master/index.js#L188

We are discussing whether it is the hacking way, or it is just the correct way.

We need to test the content for <body> because the filter will offer all the files(including all kings of HTML fragment), if we don't test for it, all the fragment will be insert a code, and the finally page will be like:(eg. index.html)

<html>
<head>
<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/shizuku.model.json"}});</script></body>
</head>
<body>
<div class=sidebar>
<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/shizuku.model.json"}});</script></body>
</div>
<div class=footer>
<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/shizuku.model.json"}});</script></body>
</div>
<script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/shizuku.model.json"}});</script></body>
</body>
</html>

We just want it be added once, but I'm not sure even (/<\/body>/gi.test(htmlContent)) can promise it.

Is there any API or ways to make it directly?

Related: https://github.com/MoePlayer/hexo-tag-dplayer/pull/18#issuecomment-375838451

xiazeyu commented 6 years ago

I found a plugin: hexo-inject, but it is now deprecated, and not workable.

SukkaW commented 4 years ago

The current way you did in your plugin (by registering a filter) is the right way.

Although I know you want to insert custom code in the page, I don't know what you want this feature to be: A filter that replace <!-- hexo_inject_[id] --> to custom HTML element? Or a helper that output configured custom code?

tomap commented 4 years ago

Why not do it in your theme's code directly?

SukkaW commented 4 years ago

@tomap

For plugins (like player) require third-party library, there is no better way to insert custom HTML element.

Themes can not handle this as well. For my own theme, I have to write custom HTML inside _config.yml; and for NexT theme, it requires manually add a head.swig to be placed under /source/_data/ directory.

I wonder if Hexo could provide a API to do this (by utilizing filter).