Widget mechanism

As the idea of a widget mechanism have been discussed here and there, as @bep suggested I am creating a specific thread. I will try to get this first post updated if the discussion should go on. The second post is intended a placeholder for technical issues / roadmap. @bep @spf13 : Don’t hesitate to edit.

To start on a good basis, I will discuss 1) What is a widget mechanism, 2) Why it can be a benefit for the hugo community, 3) How it would be used, and 4) How it might be developed.

What is a widget mechanism

A widget is intended as a block that can be put anywhere inside a website. In practice, this can be a menu, a list of the last posts, a call-to-action section, a sliding showcase, a social share block, a list of taxonomies, a search field, an inscription-to-newsletter field, a vcard, an arbitrary text block, or anything you can imagine as a separate block.

In a traditional Content Management System, a widget mechanism manages widgets: Where to put widgets (as widget areas), How to install them, and How to instance them. There are usually three main spots to have in mind:

  • The widgets files are placed somewhere inside the website’s source tree (let’s say widgets/ for instance).
  • A theme/template declares widget areas (something like {{ widgets "sidebar" . }}).
  • The end user defines widget areas inside the config file.

Benefits for the Hugo community

If we look closely at templating inside Hugo, we can see that Templates came before Themes. In some way, the theme’s mechanism is a structuration and normalization of the use of templates. We can see that it enables to easier share a website’s design.

The same analogy would be possible for partials and widgets. You can already create blocks as Partials. This is extraordinary! Now the lack of standardization leads to difficulties to share partials. For now, if we want to add a block inside a template/theme we always have to dive into the theme’s code and add a {{ partial "whatsoever.html" . }} call.

This is precisely what we want to avoid. If a theme is built with customization in mind, we can do lots of things with a single configuration. See for instance what is possible inside the Hugo Multi Bootswatch theme. A lot of customization is possible.

But what to do if the theme has sidebars and footers, or other customizable place? I see two possibilities for that: 1) to put customizable content (as an arbitrary text field set by the end-user inside the config file – this is what @digitalcraftsman does in the excellent Hugo Material Docs), or 2) to set predefined empty partials places that can be manually set by the end-user (this is the use case that @spf13 chose for the main gohugo.io website: here you see that config file is very light, and here you see the partials included).

The blocks I told about inside the first section of this post are typically what an end-user wants to add on his pages. In my opinion, the theme should be agnostic on what specific blocks to display. The use case would be setting widget areas inside themes/templates, installing/creating widgets separately, and setting inside the conf file what widgets to inject inside the widget areas.

The theme’s creator freely sets the widget areas. But the cherry on the cake would be a recommendation about the areas namings. This enables themes to work “out of the box” and freely switch and test themes.

To sum up, if all this were implemented, we would gain:

  • More generic themes, so better theme’s reusability out of the box for the community.
  • More accessibility to non-developers. To create a website with the appropriate content, an end-user only has to install themes, install widgets, and edit the configuration file. This is more accessible than having to dive into templating and partials.
  • The ability to create a centralized place to share widgets (just like the themes showcase).
  • Maybe encouraging companies to create businesses onto Hugo, selling themes and templates (this is an other but related topic).

In my mind, Hugo would be the first static site generator (opportunity?). Combined with a theme inheritance (which is a totally different subject), this would bring more and more attractiveness.

Use case

Widget structure

A widget lives in a widgets/my-widget/ directory. It has to have at least two files: widgets/my-widget/README.md (being a shareable object) and a widgets/my-widget/layouts/index.html

The could be a widget.yaml config file if needed.

Theming/Templating

The theme/template declares widget areas as follows:

{{ widgets "sidebar-left" . }} {{/* Don't forget the dot. */}}

An isActiveWidgetArea bool can be used to check if a widget area is active (if the end-user has really declared this widget area inside the config file).

First use case: putting default content

{{ if isActiveWidgetArea("sidebar-left") }} Put default widgets here {{end}}

Other use case: using default widget area names

{{ if isActiveWidgetArea("sidebar-left") }} {{ widgets "sidebar-left" . }}
{{ else if isActiveWidgetArea("sidebar") }} {{ widgets "sidebar" . }}
{{ else }} <!-- default widgets' code -->
{{end}}

