-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
Add a widget mechanism to Hugo #3412
Conversation
Please pull this project to see widgets in action. |
The CI builds are failing. |
f0ed2c7
to
7eb857e
Compare
Ok I changed the commit, now the tests should succeed. Now I have not updated the code to fit the last modifications in |
f795a5a
to
17533d0
Compare
@bep Tests pass on my environment but I cannot manage to pass the CI and Appveyor tests. What would you advise me? Thanks! |
It does not compile. You should fix that. |
Here is a first attempt to get widgets into Hugo. General tests are ok on my dev environment, but I have not already written tests for widgets. 1. Create a site 2. Create a widget directory inside `/widgets`. It should look like this: ``` widgets/ └── text ├── layouts │ └── widget.html └── README.md ``` Note that the name `widget.html` is mandatory. *Currently the context is the content of the config parameter `widgets.[mywidgetarea].[mywidget].options`*. Variables are accessible with `.content` for a text widget like the following and as described in the config below. ``` {{- if isset . "content" -}} {{- .content | safeHTML -}} {{- else -}}<pre>Here is a text widget, but there is nothing to print. Please define options.content inside every text widget in your config.</pre> {{- end -}} ``` 3. Configure your site with a `widgets` variable describing widgets inside widget areas: ``` widgets: sidebar: - type: text options: content: "<h1>IT WORKS from config</h1>" parser: html showcase: - type: text options: content: "Here lies a showcase." footer: - type: text options: content: "Powered by Hugo with widgets." foo: bar ``` 4. Create a template using the `widgets` call. This can be done like this: `{{ widgets "sidebar" . }}`. 5. Create content. You can also use the widget's shortcode: `{{% widgets "showcase" %}}` 6. Build and enjoy. - Currently the widgets' context is only the content of the config variable. We should add a wider context (easy). - I have not studied the impact on performances. - Else? Fixes gohugoio#2683 See gohugoio#2535
At last this works! It seemed capricious since it builded on my environment. |
Interesting addition to Hugo! But would using |
@Jos512 is right. Using |
Absolutely. Thank you for your comment. What would you propose?
You may define whatever you want and the widget may need an arbitrary |
Perhaps Prefixing Since we already have both a I do agree that "content" is the best word to describe the body of a widget, but am just thinking aloud here about how to make it as clear as possible that it's the content of the widget, and not the content of the page itself.
Is the
Instead of:
If this isn't the goal, I'm a bit confused why |
Thank you @Jos512! This is most interesting.
In that way, you can give each widget an ID (which we can display inside the HTML), and we get all configuration options in that.
What do you think of this design? If it is OK I will modify the code to allow testing with these design choices. |
So I modified the source to take your remarks into account. The context inside widget templates is now:
In particular, you can access
Please note that widgets still have to be declared this way:
I will modify this behaviour later. |
The context inside widget templates is now: - `.` can access all classical site variables (normally including `.Content` and so on). `.Content` refers to the actual page content content. - `.Widget` is defined as follows: ``` type Widget struct { Type string Params map[string]interface{} Identifier string Weight int Template *template.Template } ``` In particular, you can access `.Widget.Type` (name of widget type) and `.Widget.Params` (config parameters). - `.WidgetArea` contains the widget collection in the current widget area. - `.Site.Widgets` contains the collection of all widget areas.
How is this different from #2687? |
Hello @bep, This proposal is not so different from that other pull request. I have corrected some things though. Actually the 2 main points are:
Indeed, what I have written is a little bit more than a proof of concept. I assume that as it is, that PR is usable for my own needs. But I have not written any test yet, nor written any documentation. But as soon as we decide that we really want this feature, I will work on these. What do you think? |
My take on this is this:
We need to expand on the above, of course, but I do not think we want some other widget thingy with its own syntax and configuration where it is Note that this is my thoughts on this. Others may disagree. |
@lebarde Long time no chat! 😄 I know we spoke of this before on the forums, but I'm hoping you can expand on the extra utility of a widget vs partial and widget vs content view and widget vs shortcode. Is your vision that themes would ultimately use only widgets? I agree with @bep that we need to be very careful about naming, especially when it comes to assuming differences in casing, but it looks like you're already handling the difference between I appreciate I'm probably missing something obvious here, but to me it seems like improving at the function-level (e.g., #3297) is a more flexible approach without adding too much complexity, and configuration files are already getting to be too large, IMHO. (See #3090 for additional context.) Also, thanks for all your hard work on this. It's appreciated! |
@rdwatters: What @Jos512 and @KevinGimbel said about naming is totally right. And as you said we need to be very careful about naming. This is why I changed that in the second commit. So I am proposing that inside the widget template we have the following variables: As I said here:
When I develop a website, my client often asked me to add blocks in the sidebars, headings, footers, sliding showcases on the home page, and so on. This is where widgets come into play. If somebody has already made the corresponding widget, I install that one inside For instance, with the proper widgets available, I am sure that a site like consequently.org would not require much work. Now I am pretty convinced that:
|
@bep wrote:
I am not sure to understand. I am pretty convinced that Hugo is very good at content and structure, which is one of the reasons I love it. In anyway I am not talking about content, only aside blocks that will display on every page, eventually depending on the context (sidebars, footers).
And it is good at it IMO. I have currently all I want to develop a website from scratch. But in fact the lack is about reusable pieces of code. For now, if a site-maker wants to display a menu, a tag cloud, a list of the 5 last posts or a form to subscribe to a newsletter in the main sidebar, he/she has to write it from scratch in a specific layout. This is OK and feasible, but if there are some pieces of code already available he/she will be glad to not reinvent the wheel. And if the site-maker is a beginner, it could be very hard to display a simple menu entry. Widgets intend to go on that ground. Easy-to-use, reusable and fast to set up. In my model, adding a menu to the sidebar would be as easy as:
Where |
I assume you mean that the user should be able to put it on any page (which would be every page if he wanted), i.e. composable. A widget = a template and some metadata (i.e. a content file with front matter) and a way to put include it. There is a very small mental step from the current Hugo to this. I.e. a much smaller step than this PR. |
For now the widget areas display each time the template calls it (by default, on every page). I have written a shortcode that enables putting it on one specific page inside the content. But for now you cannot enable a widget area on specific pages. In that way, maybe it could be useful to manually enable or disable a widget area in the front matter of one specific page.
What would you suggest to make it smaller or to have something reusable partials like this in Hugo? |
This is a very good idea in my opinion if we go for widgets. When I worked with WordPress for clients there was always need to have different sidebars on different pages and WordPress did not have a mechanic to say where and when to display a widget. I always ended up using the Display Widgets plugin, which adds options to say when and to display a widget inside a sidebar or area. For Front-Matter this could work similar, e.g. by saying ---
title: "About me"
widgets:
sidebar:
recentpost:
hide: true
---
I do agree with @lebarde in that Widgets do add value compared to partials, especially with the re-usability and the "easy" plugin mechanism with the
Inside
I can then use it inside my content pages (e.g. Blog Post, About, etc) as Just my two cents, but I personally find the idea of widgets appealing. I think they can provide great value to Hugo and especially to configurable themes. |
I've always thought the use case for shortcodes as separate from a partial. What's been discussed already w/r/t including (or removing) a partial can very easily be taken care of via an arbitrarily named FM Boolean.You can also access page page params from within a shortcode. Instead, maybe there is some value in a convention for using such a front matter field, but it seems that would come up organically (like using app.js as an entry point, for example) or could be documented as a best practice? (This is spitballing.) Shortcodes are different because you can easily pass in Params when needing to be directly embedded within body copy...so I don't see the connection with a sidebar. This is something I've never tried, but what about creating a shortcode that calls a partial and passes the params in as a One consideration is how much Hugo wants to pollute the exportability of content developed by editors and writers; i.e., by adding yet another mechanism (widgets) to content that doesn't conform to the commonmark spec. Widgets in body copy, for example, mean people creating content that could (in their eyes) have to live in Hugo forever...rather than other SSGs, which more or less take just markdown+YAML without issue. I love shortcodes, and I have no plans to ever stop using Hugo, but I see them [shortcodes] as a potential deterrent for writers who want to keep content as small, self-contained, well-composed, standalone files that aren't tethered to any system. A Hugo export (ie, that renders the shortcode to HTML inside markdown but keeps the md format) would be a cool feature, but that's for another thread... |
You are totally right about shortcodes. Actually, I wrote some math articles which I intended to publish both as PDF (with pandoc) and as web articles. I managed to do it with LaTeX. But in case of shortcodes, it is right that they are specific of Hugo and thus not portable to other content systems. Using widget areas as shortcodes is IMO a nice way to add value in very specific cases. Here we are talking about corporation websites where we want to add slideshows, call-to-action or post lists in the main content or in place of the main content. Take for example my own site. The homepage is not intended to have textual content, but to be a place to listen to tunes, to click and see articles, and so on. I added widget areas to content-bottom ("Écouter" and the right column). But what we are talking about is an adding. The very main purpose of widgets is still to easily manage sidebars, headers, footers, and asides. On Hugo I am pretty sure that what I did on my website would need a very consequent work (same for consequently.org website, which has beautiful sidebars). But on other CMS it is very easy and done in minutes. Once again, and as @KevinGimbel said, when creating websites this is a most frequent use case. And in that situations, not having to modify raw HTML code just to switch two blocks in the sidebar is nice. Then, if I teach them to, my clients may be able to do it, which is always my target when I create a website. We don't all have only blogs with only pure content. |
And thank you @KevinGimbel for your answer. I see we had a close experience of that kind of job. |
As @KevinGimbel said, widgets really add value.
@bep: What do you have in mind exactly?
@rdwatters: Actually widgets don't go inside the content. As I said the ability to add a widget area inside the content will be most occasional for specific purposes. Within the pros and cons until now, I cannot see any con that would make the widget mechanism undesirable. I am looking forward to see widgets in Hugo. But it may not be time for it, and I would understand! |
I'm closing this. This PR is just a new iteration of the last PR with the same name. Widgets in itself may be interesting, but this PR introduces so much new in terminology etc., that even I have problems following it -- so I'm not willing to maintain/support this feature. Which currently is a winning argument. And I don't see too much enthusiasm by others, either. |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Here is a first attempt to get widgets into Hugo.
/widgets
. It should look like this:Note that the name
widget.html
is mandatory. Currently the context is the content of the config parameterwidgets.[mywidgetarea].[mywidget].options
. Variables are accessible with.content
for a text widget like the following and as described in the config below.widgets
variable describing widgets inside widget areas:widgets
call. This can be done like this:{{ widgets "sidebar" . }}
.{{% widgets "showcase" %}}
Fixes #2683
See #2535