Eleventy: Single tags treated as string rather than one item array

Created on 20 Sep 2018  路  12Comments  路  Source: 11ty/eleventy

I don't know if this is by design or if I've done something wrong, but it looks like if you have just a single tag on an item, it gets treated as a string rather than a 1 item array.

This means things go funny if you do {% for tag in tags %} - it will treat the string as an array of letters and page through each letter in turn.

For my personal site I added a filter to check if tags is an array - but it would be easier if it was one to begin with. It's a real pain not being able to do {% for tag in tags %} without first checking for one item.

Another case where it's come up: I'm attempting to recreate the tags page from the starter blog.
Here's what the starter blog looks like:
screen shot 2018-09-20 at 17 40 35
When I apply similar to my site, I get this:
screen shot 2018-09-20 at 17 41 01
Rather than a single link for the tag 'design', it's created a link for each letter.

In this case, each of these items only has a single tag, applied like this:
screen shot 2018-09-20 at 17 41 33

bug education

All 12 comments

front matter is YAML and writing tags: design tells YAML that the property tags is assigned the value design which it reads as a string. You want to define it as an array:

tags:
- design

I thought it might be something like this. I don't think it's very intuitive though.
The docs suggest the format
tags: design - this feels like something other users are likely to trip up on too.


Edit - it also feels rather fault prone. Let's say I'm a blog owner and I let people write posts. If a user ever uses just a single tag, it'll break wherever the blog uses {% for tag in tags %}. I either have to encode all uses defensively, or since collections are already a magic thing, it could just make them a one item array to be safe.

Uh, okay. You鈥檙e absolutely right. I didn鈥檛 know that.

You should always be able to iterate over something like tags. It鈥檚 a plural and implies that there might be one to many items in it. Thus, it always needs to be a list of things. tags: post is a scalar value, not a list. You can鈥檛 logically iterate over it.

Eleventy uses tags as a special front matter property to automatically create collections for each tag. There has to be some internal logic distinquishing between it being a array/list or just one element.

I don鈥檛 like that, to be honest.

I鈥檇 suggest always using lists for things that can potentially include more than one thing. If you know there won鈥檛 be a second item, then it鈥檚 not a list and then you would never want to iterate over it anyway.

I think you may be thinking of a different use case. I'm not talking about a single tag used once, but about many pages all having only a single tag. If any one of those pages tries to iterate over it's tags, it breaks.

I have several pages with the tag 'design'. And several pages with the tag 'photography' - right now I'm using collections precisely to group the design posts together and photography posts together. So far so good. Some of the pages may also have other tags.

Now within any page, I want to iterate over the tags for that page - I can't do that now because that page has a single tag (using frontmatter format tags: tag), it breaks.

Since eleventy has chosen tag to be a reserved keyword that has extra magic, it feels worth it doing the hard work here.

Any developer can't rely on doing {% for tag in tags %} on any page if there's the chance that any page has just a single tag. This is rather risky if the authors are not the same as the developers. That it still works for collections is all the more reason I feel it should be an array.

I understood you perfectly well. If you want to iterate over tags, your tags need to be iterable. A scalar property like tags: design isn鈥檛, tags: ['design'] is. Alternatively:

tags:
- design

For multiple tags:

tags:
- design
- prototype

Cool, glad we're on the same page.

I'm clear how to fix it for my case - but would like to suggest the current behaviour is risky, particularly for blogs where authors aren't developers.

As an example, here's the starter blog with a page with a single tag.
screen shot 2018-09-20 at 18 23 47
If tags are treated as a special item (collections are really helpful), we should go the whole way and protect against things like this.

Yeah @edwardhorsford that was a thing I added trying to be helpful but it鈥檒l likely end up to be more confusing than helpful. I think what should happen is that if it finds a scalar it should convert to an array behind the scenes, rather than attempt to work with both transparently.

We can make this better.

That feels like patching YAML with convenience features. Why not just remove it completely?

That feels like patching YAML with convenience features. Why not just remove it completely?

This is one of a few eleventy specific features though, it's not pure YAML (IMHO). Similar to how permalinks is a special function.

Well, my preference _now_ would be to remove it and we can add a ticket for this removal for discussion, but that鈥檇 be a breaking change and it may not be worth it. At the very least, it鈥檇 have to go into the next major version 1.0.

Major breaking change discussion/enhancement issue surfaced at #251.

In 0.5.4, Tags will always return an array, even if a single string is passed in.

This will solve most of the resulting issues but keep backwards compatibility.

Was this page helpful?
0 / 5 - 0 ratings