Default widgets

Hugo should ship some core, widely-used, predefined widgets. In that way, the themes could put some default widgets to render better out of the box.

I am thinking of:

  • Arbitrary text widget (eventually with options for raw html, markdown, templating)
  • Navigation widget (menu)
  • Last posts widget (list)

Widget areas and theming

  1. Theme developers would be encouraged to describe the widget area (at least their names) inside their README.md.
  2. Theme developers are free to choose the widget area names, but could be encouraged to use the following names: header, sidebar, sidebar-left, sidebar-right, content-top, content-bottom, footer, footer-left, footer-center, and footer-right. This enhance the ability to switch between themes (and therefore themes integration).
  3. Theme developers could be encouraged to use condition to use some name for a sidebar if it exists, but a more generic name if not (see the Theming/Templating section).

End user: configuration file

The end user only has to install widgets and write things inside the config file. Below could be an example of what could embed the configuration file.

widgets:
  sidebar:
    - type: vcard
      name: "King Arthur"
      phone: (++123)456789
      photo: "https://upload.wikimedia.org/wikipedia/commons/a/ad/Boys_King_Arthur_-_N._C._Wyeth_-_title_page.jpg"
    - type: plain-text
      content: "Website generated by **[Hugo static site generator](https://gohugo.io/ "Which is so beautiful")** on *{{ exec date }}*."
      options: allow-html, allow-markdown, allow-exec     # wink at issue https://github.com/spf13/hugo/issues/796
    - type: list-categories
  content-bottom:
    - type: disqus
      id: bstewiawzpoljzuisaei
  post3-widgets: # included inside a post!
    - type: showcase-bigflat
      slides:
        - title: "Meet us at the point"
          text: Lorem ipsum dolor sit amet […]
          picture: https://discuss.gohugo.io/uploads/gohugo/original/2X/3/3999949154d616b767f5984f74f89fb4cea50535.png
        - title: "Hugo is so nice!"
          text: Lorem 2 ipsum 3 dolor 4 sit amet 5 […]
          picture: public/some-other-picture.jpg

Other questions to discuss

Who is declaring the html structure of the widget area?

  • If this is done by Hugo this leads to normalization but rigidity (HTML5 vs XHTML vs other document language for example).
  • If this is done by the theme, it implies more work for the developer (loops or description for a site-wide structure). The Hugo documentation could help to do that with pre-written and usable examples of widget areas.
  • If this is done by the end-user this breaks the theme development process because the theme developer cannot style widget areas. Plus, this is less accessible.

IMO the Hugo could set a default behaviour (setting an <aside> html5 block for widget areas and a <section> block for widgets), which could be bypassed by the theme if necessary.

Widget template

Should it be widgets/my-widget/layouts/index.html or some kind of widgets/my-widget/widget.html?

See also

The related issue on Github: https://github.com/spf13/hugo/issues/2535

What do you think of all this? Do you think this functionality could be brought into Hugo? What would be the disadventages of such an approach? Do you think it could slow down Hugo?

(placeholder for technical realization)

It is obvious for me that I will not be able to do it myself (or at least alone, or at least for now), so I really want to start and exchange.

I think this is really more like a “component” in a lot of ways. If you wanted it to be truly flexible and allow placement anywhere on the page, it might be better to standardize things like class names since scoping will definitely be an issue. I like the BEM conventions from Yandex for this kind of thing.

  • Hard to standardize.
  • Might pigeonhole site types into the “blog” category (maybe that’s not a bad thing) with people adding a whole bunch of crap onto “posts” even when it doesn’t apply (cf. Wordpress)
  • Bloat (cf. Wordpress)

I think that standardizing the HTML output is a much harder (and in some ways, very short-sighted) approach than standardizing metadata schema (ie, front matter), content types, and a very minimal scaffolding for content modeling. The problem with standardizing a content type is that it might make data entry a pain in the neck for editors/writers in the interest of dropping future iterations of the site into a theme.

