Resaving Elements
On occasion, you may find it helpful to trigger a “save” on a group of elements, without visiting each one in the control panel. Craft will do this automatically under some circumstances (like changes to a section’s Default Title Format), but there are plenty of situations in which Craft can’t infer the correct course of action (like creating a new field and populating it with a value from an existing field).
Craft has a number of console commands to do just this, named after each built-in element type:
resave/addresses
— Addressesresave/assets
— Assetsresave/categories
Categoriesresave/entries
— Entriesresave/tags
— Tagsresave/users
— Users
In addition, the resave/all
command can be used to run each other command in series, with options common to all element types. Global sets currently cannot be resaved from the command line.
Commerce #
Craft Commerce supplements the built-in commands with a few of its own:
resave/carts
— Carts (incomplete orders)resave/orders
— Orders (completed carts)resave/products
— Products
Other plugins can extend ResaveController
with their own actions by listening to its EVENT_DEFINE_ACTIONS
event.
Common Features #
Every element type supports a number of options or CLI flags.
Constraints #
These options narrow the scope of elements to be resaved by applying the equivalent element query params.
--element-id
and--uid
— Resave one or more elements by their IDs or UUIDs.--site
— Scope the query to elements in one or more sites.--status
— Only include elements with the specified status. Statuses may be different across element types.--offset
— Skip the specified number of elements before beginning.--limit
— Set a maxmimum number of elements that will be resaved.--drafts
,--provisional-drafts
, and--revisions
— Limit the query to drafts or revisions. By default, all drafts and revisions are included.
See below for additional element type-specific options! Many of these constraints support passing multiple, comma-separated values.
Mutation #
By using a combination of --set
and --to
options, you can perform a variety of updates to elements as they’re being saved. Only one pair of these options can be used per operation.
This process begins by choosing an attribute or field handle that you want to update, using --set
:
--set title
— Targets thetitle
attribute.--set myDropdownField
— Targets a custom field instance with the handlemyDropdownField
.
The --to
option has a few different flavors:
--to mySourceAttribute
— Copies the value from the given attribute or custom field name (mySourceAttribute
).--to "=A literal value"
— Use the provided literal value (enclosed in quotes, following an=
sign.- `--to "={mySourceAttribute|lower}" — The value is determined by rendering the provided object template.
--to :empty:
— Clear the existing value.--to "fn(\\$element) => \\$element->someMethod()"
— Use the return value of a closure to populate the field with complex values.
The final option here gives you access to Craft’s entire PHP API. Keep in mind that this code is evaluated in a privileged environment, and makes potentially destructive actions possible.
Two additional options provide a means to
--if-empty
— Only set the value of the attribute or field if it is currently empty;--if-invalid
— Only set the value of the attribute or field if its current value does not validate;
Utility #
--queue
— Push aResaveElements
job into the queue rather than processing immediately.--update-search-index
— Whether Craft should spawn search indexing jobs after each save.--touch
— Force thedateUpdated
timestamp on each element to be updated. Ordinarily, Craft skips this in the interest of preserving a record of when the last human-initiated change was made.--propagate-to
— Saves the elements into the specified sites.
As of Craft 5.5.0, most built-in commands also support the --with-fields
option, allowing you to find and resave elements that use a particular field in their field layout, by its global handle. Combined with resave/all
, you can quickly set default values for new fields across any element type that uses it.
Element Types #
Addresses #
--country-code
— Filter by addresses with the given two-letter country code.--owner-id
— Resave addresses owned by elements with the provided ID(s).
Assets #
--volume
— Resave assets in the specified volume(s), using their handles.
Categories #
--group
— Resave categories from specific category group(s), using their handles.
Entries #
--type
— Resave entries based on one or more entry types.--section
— Only resave entries belonging to one or more sections.--all-sections
— Shortcut for--section=*
.--field
— Resave nested entries belonging to specific field(s).--owner-id
— Resave entries owned by elements with the provided ID(s).
If you wish to exclude nested entries, use --allSections
.
Tags #
--group
— Resave categories from specific tag group(s), using their handles.
Users #
--group
— Resave users from specific user group(s), using their handles.
Examples #
Putting together what we’ve seen so far, a resave command will often look something like this…
php craft resave/entries \
--section blog \
--set description \
--to "={author.fullName} discusses {title} in the {category.one.title} section."
…but they can be as simple as refreshing the search index:
php craft resave/categories \
--group species \
--update-search-index
If you would prefer to get your prompt back and defer the work to the queue, just pass --queue
:
php craft resave/entries \
--section profiles \
--update-search-index \
--queue
Further Reading #
Craft Shell #
The yiisoft/yii2-shell
package that comes with new projects makes it convenient to experiment with queries (and the rest of the Craft API) as you get familiar with the --set
and --to
options—especially when using closures.
With a bit of practice, you may find that you can accomplish many of the same querying, modifying, and saving operations by skipping the resave/*
commands and using the APIs directly!