# Pulling a data file based on filename

**URL:** <https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967>\
**Category:** support\
**Created:** [March 26, 2015, 12:02pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967 "2015-03-26T12:02:43Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![adamliptrot](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/adamliptrot/32/338_2.png) [@adamliptrot](https://discourse.gohugo.io/u/adamliptrot)\
**Post date:** [March 26, 2015, 12:02pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/1 "2015-03-26T12:02:43Z")

</div>

I have data files with filenames set to the same as the content files they relate to, for example:

```
content / post / content-item.md
data / content-item.toml

```

I need to have this set-up as the data files are auto-generated from an API (usually I’d put this info into the page param).

What I’ve been doing is having a param in the data file such as  
`post = "content-item"`  
and looping through the data files, comparing the post param to the slug on the content item in order to render out the correct file contents. This works fine, but I’d like to get rid of the requirement of the additional param.

Is there a way of filtering `{{ range .Site.Data }}` based on the slug directly?

(In existing example terms as on [http://gohugo.io/extras/datafiles/](http://gohugo.io/extras/datafiles/) I’d like get a specific discography based on a filename set in a variable).

Thanks

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [March 26, 2015, 12:25pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/2 "2015-03-26T12:25:12Z")

</div>

@tatsushid is the expert on this, but you can use the where filter (see doc) with params (like post in your case) with all its operators.

I guess you can also use it with Page with all its fields and methods. But you ask for several different things, so it’s hard to give a simple answer.

Test it.

---

<div class="post-metadata">

**Author:** ![biztos](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/biztos/32/373_2.png) [@biztos](https://discourse.gohugo.io/u/biztos)\
**Post date:** [April 12, 2015, 1:05pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/3 "2015-04-12T13:05:31Z")

</div>

I have this problem too, and I thought I could solve it with code like:

```
{{ range where $.Site.Data.places "name" .Params.data_name }}
   {{ . }}
{{ end }}

```

…based on the documentation at [http://gohugo.io/templates/functions/](http://gohugo.io/templates/functions/)

Here I would have for instance:

```
# data/places/first.toml
name = "foo"

```

…and in the Front Matter for content/places/first.md I would specify

```
data_name = "foo"

```

However it doesn’t work, and gives me this error:

```
ERROR: (...) error calling where: can't iterate over map[string]interface {}

```

What I really want to do, like @adamliptrot, is get the struct for a data file by name (sans extension), so I don’t have to bother with the “data\_name” business and can do it based on the path. That is, access the value of the map by its key. But I am perfectly willing to have a param/property pair if that’s what it takes.

Any suggestions? Is this a bug?

By the way, my use case is a multilingual site in which each “place” has several different content items (one per language) but they all share the same core data (address, url, etc).

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [April 12, 2015, 4:22pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/4 "2015-04-12T16:22:14Z")

</div>

You are linking to the doc; please read it:

```
Works on lists, taxonomies, terms, groups

```

It should maybe say that the list quantity is Pages, but this does not include some ad hoc string map.

The error says it’s a map, so that is a hint.

The `index` func may help.

---

<div class="post-metadata">

**Author:** ![robmuh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/robmuh/32/1302_2.png) [@robmuh](https://discourse.gohugo.io/u/robmuh)\
**Post date:** [March 28, 2016, 1:37pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/5 "2016-03-28T13:37:59Z")

</div>

Here’s another example that works nicely for creating entirely data-driven hugo sites.

Inside the `data/person/demo.toml` file we have a basic example person:

```
first = "Demo"
last = "Person"
pubname = "Demo"
github = "youraccount"

```

Then in `layouts/student/block.html` view template, (which I use to include in the `_default/single.html` template):

```
{{ with (index .Site.Data.person (substr $.File.LogicalName 0 -3)) }}
<div class="student">
  <div class="student__pubname">{{ .pubname }}</div>
</div>
{{ end }}

```

Notice that the date is a logical `person` and the template is for a `student` type. This is because in the larger application I only have `person` logical data types and cast them to roles and views using this method of type views and content, which brings us to the `content/student/demo.md` file. It’s empty. Just add it. This is because as far as I know, Hugo doesn’t actually create any single page unless there is a corresponding content file of some kind. At first this seems annoying, but turns out it is not that bad and allows you to turn on or off a page simple by removing or touching the content file.

---

<div class="post-metadata">

**Author:** ![STQOE](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/stqoe/32/3292_2.png) [@STQOE](https://discourse.gohugo.io/u/STQOE)\
**Post date:** [June 17, 2017, 8:25am UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/6 "2017-06-17T08:25:21Z")

</div>

Thanks for this solution @robmuh. I don’t quite grasp data files fully and this is as close as got to getting mine to work how I’d like them too. Using this method how would one then range through data file?

---

<div class="post-metadata">

**Author:** ![iffy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/iffy/32/15470_2.png) [@iffy](https://discourse.gohugo.io/u/iffy)\
**Post date:** [October 29, 2021, 8:59pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/7 "2021-10-29T20:59:31Z")

</div>

I was running into this same issue and wanted to post my full solution. Hopefully it will help someone.

I’m porting a blog from Jekyll and have this structure for my comments:

```nohighlight
data/blog/comments/
├── some-post/
│ ├── entry202010233322.json
│ └── entry202009014483.json
└── another-post/
    └── entry201910233322.json

```

The `some-post` and `another-post` names correspond to blog post slugs like this:

```nohighlight
content/blog/
├── 2020-01-01-some-post/
│ └── index.md
└── 2021-01-02-another-post/
    └── index.md

```

In my `single.html` template I eventually got it to iterate over comments corresponding to the current post with the following (relying on a `slug` attribute being defined in each post):

```auto
{{ with (index .Site.Data.blog.comments .Params.slug ) }}
  {{ range . }}
    ...
  {{ end }}
{{ end }}

```

And to base it on the filename of the blog post rather than `.Params.slug` I did this to chop off the date portion of the parent directory’s name (the first 11 characters):

```auto
{{ $slug := substr (index (split .File.Dir "/") 1) 11 }}
{{ with (index .Site.Data.blog.comments $slug) }}
  {{ range . }}
      ...
  {{ end }}
{{ end }}

```

With either of the above, that inner `{{ range . }}` lets me access comment data like `{{ .name }}` and `{{ .comment }}`.

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [October 29, 2021, 9:33pm UTC](https://discourse.gohugo.io/t/pulling-a-data-file-based-on-filename/967/8 "2021-10-29T21:33:22Z")

</div>


