Content Management
- Matrix fields set to the “Cards” or “Blocks” view modes now show an “Add” button per entry type group, when the viewport is wide enough to support it. (#17731)
- Matrix fields set to the “Cards” view mode now have “Copy selected entries”, “Duplicate selected entries”, and “Delete selected entries” field-level actions, if any entries are selected. (#18251)
- Matrix fields set to the “Blocks” view mode now have a “Expand/collapse selected blocks”, “Copy selected blocks”, “Duplicate selected blocks”, and “Delete selected blocks” field-level actions, if any entries are selected. (#18001, #18251)
- Matrix fields set to the “Blocks” view mode now have block action menus with “Expand/Collapse”, “Entry type settings”, and “Copy” actions, even if the field isn’t editable. (#18013)
- Chips and cards are generally no longer hyperlinked. (#17591)
- Entry revision menus now always include a “View all revisions” link. (#18050)
- Timestamps within entry revision menus now have tooltips that reveal the full date and time. (#18050)
- It’s now possible to add new sites to entries via their slideout editors. (#17795)
- Entry “Duplicate” bulk actions now duplicate entries as drafts. (#18260)
- Elements created via “Save as a new…” actions now initially have an empty slug. (#17932)
- The control panel is no longer scrollable when a menu is expanded. (#17960)
- Most site breadcrumbs no longer include selection menus if there’s only one selectable site. (#16526)
- Number fields with “Step Size” and “Min Value” or “Max Value” settings will now get
min/maxattributes set on their input. (#17973) - Element, field, and entry type edit pages now redirect back to the previous page’s URL on save. (#16140)
- Bulk element actions are now available on element indexes for mobile devices.
- Textual condition rules are now case-insensitive. (#18107)
- Added support for exporting elements as XLSX and YAML files. (#18160)
- Non-editable fields now have “Read Only” badges. (#18215)
- Revisions now keep track of which element attributes/fields were modified for the revision.
- Improved the styling of tips and warnings in field layouts. (#18261)
Accessibility
- Improved the accessibility of the Orientation setting within the Image Editor’s crop tool. (#17690)
- The Image Editor’s focal point tool is now keyboard accessible. (#17880)
- All sortable checkbox select options, selected Dashboard widgets, and site listings now have keyboard-accessible “Move up” and “Move down” action items. (#18067)
Administration
- It’s now possible to divide entry sources into multiple index pages, via the Customize Sources modal. (#17779)
- The Customize Sources modal now supports mobile devices. (#18067)
- Added the “UI Label Format” entry type setting. (#18044)
- Added the “Allow line breaks in titles” entry type setting. (#18265)
- Added the “View user” GraphQL schema option for Craft Solo. (#17863)
- Users’ User Groups settings now show a component select input, and support inline group editing/creation on environments that allow administrative changes.
- Address labels can now be made optional. (#11410)
- Relational fields now have an “Inline list” view mode. (#17744)
- Relational fields and Matrix fields now have a “Card grid” view mode, replacing the “Show cards in a grid” setting. (#17744)
- Relational fields’ selectable element conditions can now have “Status” condition rules. (#17945)
- Added the “Show ON/OFF labels in cards” setting to Lightswitch fields. (#17743)
- Control panel-defined routes now have action menus with “Move up”/“Move down” actions. (#17706)
- “Generate image transform” jobs now include the asset’s filename in the job description. (#17753)
- “Field” and “Section” condition rules now show field/section handles for users with the “Show field handles in edit forms” preference enabled. (#17909)
- Native fields within element edit pages now have “Copy attribute name” actions. (#18114)
- “Remove” actions on the Plugins index page now show a confirmation dialog. (#17922)
entrifycommands no longer require a category group/tag group/global set handle to be passed.entrifycommands now automatically assign newly-created channel/structure sections to “Categories” or “Tags” pages. (#17779)- The
clear-cachecommand now accepts a space-delimited list of cache IDs that should be cleared. - Compiled templates are now deleted by the
upcommand rather than frommigratecommands. - Added the
enableTwigSandboxconfig setting. (#18208, #18216) - Added the
useIdnaNontransitionalToUnicodeconfig setting. (#17946) - The
maxCachedCloudImageSizeconfig setting is now set to0by default. (#17997) - The
disableGraphqlTransformDirectiveconfig setting is now deprecated. - System message emails are now rendered using GitHub-flavored Markdown. (#18058)
- Drag-and-drop icons are now longer shown for devices that don’t support pointer events. (#18067)
- The Caches utility now keeps track of which options were previously selected. (#9447)
- Field layouts can now set editability conditions on custom fields, based on the edited element. (#18181)
- Element cards and table views can now include fields nested within Content Block fields. (#18206, #18252)
- Element table views can now include generated fields. (#18253)
- Element indexes can now be sorted by generated fields. (#18253)
- Generated fields now normalize
true/false/null/integer/float values to the appropriate types. (#18267) - Money fields’ icons now indicate their selected currency, for common currencies.
Development
- Reference tags now support fallback values when no attribute is specified. (#17688)
- Added support for referencing environment variables anywhere within settings that support them (e.g.
foo/$ENV_NAME/barorfoo-${ENV_NAME}-bar). (#17794) - Environmental settings can now reference
CRAFT_SITE(the current site’s handle) andCRAFT_SITE_UPPER(the current site’s handle in UPPER_SNAKE_CASE) environment variables, which are defined at runtime. (#17794) - It’s now possible to create unpublished drafts via GraphQL. (#17805)
- It’s no longer possible to instantiate objects that don’t extend
yii\base\BaseObjectvia thecreate()Twig function, which fixes a moderate-severity SSTI issue. (GHSA-94rc-cqvm-m4pw) - Added the
randomString()Twig function. (#18020) - Added the
uuid()Twig function. - The Twig
hashfilter now supports passing a hashing algorithm, such as'md5'or'sha256'. (#17885) - The
@parseRefsand@transformGraphQL directives are now optional for each GraphQL schema, which fixes a high-severity IDOR issue. (GHSA-7x43-mpfg-r9wj) - GraphQL API requests can now identify themselves as preview requests by passing an
X-Craft-Preview-Tokenheader, set to thex-craft-preview/x-craft-live-previewquery param in the preview target URL.
Extensibility
- Subnav items within the global control panel navigation can now have icons. (#17879)
- It’s now possible to modify the template path via
craft\web\View::EVENT_BEFORE_RENDER_TEMPLATEandEVENT_BEFORE_RENDER_PAGE_TEMPLATE. (#18125) - Custom fields’ icons can now be defined at the instance level, via a
getIcon()method. - Added
craft\base\ElementIndex::multiPageSources(). (#17779) - Added
craft\base\ElementTrait::$applyingDraft. (#18057) - Added
craft\base\ElementTrait::$hasProvisionalChanges. (#17915) - Added
craft\base\ElementTrait::$propagateRequired. - Added
craft\base\FieldInterface::propagateValue(). - Added
craft\elements\Entry::EVENT_DEFINE_META_FIELDS. (#17996) - Added
craft\elements\User::isInGroups(). (#17989) - Added
craft\elements\actions\Duplicate::$asDrafts. - Added
craft\elements\conditions\HintableConditionRuleTrait. (#17909) - Added
craft\events\DefineFieldActionsEvent. - Added
craft\events\DefineGqlArgumentsEvent. - Added
craft\events\DefineMetaFields. (#17996) - Added
craft\events\RegisterElementCardAttributesEvent::$fieldLayout. (#17920) - Added
craft\fieldlayoutelements\BaseField::EVENT_DEFINE_ACTION_MENU_ITEMS. (#18037) - Added
craft\fieldlayoutelements\BaseField::copyAttributeAction(). (#18114) - Added
craft\fieldlayoutelements\BaseField::getPreviewOptions(). - Added
craft\fieldlayoutelements\BaseField::key(). - Added
craft\fieldlayoutelements\CustomField::getElementEditCondition(). - Added
craft\fieldlayoutelements\CustomField::setElementEditCondition(). - Added
craft\fields\BaseRelationField::VIEW_MODE_CARDS_GRID. - Added
craft\fields\BaseRelationField::VIEW_MODE_CARDS. - Added
craft\fields\BaseRelationField::VIEW_MODE_LIST_INLINE. - Added
craft\fields\BaseRelationField::VIEW_MODE_LIST. - Added
craft\fields\BaseRelationField::VIEW_MODE_THUMBS. - Added
craft\fields\Matrix::VIEW_MODE_CARDS_GRID. - Added
craft\fields\data\LinkData::getAttributes(). (#18184) - Added
craft\gql\base\ElementArguments::EVENT_DEFINE_ARGUMENTS. (#18062) - Added
craft\helpers\Assets::resolveSubpath(). (#18103) - Added
craft\helpers\Cp::cardPreviewOptions(). - Added
craft\helpers\ElementHelper::loadProvisionalChanges(). (#17915) - Added
craft\helpers\StringHelper::convertLineBreaks(). - Added
craft\helpers\UrlHelper::cpReferralUrl(). - Added
craft\i18n\Locale::getDefaultCurrency(). - Added
craft\models\EntryType::$uiLabelFormat. - Added
craft\models\FieldLayout::$thumbFieldKey. - Added
craft\models\FieldLayout::getCardBodyHtmlForElement(). - Added
craft\models\FieldLayout::getElementByKey(). - Added
craft\models\FieldLayoutForm::getStaticElements(). - Added
craft\models\Section::getCpIndexUri(). - Added
craft\models\Section::getPage(). - Added
craft\services\ElementSources::getFirstPage(). (#17779) - Added
craft\services\ElementSources::getPageSettings(). (#17779) - Added
craft\services\ElementSources::getPages(). (#17779) - Added
craft\services\ElementSources::pageExists(). (#17779) - Added
craft\services\ElementSources::pageNameId(). (#17779) - Added
craft\services\ElementSources::savePageSettings(). - Added
craft\services\ElementSources::saveSources(). - Added
craft\services\Search::deleteOrphanedIndexJobs(). - Added
craft\services\Structure::EVENT_AFTER_UPDATE_ELEMENT. - Added
craft\services\Structure::EVENT_BEFORE_UPDATE_ELEMENT. - Added
craft\web\BaseSpreadsheetResponseFormatter. - Added
craft\web\GqlResponseFormatter. - Added
craft\web\Request::getHasInvalidToken(). - Added
craft\web\Response::FORMAT_GQL. - Added
craft\web\Response::FORMAT_XLSX. - Added
craft\web\Response::FORMAT_YAML. - Added
craft\web\View::renderSandboxedObjectTemplate(). - Added
craft\web\View::renderSandboxedString(). - Added
craft\web\View::renderSandboxedTemplate(). - Added
craft\web\XlsxResponseFormatter. - Added
craft\web\YamlResponseFormatter. - Added
craft\web\twig\AllowedInSandbox. (#18219) - Added
craft\web\twig\SecurityPolicy. - Added
craft\web\twig\nodes\BaseNode. - Added
Craft.BaseElementIndex::asyncSelectDefaultSource(). - Added
Craft.BaseElementIndex::asyncSelectSource(). - Added
Craft.BaseElementIndex::asyncSelectSourceByKey(). - Added
Craft.BaseElementIndex::ensureSourceAttributeInfo(). craft\base\Element::EVENT_AFTER_MOVE_IN_STRUCTUREis no longer deprecated.craft\base\Element::EVENT_BEFORE_MOVE_IN_STRUCTUREis no longer deprecated.craft\base\ElementInterface::afterMoveInStructure()is no longer deprecated.craft\base\ElementInterface::beforeMoveInStructure()is no longer deprecated.craft\base\ElementInterface::cardAttributes()now has a$fieldLayoutargument. (#17920)craft\events\ElementStructureEventis no longer deprecated.craft\fieldlayoutelements\CustomField::editable()now has an$elementargument.craft\helpers\ElementHelper::findSource()now has$withDisabledand$pagearguments.craft\helpers\FileHelper::writeToFile()now throws an exception if the file path isn’t writable, or there isn’t sufficient free space on the disk. (#17762)craft\helpers\UrlHelpernow encodes square brackets in generated URLs. (#17840)craft\models\FieldLayout::getCardBodyElements()now always returns an array of arrays withhtmlkeys.craft\services\ElementSources::getSources()now has a$pageargument. (#17779)craft\services\ElementSources::sourceExists()now has a$pageargument. (#17779)craft\web\Request::accepts()now accepts wildcard characters (*) in the$contentTypeargument, to check for a range of MIME types (e.g.application/*+json).craft\web\Request::getAcceptsJson()now returnstruefor requests withContent-Typeheaders that matchapplication/*+json, in addition toapplication/json.- Checkbox selects can now be configured with a
storageKeysetting. - The
_includes/forms/checkbox.twigtemplate now escapes thelabelvariable. A raw HTML label can be passed by wrapping the label value inraw()orcraft\helpers\Template::raw(). - The
_includes/forms/radio.twigtemplate now escapes thelabelvariable. A raw HTML label can be passed by wrapping the label value inraw()orcraft\helpers\Template::raw(). Craft.ui.createCheckbox()now escapes theconfig.labelproperty. A raw HTML label can be passed via theconfig.labelHtmlproperty.Craft.ui.createSelect()now escapes options’labelproperties. Raw HTML labels can be passed vialabelHtmlproperties.- Deprecated
craft\fieldlayoutelements\BaseField::$includeInCards. - Deprecated
craft\fieldlayoutelements\BaseField::$providesThumbs. - Deprecated
craft\fields\BaseRelationField::$showCardsInGrid. - Deprecated
craft\fields\Matrix::$showCardsInGrid. - Deprecated
craft\helpers\StringHelper::capitalizePersonalName().toPascalCase()should be used instead. - Deprecated
craft\helpers\StringHelper::isWhitespace().isBlank()should be used instead. - Deprecated
craft\helpers\StringHelper::upperCamelize().toPascalCase()should be used instead. - Deprecated
craft\models\FieldLayout::getCardBodyAttributes(). - Deprecated
craft\models\FieldLayout::getCardBodyFields(). - Deprecated
craft\services\Structure::EVENT_AFTER_MOVE_ELEMENT.EVENT_AFTER_UPDATE_ELEMENTshould be used instead. - Deprecated
craft\services\Structure::EVENT_BEFORE_MOVE_ELEMENT.EVENT_BEFORE_UPDATE_ELEMENTshould be used instead. - Deprecated
craft\web\CsvResponseResponseFormatter::$escapeChar. - Deprecated
Craft.BaseElementIndex::selectDefaultSource(). - Deprecated
Craft.BaseElementIndex::selectSource(). - Deprecated
Craft.BaseElementIndex::selectSourceByKey(). - Deprecated the
$cardElementsargument incraft\helpers\Cp::cardPreviewHtml(). - Deprecated the
$cardElementsargument incraft\models\FieldLayout::getCardBodyElements().
System
- GraphQL API responses now set their
Content-Typeheader toapplication/graphql-response+json. - GraphQL API responses now set cache headers based on whether a mutation was performed, regardless of the request type.
- Global set queries no longer register cache tags.
- Improved element index performance. (#17557)
- Improved element query performance. (#17850)
- Reduced the number of queries executed when working with nested entries, addresses, and content blocks. (#18142)
- Session-based cookies no longer use colons (
:) in their names. (#18158) - A rate limit is now enforced for
users/send-password-reset-emailrequests. (#17337) - Added the Illuminate Support library.
- Added the PhpSpreadsheet library.
- Updated Yii to 2.0.54.
- Updated Twig to 3.21. (#17603, #18225)
- Removed the Stringy library. (#16606)
- Fixed a bug where elements with unsaved changes could show outdated attribute/field values within element index tables, chips, and cards throughout the control panel. (#17915)
- Fixed a bug where Table fields with the “Static Rows” setting enabled would lose track of which values belonged to which row headings, if the “Default Values” table was reordered. (#17090)
- Fixed a bug where requests with invalid tokens would throw an exception before the application was fully initialized, which could lead to other errors. (#18000)
- Fixed a bug where titles, slugs, and required custom field values weren’t always getting propagated to other sites when creating a new element. (#17955)
- Fixed a bug where it was possible to create more than five users with the Team edition.
- Fixed a bug where deadlocks could occur when updating elements’ search indexes. (#18139)
- Fixed a bug where Matrix and Addresses fields weren’t loading provisional drafts for GraphQL preview requests.
- Fixed a bug where generated field values weren’t always up-to-date if their template referenced nested elements. (#17938)
- Fixed low-severity XSS vulnerabilities. (GHSA-4mgv-366x-qxvx)
- Fixed a moderate-severity RCE vulnerability. (GHSA-v47q-jxvr-p68x)
- Fixed moderate-severity permission escalation vulnerabilities. (GHSA-2xfc-g69j-x2mp, GHSA-jxm3-pmm2-9gf6)