Is it possible to extend Hugo with plugins?

2,684 views
Skip to first unread message

Nathan Rijksen

unread,
Jun 7, 2014, 12:19:15 PM6/7/14
to hugo-d...@googlegroups.com
Hi, I really like the basic concept of Hugo having to be extremely high performance and am interested in trying it for larger sites, however I cannot find any information on extending Hugo. By that I mean; how would I go about (for example) injecting a twitter feed during compilation?

Is this something that is at all possible with Hugo or is Hugo simply intended to run 10-page blogs?

Ask Bjørn Hansen

unread,
Jun 7, 2014, 2:39:13 PM6/7/14
to Nathan Rijksen, hugo-d...@googlegroups.com

On Jun 7, 2014, at 9:19, Nathan Rijksen <n.ri...@gmail.com> wrote:

> Hi, I really like the basic concept of Hugo having to be extremely high performance and am interested in trying it for larger sites, however I cannot find any information on extending Hugo.

Shortcodes is one way. If you need actual code to run, there's no easy way to have Go code "as plugins" so that'd most likely have to be done by embedding javascript or Lua. The scope for Hugo is building "static" sites though.

> By that I mean; how would I go about (for example) injecting a twitter feed during compilation?

If you want the twitter feed statically baked into every page one simple way would be putting the snippet from twitter in a file before building the site and then including that file on every page where you want it.

> Is this something that is at all possible with Hugo or is Hugo simply intended to run 10-page blogs?

Are you interested in building something or are you simply intending to make snippy remarks?


Ask

Nathan Rijksen

unread,
Jun 7, 2014, 2:47:34 PM6/7/14
to hugo-d...@googlegroups.com, n.ri...@gmail.com
> Are you interested in building something or are you simply intending to make snippy remarks?

I meant no offense, there are many static site generators that exist for that specific purpose.

The twitter example was just that; an example. I'm not looking for a solution to that specific problem per se.

To give a more specific example, I've currently built komodoide.com on using DocPad as the static site generator, I've build a plugin that pulls content from the github API to generate the Resources section.

How would I go about doing this with Hugo? Is it at all possible, or is this outside of the scope of Hugo?

Thanks

Ask Bjørn Hansen

unread,
Jun 7, 2014, 11:43:43 PM6/7/14
to Nathan Rijksen, hugo-d...@googlegroups.com

On Jun 7, 2014, at 11:47 AM, Nathan Rijksen <n.ri...@gmail.com> wrote:

> > Are you interested in building something or are you simply intending to make snippy remarks?
>
> I meant no offense, there are many static site generators that exist for that specific purpose.

Fair enough. The attitude in your last line just took the air out of your (otherwise good) question a bit and I actually had to drag it out of the trash to respond to it. :-)

> The twitter example was just that; an example. I'm not looking for a solution to that specific problem per se.
>
> To give a more specific example, I've currently built komodoide.com on using DocPad as the static site generator, I've build a plugin that pulls content from the github API to generate the Resources section.
>
> How would I go about doing this with Hugo? Is it at all possible, or is this outside of the scope of Hugo?

I don’t know if it’s outside Steve’s plans, but I don’t think there’s a reasonable way to do it now. I think the two problems you’re facing now are:

1) There’s no way to have a data source other than the markdown files and writing those from the github data would be a bit goofy (even if possible).

2) The data model for the pages is just “front matter stuff” and “blob of content”.

You could have a small script write the output from the github API into a page per entry and then put the data components into the “front matter”, but unless it’s just a small section of a much larger site then it wouldn’t really feel nice, I think.

There have been a thread or two recently about pulling data from a dynamic data source of sorts so maybe Steve has some ideas brewing.


Ask

Gour

unread,
Jun 8, 2014, 3:14:56 AM6/8/14
to hugo-d...@googlegroups.com
Ask Bjørn Hansen <a...@develooper.com> writes:

> Shortcodes is one way. If you need actual code to run, there's no easy
> way to have Go code "as plugins" so that'd most likely have to be done
> by embedding javascript or Lua. The scope for Hugo is building
> "static" sites though.

At the moment we use PHP CMS (Textpattern) for non-profit org and
e.g. host mp3 files with the audio recordings of public lectures for
which we keep download counter for each file.

Now I'm curios, knowing that Hugo is static-site-generator, whether
someone has attempted to glue some other Go code to server specific
parts of the site which need some dynamic features?

When I was considering to use some Python-powered generator, I was
thinking to use it along with e.g. Web2py or Flask, so wonder about
similar strategy with Hugo and some some Golang-based framework?


Sincerely,
Gour

