I think this would be a good feature to give proper version control for themes.
Plugins can be installed into node_modules through npm install, but there are issues with installing themes this way, e.g. the need to modify the _config.yml and potentially other files from within the theme.
💡 Perhaps one way to handle this simply treat the files in themes\[my-theme] as overrides to the original theme.
Thoughts?
I think it is good idea.
Great! So now I am thinking about the workflow to install and config a theme:
$ npm install --save hexo-theme-landscape
_config.yml to themes\hexo-theme-landscape for override. Here are some possible options for naming the command:$ hexo theme hexo-theme-landscape
$ hexo extend-theme hexo-theme-landscape
$ hexo config-theme hexo-theme-landscape
themes\hexo-theme-landscape$ npm install --save hexo-theme-landscape@latest
❔ Should we copy all files from the theme or is the _config.yml enough?
Opinions welcomed!
I was also thinking about the need to create a command to install a theme.
If we just keep the current workflow, we would do:
If you want to go in the direction of transforming themes into npm modules, then you would need to treat themes as imputables, and copy the whole theme configuration into the main _config.yml
I'm not sure I like that idea, because I spent a lot of fun time tweaking my theme, and making it immutable would just remove all the fun, but it could probably be an alternative source of theme.
The "install theme" command could handle that, and hexo should also be able to handle that, giving priority to the theme in themes/,
And then looking into node_modules/hexo_theme_
If you want to go in the direction of transforming themes into npm modules, then you would need to treat themes as imputables, and copy the whole theme configuration into the main _config.yml
I'm not sure I like that idea, because I spent a lot of fun time tweaking my theme, and making it immutable would just remove all the fun, but it could probably be an alternative source of theme.
Agree, theme should be configurable and easily modified.
I do like the idea hexo theme hexojs/hexo-theme-landscape as an alias of git clone https://github.com/hexojs/hexo-theme-landscape themes/landscape.
https://github.com/adamsiwiec/hexagon has implemented that, perhaps we can port it to hexo-cli.
I just finished a prototype of themes as npm packages!
It was fairly easy, but I learned lots of things on the way
I did that with my personal site and my theme :)
Here is the result:
https://github.com/hexojs/hexo/compare/master...tomap:feature/themeAsPackage
(I screwed the indentation on the way. will fix that before releasing :) )
Here is an summary:
First you need to exclude hexo-theme-xxx from the plugin list otherwise they will be loaded (and fail)
Fortunately, for now, there does not seem to be any collision between plugin names and themes
https://github.com/hexojs/site/blob/master/source/_data/plugins.yml
however, there are already a few themes on npm:
https://www.npmjs.com/search?q=hexo-theme-
(not sure why!)
Them I introduced a variable called themeFromNpm, which will change the theme folder from /themes/*theme_name* to /node_modules/hexo_theme_*theme_name*
Then you must move your "personal" configuration from the theme's config.yml but that part is easy because hexo already support that using theme_config in the main config.yml
Then you must transform your theme into an npm package:
https://github.com/tomap/hexo-theme-minidyne/pull/4/files#diff-b9cfc7f2cdf78a7f4b91a753d10865a2R1
(you only need to add a package.json, I'll describe the rest of the changes below)
Then, as your theme cam be considered "non editable", you need to convert the "static" colors from the style files and move them to the configuration.
In my case, I'm using Stylus, and hexo-renderer-stylus supports parameters.
They were super poorly documented, but supported :)
So, in your stylus, you can replace:
$main-color: #FAFAFA
with:
$main-color = convert(hexo-config("main-color"))
And you need to add to your theme's configuration:
main-color: "#FAFAFA"
(I will do a PR to improve documentation)
Then the issue is that hexo-renderer-stylus does not use either the theme's config.yml or the main config.yml theme_config. So I had to change the hexo-renderer-stylus. see here:
https://github.com/hexojs/hexo-renderer-stylus/compare/master...tomap:feature/theme_config
I am not fully satisfied with this fix.
I think hexo should expose a synthetic variable including the overload by theme_config so that each renderer does not have to do the job
The last comment I have is that I'm also not fully satisfied with the variable themeFromNpm
I am wondering if hexo could not detect the presence of a theme as npm package, and select it automatically if the name matches with the configuration (with preference for the old folder first)
I'm super satisfied with this new way of installing themes.
@hexojs/core please tell me what you think !
@tomap Hexo considered all hexo- prefixed packages in packages.json as a hexo plugin, thus will cause hexo to fail.
The first thing for us have to do is to exclude hexo-theme when loading plugins. For users, hexo's _config.yml support something like ../node_modules/meteor-theme-hexo to load theme from node_modules.
In order to simplify the config, we could first load theme from themes directory, then search for hexo-theme-[name] under node_modules, so we don't need have themeFromNpm. For them config, I still have no better idea than theme_config. Maybe _config.[theme-name].yml could be used.
In order to simplify the config, we could first load theme from
themesdirectory, then search forhexo-theme-[name]undernode_modules, so we don't need havethemeFromNpm. For them config, I still have no better idea thantheme_config. Maybe_config.[theme-name].ymlcould be used.
@SukkaW theme_config is cool.
The issue is that when a plugin does this.theme.config (like hexo-renderer-stylus), he only gets the config from the theme's config.yml instead of the overload if available from theme_config
@tomap Hexo considered all
hexo-prefixed packages inpackages.jsonas a hexo plugin, thus will cause hexo to fail.The first thing for us have to do is to exclude
hexo-themewhen loading plugins. For users, hexo's_config.ymlsupport something like../node_modules/meteor-theme-hexoto load theme fromnode_modules.
I don't know if you've seen, but I fixed this issue here:
https://github.com/hexojs/hexo/compare/master...tomap:feature/themeAsPackage#diff-3d0f701643104f3b0e388b8f6a9a7f3eR38
if plugin name == hexo-theme-... then this is not a plugin
But indeed, we could change the theme names to something like you propose or theme-hexo-*
The thing is that most of the themes are currently named hexo-theme-*
So I prefer to preserve this convention, and add an exclusion in the loadModuleList function
BTW, the result is here:
https://github.com/tomap/tpi2.eu/pull/17/commits/a3e7f72fe3ed5fe9a32245a805896acde625404c
(netlify demo works :) )
@NoahDragon @curbengh ?
Maybe refer to vuepress‘s theme-inheritance, looking forward to this feature implementation.
This is already in progress. Please join the discussion here https://github.com/hexojs/hexo/issues/3890 :)
Most helpful comment
I just finished a prototype of themes as npm packages!
It was fairly easy, but I learned lots of things on the way
I did that with my personal site and my theme :)
Here is the result:
https://github.com/hexojs/hexo/compare/master...tomap:feature/themeAsPackage
(I screwed the indentation on the way. will fix that before releasing :) )
Here is an summary:
First you need to exclude hexo-theme-xxx from the plugin list otherwise they will be loaded (and fail)
Fortunately, for now, there does not seem to be any collision between plugin names and themes
https://github.com/hexojs/site/blob/master/source/_data/plugins.yml
however, there are already a few themes on npm:
https://www.npmjs.com/search?q=hexo-theme-
(not sure why!)
Them I introduced a variable called
themeFromNpm, which will change the theme folder from/themes/*theme_name*to/node_modules/hexo_theme_*theme_name*Then you must move your "personal" configuration from the theme's
config.ymlbut that part is easy because hexo already support that using theme_config in the mainconfig.ymlThen you must transform your theme into an npm package:
https://github.com/tomap/hexo-theme-minidyne/pull/4/files#diff-b9cfc7f2cdf78a7f4b91a753d10865a2R1
(you only need to add a package.json, I'll describe the rest of the changes below)
Then, as your theme cam be considered "non editable", you need to convert the "static" colors from the style files and move them to the configuration.
In my case, I'm using Stylus, and hexo-renderer-stylus supports parameters.
They were super poorly documented, but supported :)
So, in your stylus, you can replace:
with:
And you need to add to your theme's configuration:
(I will do a PR to improve documentation)
Then the issue is that hexo-renderer-stylus does not use either the theme's
config.ymlor the mainconfig.ymltheme_config. So I had to change the hexo-renderer-stylus. see here:https://github.com/hexojs/hexo-renderer-stylus/compare/master...tomap:feature/theme_config
I am not fully satisfied with this fix.
I think hexo should expose a synthetic variable including the overload by theme_config so that each renderer does not have to do the job
The last comment I have is that I'm also not fully satisfied with the variable
themeFromNpmI am wondering if hexo could not detect the presence of a theme as npm package, and select it automatically if the name matches with the configuration (with preference for the old folder first)
I'm super satisfied with this new way of installing themes.
@hexojs/core please tell me what you think !