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

The proposal of installing theme through npm #3890

Closed
SukkaW opened this issue Nov 29, 2019 · 27 comments · Fixed by #4306 or #4360
Closed

The proposal of installing theme through npm #3890

SukkaW opened this issue Nov 29, 2019 · 27 comments · Fixed by #4306 or #4360

Comments

@SukkaW
Copy link
Member

SukkaW commented Nov 29, 2019

The original discussion is at #2471

Here is my proposal:

  1. We should not treat hexo-theme- prefixed package as a hexo plugin. See @tomap 's commit: master...tomap:feature/themeAsPackagediff-3d0f701643104f3b0e388b8f6a9a7f3eR38
  2. Users are still required to specify their theme's name in _config.yml, because...
  3. Hexo will read themes/[name] directory first, then search hexo-theme-[name] directory under node_modules. It means the theme under themes directory should have higher priority. In this way no extra theme_from_npm: true configuration is needed.
  4. theme_config in _config.yml looks good, but it is better to have a separate theme config. We could introduce _config.[name].yml. Currently, theme_config has higher priority than _config.yml under theme directories. After bring up _config.[name].yml, I suggest the theme_config in _config.yml > _config.[name].yml > _config.yml under theme directories which will retain highest priority for theme_config.
  5. Also, we need to fix the issue that some plugins can not read theme config from theme_config: Feature Request: Install theme through npm install #2471 (comment)

IMHO, we could easily bring up this feature without any Breaking Changes: the theme structure, current configurations and setup will not be affected. Yes, I mean we can even bring up this feature during Hexo 4.x development.

cc @hexojs/core @jiangtj

@SukkaW
Copy link
Member Author

SukkaW commented Nov 29, 2019

FYI:
Currently there are more than 50 packages on npm has hexo-theme- prefixed: https://www.npmjs.com/search?q=hexo-theme (Others are eslint-config-theme-next or -theme-hexo suffixed)

@stevenjoezhang
Copy link
Member

We should not treat hexo-theme- prefixed package as a hexo plugin.

Is there a good way to handle this situation?
Plugin: https://www.npmjs.com/package/hexo-theme-next-anchor
Theme: https://www.npmjs.com/package/hexo-theme-next

@SukkaW SukkaW pinned this issue Nov 29, 2019
@tomap
Copy link
Contributor

tomap commented Nov 29, 2019

We should not treat hexo-theme- prefixed package as a hexo plugin.

Is there a good way to handle this situation?
Plugin: https://www.npmjs.com/package/hexo-theme-next-anchor
Theme: https://www.npmjs.com/package/hexo-theme-next

We could contact all owners of hexo-theme-* on npm.org when they are not themes

The package hexo-theme-next-anchor is indeed a plugin.
We should suggest the owner to change it's name (21 downloads per week)

For the package hexo-theme-next, it is a theme. so, in this case, no problem

@tomap
Copy link
Contributor

tomap commented Nov 29, 2019

@SukkaW I edited your issue to add numbers for each items

for 1. indeed, that is the pre requisite
but in the list of packages on npm, as you mentioned, there are multiple packages prefixed "hexo-theme-*"
I looked at each of them, and I believe that none are plugins, except one:
https://www.npmjs.com/package/hexo-theme-next-anchor
=> not a big deal. we'll contact the owner
And we have to decide is that means waiting for Hexo 5 or a smaller 4.1 could be ok

for 2. ok

for 3. ok, but it will make the code a bit more complex because the theme_dir will be more complex to determine (not a big deal either)

for 4. ok also, but this is a bonus

