Skip to main content

Upgrading to 2.0

This guide covers upgrading a Sloth 1.x project to Sloth 2.0.

Automated upgrade with folivoro/climb​

The fastest way to upgrade is with folivoro/climb — a dedicated migration tool that handles the upgrade automatically.

composer global require folivoro/climb

Make sure ~/.composer/vendor/bin is in your $PATH:

export PATH="$PATH:$HOME/.composer/vendor/bin"

Then from the root of your project:

climb

climb detects the installed Sloth version automatically and runs all migration steps. See the report at the end for anything that requires manual attention.


Manual upgrade​

If you prefer to upgrade manually — or want to understand what climb does under the hood — follow these steps in order.

1. Update composer.json​

Remove the Installer scripts — they are no-ops in v2 and can be safely deleted:

- "post-install-cmd": [
- "Sloth\\Installer\\Installer::config"
- ],
- "post-update-cmd": [
- "Sloth\\Installer\\Installer::config"
- ]

Swap the package:

composer remove sixmonkey/sloth
composer require folivoro/sloth:^2.0

Install folivoro/cecropia — the MU-plugin that bootstraps Sloth v2:

composer require folivoro/cecropia

If you use Layotter, install the bridge package:

composer require folivoro/layotter-bridge

And remove any old Layotter packages:

composer remove folivoro/layotter

2. Migrate config files​

In v2, all configuration moves from Configure::write() calls to Laravel-style config files. Publish the defaults first:

wp sloth vendor:publish --tag=config

Then migrate each key. The full mapping:

Old (Configure::write)New (config/)File
twig.autoescapeview.autoescapeconfig/view.php
theme.twig.filters—Use View Extensions
theme.twig.functions—Use View Extensions
theme.image-sizestheme.image_sizesconfig/theme.php
theme.menustheme.menusconfig/theme.php
theme.routes—Use Routes
theme.layotter.row_layoutslayotter.row_layoutsconfig/layotter.php
layotter_prepare_fieldslayotter.prepare_fieldsconfig/layotter.php
layotter_custom_classeslayotter.custom_classesconfig/layotter.php
autosync_acf—No longer part of Sloth
sloth.acf.processtheme.process_acfconfig/theme.php
urls.relativeapp.relative_urlsconfig/app.php
links.urls.relativeapp.relative_linksconfig/app.php
uploads.urls.relativeapp.relative_uploadsconfig/app.php
wp-json.baseUrlapp.wp_json.base_urlconfig/app.php
core.hide_updatesadmin.hide_updates.coreconfig/admin.php
plugins.hide_updatesadmin.hide_updates.pluginsconfig/admin.php
themes.hide_updatesadmin.hide_updates.themesconfig/admin.php
plugins.autoactivate—No longer part of Sloth
plugins.autoactivate.blacklist—No longer part of Sloth

Before:

Configure::write('theme.menus', [
'primary' => 'Primary Navigation',
'footer' => 'Footer Navigation',
]);

Configure::write('theme.image-sizes', [
'hero' => [1920, 1080, true],
]);

Configure::write('urls.relative', true);

After:

// config/theme.php
return [
'menus' => [
'primary' => 'Primary Navigation',
'footer' => 'Footer Navigation',
],
'image_sizes' => [
'hero' => [1920, 1080, true],
],
];

// config/app.php
return [
'relative_urls' => true,
];

3. Migrate Twig filters and functions​

Configure::write('theme.twig.filters', [...]) and Configure::write('theme.twig.functions', [...]) are replaced by the View Extension system. Each filter or function becomes a class in theme/Extensions/View/:

// Before
Configure::write('theme.twig.filters', [
new TwigFilter('obfuscate_email', function($email) {
return str_replace('@', '[at]', $email);
}),
]);

// After — theme/Extensions/View/ObfuscateEmailHelper.php
class ObfuscateEmailHelper extends \Sloth\View\Extensions\AbstractViewExtension
{
public function getHelpers(): array
{
return [
'obfuscate_email' => fn($email) => str_replace('@', '[at]', $email),
];
}
}

4. Migrate theme supports​

add_theme_support() calls in functions.php move to config/theme.php:

// Before — functions.php
add_action('after_setup_theme', function() {
add_theme_support('title-tag');
add_theme_support('post-thumbnails');
});

// After — config/theme.php
return [
'supports' => [
'title-tag',
'post-thumbnails',
],
];

5. Fix typed properties​

PHP 8.4 raises a fatal error when a child class redeclares a property with a type that the parent (Corcel) declared without one. Remove type declarations from registration properties in your Models and Taxonomies:

// Before — fatal in PHP 8.4
class Project extends Model
{
public static string $postType = 'project';
public static array $names = ['singular' => 'Project', 'plural' => 'Projects'];
}

// After
class Project extends Model
{
public static $postType = 'project';
public static $names = ['singular' => 'Project', 'plural' => 'Projects'];
}

This affects $postType, $names, $labels, $options, $icon and any other static properties inherited from Sloth's base classes.

6. Clean up bootstrap.php​

Remove Sloth v1 bootstrapping from bootstrap.php:

- use Sloth\Core\Sloth;
- $GLOBALS['sloth'] = Sloth::getInstance();
- class_alias('\Sloth\Configure\Configure', 'Configure');
- Configure::boot();

Everything else in bootstrap.php (constants, Dotenv, DB settings) can stay.

7. Delete sloth.php​

The sloth.php MU-plugin that bootstrapped Sloth v1 is replaced by folivoro/cecropia in v2. Delete it from your MU-plugins directory.

8. Track infrastructure files in Git​

In v1, Sloth's Installer managed bootstrap.php and wp-config.php and they were typically gitignored. In v2 these files are fully owned by your project and should be committed.

Remove them from .gitignore:

- bootstrap.php
- wp-config.php
- sloth.php

9. Update the .env location​

Sloth now walks up from the App-Root to find .env. In Classic mode, .env should live next to composer.json in the project root — not inside app/:

# Classic mode
my-project/
├── .env ← here
├── composer.json
└── app/

# Theme mode — unchanged
my-theme/
├── .env
└── composer.json

Package rename​

If your project still requires sixmonkey/sloth, update it:

composer remove sixmonkey/sloth
composer require folivoro/sloth:^2.0

Removed features​

These features were removed in 2.0 with no replacement:

FeatureAlternative
Configure classconfig() and Laravel config files
theme.routes configSloth routing
plugins.autoactivate configManage plugins manually
autosync_acf configNo longer part of Sloth
Sloth InstallerNot needed — remove from Composer scripts
LayotterBridgeServiceProvidercomposer require folivoro/layotter-bridge