View Models

View Models give you a chance to manipulate or set data in PHP right before everything is passed into your view, parsed, and then rendered.


Have you ever had some complex data or conditions you found challenging to work with in your Antlers templates? Sure you have. Have you ever peeled a banana and had the stem hang onto the peel stubbornly only to have the fruit poke it’s face out of a surprise gap like a hoodie? You can probably relate to that too.

While Antlers is powerful and flexible, what if you could just jump into PHP-land, work out some tricky logic, and put the data back in place before it was rendered?

Enough rhetorical questions – in Statamic 3 you can now solve one of those two problems with a View Model. 🍌

What’s a View Model?

By defining a view_model in your entry data or anywhere in the cascade, Statamic will run the data() method of that named class and merge any array data you return before injecting it into your view/template.

While inside the view model, you have access to the full cascade and can set new variables or modify existing ones.


Let’s assume we have a Replicator field with a bunch of content blocks (an associative array) and we’d like to calculate some stats on how much content there is and how long it might take to read it.

First, let’s define the view model location. Rather than putting it in an entry, we’ll put it in the collection so that it’s applied to every entry.

# content/collections/articles.yaml
title: Articles
  view_model: App\ViewModels\ArticleStats
# content/collections/articles/
title: "A Long Article Plz Read it Mmmkay?"
    type: text
    text: # Piles of content live here

Next, we’ll loop through the content, assemble a giant string of all the content, perform some math, and return the stats.


namespace App\ViewModels;

use Statamic\View\ViewModel;

class ArticleStats extends ViewModel
    public function data(): array
        // Combine content blocks
        $html = collect($this->cascade->get('content'))
                ->implode('text', " ");

        // Remove HTML tags
        $content = strip_tags($html);

        // Calculate stats
        $character_count = strlen($content);
        $word_count      = mb_str_word_count($content);
        $read_time       = ceil($word_count / 200);

        return [
            'character_count' => $character_count,
            'word_count'      => $word_count,
            'read_time'       => $read_time

Finally, we’ll show these stats in our view.

<h1>{{ title }}</h1>
<p class="meta">
    {{ word_count }} words / read time approx {{ read_time }}m.

View models help keep your views nice and clean. Use them often and you’ll find that they’re quickly becoming your new best friend.

You’re manipulating the view’s data at the last possible moment before render, not the entry data itself. This approach isn’t appropriate for globally altering or manipulating content.

Betterify this page on Github!