Includers

Includers are awesome.  They are handy and they save typing and queries.  Includers allow you to get results back that include things related to your results.  A classic example is getting comments back with blog posts.  Here is how we could get back comments with the latest blog posts:

{'type':'post':'parent':blog.id,'count':5,'orderBy':'-publishedAt','children':{'comments':{'type':'comment'}}}

This would grab the five newest posts along with their comments.  While it may seem a bit weird to have the two levels of nesting, this is what gives the includers their power.  The first level lets us name the things we are getting back.  For example, to grab the author's name of the first comment from the first post, we would do something like this in a twig template:

{% set posts as hifi.get({'type':'post':'parent':blog.id,'count':5,'orderBy':'-publishedAt','children':{'comments':{'type':'comment'}}}) %}
{{ posts[0].children.comments[0].author }}

By requiring this naming, we can pull in multiple things in the same includer type.  So we could pull in both a set of all comments, and a set of comments by HiFi developers:

{'type':'post':'parent':blog.id,'count':5,'orderBy':'-publishedAt','children':{'comments':{'type':'comment'},'devComments':{'type':'comment','author':['Kris Jordan','Joel Sutherland']}}}

Now we would have posts.children.comments[] and posts.children.devComments[] available.

The other thing to notice, is just like anything else in HiFi, it is possible to do any kind of subquery here. 

Children

Including children is the most common type of includer.  For example, you might want to include comments when you retrieve blog posts or include subpages when you're building your main navigation.

The two things you need to do when including children are 1. giving the set a name and 2. putting together the children query.  Here is an example of grabbing blog posts with comments -- we're naming them blogcomments:

{'type':'post':'parent':blog.id,'count':5,'orderBy':'-publishedAt','children':{'blogcomments':{'type':'comment'}}}

The results that you get back will then have these available as a subobject.  So you could get these under:

results[0].children.blogcomments[]

You can do any type of query when including children, the same HiFi Query rules apply.  It is even possible to include two groups:

{'type':'post':'parent':blog.id,'count':5,'orderBy':'-publishedAt','children':{'comments':{'type':'comment'},'devComments':{'type':'comment','author':['Kris Jordan','Joel Sutherland']}}}

These would have the information available under both:

results[0].children.comments[]
results[0].children.devComments[]

It's worth noting that some comments would presumably show up in both.

It is also worth noting that it is possible to nest children as deeply as you like in the subqueries.

Relations

In HiFi it is typically easiest to just include all relations when you are fetching a post.  You can do this with the relations keyword.  Here is how you would do it:

{% set posts_with_relations as hifi.get({type: 'post', relations: '*'}) %}

This returns all related hifi objects grouped by relation name. Here is how you might use this information from the above query:

{% for post in posts_with_relations %}
    {{ post.title }}
    By:
    {% for author in post.relations.author %}
        {{ author.title }}
    {% endfor %}
    Categorized as:
    {% for category in post.relations.category %}
        {{ category.title }}
    {% endfor %}
{% endfor %}