for 5. this is not really a bonus, because without that, we cannot customize .less (and I believe it is probably the same for .sass

If I have time, I'll start with 3.
(I don't have a lot of time those days, but maybe...)

@jiangtj
Copy link
Member

jiangtj commented Dec 2, 2019

hexo-theme-* is treated as a theme by default, so this is not a problem, just contact the owner to modify it.
@stevenjoezhang rename hexo-theme-next-anchor to hexo-next-anchor, maybe better. Or load
all hexo-theme-next-* plugin manual.
https:/hexojs/hexo/blob/master/lib/hexo/load_plugins.js#L51

@stevenjoezhang
Copy link
Member

IMHO, distinguishing between a theme and a plugin is not complicated, you just need to determine whether a layout directory exists - it is a pity to deprecate some modules for this reason.

cc @1v9

@paulkre
Copy link

paulkre commented Dec 9, 2019

Great proposal! Would love to use this feature.

@SukkaW
Copy link
Member Author

SukkaW commented Dec 9, 2019

you just need to determine whether a layout directory exists - it is a pity to deprecate some modules for this reason.

Another idea is only to exclude hexo-theme-[config.theme] from being loaded as a plugin. But it means installing multiple themes will become impossible.

cc @stevenjoezhang @tomap @jiangtj

@tomap
Copy link
Contributor

tomap commented Dec 9, 2019

Also, we need to fix the issue that some plugins can not read theme config from theme_config: #2471 (comment)

I just retested the item 5. and it seems to work without my changes. I must have tested wrong :)

@jiangtj
Copy link
Member

jiangtj commented Dec 10, 2019

Another idea is only to exclude hexo-theme-[config.theme] from being loaded as a plugin. But it means installing multiple themes will become impossible.

This brings me to another idea. We can configure in the configuration file, which need to be excluded

@SukkaW
Copy link
Member Author

SukkaW commented Dec 10, 2019

@tomap Yeah, theme_config is supposed to be included in Locals.prototype.theme.

Locals.prototype.theme = Object.assign({}, config, theme.config, config.theme_config);

@jiangtj It would be more complex for a user to configure it.

This brings me to another idea. We can configure in the configuration file, which need to be excluded

@SukkaW
Copy link
Member Author

SukkaW commented Jan 1, 2020

#2471 (comment)

Related progress.

@SukkaW
Copy link
Member Author

SukkaW commented Jan 13, 2020

@tomap We could start by excluding hexo-theme-${config.theme} from being loading as a plugin.

@curbengh
Copy link
Contributor

Since this is already in progress, I'm unpinning this in favor of #4260.

@SukkaW
Copy link
Member Author

SukkaW commented Apr 26, 2020

#4120 (comment)

@sergeyzwezdin
Copy link

@SukkaW Maybe it's possible to release npm themes support before of Hexo 5? I'd like to have it without waiting for next release of Hexo.

@SukkaW SukkaW reopened this May 18, 2020
@SukkaW
Copy link
Member Author

SukkaW commented Jun 16, 2020

@stevenjoezhang

#4120 (comment)

Is it possible to merge config.theme_config into theme.config after ctx.theme loads?

The ctx.theme.config is loaded through this.theme.process():

hexo/lib/hexo/index.js

Lines 306 to 309 in edef5c2

return Promise.all([
this.source.process(),
this.theme.process()
]);

See: https:/hexojs/hexo/blob/master/lib/theme/index.js ,

return file.render().then(result => {
file.box.config = result;
this.log.debug('Theme config loaded.');
}).catch(err => {

That's right before this._generate() (Before posts are rendered, before this.generateLocals() began to build locals).

@stevenjoezhang
Copy link
Member

When executing hexo clean, customThemeName here is always the default value landscape

// Ignore plugin whose name is "hexo-theme-[ctx.config.theme]"
if (name === `hexo-theme-${customThemeName}`) return false;

This will cause Hexo to load all themes except landscape as plugins.

See also next-theme/hexo-theme-next#65

CC @hexojs/core

@SukkaW
Copy link
Member Author

SukkaW commented Jul 29, 2020

@stevenjoezhang

This will cause Hexo to load all themes except landscape as plugins.

Might be related with #4386.

@jiangtj
Copy link
Member

jiangtj commented Aug 3, 2020

How about load the plugins in theme's dependencies?

See my theme. I have add those needed dependencies.
https:/jiangtj/hexo-theme-cake/blob/91036aa12be4a577705b990252367a93ea089b18/package.json#L47-L50

These plugins are required, but user muse install them in their blog project

Here is a my solution, but I think it’s best done in hexo, do you think?
https:/jiangtj/hexo-theme-cake/blob/91036aa12be4a577705b990252367a93ea089b18/lib/load.js#L24-L27
https:/jiangtj/hexo-theme-cake/blob/91036aa12be4a577705b990252367a93ea089b18/lib/utils.js#L34-L40

@SukkaW
Copy link
Member Author

SukkaW commented Aug 3, 2020

@jiangtj

By default npm i hexo-theme-[theme's name] should install those dependencies and theme could access them.

So what you need is to make the theme loading required hexo's plugin, right?

My thought is to include those plugins inside dependencies so the npm i will be able to install them as well. We could also introduces a new entry to package.json, which will tell hexo plugins to be loaded.

@jiangtj
Copy link
Member

jiangtj commented Aug 3, 2020

So what you need is to make the theme loading required hexo's plugin, right?

My thought is to include those plugins inside dependencies so the npm i will be able to install them as well. We could also introduces a new entry to package.json, which will tell hexo plugins to be loaded.

Yesh

@noraj
Copy link
Contributor

noraj commented Jan 13, 2021

What about these kind of issues :

Because with a npm module you don't want to change any of node_modules/theme/ files. So have you an idea for file override other than for _config.yml with Alternate Theme Config.

@FossPrime
Copy link

FossPrime commented Jun 26, 2021

What about these kind of issues :

Because with a npm module you don't want to change any of node_modules/theme/ files. So have you an idea for file override other than for _config.yml with Alternate Theme Config.

Hindsight is 2020. We could have refused to automatically merge arrays, too late.

Ideas:

  • $diff/Opt-out/filter config that allows filtering elements out of arrays
  • Use intermediary config that allows hard resetting.
  • We could allow changing the merge strategy to "simple".
  • we could add a schema and theme version to the config, which would determine how we migrate it to the latest version in steps.
  • we could allow object values on strings to define special behavior like { $enabled: false, $value: "cloud" }

@tomap
Copy link
Contributor

tomap commented Jun 26, 2021

Tu change color, you can rely on variables that go from config to css. I did that in my theme with stylus

https:/tomap/hexo-theme-minidyne/blob/9bcd4e4e9b07d14db456978c7d5d12876380a132/source/css/style.styl#L3

Declare a variable with proper name and boom

@FossPrime
Copy link

FossPrime commented Jun 26, 2021

@tomap ... check the title... what we're trying to do with Hexo 5 is configure the theme, not modify it's internals with no restrictions and breaking all hope of upgradeability. We only have the ability to modify the theme using predefined endpoints, like _confgi.landscape.yml.

Case study of a mid sized mod to the landscape theme: vblip.com

  • I needed to modify 2 top level objects in _config.yml
  • overriding rss is confusing... I can do it, but it contradicts the idea that the theme config takes presence.
  • I had to modify quite a few styles. There is an _extend file in the theme, but that's internal and full of values. I ended up practically forking 4 style sheets for the nav bar and some articles. I wouldn't have had to do that if an _extend.scss file was exposed to me. A few user customizable style options like hide_date on pages would have been nice, but probably unnecessary.
  • lastly, there is very little JavaScript, which is good, but it runs in a very old school manner. Given all evergreen browsers support modules, having the nav bar code be in one exported function and giving users a 3 line JavaScript file we could override would be nice.

@stevenjoezhang
Copy link
Member

Sorry for the late reply. Modifying the layout and styles with Hexo can be difficult because different themes use different template engines and have different code styles. Hexo provides an injector that allows you to insert HTML code at specific locations, but for more precise customization, the theme needs to provide relevant interfaces. Here are my suggestions:

  1. You can try using the plugin https:/jiangtj/hexo-extend-theme, which allows you to replace any file in the theme.

  2. You can fork the theme and use it. In fact, themes like "landscape" are not updated frequently, so you can easily follow the upstream updates.

I will close this issue because the main problem has been resolved. If you have any new questions, please feel free to open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants