# .htaccess, humans.txt with template logic

**URL:** <https://discourse.gohugo.io/t/htaccess-humans-txt-with-template-logic/27624>\
**Category:** tips & tricks\
**Created:** [August 16, 2020, 3:59am UTC](https://discourse.gohugo.io/t/htaccess-humans-txt-with-template-logic/27624 "2020-08-16T03:59:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![pointyfar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/pointyfar/32/5797_2.png) [@pointyfar](https://discourse.gohugo.io/u/pointyfar)\
**Post date:** [August 16, 2020, 3:59am UTC](https://discourse.gohugo.io/t/htaccess-humans-txt-with-template-logic/27624/1 "2020-08-16T03:59:58Z")

</div>

How to have Hugo generate `.htaccess`, `humans.txt`, and other similar files while being able to use template logic and site variables.

# Option 1: Outputs

We define custom output formats.

```auto
// config.toml
[outputs]
home = ["HTML", "htaccess", "humanstxt"]

[outputFormats]
[outputFormats.htaccess]
    baseName = ""
    isPlainText = true
    mediaType = "text/htaccess"

[outputFormats.humanstxt]
    baseName = "humans"
    isPlainText = true
    mediaType = "text/plain"

```

And a custom `mediaType` in the case of `.htaccess`:

```auto
// config.toml
[mediaTypes]
  [mediaTypes."text/htaccess"]
    suffixes = ["htaccess"]

```

Then we define layouts.

```auto
// layouts/index.humanstxt.txt
// layouts/index.htaccess
{{ site.BaseURL }}

```

These generate:

```auto
// public/humans.txt
// public/.htaccess
https://example.com/

```

* * *

# Option 2: Assets\*

\*\*\*\* This only works if you will be invoking the `.Permalink` for the generated file. \*\*\*\*

```auto
// assets/txt/alsohumans.txt
{{ site.BaseURL }}

```

```auto
<!-- somewhere in your baseof/head -->
{{ $alsohumans := resources.Get "txt/alsohumans.txt" | resources.ExecuteAsTemplate "alsohumans.txt" . }}
<link type="text/plain" rel="author" href="{{$alsohumans.Permalink}}" />

```

This generates:

```auto
// public/alsohumans.txt
https://example.com/

```

* * *

These work as of time of posting.

Hugo Static Site Generator v0.74.3-DA0437B4/extended linux/amd64 BuildDate: 2020-07-23T16:30:30Z

---

<div class="post-metadata">

**Author:** ![Peter\_Prevos](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/peter_prevos/32/11548_2.png) [@Peter\_Prevos](https://discourse.gohugo.io/u/Peter_Prevos)\
**Post date:** [August 23, 2020, 12:33am UTC](https://discourse.gohugo.io/t/htaccess-humans-txt-with-template-logic/27624/2 "2020-08-23T00:33:01Z")

</div>

Great work. i was looking for a good description on how to create customer output formats.

I use this to create the htaccess content (I needed it when I migrated Wordpress to Hugo):

```
{{ range .Site.Pages }}
{{ if .Aliases }}
{{ $new := .RelPermalink }}
{{ range .Page.Aliases }}
<p>Redirect 301 {{ . }} {{ $new }}</p>
{{ end }}
{{ end }}
{{ end }}
```

---

<div class="post-metadata">

**Author:** ![egrep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/egrep/32/21832_2.png) [@egrep](https://discourse.gohugo.io/u/egrep)\
**Post date:** [May 15, 2022, 9:30am UTC](https://discourse.gohugo.io/t/htaccess-humans-txt-with-template-logic/27624/4 "2022-05-15T09:30:38Z")

</div>

Thank you for the tip! This is exactly I looked for. I’d like to share a possibility to generate `humans.txt` based on your approach.

**`config.toml`:**

```auto
# Possible 'Author' formats are:
#
# [author]
# name = 'John Doe'
# email = 'john@example.com'
# github = '@john_doe'
# location = 'Kyiv, Ukraine'
#
# OR
#
# [author]
# [author.john_doe]
# name = 'John Doe'
# email = 'john@example.com'
# github = '@john_doe'
# location = 'Kyiv, Ukraine'
# [author.jane_doe]
# name = 'Jane Doe'
# email = 'jane@example.com'
# github = '@jane_doe'
# location = 'Lviv, Ukraine'
[author]
  name = 'John Doe'
  email = 'john@example.com'
  github = '@john_doe'
  location = 'Kyiv, Ukraine'

```

**`layouts/index.humanstxt.txt`:**

```auto
{{ with site.Author }}
    {{- $author_type := (printf "%T" site.Author) }}
    {{- if (or (eq $author_type "map[string]string") (eq $author_type "map[string]interface {}")) }}
    /* TEAM */
        {{ range $i, $member := site.Author }}
            {{- if (eq (printf "%T" $member) "maps.Params") }}
                {{- partial "team-member.html" (dict "context" . "member" $member) -}}
            {{- else if (eq (printf "%T" $member) "string") }}
                {{- partial "team-member.html" (dict "context" . "member" site.Author) -}}
                {{- break -}}
            {{- end }}
        {{- end }}
    {{- end }}
{{- end }}

    /* SITE */

    Last update: {{ now.Format "2006/01/02" }}
    Language: {{ range $i, $l := site.Languages }}{{ if $i }}, {{ end }}{{ .LanguageName }}{{ end }}
    Doctype: HTML5
    Standards: HTML5, CSS3, Open Graph protocol, Schema.org
    Components: Hugo, jQuery, Ed Theme

```

**`layouts/partials/team-member.html`:**

```nohighlight

    Author: {{ $.member.name | default "-" }}
    Contact: {{ $.member.email | default "-" }}
    GitHub: {{ $.member.github | default "-" }}
    From: {{ $.member.location | default "-" }}

```

Output:

```auto
    /* TEAM */

    Author: Jane Doe
    Contact: jane@example.com
    GitHub: @jane_doe
    From: Lviv, Ukraine

    Author: John Doe
    Contact: john@example.com
    GitHub: @john_doe
    From: Kyiv, Ukraine

    /* SITE */

    Last update: 2022-05-15
    Language: English
    Doctype: HTML5
    Standards: HTML5, CSS3, Open Graph protocol, Schema.org
    Components: Hugo, jQuery, Ed Theme

```

Note, due to `{{- break -}}` in `layouts/index.humanstxt.txt` you have to use Hugo \>= 0.95.0. For more see:

- [`continue` statement in `range` block](https://discourse.gohugo.io/t/continue-statement-in-range-block/19015)
- [text/template: add break and continue support · Issue #20531 · golang/go · GitHub](https://github.com/golang/go/issues/20531)
- [Release v0.95.0 · gohugoio/hugo · GitHub](https://github.com/gohugoio/hugo/releases/tag/v0.95.0)
