<commit_before>[up](../../../../tree/master/Guides/sample_code), [next](../forking.md)

Indexes
=======

Mustache is a simple template language. Its [specification](https://github.com/mustache/spec) does not provide any built-in access to loop indexes. It does not provide any way to render a section at the beginning of the loop, and another section at the end. It does not help you render different sections for odd and even indexes.

If your goal is to design your templates so that they are compatible with [other Mustache implementations](https://github.com/defunkt/mustache/wiki/Other-Mustache-implementations), the best way to render indices and provide custom looping logic is to have each of your data objects provide with its index, regardless of how tedious it may be for you to prepare the rendered data.

For instance, instead of `[ { name:'Alice' }, { name:'Bob' } ]`, you would provide: `[ { name:'Alice', index:0, first:true, last:false, even:false }, { name:'Bob', index:1, first:false, last:true, even:true } ]`.


GRMustache solution: filters
----------------------------

**[Download the code](../../../../tree/master/Guides/sample_code/indexes)**

The [GRMustacheFilter](../filter.md) protocol can help you extend the mustache language, and avoid preparing your data.

Below we'll implement the special keys `position`, `isFirst`, and `isOdd`. We'll render the following template:

    {{% FILTERS}}
    <ul>
    {{# withPosition(people) }}
      <li class="{{#isOdd}}odd{{/isOdd}} {{#isFirst}}first{{/isFirst}}">
        {{ position }}:{{ name }}
      </li>
    {{/ withPosition(people) }}
    </ul>

We expect, on output, the following rendering:

    <ul>
      <li class="odd first">
        1:Alice
      </li>
      <li class=" ">
        2:Bob
      </li>
      <li class="odd ">
        3:Craig
      </li>
    </ul>
    

Our people array will be a plain array filled with plain people who don't know anything but their name. The support for the special positional keys will be entirely done by a filter object.

We can thus focus on the two subjects separately.

Let's first assume that the class PositionFilter is already written. Here is its documentation:

```objc
/**
 * A GRMustache filter that, given an array, returns another array made of
 * objects that forward all keys to the original array items, but the following:
 *
 * - position: returns the 1-based index of the item
 * - isOdd: returns YES if the position of the item is odd
 * - isFirst: returns YES if the item is at position 1
 */
@interface PositionFilter : NSObject<GRMustacheFilter>
@end
```

Well, it looks quite a good fit for our task: let's see what happens it we set the `withPosition` to be an instance of PositionFilter:

When GRMustache renders `{{# withPosition(people) }}...{{/ withPosition(people) }}`:

1. It looks for the `people` key, and finds an array of people.
2. It gives this array to the filter associated with the `withPosition` key, which is a PositionFilter instance.
3. The filter states very clearly its return value: "another array made of objects that forward all keys to the original array items, but the following: position, isOdd, isFirst.".
4. This new array is rendered by a Mustache section tag, and the inner content of the section is rendered as many times as there are items in the array.

Right. Let's focus on the `{{ position }}:{{ name }}` portion of this inner content. GRMustache will render this portion for each item in the filtered array. As stated by PositionFilter, the `position` key will be directly provided by the item. The `name` key, however, will be forwarded to the original object, which is a person, and fortunately knows its own name.

Perfect. We have everything we need to render our template:

```objc
- (NSString *)render
{
    /**
     * Our template want to render the `people` array with support for various
     * positional information on top of regular keys fetched from each person
     * of the array:
     *
     * - position: the 1-based index of the person<commit_msg>Rewrite indexes sample code with filters (WIP)<commit_after>[up](../../../../tree/master/Guides/sample_code), [next](../forking.md)

Indexes
=======

Mustache is a simple template language. Its [specification](https://github.com/mustache/spec) does not provide any built-in access to loop indexes. It does not provide any way to render a section at the beginning of the loop, and another section at the end. It does not help you render different sections for odd and even indexes.

If your goal is to design your templates so that they are compatible with [other Mustache implementations](https://github.com/defunkt/mustache/wiki/Other-Mustache-implementations), the best way to render indices and provide custom looping logic is to have each of your data objects provide with its index, regardless of how tedious it may be for you to prepare the rendered data.

For instance, instead of `[ { name:'Alice' }, { name:'Bob' } ]`, you would provide: `[ { name:'Alice', index:0, first:true, last:false, even:false }, { name:'Bob', index:1, first:false, last:true, even:true } ]`.


GRMustache solution: filters
----------------------------

**[Download the code](../../../../tree/master/Guides/sample_code/indexes)**

The [GRMustacheFilter](../filter.md) protocol can help you extend the mustache language, and avoid preparing your data.

Below we'll implement the special keys `position`, `isFirst`, and `isOdd`. We'll render the following template:

    {{% FILTERS}}
    <ul>
    {{# withPosition(people) }}
      <li class="{{#isOdd}}odd{{/isOdd}} {{#isFirst}}first{{/isFirst}}">
        {{ position }}:{{ name }}
      </li>
    {{/ withPosition(people) }}
    </ul>

We expect, on output, the following rendering:

    <ul>
      <li class="odd first">
        1:Alice
      </li>
      <li class=" ">
        2:Bob
      </li>
      <li class="odd ">
        3:Craig
      </li>
    </ul>
    

Our people array will be a plain array filled with plain people who don't know anything but their name. The support for the special positional keys will be entirely done by a filter object.

We can thus focus on the two subjects separately.

Let's first assume that the class PositionFilter is already written. Here is its documentation:

```objc
/**
 * A GRMustache filter that, given an array, returns another array made of
 * objects that forward all keys to the original array items, but the following:
 *
 * - position: returns the 1-based index of the item
 * - isOdd: returns YES if the position of the item is odd
 * - isFirst: returns YES if the item is at position 1
 */
@interface PositionFilter : NSObject<GRMustacheFilter>
@end
```

Well, it looks quite a good fit for our task: if we provide to this filter an array of people, it will return an array of objects that will be able to tell a template their position, and for all other keys, will give the original person's value. 

We have everything we need to render our template:

```objc
- (NSString *)render
{
    /**
     * Our template want to render the `people` array with support for various
     * positional information on top of regular keys fetched from each person
     * of the array:
     *
     * - position: the 1-based index of the person
{'fraction_non_alphanumeric': 0.10941370767960364, 'fraction_numerical': 0.0027525461051472614, 'mean_word_length': 3.4500918554807103, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6788287', 'n_tokens_mistral': 2012, 'n_tokens_neox': 1930, 'n_words': 949}