That said, there is something appealing about a single, community-maintained library for partials and shortcodes that represent common list patterns and “widgets,” respectively. I can see why spf13 wanted built-in shortcodes that ship with Hugo since he used the first version of the project as a means to learn Golang and build his own site, but I think it would be better if these weren’t there in the first place…

Thanks to your answer @rdwatters

[quote=“rdwatters, post:3, topic:4428, full:true”]
If you wanted it to be truly flexible and allow placement anywhere on the page […][/quote]

I did not explicitely write that I would also like a widget area to be declared inside a post.

Might pigeonhole site types into the “blog” category (maybe that’s not a bad thing) with people adding a whole bunch of crap onto “posts” even when it doesn’t apply (cf. Wordpress)

Website creation should always be done methodically. This is true if there are a lot of tools available but remains true when this is not the case. Having more tools to enhance adoption by non-technical users will fatally bring misuse, but you cannot avoid it.

Now, IMO we cannot say that Wordpress sticks only to blogs. When I used Wordpress for my clients, I used widgets and this was most useful to focus mainly on content and design when we don’t have to reinvent the wheel. But even on Wordpress you have to dive into coding when the behaviour is not the one you need.

I don’t see why having such kind of widgets would categorize site types into the blog category. This only would bring more efficience if an already existing widget does exactly what you want.

I haven’t read all of this.

But for me, we miss a core feature in Hugo that this and other stuff depends on: Dependency management.

We currently have themes as external dependencies – and it is this hard-to-get-right copy or clone the theme(s) to a specific folder.

I would like to copy the model of Go itself with its go get and have a hugo get to pull the dependencies for a Hugo site.

Go has its GOPATH with /src, /pkg … we could have a HUGOPATH (default to $HOME/hugo) that could contain:

  • /themes
  • /shortcodes
  • /partials
  • /widgets
  • /whatever

And we have a content address scheme ala go that says:

theme: https://github.com/devcows/hugo-universal-theme

and so on …

and then have

hugo get all -u -v -f

(see the help for go get to get a drift of what I mean about the flags)

The main point of this post is this: This stuff needs to live outside of the Hugo main project, and to make that happen there needs to be a proper dependency manager in place.

There are plenty of versioning and other issues that eventually needs to be solved, but …

2 Likes

This is indeed very nice, and I think this should be implemented! But note that if it is related to the use of a widget mechanism, this is another functionality that should be discussed in a separate thread.

I agree. Best practices extend to more than just websites.

I would say you misinterpreted my comment, but it’s my fault for not being clearer on this. Sorry about that. You’re right that nobody would argue that Wordpress is just for blogging (see Conde Nast), but Wordpress was originally conceived as a blogging platform and therefore has a lot of complexity cost and baggage. I don’t want to turn this into a Wordpress thread. I think it’s a great platform for so many things, including personal blogs :smile:

A dependency manager sounds great. I would go a step further and say that most of the features people have been asking for lately should stay across the aisle from Hugo.

It’s ballsy for me to make this kind of suggestion since I’m not one of the maintainers, but I said it on Gitter as well as in multiple threads on this forum. I think Hugo should just be the world’s greatest content generator for static websites (ie, html, xml, json, images) and do this by extending the functions/templating in a way that makes managing content files (markdown, asciidoc…), creating layouts, etc—even at scale—exceptionally easy while remaining blisteringly fast. The maintainers already do a wicked good job at this.

Maybe @lebarde the best approach would be something similar to Octopress with Jekyll? Ie, create a framework that sits on top of Hugo? Maybe it just provides a whole slew of conventions that the community can build around? Then it remains outside of Hugo while still building on top of it and through conventions allows for easy-to-reuse “widgets” and the like?

I’m not sure that going the configuration-over-convention route is a good idea. If you had a large set of community-maintained partials and shortcodes, I don’t see how widgets would be any different?

Also, “non-developers” as a target can get tricky. But you’re still asking creators of websites to use a text editor, likely work with git, hosted source control, templating, etc. So at least some development is necessary for any level of customization, right? Also, I’m not sure what “create a website with the appropriate content” means. If you had a widget, there would still be a certain set of metadata (front matter) you would need associated with each content file in order to transfer a large site with multiple pages to a new theme, right? Otherwise you’re saying that visual presentation should come first, with editors/writers adding the necessary metadata after the fact, which doesn’t subscribe to a content-before-form approach to building websites, which is still the best “methodology” around, IMHO.