p.s. I sent this reply from my other - primary/non-Gmail - account, but
it looks that Google groups does not like such posts, so here is my
humble request to please subscribe this list to Gmane.org not forcing
eveyone to use Google's UI to contribute to this list.

--

Nathan Rijksen

unread,
Jun 8, 2014, 11:31:50 AM6/8/14
to hugo-d...@googlegroups.com
There have been a thread or two recently about pulling data from a dynamic data source of sorts so maybe Steve has some ideas brewing. 

While this would be great (!) the overarching "issue" I face in evaluating Hugo is whether it is extendable in any form. Having alternate data sources is probably the most important one for me at the moment but similarly it would be nice if one could (for example) create a pagination plugin (this probably already exists, its just an example).

Are there any plans for such functionality? And is there some type of established roadmap that I can look over?

Whilst I am not a Golang programmer I am interested in the language and I'd be happy to contribute if the project goals align with my own.

@Gour: I think your particular question might live better in its own thread, as it seems significantly enough off-topic from the subject at hand to make this a difficult discussion to follow if both questions are to be answered in this thread.

-- 
Nathan Rijksen

Gour

unread,
Jun 10, 2014, 7:30:07 PM6/10/14
to hugo-d...@googlegroups.com
Ask Bjørn Hansen <a...@develooper.com> writes:

> Shortcodes is one way. If you need actual code to run, there's no easy
> way to have Go code "as plugins" so that'd most likely have to be done
> by embedding javascript or Lua. The scope for Hugo is building
> "static" sites though.

At the moment we use PHP CMS (Textpattern) for non-profit org and
e.g. host mp3 files with the audio recordings of public lectures for
which we keep download counter for each file.

Now I'm curios, knowing that Hugo is static-site-generator, whether
someone has attempted to glue some other Go code to server specific
parts of the site which need some dynamic features?

When I was considering to use some Python-powered generator, I was
thinking to use it along with e.g. Web2py or Flask, so wonder about
similar strategy with Hugo and some some Golang-based framework?


Sincerely,
Gour

--

Bill Anderson

unread,
Jun 28, 2014, 3:53:47 AM6/28/14
to hugo-d...@googlegroups.com, n.ri...@gmail.com
I apologize a bit for the thread necro here, but this thread I think gives good context for my questions (while illustrating I looked for the answer. ;) ) The remainder of my comments/questions are in-line.


On Saturday, June 7, 2014 10:43:43 PM UTC-5, Ask Bjørn Hansen wrote:

I don’t know if it’s outside Steve’s plans, but I don’t think there’s a reasonable way to do it now. I think the two problems you’re facing now are:

1) There’s no way to have a data source other than the markdown files and writing those from the github data would be a bit goofy (even if possible).

2) The data model for the pages is just “front matter stuff” and “blob of content”.

You could have a small script write the output from the github API into a page per entry and then put the data components into the “front matter”, but unless it’s just a small section of a much larger site then it wouldn’t really feel nice, I think.

There have been a thread or two recently about pulling data from a dynamic data source of sorts so maybe Steve has some ideas brewing.


Ask

Ok, here is a more specific scenario, and one I don't think I'd be alone in. It is something I've done in another Language/Framework and would love to be able to do with Hugo.

I have a site with multiple authors (using a GitHub repo w/fork-pr for "content management"). I'd like to have the following:

A 'central' means for detailing information about each author (social handles, email, personal site, etc. Google authorship data). I'm comfortable with that being a data file such as JSON in the repo - or even one per author in a 'authors' directory.

I'd also like to have a page for each author which shows this information as well as links to their local content, show perhaps their StackExchange profile if they've added that to their file, etc..

In their articles I want to pull in various bits about the author (short bio, name, link their local author page) - and I do not want them (or me!) needing to repeat it all in every article - and then going to each and every one to make updates. 

Ideally I'd be able to pull the data from the 'central' store and fall back to the front-matter if missing. But if I had to give up pulling from the store (other than pulling the author name/email from the article's front matter to even know whom to look up of course) I'd be fine with that.

Now, technically this is all static data in the sense that any articles in Hugo are static. I'm not needing remote DB connectivity (though I wouldn't be against having that capability in general), just a bit more site-wide ... shall we say orchestration?

I've not yet made it through *all* of the docs just yet (gotta get my feet wet before I can do that effectively ;) ), but I am working my way through them. I see inklings of the pieces which might support such a thing with the Menu aspect (mind you I've not yet played with this - just a brief doc read so far).

I *think* this should be doable in Hugo - but then again I'm not yet familiar with the code. It seems to me an underlying mechanism here is a "global structure" (for lack of a better term; I don't mean specifically the datatype) from which we can push and pull data as needed. For example, in the layout of authors/author-name.json then when these files are read the resulting data is stored into this underlying structure from which processing articles/posts/etc. could pull from. This is how I've done it in the other (Python based) framework - it may not be idiomatic here - just trying to explain and perhaps ramble a bit at 3am I suppose.

