Replicate ACF's Page Link field in Statamic

It's one of the most useful fieldtypes in the popular WordPress plugin. Here's how to recreate it in Statamic.

Published May 23rd 2018

One of the most useful fieldtypes in WordPress' Advanced Custom Fields' plugin is page link. This field allows you to limit users to selecting a post from a dropdown, rather than allowing them to input a URL. This isn't just easier for non-technical users; it also prevents some potentially nasty security issues and the ever present shadow of broken links.

Out of the box, Statamic has the pages fieldtype. However, getting it to output a URL isn't as straightforward as ACF's page link fieldtype.

It's all about Relate

If you take a look at Statamic's source code, you can see that the page fieldtype extends the RelateFieldType. This explains why the templating section in the docs state you need to use the relate tag to output anything useful. (If you actually look at what Statamic puts in the index.md file of the page you're editing, you'll see an ID rather than a link).

The relate tag (i.e. relate:tag) is a tag pair, so you can input the ID that is returned when you select a page and get all kinds of information from it. Of course, the most common usecase is going to be the title and the URL. However, you could use almost any information stored in the page object you're returning.

For the purpose of this post, we'll ignore that though and focus on replicating ACF's page link functionality.

How to do it

Now because you're only wanting to return one URL, the first thing to do is make sure you're limiting the number pages that can be selected to 1. You can do this by adding the parameter max_items: 1 to the field's settings.

link:
  type: pages
  display: Page Link
  validate: required
  max_items: 1

This will change the field in the control panel from a multi-select to a dropdown.

It's easy to miss this. The best thing you can do is always look at the Settings section at the bottom of a page in Statamic's docs and see if it supports additional settings from another tag. If it does, always take a look as sometimes key functionality is hidden away there.

Now when outputting the link, you'll want to use the following approach. (For the sake of making it easier, let's assume the field's name is link.

{{ relate:link }}
    <a href="{{ url }}">{{ title }}</a>
{{ /relate:link }}

That's it. Sorry if you were expecting more!