1 Like

This is most interesting. We actually can see a lot of FOSS projects that stick to the good UNIX basic statement that is, “do one single thing and do it well”, and then build stacks on it. I totally agree to that.

So if we go this way a little bit further, maybe Hugo should be split into a basic (but powerful) tool, and a framework stack on it. In that way, I assume that partials should live in the first project and themes should be handled in the framework, as long as widgets, and a hugo get command. I don’t know much about Jekyll and octopress yet, but I guess this is the choice that has been made. Also, maybe a second project would dilute the efforts and the visibilty/transparency of the project.

What I can say is, as a website developer, I sometimes need a tool that does not assume for me what are my needs (say, a low-level project), and I sometimes need a tool that brings functionalities that make me concentrate on questions that will go straight to content strategy, graphical design and ease of use (for the client) and maintenance (for me).

For instance, I used the Symfony framework when I needed sites that had a non-common content model. But in the vast majority of cases, I needed a tool that enabled my client to manage the main processes: creating content, eventually move/rearrange menus, eventually move/rearrange widgets (but never to change the themes or modify the graphical design). For all that projects, I must say that I chose Wordpress.

The Wordpress theming/widgets/hooks/… documentation definitely aims developers, whereas a non technical user can search for themes, widgets, plugins in general, even if they won’t build the best websites ever. I am also a professional lyrical singer and as so I have met some absolutely non-technical singers building wordpress websites by themselves.

If, as you say, Hugo should be the leader in the static site generator race, I am convinced that Hugo should be of the second type. And if it is only a question of writing conf files, manage dependancies through git and manage the file uploads, actually this can made by a GUI built on top of it.

The true question about conventioned widgets is that you cannot currently create a theme that embeds a non-determined number of partials. And you cannot make the end user use them as reusable pieces without coding.

Much of the beauty of Hugo is that it largely tries to be an all-in-one binary program without supporting or depending on external plugins like the main competitors: Jekyll, Middleman, etc.

Essentially a widget system is an extension of the Hugo shortcodes concept, that allows to re-use blocks of code independently of the theme being used. Almost every medium-large website uses a widget based design principle. However, only a small subset of those websites have a native multi-lingual feature. For those concerned with ‘bloat’, if anything, the multilingual feature should be removed from Hugo and the widget feature should be added.

