<p>This isn't really a job for the Element API plugin. You can accomplish what you want much easier by just creating a plain ol' Twig template (e.g. <code>templates/updates.json</code>) that pulls the three latest updated entries from each section, and returns the entries' <code>dateUpdated</code> values as JSON:</p>

<pre><code>{% header "Content-Type: application/json" %}

{%- spaceless -%}

{% set sections = ['themes', 'videos', 'screensavers'] %}
{% set entries = [] %}
{% for section in sections %}
    {% set entry = craft.entries.section(section).order('dateUpdated desc').limit(1).first() %}
    {% set entries = entry ? entries|merge([entry]) : entries %}
{% endfor %}

{
  {%- for entry in entries -%}
    "{{ entry.section.handle }}":"{{ entry.dateUpdated }}"{% if not loop.last %},{% endif %}
  {%- endfor -%}
}

{%- endspaceless -%}
</code></pre>

<p>The above would render a JSON payload exactly like the one you have in your example.</p>

<p>If you really want to use Element API for some reason, you can get pretty close to what you want (but not quite). Here's why it's difficult to do, though:</p>

<p>For one, the <code>transformer</code> property function operates on a single entry at the time, which is a problem in terms of your desired payload.</p>

<p>Second, with Element API you don't have full control of the JSON format the plugin returns – so you'll never get the payload to look exactly like you want (the actual data will be wrapped in a <code>data</code> property).</p>

<p>Third and most importantly, an Element API endpoint requires a single query (or actually, a single <a href="https://craftcms.com/docs/plugins/working-with-elements" rel="nofollow">ElementCriteriaModel</a>) to pull your elements. Unfortunately, it isn't possible to tell an ElementCriteriaModel to return 1 entry from each section – notice that even in the template example above, there's actually <em>three</em> queries – one for each section (they're just wrapped in a <code>for</code> loop to keep the code small and DRY).</p>

<p>So basically, you'll need to "trick" Element API to return something similar to your example JSON.</p>

<p>First, since you can't use a single ElementCriteriaModel to query your 3 latest entries, you'll actually need three of those suckers. The Element API plugin gives you one, but you'll need to create the other two inside the <code>transformer</code> function – you just need to ensure that Element API actually runs that function, and <em>only runs it once</em>, by pulling a single entry (in other words; you'll need a <code>limit =&gt; 1</code> for your endpoint's <code>criteria</code>). It makes sense to have the endpoint pull one of the three entries you need, so you'll avoid a redundant database query. Then, you'll have to pull the other two entries "manually". Finally, for the return value you can return an array similar to what you have in your example:</p>

<pre><code>'updates.json' =&gt; [
    'elementType' =&gt; 'Entry',
    'paginate' =&gt; false,
    'criteria' =&gt; ['section' =&gt; 'themes', 'order' =&gt; 'dateUpdated desc', 'limit' =&gt; 1],
    'transformer' =&gt; function(EntryModel $entry) {

        $themesEntry = $entry;

        $videosEntry = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry, [
            'section' =&gt; 'videos',
            'order' =&gt; 'dateUpdated desc',
            'limit' =&gt; 1
        ])-&gt;first();

        $screensaversEntry = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry, [
            'section' =&gt; 'screensavers',
            'order' =&gt; 'dateUpdated desc',
            'limit' =&gt; 1
        ])-&gt;first();

        return [
            'themes' =&gt; date('Y-m-d', $themesEntry-&gt;dateUpdated-&gt;getTimestamp()),
            'videos' =&gt; date('Y-m-d', $videosEntry-&gt;dateUpdated-&gt;getTimestamp()),
            'screensavers' =&gt; date('Y-m-d', $screensaversEntry-&gt;dateUpdated-&gt;getTimestamp()),
        ];
    }
]
</code></pre>

<p>The above would return a JSON payload looking something like this:</p>

<pre><code>{"data":[{"themes":"2016-02-23","videos":"2016-08-23","screensavers":"2016-07-16"}]}   
</code></pre>

CC BY-SA 3.0
2016-08-23T10:18:09.303Z
Thanks a  bunch, this has really broadened my knowledge of the element API plugin! Worked perfectly, cheers!
Graham Winston
CC BY-SA 3.0
2016-08-23T10:18:42.123Z
@GrahamDragonbornWilsdon Awesome!
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2016-08-23T09:45:36.203Z
2016-08-23T12:27:36.373Z
2016-08-23T12:27:36.373Z
Mats Mikkel Rummelhoff
<p>I am trying to create an endpoint that outputs the latest updated entry in each section (Themes, Videos and Screensavers) like this:</p>

<p><strong>url/updated.json</strong></p>

<pre><code>{
 themes: '2016-08-22',
 videos: '2016-08-18',
 screensavers: '2016-07-20'
}
</code></pre>

<p>I can't think of how to do this but here is my code so far, no dice so far tho:</p>

<pre><code>'updates.json' =&gt; [
        'elementType' =&gt; 'Entry',
        'paginate' =&gt; false,
        'criteria' =&gt; ['section' =&gt; '', 'limit' =&gt; null,],
        'transformer' =&gt; function(EntryModel $entry) {
            $screensaversLastUpdated = $entry-&gt;dateUpdated;
            $videosLastUpdated = $entry-&gt;dateUpdated;
            $themesLastUpdated = $entry-&gt;dateUpdated;
            return [
                'themes' =&gt; $screensaversLastUpdated ,
                'screensavers' =&gt; $screensaversLastUpdated ,
                'videos' =&gt; $videosLastUpdated
            ];
        }
    ]
