Trouble understanding Hugo's page template structure?

I’m coming from Jekyll & am having trouble understanding Hugo’s layout + page structure.

In Jekyll:

  • I have my layout templates - _layouts/default.html
  • I have my page specific markup / markdown - _pages/foobar.html
  • I set my url slug in the page’s front matter - permalink: /random/
  • The page is built at www.mydomain.com/random/

How can I do something similar in Hugo?

1 Like

Common templates are:

layouts/
    _default/
        baseof.html
        list.html
        single.html

Content lives under the content/ folder


You configure permalinks in your config file, the default file is named config.toml


You need to set the baseURL value in your config file


In the end, you’ll need to thoroughly explore the docs. And perhaps that tutorial @mojoa linked will be helpful to you.

2 Likes

I had the same when I changed from Jekyll to Hugo longer ago (never will go back). So I wrote my thoughts as a newbie and perhaps this helps:

These are thoughts about the lookup order:
https://discourse.gohugo.io/t/my-experiences-with-hugos-template-lookup-order/9959/3

This is a way how to check which template is used by Hugo (for Development purposes):
https://discourse.gohugo.io/t/see-which-template-is-used-by-hugo/9983/3

1 Like

@Leo_Merkel @zwbetz @mojoa

I really appreciate you all!
The layout structure makes much more sense now

Last question for you about permalinks - does the permalink configs work with nested directories?

This setup properly generates content in /members/ into the site root (based on slug).

  • members/faqs.md would generate to foobar.com/faqs/

However, this setup fails with nested folders

  • :white_check_mark: /members/videos/_index.md renders foobar.com/videos/
  • :x: /members/videos/happy.md does not render foobar.com/videos/happy/

Am I missing something or does this not work by design?

This is because the _index.md in

/members/videos/_index.md

is the “content file” for the videos section itself, if that makes sense

Here’s a great Hugo theme for you to explore: SimpleIT. It makes heavy use of nested sections and you can see in the templates how to display nested sections, headlines etc.

Sorry for blowing you all up - thanks so much

Because of my permalink config /:slug/ - even files inside nested directories are affected.

  • Expectation:
    • /members/videos/happy.md should render foobar.com/videos/happy/
  • What happens:
    • /members/videos/happy.md render foobar.com/happy/

Is there a way to get that working?

I’m porting a large site over & this would really help for organization opposed to the base leaf / branch model.

Have you tried setting a permalink for videos?

What’s the structure of the importing content source? You might still make the pattern you are looking for, but not with just slug.

There are a bunch of values available, listed in the permalinks doc. The way it normally plays out is to create a general pattern to capture as much of a given section as possible, and then override on the individual content piece level by setting front matter to produce the permalink values desired, with title, slug, or url (see the front matter doc), if needed.

Folks have tried a lot of content strategies, so the easiest way is to just point to a site, repo or example online. Then we can recommend. :slight_smile:

.
└── content
    └── pages
        ├── about-us.md   // <- https://example.com/about-us/
        ├── videos
        |   └── _index.md  // <- https://example.com/videos/
        |   └── superman.md  // <- https://example.com/videos/superman/
        |   └── batman.md  // <- https://example.com/videos/batman/
        └── random.md  // <- https://example.com/random/

@maiki So is this possible with the permalinks config?

  • pages section renders to root /
  • pages subsections renders as normal, respective to root /videos/batman/

Perhaps a regex-like passthrough config like this? (non-working example)

[permalinks]
    pages = "/(:slug|:section)/*"

I was hoping to avoid cluttering up the content directory with dozens of one-off subdirectories.

I’d do this a bit differently:

content/
├── pages
│   ├── about-us.md
│   └── random.md
└── videos
    ├── mary-poppins-returns.md
    └── princess-switch.md

In config, permalinks:

[permalinks]
    pages = "/:slug/"
    videos = "/videos/:slug/"

That will output:

https://example.org/about-us/
https://example.org/random/
https://example.org/videos/mary-poppins-returns/
https://example.org/videos/princess-switch/

It is a common practice, and a good one, to keep loose pages in their own section, so for this example that is pages and the /:slug/ means we can create a slug in front matter and “place” a page wherever we want.

Want https://example.org/about-us/contact/? Make a file at /content/pages/contact.md and in front matter set slug = "/about-us/contact/".

As for videos, that is a section, so it can have it’s own pattern. The one I suggested worked for most things, and you can set the slug when a video’s name doesn’t map well to URLs.

Now, the obvious omission is what happens at https://example.org/videos/. I didn’t know what you wanted that page to be. So, the default idea is a section root being a list template, listing the pages beneath it, with access to pagination, and other niceties. You can customize it, of course. You could say, add text or images in a content file, that would have the underscore: _index.html. And if you want that specific page (/videos/) to behave differently you can override in the layout template for that specific section (I’m running out of steam and have a 7 year old to wrestle, so I’ll leave it to you to figure out which template that is).

Whatcha think? Doable with your current content structure? I’m not adverse to debugging your specific site, if you’d like to contribute it as an example to our community on how to migrate an existing Jekyll site. :slight_smile:

2 Likes

Thanks @maiki & everyone for the help. I ended up taking that route instead.

I’ll submit a pull request to the docs on Jekyll migration.