Passing runtime data for a Form fieldtype in Statamic

Published November 28th, 2023

Statamic ships with over 40 different fieldtypes you can use to create your Blueprints, giving you incredible flexibility with how you craft the components of your site: from your content authors in the Statamic Control Panel through to the frontend Forms on the public side of your site.

And Statamic allows you to create your own fieldtypes too: whether it is a simple extension of an existing fieldtype, or creating your own smarts, logic and interface, you can create fieldtypes that add the functions and interactions your site needs.

When creating a fieldtype for the Control Panel (CP), you have access to the preload method which is called as a field is being prepared for render on the frontend. This gives you the ability to add additional metadata from the server-side PHP to your Vue component that you can then access – maybe you need to conditionally do something based on the logged in user, or pull from a third-party API or even a local cache.

However, frontend fieldtypes (for the Forms blueprints), do not call the preload method, and do not have a Vue component – these are rendered as HTML templates… you know, those snippets you publish and customise in your own site by running a vendor:publish command?

A recent update to Statamic has changed this though, adding a getRenderableFieldtypeData method to the fieldtype definition. This returns an associative array of data, and is passed to your fieldtype Antlers template, with each key being available as a variable.

3namespace App\Fieldtypes;
5use Illuminate\Support\Facades\Auth;
6use Statamic\Fields\Fieldtype;
8class RuntimeDataFieldtype extends Fieldtype
10 // there would be more code here for your fieldtype
12 public function getRenderableFieldtypeData()
13 {
14 // do something to get dynamic runtime data:
15 // maybe something from a database...
16 // or a third party service like Stripe or an API...
17 // or maybe just something specific to the logged in user
19 return [
20 'key' => Auth::user()->id,
21 'properties' => [
22 'name' => Auth::user()->name,
23 'avatar' => Auth::user()->avatar(),
24 ],
25 'pets' => [
26 [
27 'label' => 'Peter',
28 'type' => 'rabbit',
29 ],
30 [
31 'label' => 'Toby',
32 'type' => 'cat',
33 ],
34 [
35 'label' => 'Zack',
36 'type' => 'cat',
37 ],
38 ],
39 ];
40 }

When a fieldtype is rendered, you will always have a number of variables including instructions, display (the label), width and default, old and value properties – among others. With the example above, we also will have access to:

  • key, of the User’s ID

  • a properties array, with the name and avatar details

  • an array of pets, each with a label and type

This means we can access these variables in our fieldtype’s template:

2 <!-- all sorts of fun fieldtype markup can go here -->
4 <div>
5 <div>
6 {{# accessing our avatar via the properties array #}}
7 <img src="{{ properties:avatar }}" alt="{{ properties:name }}" class="w-10 h-10">
8 </div>
9 <div>
10 <div>{{ properties:name }}</div>
12 {{# accessing a simple variable #}}
13 <div class="text-xs">{{ key }}</div>
14 </div>
15 </div>
17 <div>
18 <div>Pets</div>
19 <ul>
20 {{# looping through an array #}}
21 {{ pets }}
22 <li>{{ label }} ({{ type }})</li>
23 {{ /pets }}
24 </ul>
25 </div>

It is important to note that the keys you provide in getRenderableFieldtypeData will override any keys that the inner workings of the field return – so if you return a key called “instructions” it will override any instructions configured in your Blueprint.

This can, however, be useful for some Fieldtypes – like a Select.

In your Blueprint, you can provide an array of Options that gets passed to your template – and this has the key options. The getRenderableFieldtypeData method allows you to override the options key – so your Blueprint-level options could be considered a ‘default’ set of options, but then the getRenderableFieldtypeData method updates them based on that server-side process: an API, Stripe, database, something about the user… whatever you need to do.

So while it is important to note this method will override properties, that can actually be useful too.

This allows you to have new variables made available within your template – so perhaps you need to talk to a database… or call an API… or check something with the logged in user status. While a small and subtle change, this opens up the possibilities of what you can do with frontend fieldtypes within Statamic.

You may be interested in...