Getting a specific item from a collection in Jekyll











up vote
12
down vote

favorite
6












I'm rebuilding my company's current site in Jekyll and attempting to set up the structure around a content model using objects (files in a collection) that have attributes (key/value pairs in YAML front-matter). Simple conceptual stuff designed to demonstrate effective content modeling to my team.



Anything on the site that gets reused becomes an object, with the type of object defined by the specific collection that contains its file. So, I have a "services" collection for services offered by the company, a "clients" collection, and a "people" collection with a file for each person.



The problem I'm having is referencing a specific item in a collection. For example, I want my posts to have authors. I've found a ton of solutions for this using _data, but I want my authors to have pages and collections automatically outputs a page for each person. I've been able to get _data to generate pages, but I have no control over the order in which items are listed, whereas with a collection there are a lot of ways for me to control the order.



My current solution feels hacky. I'm giving each person an id which is equal to "firstname-lastname" so in the YAML front-matter it would say id: steve-hickey. Then I use the following code to loop through every person on the site and return any that match the author-id specified in the post.



The post layout template:



---
layout: default
---

<header class="intro post-header">
<h1>{{ page.title }}</h1>
{% assign people = site.people | where:"id", page.author-id %}
{% for person in people %}
<p>Written by <a href="/about/{{ page.author-id }}/">{{ person.first-name }} {{ person.last-name }}</a> on <p>{{ page.date | date: '%B %d, %Y' }}</p></p>
{% endfor %}
</header>
<div class="post-body">

{{ content }}

</div>


A post's front-matter:



---
title: User Offboarding
layout: post
nav-area: blog
author-id: steve-hickey
---


A person file from the people collection:



---
id: steve-hickey
first-name: Steve
last-name: Hickey
job: User Experience Strategist & AUX Director
layout: person
nav-area: about
portrait-url:
---


It seems like there should be a way to identify a specific file or object based on a unique attribute that it already possesses, such as its name or url. That way I can just point to a specific object instead of evaluating all of them for a unique property I have to write. But after 3 days of searching I can't find a good answer to this.










