summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Turnbull <realdavidturnbull@gmail.com>2017-06-12 16:03:08 +1000
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-06-12 08:03:08 +0200
commit0f8f51414d9e600129353781c41aded7c83a3947 (patch)
tree29c3daa94df300e11cf4cac7add7f08e77b97c5a
parent39408925fd649ff202470c300d79bff457e52bcc (diff)
docs: Rewrite “Archetypes” article
-rw-r--r--docs/content/content/archetypes.md350
-rw-r--r--docs/static/img/content/archetypes/archetype-hierarchy.pngbin0 -> 38799 bytes
2 files changed, 265 insertions, 85 deletions
diff --git a/docs/content/content/archetypes.md b/docs/content/content/archetypes.md
index d510456a9..580783dec 100644
--- a/docs/content/content/archetypes.md
+++ b/docs/content/content/archetypes.md
@@ -11,140 +11,320 @@ weight: 50
toc: true
---
-In Hugo v0.11, we introduced the concept of a content builder. Using the CLI
-command <code>hugo new <em>[path/to/my/content]</em></code>, an author could
-create an empty content file, with the date and title automatically defined in
-the front matter of the post. While this was a welcome feature, active writers
-need more flexibility.
+Typically, each piece of content you create within a Hugo project will have [front matter](/content/front-matter/) that follows a consistent structure. If you write blog posts, for instance, you might use the following front matter for the vast majority of those posts:
-When defining a custom content type, you can use an **archetype** as a way to
-define the default metadata for a new post of that type.
+```toml
++++
+title = ""
+date = ""
+slug = ""
+tags = [
+ ""
+]
+categories = [
+ ""
+]
+draft = true
++++
+```
+
+You can always add non-typical front matter to any piece of content, but since it takes extra work to develop a theme that handles unique metadata, consistency is simpler.
+
+With this in mind, Hugo has a convenient feature known as *archetypes* that allows users to define default front matter for new pieces of content.
-**Archetypes** are quite literally archetypal content files with pre-configured
-[front matter](/content/front-matter). An archetype will populate each new
-content file of a given type with any default metadata you've defined whenever
-you run the `hugo new` command.
+By using archetypes, we can:
-## Example
+1. **Save time**. Stop writing the same front matter over and over again.
+2. **Avoid errors**. Reduce the odds of typos, improperly formatted syntax, and other simple mistakes.
+3. **Focus on more important things**. Avoid having to remember all of the fields that need to be associated with each piece of content. (This is particularly important for larger projects with complex front matter and a variety of content types.)
-### Step 1. Creating an archetype
+Let's explore how they work.
-In the following example scenario, suppose we have a blog with a single content
-type (blog post). Our imaginary blog will use ‘tags’ and ‘categories’ for its
-taxonomies, so let's create an archetype file with ‘tags’ and ‘categories’
-pre-defined:
+## Built-in Archetypes
-#### archetypes/default.md
+If you've been using Hugo for a while, there's a decent chance you've come across archetypes without even realizing it. This is because Hugo includes a basic, built-in archetype that is used by default whenever it generates a content file.
+
+To see this in action, open the command line, navigate into your project's directory, and run the following command:
+
+```bash
+hugo new hello-world.md
+```
+
+This `hugo new` command creates a new content file inside the project's `content` directory — in this case, a file named `hello-world.md` — and if you open this file, you'll notice it contains the following front matter:
```toml
+++
-tags = ["x", "y"]
-categories = ["x", "y"]
+date = "2017-05-31T15:18:11+10:00"
+draft = true
+title = "hello world"
+++
```
-> __CAVEAT:__ Some editors (e.g. Sublime, Emacs) do not insert an EOL (end-of-line) character at the end of the file (i.e. EOF). If you get a [strange EOF error](/troubleshooting/strange-eof-error/) when using `hugo new`, please open each archetype file (i.e.&nbsp;`archetypes/*.md`) and press <kbd>Enter</kbd> to type a carriage return after the closing `+++` or `---` as necessary.
+Here, we can see that three fields have been added to the document: a `title` field that is based on the file name we defined, a `draft` field that ensures this content won't be published by default, and a `date` field that is auto-populated with the current date and time in the [RFC 3339](https://stackoverflow.com/questions/522251/whats-the-difference-between-iso-8601-and-rfc-3339-date-formats) format.
+This, in its most basic form, is an example of an archetype. To understand how useful they can be though, it's best if we create our own.
-### Step 2. Using the archetype
+## Creating Archetypes
-Now, with `archetypes/default.md` in place, let's create a new post in the `post`
-section with the `hugo new` command:
+In this section, we're going to create an archetype that will override the built-in archetype, allowing us to define custom front matter that will be included in any content files that we generate with the `hugo new` command.
- $ hugo new post/my-new-post.md
+To achieve this, create a file named `default.md` inside the `archetypes` folder of a Hugo project. (If the folder doesn't exist, create it.)
-Hugo will now create the file with the following contents:
+Then, inside this file, define the following front matter:
-#### content/post/my-new-post.md
+```toml
++++
+slug = ""
+tags = []
+categories = []
+draft = true
++++
+```
+
+You'll notice that we haven't defined a `title` or `date` field. This is because Hugo will automatically add these fields to the beginning of the front matter. We do, however, need to define the `draft` field if we want it to exist in our front matter.
+
+You'll also notice that we're writing the front matter in the TOML format. It's possible to define archetype front matter in other formats, but a setting needs to be changed in the configuration file for this to be possible. See the "[Archetype Formats](#archetype-formats)" section of this article for more details.
+
+Next, run the following command:
+
+```bash
+hugo new my-archetype-example.md
+```
+
+This command will generate a file named `my-archetype-example.md` inside the `content` directory, and this file will contain the following output:
```toml
+++
-title = "my new post"
-date = "2015-01-12T19:20:04-07:00"
-tags = ["x", "y"]
-categories = ["x", "y"]
+categories = []
+date = "2017-05-31T15:21:13+10:00"
+draft = true
+slug = ""
+tags = []
+title = "my archetype example"
+++
```
-We see that the `title` and `date` variables have been added, in addition to the
-`tags` and `categories` variables which were carried over from `archetype/default.md`.
+As we can see, the file contains the `title` and `date` property that Hugo created for us, along with the front matter that we defined in the `archetypes/default.md` file.
+
+You'll also notice that the fields have been sorted into alphabetical order. This is an unintentional side-effect that stems from the underlying code libraries that Hugo relies upon. It is, however, [a known issue that is actively being discussed](https://github.com/spf13/hugo/issues/452).
-Congratulations! We have successfully created an archetype and used it to
-quickly scaffold out a new post. But wait, what if we want to create some content
-that isn't exactly a blog post, like a profile for a musician? Let's see how
-using **archetypes** can help us out.
+## Section Archetypes
-### Creating custom archetypes
+By creating the `archetypes/default.md` file, we've created a default archetype that is more useful than the built-in archetype, but since Hugo encourages us to [organize our content into sections](/content/sections/), each of which will likely have different front matter requirements, a "one-size-fits-all" archetype isn't necessarily the best approach.
-Previously, we had created a new content type by adding a new subfolder to the
-content directory. In this case, its name would be `content/musician`. To begin
-using a `musician` archetype for each new `musician` post, we simply need to
-create a file named after the content type called `musician.md`, and put it in
-the `archetypes` directory, similar to the one below.
+To accommodate for this, Hugo allows us to create archetypes for each section of our project. This means, whenever we generate content for a certain section, the appropriate front matter for that section will be automatically included in the generated file.
-#### archetypes/musician.md
+To see this in action, create a "photo" section by creating a directory named "photo" inside the `content` directory.
+
+Then create a file named `photo.md` inside the `archetypes` directory and include the following front matter inside this file:
```toml
+++
-name = ""
-bio = ""
-genre = ""
+image_url = ""
+camera = ""
+lens = ""
+aperture = ""
+iso = ""
+draft = true
+++
```
-Now, let's create a new musician.
+Here, the critical detail is that the `photo.md` file in the `archetypes` directory is named after the `photo` section that we just created. By sharing a name, Hugo can understand that there's a relationship between them.
- $ hugo new musician/mozart.md
+Next, run the following command:
-This time, Hugo recognizes our custom `musician` archetype and uses it instead of
-the default one. Take a look at the new `musician/mozart.md` post. You should see
-that the generated file's front matter now includes the variables `name`, `bio`,
-and `genre`.
+```bash
+hugo new photo/my-pretty-cat.md
+```
-#### content/musician/mozart.md
+This command will generate a file named `my-pretty-cat.md` inside the `content/photo` directory, and this file will contain the following output:
```toml
+++
-title = "mozart"
-date = "2015-08-24T13:04:37+02:00"
-name = ""
-bio = ""
-genre = ""
+aperture = ""
+camera = ""
+date = "2017-05-31T15:25:18+10:00"
+draft = true
+image_url = ""
+iso = ""
+lens = ""
+title = "my pretty cat"
++++
+```
+
+As we can see, the `title` and `date` fields are still included by Hugo, but the rest of the front matter is being generated from the `photo.md` archetype instead of the `default.md` archetype.
+
+### Tip: Default Values
+
+To make archetypes more useful, define default values for any fields that will always be set to a range of limited options. In the case of the `photo.md` archetype, for instance, you could include lists of the various cameras and lenses that you own:
+
+```toml
++++
+image_url = ""
+camera = [
+ "Sony RX100 Mark IV",
+ "Canon 5D Mark III",
+ "iPhone 6S"
+]
+lens = [
+ "Canon EF 50mm f/1.8",
+ "Rokinon 14mm f/2.8"
+]
+aperture = ""
+iso = ""
+draft = true
++++
+```
+
+Then, after generating a content file, simply remove the values that aren't relevant. This saves you from typing out the same options over and over again while ensuring consistency in how they're written.
+
+## Scaffolding Content
+
+Archetypes aren't limited to defining default front matter. They can also be used to define a default structure for the body of Markdown documents.
+
+For example, imagine creating a `review.md` archetype for the purpose of writing camera reviews. This is what the front matter for such an archetype might look like:
+
+```toml
++++
+manufacturer = ""
+model = ""
+price = ""
+releaseDate = ""
+rating = ""
++++
+```
+
+But reviews tend to follow strict formats and need to answer specific questions, and it's with these expectations of precise structure that archetypes can prove to be even more useful.
+
+For the sake of writing reviews, for instance, we could define the structure of a review beneath the front matter of the `review.md` file:
+
+```markdown
++++
+manufacturer = ""
+model = ""
+price = ""
+releaseDate = ""
+rating = ""
+++
+
+## Introduction
+
+## Sample Photos
+
+## Conclusion
```
-## Using a different front matter format
+Then, whenever we use the `hugo new` command to create a new review, not only will the default front matter be copied into the newly created Markdown document, but the body of the `review.md` archetype will also be copied.
+
+To take this further though — and to ensure authors on multi-author websites are on the same page about how content should be written — we could include notes and reminders within the archetype:
+
+```markdown
++++
+manufacturer = ""
+model = ""
+price = ""
+releaseDate = ""
+rating = ""
++++
+
+## Introduction
+
+<!--
+ What is the selling point of the camera?
+ What has changed since last year's model?
+ Include a bullet-point list of key features.
+-->
+
+## Sample Photos
+
+<!-- TODO: Take at least 12 photos in a variety of situations. -->
-By default, the front matter will be created in the TOML format
-regardless of what format the archetype is using.
+## Conclusion
-You can specify a different default format in your site-wide config file
-(e.g. `config.toml`) using the `MetaDataFormat` directive.
-Possible values are `"toml"`, `"yaml"` and `"json"`.
+<!--
+ Is this camera worth the money?
+ Does it accomplish what it set out to achieve?
+ Are there any specific groups of people who should/shouldn't buy it?
+ Would you recommend it to a friend?
+ Are there alternatives on the horizon?
+-->
+
+```
+
+That way, each time we generate a new content file, we have a series of handy notes to push us closer to a piece of writing that's suitable for publishing.
+
+(If you're wondering why the notes are wrapped in the HTML comment syntax, it's to ensure they won't appear inside the preview window of whatever Markdown editor the author happens to be using. They're not strictly necessary though.)
+
+This is still a fairly simple example, but if your content usually contains a variety of components — headings, bullet-points, images, [short-codes](/extras/shortcodes/), etc — it's not hard to see the time-saving benefits of placing these components in the body of an archetype file.
+
+## Theme Archetypes
+
+Whenever you generate a content file with the `hugo new` command, Hugo will start by searching for archetypes in the `archetypes` directory, initially looking for an archetype that matches the content's section and falling-back on the `default.md` archetype (if one is present). If no archetypes are found in this directory, Hugo will continue its search in the `archetypes` directory of the currently active theme. In other words, it's possible for themes to come packaged with their own archetypes, ensuring that users of that theme format their content files with correctly structured front matter.
+
+To allow Hugo to use archetypes from a theme, [that theme must be activated via the project's configuration file](/themes/usage/):
+
+```toml
+theme = "ThemeNameGoesHere"
+```
-## Which archetype is being used
+If an archetype doesn't exist in the `archetypes` directory at the top-level of a project or inside the `archetypes` directory of an active theme, the built-in archetype will be used.
-The following rules apply when creating new content:
+{{< figure src="/img/content/archetypes/archetype-hierarchy.png" alt="How Hugo Decides Which Archetype To Use" >}}
-* If an archetype with a filename matching the new post's [content type](/content/types) exists, it will be used.
-* If no match is found, `archetypes/default.md` will be used.
-* If neither is present and a theme is in use, then within the theme:
- * If an archetype with a filename that matches the content type being created, it will be used.
- * If no match is found, `archetypes/default.md` will be used.
-* If no archetype files are present, then the one that ships with Hugo will be used.
+## Archetype Formats
-Hugo provides a simple archetype which sets the `title` (based on the
-file name) and the `date` in RFC&nbsp;3339 format based on
-[`now()`](http://golang.org/pkg/time/#Now), which returns the current time.
+By default, the `hugo new` command will generate front matter in the TOML format. This means, even if we define the front matter in our archetype files as YAML or JSON, it will be converted to the TOML format before it ends up in our content files.
+
+Fortunately, this functionality can be overwritten.
+
+Inside the project's configuration file, simply define a `metaDataFormat` property:
+
+```toml
+metaDataFormat = ""
+```
+
+Then set this property to any of the following values:
+
+* toml
+* yaml
+* json
+
+By defining this option, any front matter will be generated in your preferred format.
+
+It's worth noting, however, that when generating front matter in the TOML format, you might encounter the following error:
+
+```bash
+Error: cannot convert type <nil> to TomlTree
+```
+
+This is because, to generate TOML, all of the fields in the front matter need to have a default value, even if that default value is just an empty string.
+
+For example, this YAML would *not* successfully compile into the TOML format:
+
+```yaml
+---
+slug:
+tags:
+categories:
+draft:
+---
+```
+
+But this YAML *would* successfully compile:
+
+```yaml
+---
+slug: ""
+tags:
+ -
+categories:
+ -
+draft: true
+---
+```
-> *Note: `hugo new` does not automatically add `draft = true` when the user
-> provides an archetype. This is by design, rationale being that
-> the archetype should set its own value for all fields.
-> `title` and `date`, which are dynamic and unique for each piece of content,
-> are the sole exceptions.*
+It's a subtle yet important detail to remember.
-The content type is automatically detected based on the file path passed to the
-Hugo CLI command <code>hugo new <em>[my-content-type/post-name]</em></code>. To
-override the content type for a new post, include the `--kind` flag during creation.
+## Notes
-> *Note: if you wish to use archetypes that ship with a theme, the theme MUST be specified in your `config.toml`.*
+* Prior to Hugo v0.13, some users received [an "EOF" error when using archetypes](https://github.com/spf13/hugo/issues/776), related to what text editor they used to create the archetype. As of Hugo v0.13, this error has been [resolved](https://github.com/spf13/hugo/pull/785).
diff --git a/docs/static/img/content/archetypes/archetype-hierarchy.png b/docs/static/img/content/archetypes/archetype-hierarchy.png
new file mode 100644
index 000000000..cb0d0bcf4
--- /dev/null
+++ b/docs/static/img/content/archetypes/archetype-hierarchy.png
Binary files differ