As the developer of one of the most popular Hugo themes ( https://github.com/gcushen/hugo-academic ), we have implemented widget functionality using Hugo’s Go templating language, but this is inherently very hacky and far from ideal. A number of other popular Hugo themes are also using some variation of widgets and even SPF himself tries to use widget based design principles with his own site.

Hence, it appears pretty obvious that this is a much needed feature for Hugo. Anyone who thinks this will ‘bloat’ Hugo is probably not a theme developer. It’s better to have one program contain widget functionality than hundreds of themes each with their own (varying) implementation of it in the Go templating language. By including the widget feature in core Hugo, the themes become less ‘bloated’ and the widget system becomes standardised so widgets can be used with any theme.

Furthermore, surely the solution cannot be to make a big barrier for theme installation by requiring theme users to download another program (containing the widget framework) just to use widgets. This is just going to put a lot of people off using these more customizable themes.

Thanks to @lebarde for working on this!

Finally, regarding @bep’s Dependency Manager concept - it is obviously a separate but related feature. I have heard a number of users have trouble installing themes, especially those without much experience with Git or command line. I believe such a feature can open Hugo up to a wider audience by lowering the technical knowledge and experience needed to build a website, whilst also making the Hugo experience a lot more user friendly for everyone. I suggest that the dependency manager should have an option to automatically setup the exampleSite provided by the theme developer when installing a theme, since many themes require specific configuration and content types.

1 Like

I would never put visual stylistic needs before accessibility and internationalization, but I’m a content strategist, writer, and editor by trade…and not a developer.

I am with you on this. Awesome :smile:

Maybe I shouldn’t have thrown these two out as an example, but at one point according to staticgen, Jekyll was the most popular SSG, with Octopress just behind it. Now it’s #1 and #5, respectively. So I’m not sure it would reduce visibility for the project. That said, the plugin landscape for Jekyll is vast and Hugo obviously has different hurdles w/r/t building this kind of ecosystem…and I’m not necessarily advocating for plugins…mostly because I haven’t really thought about it.

You’re absolutely right. My career is in content.

This is an interesting point. The site I managed two jobs ago had 65,000 pages (including print documents) and a distributed authorship of 120 people across a 400-person organization. I could barely teach people to write in markdown on a separate microsite. Before that, I worked as an editor on the second-highest impact factor pediatric journal in the world. The thing I’ve always found most difficult about managing large amounts of content on a site had to do with creating relationships between content (similar to Hugo’s taxonomies, but considerably more expansive because I work in medical publishing) and getting authors to understand COPE concepts. Are you two talking about a CMS layer or GUI? In my experience, and believe me it’s a bummer, that’s the most (but not only) effective method for promoting non-technical user adoption. Then there’s matters of approval workflows, versioning (I don’t mean git), collaboration, etc. You’re going to have to trust me on this: I’m the employee left with managing the content and people for a web property long after the consultant/developer has handed off the project.

You’ll have to help me understand this, @neutreno and @lebarde. So are the widgets for theme developers, hugo developers in general, writers and editors for a website’s content, or all of the above? I want to make sure that I am using the same terms as both of you.

Again, I’m not sure who you’re talking about here. A “big barrier” for who? Are we talking about theme developers? As far as clients, is it your experience that non-technical users of a website are comfortable dropping into a config file or even using the command line in the first place to install a binary?

I couldn’t agree more that the single-binary is a great thing. Interestingly, Jekyll has considerably more themes available than Hugo, even on themeforest. Also, WordPress is pretty plugin heavy, no? To my knowledge, it has more themes than any CMS or SSG on the planet. I don’t really have opinions on themes; I’m just interested in the logic.

A. Your job is awesome.
B. True, but they use things like the WordPress visual designer after they drop 80 bucks at Themeforest…and as you’ve already alluded to, these sites are often unmaintainable. I guess the question is whether you see this as a long-term goal of Hugo itself or other tools or conventions the community would build on top of the core?

Thank you @neutreno. Until now I have had the feeling that the answers were mostly “why not such a feature BUT BUT BUT”. I was feeling I would always have to fight in order to make that idea accepted. In fact, I firstly thought that this suggestion would have been welcome.

As you say, a theme developer wouldn’t argue against such a widget mechanism as its lack makes their work so difficult.

@rdwatters Actually my current carrier is at the Paris Opera, but I have had several carriers, including development as an engineer, and making my own website company. The typical websites I made with my company were generally little, and managed by only one person (my client, would he/she be a restaurant manager, a massage professional, a classical singer or else). And therefore, he/she had to manage most of the website’s use. I can tell, as a website creator in general (and theme developer in particular), that having widgets, as described in my first post, is not a waste of time.

Hat’s off, man. Those are all very cool jobs.

I never said it was. I think you’re taking this too personally. I’m looking forward to seeing how it turns out :smile:

Hello everyone,
So I am very pleased to announce that I have developed a widget system into hugo, as you can see here! I worked hard to create in my spare time a 250 lines commit that can be discussed here.

The widget system works as described in the pull request I made. Comments are welcome!

You are invited to try it. Feel free to clone my hugo repository and get the widgets_MERGE branch. I will push a working website with the widget system I wrote.

Bep told me that unfortunately we will have to wait a little bit. I had not realized, but as bed said, it is possible that such a widget system could be managed with nodes. We will see then how all this will become!

2 Likes

Hello,
Is it now time to reconsider adding a widget functionality right into Hugo? I can see on https://www.staticgen.com/ that Hugo is gaining more and more reputation, so it may be nice to have such a functionality!

I don’t see the “reputation thing” as a weight in all of this. There is a limited set of development resources and widgets isn’t on my short term list … and as I said earlier, we need some fundamental framework for handling external resources, which also isn’t on my short term list. But it may be on some other person’s list.