share|improve this question


























    up vote
    12
    down vote

    favorite
    6












    I'm rebuilding my company's current site in Jekyll and attempting to set up the structure around a content model using objects (files in a collection) that have attributes (key/value pairs in YAML front-matter). Simple conceptual stuff designed to demonstrate effective content modeling to my team.



    Anything on the site that gets reused becomes an object, with the type of object defined by the specific collection that contains its file. So, I have a "services" collection for services offered by the company, a "clients" collection, and a "people" collection with a file for each person.



    The problem I'm having is referencing a specific item in a collection. For example, I want my posts to have authors. I've found a ton of solutions for this using _data, but I want my authors to have pages and collections automatically outputs a page for each person. I've been able to get _data to generate pages, but I have no control over the order in which items are listed, whereas with a collection there are a lot of ways for me to control the order.



    My current solution feels hacky. I'm giving each person an id which is equal to "firstname-lastname" so in the YAML front-matter it would say id: steve-hickey. Then I use the following code to loop through every person on the site and return any that match the author-id specified in the post.



    The post layout template:



    ---
    layout: default
    ---

    <header class="intro post-header">
    <h1>{{ page.title }}</h1>
    {% assign people = site.people | where:"id", page.author-id %}
    {% for person in people %}
    <p>Written by <a href="/about/{{ page.author-id }}/">{{ person.first-name }} {{ person.last-name }}</a> on <p>{{ page.date | date: '%B %d, %Y' }}</p></p>
    {% endfor %}
    </header>
    <div class="post-body">

    {{ content }}

    </div>


    A post's front-matter:



    ---
    title: User Offboarding
    layout: post
    nav-area: blog
    author-id: steve-hickey
    ---


    A person file from the people collection:



    ---
    id: steve-hickey
    first-name: Steve
    last-name: Hickey
    job: User Experience Strategist & AUX Director
    layout: person
    nav-area: about
    portrait-url:
    ---


    It seems like there should be a way to identify a specific file or object based on a unique attribute that it already possesses, such as its name or url. That way I can just point to a specific object instead of evaluating all of them for a unique property I have to write. But after 3 days of searching I can't find a good answer to this.










    share|improve this question
























      up vote
      12
      down vote

      favorite
      6









      up vote
      12
      down vote

      favorite
      6






      6





      I'm rebuilding my company's current site in Jekyll and attempting to set up the structure around a content model using objects (files in a collection) that have attributes (key/value pairs in YAML front-matter). Simple conceptual stuff designed to demonstrate effective content modeling to my team.



      Anything on the site that gets reused becomes an object, with the type of object defined by the specific collection that contains its file. So, I have a "services" collection for services offered by the company, a "clients" collection, and a "people" collection with a file for each person.



      The problem I'm having is referencing a specific item in a collection. For example, I want my posts to have authors. I've found a ton of solutions for this using _data, but I want my authors to have pages and collections automatically outputs a page for each person. I've been able to get _data to generate pages, but I have no control over the order in which items are listed, whereas with a collection there are a lot of ways for me to control the order.



      My current solution feels hacky. I'm giving each person an id which is equal to "firstname-lastname" so in the YAML front-matter it would say id: steve-hickey. Then I use the following code to loop through every person on the site and return any that match the author-id specified in the post.



      The post layout template:



      ---
      layout: default
      ---

      <header class="intro post-header">
      <h1>{{ page.title }}</h1>
      {% assign people = site.people | where:"id", page.author-id %}
      {% for person in people %}
      <p>Written by <a href="/about/{{ page.author-id }}/">{{ person.first-name }} {{ person.last-name }}</a> on <p>{{ page.date | date: '%B %d, %Y' }}</p></p>
      {% endfor %}
      </header>
      <div class="post-body">

      {{ content }}

      </div>


      A post's front-matter:



      ---
      title: User Offboarding
      layout: post
      nav-area: blog
      author-id: steve-hickey
      ---


      A person file from the people collection:



      ---
      id: steve-hickey
      first-name: Steve
      last-name: Hickey
      job: User Experience Strategist & AUX Director
      layout: person
      nav-area: about
      portrait-url:
      ---


      It seems like there should be a way to identify a specific file or object based on a unique attribute that it already possesses, such as its name or url. That way I can just point to a specific object instead of evaluating all of them for a unique property I have to write. But after 3 days of searching I can't find a good answer to this.










      share|improve this question













      I'm rebuilding my company's current site in Jekyll and attempting to set up the structure around a content model using objects (files in a collection) that have attributes (key/value pairs in YAML front-matter). Simple conceptual stuff designed to demonstrate effective content modeling to my team.



      Anything on the site that gets reused becomes an object, with the type of object defined by the specific collection that contains its file. So, I have a "services" collection for services offered by the company, a "clients" collection, and a "people" collection with a file for each person.



      The problem I'm having is referencing a specific item in a collection. For example, I want my posts to have authors. I've found a ton of solutions for this using _data, but I want my authors to have pages and collections automatically outputs a page for each person. I've been able to get _data to generate pages, but I have no control over the order in which items are listed, whereas with a collection there are a lot of ways for me to control the order.



      My current solution feels hacky. I'm giving each person an id which is equal to "firstname-lastname" so in the YAML front-matter it would say id: steve-hickey. Then I use the following code to loop through every person on the site and return any that match the author-id specified in the post.



      The post layout template:



      ---
      layout: default
      ---

      <header class="intro post-header">
      <h1>{{ page.title }}</h1>
      {% assign people = site.people | where:"id", page.author-id %}
      {% for person in people %}
      <p>Written by <a href="/about/{{ page.author-id }}/">{{ person.first-name }} {{ person.last-name }}</a> on <p>{{ page.date | date: '%B %d, %Y' }}</p></p>
      {% endfor %}
      </header>
      <div class="post-body">

      {{ content }}

      </div>


      A post's front-matter:



      ---
      title: User Offboarding
      layout: post
      nav-area: blog
      author-id: steve-hickey
      ---


      A person file from the people collection:



      ---
      id: steve-hickey
      first-name: Steve
      last-name: Hickey
      job: User Experience Strategist & AUX Director
      layout: person
      nav-area: about
      portrait-url:
      ---


      It seems like there should be a way to identify a specific file or object based on a unique attribute that it already possesses, such as its name or url. That way I can just point to a specific object instead of evaluating all of them for a unique property I have to write. But after 3 days of searching I can't find a good answer to this.







      jekyll liquid






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 8 '15 at 17:55









      Steve Hickey

      6316




      6316
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          14
          down vote



          accepted










          If people are unique in your collection {% assign author = site.people | where:"id", page.author-id %} will return an array with one element.
          In order to directly access this element do :



          {% assign author = site.people | where:"id", page.author-id  | first %}


          This grab the first (and only) element in you array. You now do {{ author.anykey }} directly.






          share|improve this answer























          • Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
            – Steve Hickey
            Dec 9 '15 at 3:28













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f34162726%2fgetting-a-specific-item-from-a-collection-in-jekyll%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          14
          down vote



          accepted










          If people are unique in your collection {% assign author = site.people | where:"id", page.author-id %} will return an array with one element.
          In order to directly access this element do :



          {% assign author = site.people | where:"id", page.author-id  | first %}


          This grab the first (and only) element in you array. You now do {{ author.anykey }} directly.






          share|improve this answer























          • Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
            – Steve Hickey
            Dec 9 '15 at 3:28

















          up vote
          14
          down vote



          accepted










          If people are unique in your collection {% assign author = site.people | where:"id", page.author-id %} will return an array with one element.
          In order to directly access this element do :



          {% assign author = site.people | where:"id", page.author-id  | first %}


          This grab the first (and only) element in you array. You now do {{ author.anykey }} directly.






          share|improve this answer























          • Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
            – Steve Hickey
            Dec 9 '15 at 3:28















          up vote
          14
          down vote



          accepted







          up vote
          14
          down vote



          accepted






          If people are unique in your collection {% assign author = site.people | where:"id", page.author-id %} will return an array with one element.
          In order to directly access this element do :



          {% assign author = site.people | where:"id", page.author-id  | first %}


          This grab the first (and only) element in you array. You now do {{ author.anykey }} directly.






          share|improve this answer














          If people are unique in your collection {% assign author = site.people | where:"id", page.author-id %} will return an array with one element.
          In order to directly access this element do :



          {% assign author = site.people | where:"id", page.author-id  | first %}


          This grab the first (and only) element in you array. You now do {{ author.anykey }} directly.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '16 at 11:41

























          answered Dec 8 '15 at 21:04









          David Jacquel

          36.3k273103




          36.3k273103












          • Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
            – Steve Hickey
            Dec 9 '15 at 3:28




















          • Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
            – Steve Hickey
            Dec 9 '15 at 3:28


















          Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
          – Steve Hickey
          Dec 9 '15 at 3:28






          Thanks! I ended up finding this solution somewhere. Slightly different syntax than yours, but same exact idea. Yours is less verbose though, so I think I'll swap to that. {% assign author = site.people | where: 'id', page.author-id %} {% assign author = author[0] %}
          – Steve Hickey
          Dec 9 '15 at 3:28




















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f34162726%2fgetting-a-specific-item-from-a-collection-in-jekyll%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()