Create new layout for an about page

I have about page in : ./content/about.md

I would like it to have a custom template so in about.md here are my settings :

+++
date = “2017-04-17T11:01:21-04:00”
draft = false
title = “About”
layout = “mylayout”
+++

I made a single.html in ./themes/mytheme/layouts/mylayout/single.html

I am getting a 404 error.

Any help would be appreciated.

5 Likes

I am going to need more information in order to help you debug this. Do you have a repo somewhere you can point me to? Or at least show me what you are working with in terms of templating?

But from what you read, am I doing this correctly? I’ll set a repo, give me 5 minutes

Try changing layout in your front matter to type

6 Likes

that works thanks!! what is the difference between type and layout in the toml?

1 Like

I don’t think there is a “layout” parameter. That file would default to the _default/single.html layout (so you shouldn’t have been getting a 404 anyway, unless you don’t have one at all, I suppose), but “type” is a way of dictating what layout is used. Read more about their stated purpose here: https://gohugo.io/content-management/types/

Not necessarily in TOML, but I think you mean in terms of how you are declaring a type and layout in your content files’ front matter.

By default, the type for a piece of content is inherited from the the content’s section. So, the file you create for content at content/posts/my-post.md automatically has a type of posts. However, you may want to keep my-post.md within that section because you want to rely on Hugo’s default behavior to render the page to yoursite.com/posts/my-post, but you want it to render according to a different layout. In this case, you can specify a type for the content that overrides the default behavior. Types are always singular.

You can then put specific layouts in a layout folder of the same name as the type (hence why it works with mylayout). You are telling Hugo that your About page, while living inside the root content section, is of the specific mylayout type. Further, you could even specify a layout that Hugo should use to render your About page:

+++
date = "2017-04-17T11:01:21-04:00"
draft = false
title = "About"
type = "mylayout"
layout = "speciallayout"
+++

In this example, Hugo will render the page according to what you create in ./themes/mytheme/layouts/mylayout/speciallayout.html. If you do not specify the layout, Hugo then looks for the the next layout in the lookup order. Here are the respective docs:

  1. For understanding what a type is in Hugo:
  1. For understanding Hugo’s lookup order for single content templates:
  1. If you are unfamiliar with the lookup order in general, the following may help as well:
4 Likes

So, @rdwatters - what I think you are saying there is indeed a “layout” parameter, but only in context of a type?

Not necessarily. If you have a posts sections and you have the following front matter for content/posts/my-post.md:

+++
date = "2017-04-17T11:01:21-04:00"
draft = false
title = "About"
layout = "mylayout"
+++

You could also create a layout at layouts/posts/mylayout.html that Hugo can use to render the page since Hugo is making an assumption about the type that is not included in the front matter.

Note: Declaring type in front matter can affect where statements like {{range where .Site.Pages "Type" "posts"}} vs {{range where .Site.Pages "Section" "posts"}}

It’s just flexible to tackle every situation but sometimes so flexible as to make my head hurt :smile:

1 Like

Although @budparr now that I’m testing it, it appears that Hugo doesn’t follow the lookup in the above example all the way down to the _default layout folder. Do you think it makes the most sense for a single content page with the following front matter…

+++
date = "2017-04-17T11:01:21-04:00"
draft = false
title = "About"
layout = "mylayout"
+++

…to check the following two locations last at the end of the lookup order (ignoring themes)?

  • layouts/_default/mylayout.html and then…
  • layouts/_default/single.html

Thoughts?

I wouldn’t expect it to look in the layouts/_default folder, but under layouts/mylayout

[[EDIT: The behavior is as expected but I noticed a bug when it comes to making changes with the live server and (possibly, I’m opening an issue) when declaring a specific layout in front matter when the layout doesn’t exist]]

1 Like

[[EDIT: The behavior is as expected but I noticed a bug when it comes to making changes with the live server and (possibly, I’m opening an issue) when declaring a specific layout in front matter when the layout doesn’t exist]]

Thank you so much for the explanations. I am wondering why my initial build did not work though? Does layout = name of file. so it should have been ./themes/mytheme/layouts/mylayout.html?

Is it better just to use type and call it a day or should layout be what I should try doing?

@stephenbe Do you have a source repo you can point me to so I have a better all-around picture of what you’re trying to accomplish. To keep this simple, you can just declare the type per @budparr 's original suggestion…

Okay I will do as @budparr suggestion. What I understood is this :

If you want a custom template use type
If you have multiple templates in one type use layouts to specify what template to use.

For exemple, if I have 10 events and I have two templates : layouts/events/event-list.html and layouts/events/event-details.html

It would be :

type =  "events"
layout = "event-list"
--
type="events"
layout = "event-details"

Correct?

Thank you so much for the quick answers by the way!! :slight_smile:

This depends on where these content files live. If they are already in content/events, you shouldn’t have to declare type = "events" because Hugo already makes that assumption.

Yes, although Hugo has some sane defaults to make your life easier. That’s why I was recommending looking at the documentation for the lookup order.

1 Like

Thank you so much! I juste had a “ah ha!” moment.

I very much appreciate your help, thank you! :slight_smile:

1 Like

Oh god now {{ .Site.BaseURL }} doesn’t work anymore…should I open a new issue @rdwatters?

Please don’t open an issue. What do you mean by it doesn’t “work” anymore?