</code></pre>

<p>Any help would be much appreciated!</p>

<h2>Thanks!</h2>

<elementcriteriamodel><php><plugin-elementapi>
Element API "Last Updated Sections"
# Element API "Last Updated Sections"

(Asked by: username_0 on 2016-08-22)

I am trying to create an endpoint that outputs the latest updated entry in each section (Themes, Videos and Screensavers) like this:
url/updated.json
{
 themes: '2016-08-22',
 videos: '2016-08-18',
 screensavers: '2016-07-20'
}

I can't think of how to do this but here is my code so far, no dice so far tho:
'updates.json' => [
        'elementType' => 'Entry',
        'paginate' => false,
        'criteria' => ['section' => '', 'limit' => null,],
        'transformer' => function(EntryModel $entry) {
            $screensaversLastUpdated = $entry->dateUpdated;
            $videosLastUpdated = $entry->dateUpdated;
            $themesLastUpdated = $entry->dateUpdated;
            return [
                'themes' => $screensaversLastUpdated ,
                'screensavers' => $screensaversLastUpdated ,
                'videos' => $videosLastUpdated
            ];
        }
    ]

Any help would be much appreciated!
Thanks!

**Tags:** elementcriteriamodel, php, plugin-elementapi


---

## 1 answers

### Answer by username_1 on 2016-08-23. Score: 2 | Accepted answer

This isn't really a job for the Element API plugin. You can accomplish what you want much easier by just creating a plain ol' Twig template (e.g. templates/updates.json) that pulls the three latest updated entries from each section, and returns the entries' dateUpdated values as JSON:
{% header "Content-Type: application/json" %}

{%- spaceless -%}

{% set sections = ['themes', 'videos', 'screensavers'] %}
{% set entries = [] %}
{% for section in sections %}
    {% set entry = craft.entries.section(section).order('dateUpdated desc').limit(1).first() %}
    {% set entries = entry ? entries|merge([entry]) : entries %}
{% endfor %}

{
  {%- for entry in entries -%}
    "{{ entry.section.handle }}":"{{ entry.dateUpdated }}"{% if not loop.last %},{% endif %}
  {%- endfor -%}
}

{%- endspaceless -%}

The above would render a JSON payload exactly like the one you have in your example.
If you really want to use Element API for some reason, you can get pretty close to what you want (but not quite). Here's why it's difficult to do, though:
For one, the transformer property function operates on a single entry at the time, which is a problem in terms of your desired payload.
Second, with Element API you don't have full control of the JSON format the plugin returns – so you'll never get the payload to look exactly like you want (the actual data will be wrapped in a data property).
Third and most importantly, an Element API endpoint requires a single query (or actually, a single ElementCriteriaModel) to pull your elements. Unfortunately, it isn't possible to tell an ElementCriteriaModel to return 1 entry from each section – notice that even in the template example above, there's actually three queries – one for each section (they're just wrapped in a for loop to keep the code small and DRY).
So basically, you'll need to "trick" Element API to return something similar to your example JSON.
First, since you can't use a single ElementCriteriaModel to query your 3 latest entries, you'll actually need three of those suckers. The Element API plugin gives you one, but you'll need to create the other two inside the transformer function – you just need to ensure that Element API actually runs that function, and only runs it once, by pulling a single entry (in other words; you'll need a limit => 1 for your endpoint's criteria). It makes sense to have the endpoint pull one of the three entries you need, so you'll avoid a redundant database query. Then, you'll have to pull the other two entries "manually". Finally, for the return value you can return an array similar to what you have in your example:
'updates.json' => [
    'elementType' => 'Entry',
    'paginate' => false,
    'criteria' => ['section' => 'themes', 'order' => 'dateUpdated desc', 'limit' => 1],
    'transformer' => function(EntryModel $entry) {

        $themesEntry = $entry;

        $videosEntry = craft()->elements->getCriteria(ElementType::Entry, [
            'section' => 'videos',
            'order' => 'dateUpdated desc',
            'limit' => 1
        ])->first();

        $screensaversEntry = craft()->elements->getCriteria(ElementType::Entry, [
            'section' => 'screensavers',
            'order' => 'dateUpdated desc',
            'limit' => 1
        ])->first();

        return [
            'themes' => date('Y-m-d', $themesEntry->dateUpdated->getTimestamp()),
            'videos' => date('Y-m-d', $videosEntry->dateUpdated->getTimestamp()),
            'screensavers' => date('Y-m-d', $screensaversEntry->dateUpdated->getTimestamp()),
        ];
    }
]

The above would return a JSON payload looking something like this:
{"data":[{"themes":"2016-02-23","videos":"2016-08-23","screensavers":"2016-07-16"}]}

> **Comments:**
> **username_0**: Thanks a  bunch, this has really broadened my knowledge of the element API plugin! Worked perfectly, cheers!  
> **username_1**: @GrahamDragonbornWilsdon Awesome!  

---

