Overview
Statamic 3 takes everything you love about v2, rewrites all the old stuff (Laravel 5.1 and Vue.js 1) with the latest hotness, adds roughly 80 million fantastic new features, and speeds up performance by 5x-200x. What's not to love about that?
Try out our migrator package to help automate most of your v2 upgrade!
Philosophies
We've taken the lessons learned from years of work on Statamic v2 and updated our philosophy-level approach to flat file content management. These principles guide many of the changes — breaking and otherwise — you'll find in Statamic v3.
We don't break things for the fun of it. We hope understanding these philosophies will help defuse any frustration you may encounter when faced with needing to relearn something fundamental.
Git changes should be as small and discrete as possible
Wherever reasonable and possible, we opt for patterns resulting in smaller git changes, especially those avoiding filename changes. Filename changes cause a messy delete
and add
diff in your git history. Examples of this principle in action:
- Publish status is now controlled by a YAML variable and no longer results in a file move/delete/add.
- Pages and their parent/child folder hierarchies are now standard entries combined with a single YAML file storing the tree (this feature is called Structures). Rearranging your nav results in a single file change instead of a huge file/folder wangjanglification.
Building in the open benefits everyone
- Statamic v3 is now installed via Composer.
- Dependencies can be updated to take advantage of features and fixes without needing a Statamic core update or patch release.
- The vendor directory is not included, making the package much, much smaller.
- Your own Statamic site repos can be
public
.
Reinventing Laravel's wheels is counterproductive
Statamic v3 is built as a Laravel package instead of a "siloed" application like v2. This makes it drop-in friendly for existing Laravel applications and your own Statamic sites become much easier to extend and customize — often without needing to make addons.
To accomplish this we've had to follow more Laravel conventions, a positive thing in many ways, which result in numerous small changes. For example...
- Application-level configuration settings are now in Laravel config files — PHP files in
config/statamic
— managed only on the file level. - Many behaviors can now be overridden in your own service provider.
- Addons are now Composer packages.
- You can swap in your own favorite template language by customizing Laravel's view handler. We've heard some people like Twig.
Breaking Changes: Core
First, let's look at the breaking changes on the core application side. These are changes affecting the control panel, front-end, cli, and generally anything that doesn't require custom PHP.
General
-
site/content
directory is nowcontent
-
site/users
directory is nowusers
-
site/settings/*.yaml
have moved to php config files inconfig/statamic
. See settings.
Theming and Views
- The concept of "themes" is gone. Your site just has just one frontend, and it's in
resources
. - Templates (views) are now located in the
resources/views
instead of separatetemplates
,layouts
, andpartials
directories. - Removed
theme:partial
tag in favor ofpartial
. - The
content
field is no longer automatically parsed for Antlers. You can flag it for parsing in the blueprint. (As well as any other fields) - Inside loops
index
now starts at0
,count
starts at1
, andzero_index
is no more. - Statamic no longer automatically registers routes for taxonomies. If you need them, you can register them yourself.
Collections
- The
folder.yaml
is now up one directory so it's not mixed in amongst all the entries. - It's also renamed to the handle of the collection. eg
blog.yaml
- Instead of all values in the YAML file cascading to entries, only values nested inside
data
will. - Date based collections should have
date: true
, instead oforder: date
- Ordered collections should have
orderable: true
, instead oforder: numeric
- Mounting to a page is reversed. Instead of adding
mount: collection
to an page, you now addmount: page-id
to the collection. - Instead of
fieldset: foo
, you should useblueprints: [foo]
(it's plural, and an array).
Globals
- Data gets nested inside a
data
key. This separates the data from the meta data, which you don't really want to be used as global variables. - When using multiple sites, the data gets stored in completely separate files.
Users
- The locale preference for the CP has become an actual preference. Move
locale: en
from the top level of the user file into thepreferences
array.
Fieldtypes
- Array fieldtype terminology was changed from
value => text
tokey => value
, and thus config options were also changed toadd_button
,key_header
andvalue_header
to match the new terminology. - Relate and Suggest fieldtypes have been removed in favor of Relationship fieldtypes.
- Redactor fieldtype has been removed in favor of the Bard fieldtype.
- Pages and Collection fieldtypes have been removed in favor of the Entries fieldtype.
Fieldsets
Fieldsets technically still exist, although they are now a smaller, companion feature to Blueprints. Blueprints get attached to content. Fieldsets are an optional feature and can be used inside blueprints.
- In content etc, you should reference
blueprint: foo
instead offieldset: foo
. - There is no more
fieldsets
fieldtype. You should use theblueprints
fieldtype. - Field conditions use a slightly different syntax for multiple
OR
conditions and null/empty checks. - Consider using the
statamic:migrate:fieldset
command to convert your v2 fieldsets to blueprints. - The
partial
fieldtype has been removed in favor of the import feature in Blueprints.
Tags
-
get_content
- Now only accepts IDs, not URLs.
-
get_values
- Removed. Use
get_content
.
- Removed. Use
-
glide
- When used as a tag pair simply passes data inside. It no longer parses the contents as the
src
parameter.
- When used as a tag pair simply passes data inside. It no longer parses the contents as the
-
glide:generate
- Removed. This is now the default behavior of the main
glide
tag when used as a pair. You can useglide:batch
for this use case.
- Removed. This is now the default behavior of the main
-
entries
,entries:listing
,pages
- Removed. Use
collection
.
- Removed. Use
-
form
- Replaced
name
element infields
array withhandle
. - Replaced
field
element infields
array with a renderable view.
- Replaced
-
form:create
-
attr
is no longer a parameter, add them directly to the tag
-
-
form:submissions
- No longer inherits parameters from the
collection
tag.
- No longer inherits parameters from the
-
nav:exists
- Removed. It's much cleaner to use the main nav tag, alias the results to a variable, and check if it's empty.
-
relate
- No longer inherits parameters from the
collection
tag. - You can probably remove this tag entirely, as the values should be augmented.
- No longer inherits parameters from the
Tag Conditions
Content tag conditions still exist, but now use our new content query builders under the hood. It's worth noting some of these conditions may differ in behavior slightly, as they are now implemented using more agnostic query builder compatible comparisons or regular expressions instead of PHP logic.
The most notable breaking changes are as follows:
- All comparisons and regex patterns are now case-insensitive by default.
-
is
,equals
,not
,isnt
, andaint
no longer work with_strict
modifier. -
contains
anddoesnt_contain
no longer work on array/object data. -
matches
,match
,regex
anddoesnt_match
now ignore pattern delimiters and modifiers. -
is_uppercase
,is_lowercase
,is_today
,is_yesterday
,is_between
,is_leap_year
,is_weekday
,is_weekend
,in_array
andis_json
conditions were removed.
Breaking Changes: API
Global Functions
Most of the global functions have been removed in an effort to prevent pollution of the global namespace.
- Removed
array_get()
, useStatamic\Support\Arr::get()
- Removed
array_reindex()
- Removed
array_filter_key()
- Removed
translate()
, usetrans()
- Removed
translate_choice()
, usetrans_choice()
- Removed
bool_str()
, useStatamic\Support\Str:bool()
- Removed
str_bool()
, useStatamic\Support\Str::toBool()
- Removed
site_locale()
, useStatamic\Facades\Site::current()->handle()
- Removed
default_locale()
, useStatamic\Facades\Config::getDefaultLocale()
-
cp_resource_url()
is nowStatamic\Statamic::assetUrl()
(being consistent with what Laravel considers an asset) -
resource_url()
is nowStatamic\Statamic::url()
- Removed
path()
, useStatamic\Facades\Path::tidy($from . '/' . $to)
- Removed
root_path()
, usebase_path()
- Removed
webroot_path()
, usepublic_path()
- Removed
site_path()
- Removed
local_path()
- Removed
bundles_path()
- Removed
addons_path()
- Removed
settings_path()
- Removed
site_storage_path()
- Removed
cache_path()
- Removed
logs_path()
- Removed
temp_path()
- Removed
carbon()
, useIlluminate\Support\Carbon
- Removed
datastore()
- Removed
site_root()
- Removed
resources_root()
- Removed
collect_content()
- Removed
collect_entries()
, useEntryCollection::make()
- Removed
collect_globals()
, useGlobalCollection::make()
- Removed
collect_assets()
, useAssetCollection::make()
- Removed
collect_terms()
, useTermCollection::make()
- Removed
collect_users()
, useUserCollection::make()
- Removed
collect_files()
, useFileCollection::make()
- Removed
collect_pages()
- Removed
me()
, useStatamic\Facades\User::current()
- Removed
addon()
- Removed
nav()
- Removed
col_class()
- Removed
svg()
- Removed
inline_svg()
- Removed
is_id()
- Removed
active_for()
- Removed
nav_is()
- Removed
format_url()
, useStatamic\Facades\URL::format()
- Removed
markdown()
, useStatamic\Support\Html::markdown()
- Removed
textile()
, useStatamic\Support\Html::textile()
- Removed
t()
, use__()
- Removed
slugify()
, useStatamic\Support\Str::slug()
- Removed
smartypants()
, useStatamic\Support\Html::smartypants()
- Removed
bool()
, useStatamic\Support\Str::toBool()
- Removed
int()
, useintval()
- Removed
d()
, usedump()
- Removed
gravatar()
, useStatamic\Support\URL::gravatar()
- Removed
format_input_options()
from both PHP and JS (useHasInputOptions
mixin) - Removed
format_update()
- Removed
modify()
- Removed
refreshing_addons()
- Removed
cp_middleware()
- Removed
sanitize()
, useStatamic\Support\Str::sanitize()
- Removed
sanitize_array()
, useStatamic\Support\Arr::sanitize()
- Removed
array_filter_recursive
- Removed
array_filter_use_both
, usearray_filter($arr, $cb, ARRAY_FILTER_USE_BOTH)
- Removed
mb_str_word_count
- Removed
to_moment_js_date_format
Suggest Modes
Suggest modes have been replaced by customized relationship fieldtypes.
Statamic\API
Statamic\API
classes are now Statamic\Facades
Statamic\API\Addon
- Removed
manager()
- Renamed
create
tomake
Statamic\API\Arr
- Moved to
Statamic\Support\Arr
Statamic\API\Asset
- Renamed
whereId
tofindById
- Renamed
whereUrl
tofindByUrl
Statamic\API\AssetContainer
- Removed
wherePath
- Renamed
create
tomake
Statamic\API\Assets
- Removed, use
Asset
.
Statamic\API\Auth
- Removed. Use
Illuminate\Support\Facades\Auth
Statamic\API\AssetContainer
- Removed
create
, usemake
. - Removed
wherePath
Statamic\API\Cache
- Removed. Use
Illuminate\Support\Facades\Cache
-
put()
would accept a third argument for minutes,null
for forever. The Laravel class requires a time. UseCache::forever()
to put forever.
Statamic\API\Collection
- Renamed
create
tomake
. - Removed
handleExists
- Renamed
whereHandle
tofindByHandle
Statamic\API\Content
- Removed. Use
Data
.
Statamic\API\Cookie
- Removed. Use
Illuminate\Support\Facades\Cookie
Statamic\API\Crypt
- Removed. Use
Illuminate\Support\Facades\Crypt
Statamic\API\Email
- Removed. Use Laravel Mailables.
Statamic\API\Entries
- Removed. Use
Entry
Statamic\API\Entry
-
whereCollection()
now only supports a single collection (usewhereInCollection()
if you need to pass multiple) - Renamed
whereUri
tofindByUri
- Removed
exists
- Removed
slugExists
- Removed
countWhereCollection()
- Renamed
create
tomake
Statamic\API\Event
- Removed. Use
Illuminate\Support\Facades\Event
Statamic\API\Fieldset
- Tip: You probably want
Blueprint
now. - Removed
create
- Renamed
get
tofind
, and removed the$type
argument.
Statamic\API\Form
- Renamed
get
tofind
- Removed
getAllFormsets
- Renamed
create
tomake
- Removed
fields
Statamic\API\Globals
- Removed. Use
GlobalSet
Statamic\API\GlobalSet
- Renamed
create
tomake
- Renamed
whereHandle
tofindByHandle
Statamic\API\Hash
- Removed. Use
Illuminate\Support\Facades\Hash
Statamic\API\Helper
- Removed
Statamic\API\Please
- Removed. Use
Illuminate\Support\Facades\Artisan
.
Statamic\API\Str
- Moved to
Statamic\Support\Str
Statamic\API\URL
- Removed
removeSiteRoot()
Statamic\API\Zip
- Removed because core no longer uses it.