# Trouble understanding Hugo's page template structure?

**URL:** <https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718>\
**Category:** support\
**Created:** [January 29, 2019, 9:28pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718 "2019-01-29T21:28:15Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![araphiel](https://avatars.discourse-cdn.com/v4/letter/a/5f8ce5/32.png) [@araphiel](https://discourse.gohugo.io/u/araphiel)\
**Post date:** [January 29, 2019, 9:28pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/1 "2019-01-29T21:28:15Z")

</div>

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/](http://www.mydomain.com/random/)

How can I do something similar in Hugo?

---

<div class="post-metadata">

**Author:** ![mojoa](https://avatars.discourse-cdn.com/v4/letter/m/8491ac/32.png) [@mojoa](https://discourse.gohugo.io/u/mojoa)\
**Post date:** [January 29, 2019, 9:33pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/2 "2019-01-29T21:33:57Z")

</div>

> [@Tutorial: Make a Hugo blog from scratch](https://discourse.gohugo.io/t/make-a-hugo-blog-from-scratch/16375):
>
> Copied from the tutorial intro: In my opinion, Hugo’s current quick start is ample. It does just what the name says, gets you started you quickly . Still, there have many requests on the forums for a tutorial that dives deeper than the quick start, and gets into some templating basics. The thing you’re reading is my go at that. Starting from scratch, we’ll build a Hugo blog. For the folks out there thinking, “just show me the money already”, here’s the finished product [source code](https://github.com/zwbetz-gh/make-a-hugo-blog-from-scratch) and [demo](https://make-a-hugo-blog-from-scratch.netlify.com/). …

---

<div class="post-metadata">

**Author:** ![zwbetz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/zwbetz/32/16088_2.png) [@zwbetz](https://discourse.gohugo.io/u/zwbetz)\
**Post date:** [January 29, 2019, 9:44pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/3 "2019-01-29T21:44:52Z")

</div>

> [@araphiel](#):
>
> I have my layout templates - `_layouts/default.html`

Common [templates](https://gohugo.io/templates/) are:

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

```

* * *

> [@araphiel](#):
>
> I have my page specific markup / markdown - `_pages/foobar.html`

[Content](https://gohugo.io/content-management/organization/) lives under the `content/` folder

* * *

> [@araphiel](#):
>
> I set my url slug in the page’s front matter - `permalink: /random/`

You configure [permalinks](https://gohugo.io/content-management/urls/#permalinks) in your config file, the default file is named `config.toml`

* * *

> [@araphiel](#):
>
> The page is built at `www.mydomain.com/random/`

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.

---

<div class="post-metadata">

**Author:** ![Leo\_Merkel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/leo_merkel/32/3321_2.png) [@Leo\_Merkel](https://discourse.gohugo.io/u/Leo_Merkel)\
**Post date:** [January 30, 2019, 8:09am UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/4 "2019-01-30T08:09:46Z")

</div>

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](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](https://discourse.gohugo.io/t/see-which-template-is-used-by-hugo/9983/3)

---

<div class="post-metadata">

**Author:** ![araphiel](https://avatars.discourse-cdn.com/v4/letter/a/5f8ce5/32.png) [@araphiel](https://discourse.gohugo.io/u/araphiel)\
**Post date:** [January 30, 2019, 6:11pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/6 "2019-01-30T18:11:17Z")

</div>

@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?

 ![34%20AM](https://canada1.discourse-cdn.com/flex036/uploads/gohugo/original/2X/4/488cfa379587ea15ec72f4c201621f51f053b78c.png)

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

- ✅`/members/videos/_index.md` renders `foobar.com/videos/`
- ❌ `/members/videos/happy.md` **does not** render `foobar.com/videos/happy/`

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

---

<div class="post-metadata">

**Author:** ![zwbetz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/zwbetz/32/16088_2.png) [@zwbetz](https://discourse.gohugo.io/u/zwbetz)\
**Post date:** [January 30, 2019, 6:15pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/7 "2019-01-30T18:15:30Z")

</div>

This is because the `_index.md` in

```nohighlight
/members/videos/_index.md

```

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

---

<div class="post-metadata">

**Author:** ![Leo\_Merkel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/leo_merkel/32/3321_2.png) [@Leo\_Merkel](https://discourse.gohugo.io/u/Leo_Merkel)\
**Post date:** [January 30, 2019, 6:21pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/8 "2019-01-30T18:21:26Z")

</div>

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.

> **[marcanuy/simpleit-hugo-theme](https://github.com/marcanuy/simpleit-hugo-theme)**
>
> Responsive Hugo theme for hierarchical content websites - marcanuy/simpleit-hugo-theme

---

<div class="post-metadata">

**Author:** ![araphiel](https://avatars.discourse-cdn.com/v4/letter/a/5f8ce5/32.png) [@araphiel](https://discourse.gohugo.io/u/araphiel)\
**Post date:** [January 30, 2019, 6:35pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/9 "2019-01-30T18:35:21Z")

</div>

Sorry for blowing you all up - thanks so much

> [@araphiel](#):
>
> ![Screen Shot 2019-01-30 at 11.55.34 AM.png](https://canada1.discourse-cdn.com/flex036/uploads/gohugo/original/2X/4/488cfa379587ea15ec72f4c201621f51f053b78c.png)
> 
> 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
> 
> - ✅ `/members/videos/_index.md` renders `foobar.com/videos/`
> - ❌ `/members/videos/happy.md` **does not** render `foobar.com/videos/happy/`

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.

---

<div class="post-metadata">

**Author:** ![zwbetz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/zwbetz/32/16088_2.png) [@zwbetz](https://discourse.gohugo.io/u/zwbetz)\
**Post date:** [January 30, 2019, 6:36pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/10 "2019-01-30T18:36:39Z")

</div>

Have you tried setting a permalink for `videos`?

---

<div class="post-metadata">

**Author:** ![maiki](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/maiki/32/16384_2.png) [@maiki](https://discourse.gohugo.io/u/maiki)\
**Post date:** [January 30, 2019, 6:51pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/11 "2019-01-30T18:51:10Z")

</div>

> [@araphiel](#):
>
> 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.

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](https://gohugo.io/content-management/urls/#permalink-configuration-values). 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](https://gohugo.io/content-management/front-matter#predefined)), 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. 🙂

---

<div class="post-metadata">

**Author:** ![araphiel](https://avatars.discourse-cdn.com/v4/letter/a/5f8ce5/32.png) [@araphiel](https://discourse.gohugo.io/u/araphiel)\
**Post date:** [January 31, 2019, 5:12pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/12 "2019-01-31T17:12:22Z")

</div>

```auto
.
└── 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)

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

```

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

---

<div class="post-metadata">

**Author:** ![maiki](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/maiki/32/16384_2.png) [@maiki](https://discourse.gohugo.io/u/maiki)\
**Post date:** [February 1, 2019, 1:11am UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/13 "2019-02-01T01:11:48Z")

</div>

I’d do this a bit differently:

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

```

In config, permalinks:

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

```

That will output:

```auto
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. 🙂

---

<div class="post-metadata">

**Author:** ![araphiel](https://avatars.discourse-cdn.com/v4/letter/a/5f8ce5/32.png) [@araphiel](https://discourse.gohugo.io/u/araphiel)\
**Post date:** [February 1, 2019, 4:17pm UTC](https://discourse.gohugo.io/t/trouble-understanding-hugos-page-template-structure/16718/14 "2019-02-01T16:17:08Z")

</div>

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.
