Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Hugo: A Fast And Flexible Static Site Generator Built In GoLang (spf13.com)
99 points by spf13 on Aug 5, 2013 | hide | past | favorite | 50 comments


I took a quick look at your main.go file and have a suggestion.

I strongly recommend against using external dependencies (e.g. bitbucket.org/howeyc/fsnotify) for something important. It's fine for development, but if "howeyc" decides he's sick of bitbucket and deletes his account, you're now screwed.

If you want to use "go get" to install Hugo, make forks of the external dependencies. bitbucket.org/spf13/fsnotify and what not. You can then keep those updated at your own pace, rather than waking up to see that someone has changed their API and your code no longer compiles.

Remember the game "Haunts"? IIRC this was one of their problems--they failed to manage dependencies appropriately and got into major hell. Many C and C++ programs ship source to external libraries along with their own source for this exact reason. We've taken to doing the same.

Here's what Brian Fitzpatrick has to say about "go get":

"Go get is nice, for you know, playing around, but if you're doing something serious and you're going to deploy binaries to production, your deploy to production script should not involve fetching some random dude's stuff on Github"

We have taken to making a go "workspace" in our repos, with a bash script at the top level and a src/ directory containing all the libraries and such we've written. The bash script sets GOPATH and compiles everything in src/. It's quick and you avoid dependency hell.


> I strongly recommend against using external dependencies (e.g. bitbucket.org/howeyc/fsnotify) for something important. It's fine for development, but if "howeyc" decides he's sick of bitbucket and deletes his account, you're now screwed.

How? When you `go get` a package, it physically becomes part of your repository. If "howeyc" deletes his account, it doesn't affect the copy checked out under my repository. Unless you go out of your way to exclude the `go get` packages from getting checked in, you are safe.


When you 'go get github.com/spf13/hugo', it checks out a copy into $GOPATH/src/github.com/spf13/hugo. It then fetches all the external dependencies listed in hugo's source and fetches them, so you'll get $GOPATH/src/bitbucket.org/howeyc/fsnotify etc. Those exist in your own local tree, but if howeyc deletes his repository and somebody new tries to check out hugo, he'll get an error when "go get" fails to find bitbucket.org/howeyc/fsnotify.

Now, what you as the developer can do, as I mentioned in my original post, is get all the packages you need and put them in a $GOPATH directory, so you have $GOPATH/src/hugo and $GOPATH/src/fsnotify etc., then check in the entire $GOPATH directory. Your code then imports "fsnotify" rather than "bitbucket.org/howeyc/fsnotify" and so on. This repository is no longer trivially fetchable+compileable with "go get", but in my opinion that's a small price to pay--and compilation is still very simple.


Great idea. That will make a lot of things easier. A lot of people struggle with obtaining the right dependencies as many people don't already have mercurial and bazaar.


It puts a bit more work on you, since you have to track the dependencies, but it'll pay off the first time somebody decides to check in a radical API overhaul; you'll be able to update your code on your own schedule, not in a panicked rush because bug reports are flooding in.

It also makes things easier if you decide to modify the libraries, or if the author abandons his code and someone else becomes the "canonical" source. Your code will just import "fsnotify", and you can put whatever source you prefer in $GOPATH/src/fsnotify/


I like the idea of a static binary with no dependencies. It would be nice if my static blog generator fit in with my usual unix toolset. So good job.

Just one nitpick on the marketing copy: why does it matter what it's written in? As a user it could be written in assembler for all I care. As long as it works as advertised on the tin and it's what I'm looking for, who cares if it's written in Go?

Anyway, I'm looking forward to checking it out and seeing if it'll fit my use case.


"why does it matter what it's written in?"

As jpalomaki pointed out, it matters since it's open source. If the user chooses Hugo and wants to modify or extend it down the line, he or she will be writing Go.

And it might also matter to the author for a few more reasons:

