-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Allow theme = ["base", "my-theme" ] (aka theme composition and inheritance) #4460
Comments
Note that this is a "proposal", I'm not done with my part of the thinking here -- maybe this belongs in the theme itself etc... |
One thing I see on the forum a lot is, "how can I make page X look different from the rest of the site". Could this facilitate styling a page like that, kind of overriding the theme applied to most of the site? |
From @bep's description, yes it does. You could for example have your own version of single.html or of a shortcode. I can see how this is useful. It's the same mechanic that Wordpress uses in creating 'child-themes', but I am not a fan. I remember losing track of whether I was editing the right files. It's a personal perspective. Others will make it useful and may help produce more themes for Hugo. I don't have the knowledge to comment on the implementation. So I will abstain from voting and may even end up using it anyway. |
+1 if I can have my personal "theme" of partial and shortcode collection, and can keep that theme as the secondary theme. Thinking of something like:
I've wanted this feature for a while. I had tried symlinking my commonly used partials/shortcodes from a common git repo, but symlinks don't work. |
@kaushalmodi +1 for that. That's a cool idea. |
Child themes are a great idea. In theory a feature like this should make it easier to get started with Hugo for beginners. And they probably also make it a lot easier for people to update the original, parent theme. |
@RickCogley not sure about your example, but @kaushalmodi 's example is a primary use case, and I think this becomes super-powerful when we get proper dependency management, i.e: theme = ["https://github.com/spf13/hyde/v2", "https://github.com/kaushalmodi/shortcode-pack/v1" ] When Russ Cox is done with his brilliant thinking, I'm going to steal his thoughts: https://research.swtch.com/vgo To me, this is mostly about DRY. On the project side, we can already today extend the theme by adding a Thinking about it, I think I will try to get this to work both on theme and in project level (themable themes). So in # This theme is based on SPF13's port of Hyde, but with prettier colours.
theme = ["hyde"] And then in my theme = ["hyde32", "partial-shortcode-collection-theme"] The ordered set of file collections will then be: hyde, hyde32, partial-shortcode-collection-theme This may be too complex if the graph gets too big. Will think. In its first iteration, the end user is responsible for pulling the above 3 themes into /themes -- but the ultimate goal here is to do: # Shallow clone, no themes (only referenced in config.toml)
git clone https://github.com/bep/my-site
cd my-site
# hugo will download dependencies if not cached.
hugo |
I think it will be very useful. One use case coming to mind is with output formats. If you want to add an "api" (json output) layer to your content, all you'd have to do is add a special "api" theme and reference it. Rather than singlehandedly adding the json templates in your layouts/_default or other. |
Also it will allow theme developer to release several "extension" for their theme which not everyone will need. Like a "photo gallery" extension or a "Dentist" extension for a theme whose base is made for broader "health" structure. |
This would be very useful. My use case is similar to @kaushalmodi in that I keep a set of really basic files (_default layouts, etc.) to reuse on all projects and then layouts/themes for specific types of projects on top of that. |
A development tip: Features like this are hard to get going unless you have a solid and failing test up and running: const (
themeStandalone = `
name = "Theme Standalone"
`
themeCyclic = `
name = "Theme Cyclic"
theme = "theme3"
`
theme1 = `
name = "Theme #1"
`
theme2 = `
name = "Theme #2"
theme = "theme1"
`
theme3 = `
name = "Theme #3"
theme = ["theme2", "themeStandalone", "themeCyclic"]
`
theme4 = `
name = "Theme #4"
theme = "theme3"
`
site1 = `
theme = "theme4"
`
site2 = `
theme = ["theme2", "themeStandalone"]
`
) With a test that fails to build |
On more use case is "shortcode" bundles. Your theme layout files would only contains shortcode files and people could use them by just adding your theme to their "theme set" and easily upgrade with future updates. I am not very intelligible when excited. Just saw @kaushalmodi's comment above :/ |
I just figured out that this would also be really cool for bundling of shortcodes! :-) |
Or bundling of output formats templates ! 🎉 So much possibilities! |
Yep, all those things that we copy from theme to theme, often without changing a single line. Shortcodes, output formats. Heck even "base" for many. Note if it makes dealing with static asset customization (like a site font file or landing image |
Just a quick note that this is still pretty much priority. In Hugo 0.38 themes got |
I've been thinking of it as everything is a set of one or more templates that operate on your content following a "theme". It could be visual layout, or shortcodes, or an output format, or all of those. So if we explain how we use "theme", it should be fairly straightforward. I've read this conversation in a lot of projects over the years (naming and "theme"), and it is recurring issue that new users will likely know about themes solely via a PHP CMS. So they have to explain it a bit more. And we kinda have to explain everything a bit more with Hugo, it seems; a lot of folks don't quite grok the simplicity of a "template + content" workflow. ^_^ |
Just a little heads up to people waiting for this: I'm very close to finishing implementing this now. To get this done, I had to refactor and get real control of all the theme related filesystem handling. With this issue closed, we will have a fully virtualized filesystem interaction without all the path logic sprinkled around. And it seems to make Hugo faster, at least for sites with themes. The hugo docs builds about 15% faster on my MacBook. |
This commit adds support for theme composition and inheritance in Hugo. With this, it helps thinking about a theme as a set of ordered components: ```toml theme = ["my-shortcodes", "base-theme", "hyde"] ``` The theme definition example above in `config.toml` creates a theme with the 3 components with presedence from left to right. So, Hugo will, for any given file, data entry etc., look first in the project, and then in `my-shortcode`, `base-theme` and lastly `hyde`. Hugo uses two different algorithms to merge the filesystems, depending on the file type: * For `i18n` and `data` files, Hugo merges deeply using the translation id and data key inside the files. * For `static`, `layouts` (templates) and `archetypes` files, these are merged on file level. So the left-most file will be chosen. The name used in the `theme` definition above must match a folder in `/your-site/themes`, e.g. `/your-site/themes/my-shortcodes`. There are plans to improve on this and get a URL scheme so this can be resolved automatically. Also note that a component that is part of a theme can have its own configuration file, e.g. `config.toml`. There are currently some restrictions to what a theme component can configure: * `params` (global and per language) * `menu` (global and per language) * `outputformats` and `mediatypes` The same rules apply here: The left-most param/menu etc. with the same ID will win. There are some hidden and experimental namespace support in the above, which we will work to improve in the future, but theme authors are encouraged to create their own namespaces to avoid naming conflicts. A final note: Themes/components can also have a `theme` definition in their `config.toml` and similar, which is the "inheritance" part of this commit's title. This is currently not supported by the Hugo theme site. We will have to wait for some "auto dependency" feature to be implemented for that to happen, but this can be a powerful feature if you want to create your own theme-variant based on others. Fixes gohugoio#4460 Fixes gohugoio#4450
#2639 cross-linking for reference |
Is there any tutorial on how to use this function? I'm trying to use specific theme (hugo-resume) for 'about' page and common theme (AllinOne) for others. Will this function works for this situation? I've tried this method to use two themes. But the structure is different and results in the wrong 'about' page. |
The first homonymous template/data/i18n match will overwrite the later. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
I know this has been requested before, in the form of some
extends = some-other-theme
.This isn't "theme inheritance" in its purest form (which would be "theme1 extends theme2 extends theme3"), more like theme composition. Which is much simpler to understand/implement, but with most of the added benefits.
This relates to my work on https://github.com/bep/html5up-to-hugo -- which, with the current Hugo, becomes less elegant than it could be.
The simple rule is that the themes' files will form a big overlay/union file system from left to right.
So:
base
will be used unless there is a file with the same name inmy-theme
.What do you say?
The text was updated successfully, but these errors were encountered: