Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard data model for individual templates, items in a collection, pages in pagination #338

Closed
zachleat opened this issue Dec 9, 2018 · 15 comments
Labels
enhancement: favorite Vanity label! The maintainer likes this enhancement request a lot. enhancement feature: 🥸 API consistency high-priority needs-votes A feature request on the backlog that needs upvotes or downvotes. Remove this label when resolved.

Comments

@zachleat
Copy link
Member

zachleat commented Dec 9, 2018

Per @paulrobertlloyd documentation:

Individual Template Collection Item or Pagination Item
page.url item.url should be item.page.url
page.date item.date should be item.page.date
page.inputPath item.inputPath should be item.page.inputPath
page.outputPath item.outputPath should be item.page.outputPath
page.fileSlug item.fileSlug should be item.page.fileSlug
content or layoutContent (only available in layouts) item.templateContent should be item.content
title item.data.title should be item.title
foobar item.data.foobar should be item.foobar

https://www.11ty.io/docs/collections/#individual-collection-items-(useful-for-sort-callbacks)

@zachleat zachleat added enhancement needs-votes A feature request on the backlog that needs upvotes or downvotes. Remove this label when resolved. labels Dec 9, 2018
@zachleat
Copy link
Member Author

zachleat commented Dec 9, 2018

This repository is now using lodash style issue management for enhancements. This means enhancement issues will now be closed instead of leaving them open.

The enhancement backlog can be found here: https://github.com/11ty/eleventy/issues?utf8=%E2%9C%93&q=label%3Aneeds-votes+sort%3Areactions-%2B1-desc+

Don’t forget to upvote the top comment with 👍!

@zachleat zachleat closed this as completed Dec 9, 2018
@zachleat zachleat added the enhancement: favorite Vanity label! The maintainer likes this enhancement request a lot. label Dec 9, 2018
@zellwk
Copy link

zellwk commented Dec 9, 2018

I remember I had an error where I could only get page date with ``page.data.date`. Can't remember how to reproduce this error, but I thought you should know. Didn't file an issue then. Will update again if I encounter the error.

Otherwise, everything else looks good! :D

@edwardhorsford
Copy link
Contributor

Per #280, I'd really like if paginated pages exposed the key of the thing currently being iterated.

@zachleat
Copy link
Member Author

zachleat commented Jul 8, 2019

Per https://mobile.twitter.com/zachleat/status/1148228091703152640 it might be nice to also expose the inputContent of the template in both page and collection items.

I believe this might be already on the issue somewhere but was unable to track it down in a search. If someone finds it please link it up!

@Ryuno-Ki
Copy link
Contributor

Ryuno-Ki commented Jul 8, 2019

inputContent is only mentioned in #13 and #179 beside here.

@edwardhorsford
Copy link
Contributor

It's been a while since I looked at it, but I think inputContent would have made my rss feed much easier (not built yet because the rendered html was harder to work with)

@Munter
Copy link
Contributor

Munter commented Jul 17, 2019

I just want to mention I had a very hard time finding this information since it isn't really clear from the docs that custom data properties are exposed in the global scope of the individual template.

My troubles were further increased by not being able to json stringify many of the data structures inside the template because of circular references. Otherwise I normally just use <pre>{{ page || json }}</pre> to see what's available to me. However, this failed completely when trying with page.data. There is also no good way to have liquid json stringify its outer scope.

So essentially, as a first time user, I had to do a LOT of guessing and googling until I finally found this page

@paulrobertlloyd
Copy link
Contributor

paulrobertlloyd commented Mar 24, 2020

I have an additional use case for having a consistent/predictable data model for page frontmatter data.


I’m trying to create pages from data. I have a global data file that contains an array of data, then formats this in way that reflects the page data model used internally by 11ty:

const slugify = require('@sindresorhus/slugify');

module.exports = function () {
  const things = [{
    title: 'Foo',
    summary: 'Bar.'
  }, {
    title: 'Baz',
    summary: 'Qux.'
  }];

  return things.map(thing => {
    const fileSlug = slugify(thing.title);

    return {
      date: new Date(),
      fileSlug,
      url: `/things/${fileSlug}`,
      data: {
        layout: 'thing',
        title: thing.title,
        summary: thing.summary
      }
    };
  });
};

This provides following data object for each item:

{
  date: '2020-03-23T09:17:41.270+0000',
  fileSlug: 'foo',
  url: '/things/foo',
  data: {
    layout: 'thing',
    title: 'Foo',
    summary: 'Bar'
  }
}

I can create pages by paginating over this data, and give each item in the pagination array the alias page:

---
layout: thing
title: Thing
pagination:
  data: things
  size: 1
  alias: page
permalink: "projects/things/{{ page.fileSlug }}.html"
---

This means in my templates I can call the following variables:

{{ page.data.title }}
{{ page.data.summary }}

However, for pages not created this way, I need to use the following variables:

{{ title }}
{{ summary }}

Might it be an idea to maintain the shorter variables for frontmatter data (e.g. {{ foo }}, but as aliases to the ‘true’ variable name (e.g. {{ page.data.foo }}).

This would also maintain consistency with how you loop over collection items; you can’t use {{ foo }} but have to use {{ item.data.foo }}.

Does this make any sense?

@paulrobertlloyd
Copy link
Contributor

paulrobertlloyd commented Apr 30, 2020

@zachleat I think this issue is closely related to computed data, at least from my experience. Much of my use of computed data is an attempt to expose a predictable and consistent API for templates; were that already the case, my use of this new feature would be solely for computing data, not reassigning values.

I say this having now found myself with a variable in my templates called item.data.venue.data.venue.title 😅 That said, I’ve arrived at this point because I’m addressing data from a collection (called venue) created by pagination (with the alias venue) which uses data from global data, so maybe this is an accurate reflection! 🤪

@paulrobertlloyd
Copy link
Contributor

Really hoping to see this breaking change make an appearance in upcoming betas for v1.0 😉

@hidegh
Copy link

hidegh commented Mar 10, 2021

@zachleat

  1. missing page.data on the frontmatter (post) - will this be addressed? it's a BUG!

  2. page.data.tags neither page.tags is avail. on the fontmatter
  3. varialbes as titlt | tags - variable pollution

Solution for Nr. 3 would be:

  • introduce full page.data on the template in v1.0
  • mark shortcuts as obsolete / becoming obsolete (summary aft. build)
  • remove them in the next released version

BUG: on the page template, i'm not able to display categories, as page.data, thus page.data.categories does not exists:
image


detailed desc.:

there seems to be a mess with page object when used in template. it's ok that in collection we have to use item.page but unfortunately the item.page is not the same as the page object on the given page template.

so when using custom filter, we might got in trouble if i use:
page | myFilter
whereas collections['my_coll'][0].page | myFilter would work as intended (as this object does have data property filled)

on the template, we don't have: {{ page.data.tags }}, neither {{ page.tags }} but we do have {{ tags }}. these direct shortcuts probably do hurt also (code / variable pollution, that JavaScript tries to solve with IIFE, modules, ...)


comparison:

comparing 11ty to other frameworks, when considering the object model, this shortcoming and inconsistency is one of the 1st things that really does bother me. haven't found such exception in jekyll, nor hugo, nor hexo (althoug last one I javent checked deeply).

@kvz
Copy link

kvz commented Sep 19, 2022

To add to my confusion there also is item.data.page.excerpt :) Possibly for a good reason but as a new user that isn't immediately clear to me. Coming from Jekyll, I also think it would also be nice if include variables were scoped.

@pdehaan
Copy link
Contributor

pdehaan commented Sep 19, 2022

FWIW, since I was looking at this the other day… page.excerpt comes from https://www.11ty.dev/docs/data-frontmatter-customize/#example-parse-excerpts-from-content when you set the front matter parsing options to extract excerpts based on a separator.

@kvz
Copy link

kvz commented Sep 19, 2022

Ah, thank you ❤️

@zachleat
Copy link
Member Author

Some work will ship on this with #1522 (you can see those changes better defined in #2695) but I would consider the inconsistency in collection items that data is not available at the top level as properties to be one of the last remaining items here.

https://www.11ty.dev/docs/collections/#collection-item-data-structure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement: favorite Vanity label! The maintainer likes this enhancement request a lot. enhancement feature: 🥸 API consistency high-priority needs-votes A feature request on the backlog that needs upvotes or downvotes. Remove this label when resolved.
Projects
None yet
Development

No branches or pull requests

9 participants