First, Go is a language rising in popularity (http://www.google.com/trends/explore?q=golang#q=golang&cmpt=...), and seems especially popular on HN lately. Mere mention of Go will drive more traffic to his site. (This could be supported by the fact that he constantly refers to the language as GoLang, which is much more search-engine friendly than the proper name Go).

Second, if he enjoys working with Go, then raising the language's visibility will be good for the language, and good for developers who have invested in the language.


Looking at the GoLang graph : I have to admit that I'm a little surprised to see so much of that interest originating from China (Shenzhen specifically).


Not surprising. The code example on golang.org says "Hello, 世界". Every Chinese programmer will immediately love it for this reason.


They seem to be making a concerted effort to make Go Chinese friendly https://code.google.com/p/go-zh/


That would imply the initiative came from the Go team, and I can't recall ever seeing anything on go-dev or go-nuts suggesting such. That said, there are quite a lot of Asians on the go-nuts board.

What might play part of this is that one of the main contributors to Go is a guy calling himself "minux"; the guy is pretty fucking brilliant. IIRC, minux is French with Chinese roots, and he's one of the owners of the Chinese port. Note that he doesn't actually work for Google, so so far it's all community driven. Similarly, one of the earliest Go-specific IDE's is LitteIDE, written by VisualFC. I suspect it's partially thanks to them that the Chinese community was off to a good start. Well, that and UTF8.

Anyway, it's all speculation at this point; it would be nice if someone involved with the Chinese Go community could clear this up though.


Could this be the result of the intersection of "golang" and words in spoken languages?


Go's Rising popularity is false assumption. Comparing to popularity of only modern languages; Go barely registers on the graph & you will have to very careful to note Golang is actually present. so practically, Go is still a niche language.

http://www.google.com/trends/explore?q=golang#q=golang%2C%20...


"Go's Rising popularity is false assumption. Comparing to popularity of only modern languages..."

#1. I'm not comparing popularity, but the trend in popularity. Of the three languages you're comparing against, only Go is showing an upward trend, which might be expected since it's so new. This novelty may explain why we're seeing so many Go articles hit the front page lately.

Many of the articles are the same: "We recently switched to Go, and here are our impressions." Nothing earth shattering, but people apparently are curious. Python and Rails aren't as new, and a good portion of the HN audience are probably already quite familiar with them. The threshold required to get clicks on a Rails article will be much higher.

#2. Your metrics are flawed. Notice all the news stories related to "python" and "ruby." None of the articles are actually about the Python or Ruby programming languages (though many are about Berlusconi's underage prostitute). If you look at Scala in isolation, you'll notice almost none of its news stories relate to Scala the language either. They're about La Scala the Italian opera house, or scala the italian word, etc. GoLang only refers to Go the programming language.

Perhaps it makes more sense to view it in the context of other unique programming names, as compared here with Erlang and Node.js (http://www.google.com/trends/explore?q=golang#q=erlang%2C%20...). It looks like Go will surpass Erlang soon, but Node.js searches have been growing about 3x as fast as Go.

"practically, Go is still a niche language."

You're right, but that doesn't seem to stop it from generating a lot of traffic on HN. Which is what we're talking about, after all. And here we are, discussing it.


You're comparing apples to oranges. The language's name is "Go", not "golang". The trend chart for "golang" is meaningful only in relation to itself.


TIOBE Programming Community Index for August 2013

(...) Winners are Go (from 42 to 26), (...)

http://www.tiobe.com/index.php/content/paperinfo/tpci/index....


I'm really not sure Go is a plus in this category of application, anyway. With jekyll and it's ilk, part of the allure is that if I need to do something it doesn't support out of the box, I can just embed some code right there along with the site sources, and it'll be executed when building the site.

With Go, the second you step outside the box, you'd have to recompile the site compiler first. I've had so many experiences in the Java world with having to get a whole development environment and build working just to change one little piece of text, that I really think interpreted languages are a plus here.


Don't hold Java against Go :). It is all a matter of perspective I guess. Go requires 2 environmental (GOROOT, GOPATH) variables and you are ready to Go (zing). go run foo plus near instant compile times makes it feel extraordinarily script-y for small stuff.

Hugo adds some external dependencies which can be fetched with `go get` (fsnotify, fsync, pflag, hugolib). One command deps are filled and you still have all the Go goodness.

Jekyll requires (or generally expects) gem and requires at runtime (classifier, colorator, commander, directory_watcher, kramdown, liquid, maruku, pygments, redcarpet, safe_yaml) and for development (activesupport, cucumber, launchy, rake, rdiscount, rdoc, RedCloth, redgreen, rr, shoulda, simplecov, simplecov-gem-adapter)

So, it all depends on what you value.


The language can be important since this is an open source project. Given two open source projects that are otherwise similar, I'm more likely to pick the one that is written in language I'm familiar with.


> who cares if it's written in Go?

HN. Static site generators in Visual Basic, PL/SQL, Java etc are not going to upvoted and will garner no job offers.


Well, here is mine: https://github.com/piranha/gostatic

Unfortunately it has no pretty documentation, only README on Github. On the other hand, Hugo seems to have a bit more hardcoded configuration, while gostatic was written with 'whatever you want' idea in mind and is (maybe, I just skimmed though Hugo docs) a bit more tech-savvy people oriented.

Anyway, it would be interesting to compare performance. :)


I hadn't seen yours before. It looks good as well. I'd agree that Hugo is more opinionated (but not as opinionated as jekyll) and aimed at a broader audience.

It would be great to compare approaches to things and see if we can't share and improve both in the process.

The shortcodes feature impacts performance quite a bit as it's all runtime inspection, but I felt it was an essential feature. Even with it it's still fast enough that it still builds the entire site in what feels like realtime.


> It would be great to compare approaches to things and see if we can't share and improve both in the process.

Indeed. Do you track dependencies to not re-render things which were not changed?

> The shortcodes feature impacts performance quite a bit as it's all runtime inspection

Ha-ha, in gostatic you have this `inner-template` processor, which parses your page as go template and then renders it. Naturally, it slows down rendering a bit, but still it renders my site from scratch in 0.5s (~250 pages with some inner-templates, heh).


Nice work! Here's my Node.js-based static site generator, for interested users or devs who want to borrow ideas:

https://github.com/jaredhanson/kerouac


Dammit, already taken:

http://hugo.neocities.org/

Would have been such a nice fit.


This looks great, nice work! A few things I'd recommend for the future:

- Theme plugins; text based as input to Hugo, not golang packages that would have to be compiled.

- Editor integration so others can make a WordPress-style site editor. Just conventions about layout, I think?


Great ideas.

For the theme plugins, could you expand a bit on what you mean or how this would work?


Themes should be a collection of template/css/whatever files that can be unzipped to the right location and used by Hugo. That would need standards for the file types and directory structure, config settings for which themes to use, or which parts of the theme to use.

I was thinking about a WordPress replacement in Golang. WordPress themes can be zipped and shared as a bundle, which has made a large variety of themes freely available.


This is already the case. The source directory has this structure. /layouts is all the templates, /static is all the css & javascript. Just don't include a content directory and it would work just like a wordpress theme.


Just a plug for a similar tool I wrote in python. I feel it's a bit more lightweight than Hugo.

https://github.com/jimktrains/gus


More lightweight in what way?

I wrote something similar myself, also in python, and put it all in one file, organized logically, with extra tools for making management easier. I'm not sure I really see how this is "more lightweight" compared to something else...

For reference, it's located at https://github.com/dkuntz2/essays/blob/master/pavement.py.


More light-weight as it doesn't have dependencies on Git, Hg, and Bzr.


These deps are only for installing from source (due to third-party packages using different SCMs).


Makes sense. I was trying to figure out what he was doing with so many in his own code.


But that's just the version control used by the owners of various Go packages this Go package depends on - it has nothing to do with the code itself?


Makes sense. I was trying to figure out what he was doing with so many in his own code.


This'd work pretty well with git hooks. Pretty sure you could configure a server so that if you pushed to a repository on it it'd recompile the website. That'd be pretty handy.


Why in the world is there a static screenshot of the hugo website, with a button labeled "Get Started", on the hugo website?


'cause, y'know, the more static the better.


I've seen this a few days ago, and I've started building a Yeoman generator for it.

It's at https://github.com/celsomiranda/generator-hugo

There's not much done yet, but all contributions/ideas are welcome.


So this depends on git, bzr and hg? Why?


Only if you're building from the source which is stored in a git repo and uses dependencies from projects stored in bzr and hg repos.


Looks like the contribution guide link on http://hugo.spf13.com/doc/installing is pointing to the wrong place (http://doc/contributing)


Thanks. Fixed.


This is awesome. I've been looking more and more into these types of generators for creating an OSS portal directory for Web, Mobile, Desktop, and Servers; Essentially a Kippt.

Also thanks to everyone posting their projects.


I've got a mini-review, stalled, of some of the options:

https://github.com/skx/static-site-generators


What's the advantage of something like Jekyll over Hugo? I'm thinking of using the latter, it looks nice.


git, mercurial, and bazaar?

Those dependencies give me pause.


Those dependencies exist in order for "go get" to be able to download source dependencies that are stored in those kinds of repositories. You don't have to install them. "go get" would complain about if it encountered a dependency that required one of them, but you could install the dependency manually if you wanted to. It's, of course, less convenient.


Since `go get` (official way to install go libraries) just calls the proper executable to fetch source and compiles the library, that only shows what VCS its libraries use.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: