Upgrade from 3.3 to 3.4

A guide for upgrading from 3.3 to 3.4. For most sites, the process will take less than 5 minutes.

Overview

First read through this guide to see if there's anything that you might need to adjust. When upgrading, Statamic may automate some things for you. They'll be noted below.

In your composer.json, change the statamic/cms requirement:

"statamic/cms": "3.4.*"

Then run:

composer update statamic/cms --with-dependencies

High impact changes

The runtime Antlers parser is the default

In 3.3 we introduced a new Antlers parser but you had to opt into it.

In 3.4 it becomes the default.

You may continue to use the old "regex" parser, but you'll need to make sure to specify that in config/statamic/antlers.php.

'version' => 'regex', // or "runtime" for the new parser

Bard addons / extensions will no longer work

Bard's underlying editor, Tiptap, has been updated from v1 to v2 which required significant changes to Bard. This means that Bard addons will no longer work until they've been updated to support Statamic 3.4.

You should check if the Bard addons you have installed have been updated for 3.4, or if they are even necessary anymore since the native Bard editor now has more features.

Read how to upgrade your addons for Bard 2

Draft entries no longer get added to search indexes

In 3.3 drafts would be indexed, in 3.4 they are not.

If you're linking a search index to a collection, when you use the control panel since drafts are no longer indexed they will not show up in results. You can cancel out that behavior by using a filter that allows everything:

# content/collections/articles.yaml
search_index: articles
// config/statamic/search.php
'articles' => [
    'driver' => 'local',
    'searchables' => ['collection:articles'],
    'filter' => fn () => true, // [tl! ++]
]

Medium impact changes

Term queries return all localizations

This will not affect any native tags, like taxonomy. It will only affect you if you are performing term queries in PHP, such as:

Term::all();
Term::query()->get();

In 3.3, these would deduplicate the terms and only give you a single localization. i.e. If you had 2 sites configured, and 3 terms, you'd end up with 3 results.

In 3.4, you will get all the localizations. i.e. You would get 6 results.

To get the previous behavior (even though it was buggy, and the reason for the change), you can query for a specific site:

$query = Term::query();
$query->where('site', 'english'); // [tl! ++]
$terms = $query->get();

Search queries return Result classes

This will not affect the search:results tag. This would only affect you if you were performing searches manually in PHP. Depending on what you were doing with the results, it's possible no changes would be necessary anyway.

Search queries now return Result instances. Previously they returned instances of the actual searchable items. (e.g. an Entry)

You can continue to get the underlying classes by mapping using the getSearchable() method.

$results = Search::index('default')->search('foo')->get();
$results = $results->map->getSearchable(); // [tl!++]

Low impact changes

Slugs no longer include extra characters

In some forms, the slug will get automatically generated. e.g. When you type into the title field on a publish form.

In 3.3, some special characters would get converted. e.g. The & would become and.

In 3.4, these characters will not get converted.

To enable these character conversions, you can enable a new setting in config/statamic/system.php.

'ascii_replace_extra_symbols' => true,

Replicator, Bard, and Grid IDs

All three fieldtypes will now supply their id to templates. Previously, the id would have been the entry's ID.

If you still need to access the entry's ID within the field tag pair, you may use the page variable:

{{ grid }}
    {{ id }} the entry id {{# [tl! --] #}}
    {{ id }} the grid item's id {{# [tl! ++] #}}
    {{ page:id }} the entry id {{# [tl! ++] #}}
{{ /grid }}

LocalizedTerm reference now includes site handle

The reference method of the LocalizedTerm class now includes the site handle, even when only a single site is configured.

term::categories::hats # [tl! --]
term::categories::hats::en # [tl! ++]

Entries etc must implement Searchable

The Entry, LocalizedTerm, Asset, and User classes must implement the Searchable interface.

If you've customized any of these classes, you'll need to make sure to implement the appropriate methods. If you are extending from the native classes, then you probably don't need to make any changes.

Custom search index drivers accept locale

This only affects users that have created custom search index drivers.

Now that search indexes can be localized, when they are constructed, a nullable $locale string will be passed to it. You should make sure that the name includes it.

Search::extend('custom', function ($app, $config, $name, $locale) {
    return new CustomDriver(
        $config,
        $name,
        $locale // [tl!++]
    );
});

If you are extending the native Statamic Index class, this will be done for you.

Search default index

When using the Search facade, certain methods would apply directly to the default index.

Since 3.4 introduces localized indexes, if your default index is localized, these magic methods will target the current site.

For example:

// If currently on the "english" site,
Search::for('foo'); // applies to english index

// If currently on the "french" site
Search::for('foo'); // applies to french index

If needed, you can be explicit:

Search::index('default', 'french')->for('foo');

Search methods removed

The clearIndex and indexExists methods have been removed.

Zero impact changes

These are items that you can completely ignore. They are suggestions on how to improve your code using newly added features.

Utility and Permission registration

3.4 fixes an issue where translations for utilities and permissions may not have been displayed in the right language when a user has a custom locale preference.

The core utilities and preferences were fixed, however in order to fix it for addons, you will need to wrap your existing code in closures.

Permission::extend(function () { // [tl! ++]
    Permission::register('foo', '...');
}); // [tl! ++]

Utility::extend(function () { // [tl! ++]
    Utility::make('foo')->register();
}); // [tl! ++]

Utility fluent methods

The utility class was updated to be consistent with permissions syntax. You no longer need to chain register to the end. You can simply use register at the start instead of make.

Utility::make('foo')->title('Foo')->etc()->register(); // [tl! --]
Utility::register('foo')->title('Foo')->etc(); // [tl! ++]
Docs feedback

Submit improvements, related content, or suggestions through Github.

Betterify this page →