So, is something like this something we would entertain, and if so what do we need to do to get it going? I'm relatively new to Go itself, but that is rapidly changing, and not to programming overall and would be up for working on it. If there is already an effort moving in this direction, I'm happy to get a pointer to it. 

Cheers,
Bill

Bill Anderson

unread,
Jun 28, 2014, 1:34:03 PM6/28/14
to hugo-d...@googlegroups.com
Gour,
Running a site with the majority being static content and the rest being on-demand regeneration is fairly simple. Use common JS/CSS to preserve the look and feel of the site across both on-demand and pre-generated, then use a web server front end to route on-demand actions to the appropriate server/service. With basic rules in either Apache or Nginx, for example, you can easily route the on-demand/interactive bits of the site to wherever you need them to be. 
 

Cheers,
Bill

Gour

unread,
Jun 28, 2014, 2:12:53 PM6/28/14
to hugo-d...@googlegroups.com
Bill Anderson <ucn...@gmail.com> writes:

> Use common JS/CSS to preserve the
> look and feel of the site across both on-demand and pre-generated, then use
> a web server front end to route on-demand actions to the appropriate
> server/service.

That's clear, I just wonder what to use for that on-demand part,
iow. some light Go-framework or plain/standard Go technology with http
package?


Sincerely,
Gour

--
Even a man of knowledge acts according to his own nature, for
everyone follows the nature he has acquired from the three modes.
What can repression accomplish?

Phil Pennock

unread,
Jun 30, 2014, 12:39:41 AM6/30/14
to Bill Anderson, hugo-d...@googlegroups.com, n.ri...@gmail.com
On 2014-06-28 at 00:53 -0700, Bill Anderson wrote:
> A 'central' means for detailing information about each author (social
> handles, email, personal site, etc. Google authorship data). I'm
> comfortable with that being a data file such as JSON in the repo - or even
> one per author in a 'authors' directory.

> I *think* this should be doable in Hugo - but then again I'm not yet

Disclaimer: I am not a Hugo maintainer, only a patch submitter (and the
author of the feature pushed as the solution below).

It can be done now, as long as you're happy putting the data in the
top-level config file, which can be TOML, YAML or JSON.

You could use a language of your choice to make a small tool which
maintains the data in a separate JSON file but merges it into the
top-level config file. There is probably scope for more dynamic
dispatch into other config files.

Right now: you'd put the data into the `Params` section of the top-level
config file, then reference it via `.Site.Params` within template pages.

There are documented examples of using this in
<http://hugo.spf13.com/templates/go-templates> under "Using Site
(config) Parameters" (which *cough* seems to use examples lifted
wholesale from one of my emails to the list? Works for me :) ).

The site params can be arbitrarily nested -- Hugo imposes no structure,
it's up to you to make sure that the page templates sensibly use the
parameters which you provide.

My blog's config.yaml includes:

params:
#...
FaviconPath: "/troll1.ico"
PGPkeys:
- "0x4D1E900E14C1CC04"
- "0x403043153903637F"
Mugshot: "/images/qart-pdp1-sm.png"
#...

Then, one of my chrome entries for the sidebar includes:

{{ with .Site.Params.PGPkeys }}
<div class="pgpkeys">
PGP Keys: {{ range $key := . }}
<a href="http://ha.pool.sks-keyservers.net:11371/pks/lookup?op=index&search={{$key}}"><code>{{$key}}</code></a>{{end}}
</div>
{{ end }}

That's a sequential list, but you could use a map/dict/hash/term-du-jour
instead, and provide arbitrary author data.

params:
Authors:
Fred:
FullName: "Fred Bloggs"
Blurb: "Fred is a foo hacker"
Homepage: http://www.example.org/fred/
Gladys:
FullName: "Gladys Bloggs"
Blurb: "Gladys puts up with Fred's idiosyncratic ways"
Homepage: http://www.example.org/gladys/

You could then use a page `.Params` entry as a key into
`.Site.Params.Authors`; more docs on the Go template language are at:
<http://godoc.org/text/template>

I haven't tried it, but I suspect that this would work:

{{ with .Site.Params.Authors.(.Params.Author) }}
Written by <a href="{{ .Homepage }}">{{ .Fullname }}</a>
{{ end }}

Regards,
--
My employer, Apcera Inc, is hiring sysadmin; primarily San Francisco:
http://www.apcera.com/jobs/#operations-engineer
(but all the mistakes in this email are made in my personal capacity)
Reply all
Reply to author
Forward
0 new messages