Elements
An element is the most basic unit of content in Craft. Elements provide smart management, routing, and querying interfaces for users and developers. Each type of element has some unique capabilities, but they’re all built on top of a set of common features.
# Element Types
In the control panel, you’ll encounter the seven element types common to all Craft installations:
- Addresses — Attach physical locations to other elements.
- Assets — Upload files and store rich metadata.
- Categories — Design hierarchical or ordered taxonomies.
- Entries — Model anything with flexible and nestable content containers.
- Global Sets — Manage universally-accessible data.
- Tags — Grow a folksonomy alongside your content.
- Users — Represent people with powerful identity and access tools.
Choosing the appropriate element type for your content model is essential—but don’t be afraid to mix, match, and combine them. Plugins (and custom modules) can provide custom element types, giving developers and authors a consistent experience across all their content.
# Common Features
Some features are available to all (or most) element types:
- Control panel interfaces, including forms, indexes, slide-outs, and chips and cards;
- Custom fields and field layouts with advanced condition rules for storing content;
- Slugs, URIs, URLs, and automatic routing;
- Localization via sites;
- Sophisticated permissions;
- Element queries with advanced sorting and filtering capabilities;
- Bi-directional relationships;
- Automatic indexing for search;
- Statuses for managing visibility of content;
Other features are specific to a type—like Assets’ tie to files, or Entries’ nesting capability.
# Indexes
You’ll access most elements via their element index. Indexes allow you to browse, sort, filter, and search for elements in a paginated, table-like view.
Matrix fields also have a compact element index View Mode.
# Sources
Indexes are broken down into sources. Sources can be permanent fixtures of an element type (like the Admin source for users), dynamically added based on configuration (like those for user groups), or defined by an admin using custom condition rules.
Each source also controls what columns are visible in the index, and its default sorting.
Custom sources are stored in Project Config. The interface for conditions that involve specific elements (like an author) may appear differently than the equivalent filter, because the ID may not be stable between environments.
Instead of an element select field, you’ll see an autosuggest input.
# Filters and Columns
As a complement to search and custom sources, any user with access to an element index can temporarily filter results using the condition builder interface:
Similarly, they can customize which columns appear in the table (and how the results are ordered) with the View menu:
If every field layout that would be used by an element in a source defines the same label override for a field, that label will appear in the column’s header. When a consensus cannot be reached, the original field’s label is used. This most commonly applies when a source is limited to a single entry type, asset volume, category group, or other property that also defines field layouts.
# Structures
Entries in Structure sections and Categories support a hierarchical view mode on their indexes. Elements in structures track their relative position among siblings, and can be easily relocated by dragging-and-dropping
Use the View controls to switch back into structure mode on an index if you had previously sorted it by another attribute.
# Actions
Each element type supports its own set of actions that can be performed on one or more elements, from an index. These actions are either visible directly in the index toolbar (like Status), or collected under the
# In-line Editing New!
Click Edit at the bottom of any element index to switch into an in-line editor. Click Save to update any rows that changed, or Cancel to return to the read-only mode.
Not all fields are editable in-line, and some may have simplified controls or interfaces. This is best used when the index’s default columns include scalar values like text, numbers, and dates.
# Exporters
Craft can export sets of elements to CSV, JSON, or XML. The Export… button in the index footer displays all options, including any custom exporters registered by modules and plugins.
# Modals & Contexts
A streamlined version of indexes are used when adding elements to a relational field via a modal. Depending on the field’s configuration, Craft may hide sources or actions, and disable slideouts (except to create a new element, in-context) and pagination (in favor of scrolling). Internally, Craft refers to these variations as “contexts,” which plugins have an opportunity to modify.
# Chips & Cards New!
Throughout the control panel, you’ll encounter references to elements in a number of different contexts, like element indexes, Matrix fields, and other relational fields. Element cards are a new way to display nested or related elements. They share the core features of element chips (like quick-actions and ordering controls), but provide an additional layer of customization via the element’s field layout.
Both chips and cards support thumbnails, but only cards allow additional custom field values to be bubbled up. The presence and order of those fields is dictated by the field layout; additional features like colorization and icons are supported by entries.
# Rendering Elements New!
Every element has a render()
method, which you can call from a template to get an HTML representation of the object.
This is mostly a convenience feature, not the primary means by which you are apt to output an element or its content.
The CKEditor plugin (opens new window) uses this method to convert each nested entry from a placeholder to a rich, personalized block—while remaining exactly where the author placed it in the editor.
Without any configuration, this will typically be its title (if the element type uses titles), or it’s element type and ID. This default behavior is handled by the element’s magic __toString()
method, meaning {{ element.render() }}
and {{ element }}
are functionally equivalent.
However, the output of element.render()
can be customized by placing a template in your partialTemplatesPath that follows a specific naming convention. The full path to each element’s template is comprised of:
- The element’s type or
refHandle
: Typically its lower-cased, singular name—entry
oraddress
, for instance. TherefHandle
is the same as is used for reference tags, elsewhere in the system. - The field layout provider’s handle: Differs based on the type of element and how its field layout is configured. For assets, it would be the volume’s handle; for entries, its entry type handle; for global sets, the set handle.
As an example, if you wanted to customize the output of an asset in a volume with the handle images
, you would create a template with this path:
_partials/asset/images.twig
If some property of the asset (like its extension, or the user group its uploader is in) should affect its template, you can put whatever logic you need into the template and render something different:
<figure>
{{ asset.getImg() }}
<figcaption>
{{ asset.title }}
{% if asset.uploader.can('accessCp') %}
<a href="{{ asset.getCpEditUrl() }}">Edit</a>
{% endif %}
</figcaption>
</figure>
You can also render lists of elements by calling the render()
method on an element query.
Nested entries (like those in Matrix and CKEditor (opens new window) fields) include information about where they live in the system, via owner
and field
properties:
{# _partials/entry/ingredient.twig #}
{% if entry.field and entry.field.handle == '' %}
{{ entry.typicalCalories }}
{% endif %}
Because entries can be nested within fields on different element types (i.e. a CKEditor field on an entry or a Matrix field in a global set), it’s important that your template consider discrepancies between properties on the owner. For instance, an entry that owns another entry will have a type
property; a category that owns an entry has a group
property. If an entry type is used both in a section and as a nested entry, the owner
and field
properties will only be available in the latter context!
# Parameters
Each template is passed its element under a variable that agrees with its refHandle
—same as would be passed to a template, when Craft matches an element’s route.
When manually rendering an element partial (by calling element.render()
or .render()
on an element collection), you have an opportunity to make additional variables available to the template:
{{ recipe.ingredients.render({
portionSize: currentUser.householdSize,
}) }}
Keep in mind that partials can be rendered from multiple contexts, not all of which will provide these extra variables. Guard against missing parameters with the |default()
filter:
{# _partials/entry/ingredient.twig #}
{% set portionSize = portionSize|default(1) %}
{{ entry.title }}: {{ entry.quantity * portionSize }} {{ entry.unit }}
# Eager-Loading
When accessing related or nested content within an element partial, use the .eagerly()
method to eager-load elements for other partials that might be rendered in sequence.
{# _parials/entry/post.twig #}
{% set headerImage = entry.headerImage.eagerly().one() %}
{% if headerImage %}
{{ headerImage.getImg() }}
{% endif %}
<h3>{{ entry.title }}</h3>
{# ... #}
# Properties and Methods
All elements share a few characteristics that make them familiar to work with in your templates. Each element type will supplement these lists with their own properties and methods.
Additionally, custom fields attached to an element are automatically made available as properties corresponding to their handles—so a field called “Post Summary” with a handle of summary
would be accessed as entry.summary
(if it were attached to an entry type’s field layout).
This is not an exhaustive list! If you’re curious, consult the craft\base\Element (opens new window) and craft\base\ElementTrait (opens new window) class reference for a complete picture of what data is available inside elements and how it can be used.
# Properties
Properties give you access to values, and do not accept arguments.
Property | Type | Notes |
---|---|---|
archived | bool|null | Whether the element is soft-deleted, or “trashed.” |
dateCreated | DateTime | Date the element was originally created. |
dateDeleted | DateTime|null | Date the element was soft-deleted or null if not. |
dateUpdated | DateTime | Date the element was last updated. |
enabled | bool | Whether the element is enabled (globally). |
id | int | ID of the element. |
level | int|null | Depth of the element in a structure. Structures only. |
parentId | int|null | ID of the parent element. Structures only. |
searchScore | int | Score relative to other results when returned from an element query using the search param. |
siteId | int | ID of the craft\models\Site (opens new window) the element was loaded in. |
slug | string|null | Only for elements with slugs. |
title | string|null | Only for elements with titles. |
trashed | bool | Whether or not the element has been soft-deleted. |
uid | string|null | A UUIDv4 string that uniquely identifies this element. |
uri | string|null | Rendered URI or path for the site the element was loaded in. Only for elements with URLs. |
# Methods
Methods also return values, but may accept or require arguments.
Any method beginning with get
can be used like a property by removing the prefix and down-casing the first letter. For example, {{ entry.getLink() }}
can also be accessed as {{ entry.link }}
Method | Notes |
---|---|
getAncestors(dist) | Returns up to dist parents of the element, or all parents when omitted. Structures only. |
getChildren() | Returns immediate children of the element. Structures only. |
getCpEditUrl() | Gets a URL to the Craft control panel. |
getDescendants(dist) | Returns descendants of the element, down to dist levels below this one, or all descendants, when omitted. Structures only. |
getEnabledForSite(siteId) | Whether the element is enabled in the provided site, or the site it was loaded in if no ID is provided. |
getHasDescendants() | Build an HTML anchor tag with its front-end URL and title. Elements with URLs only. |
getLink() | Build an HTML anchor tag with its front-end URL and title. Elements with URLs only. |
getNext(criteria) | Load the “next” element relative to this one, given a set of criteria. |
getNextSibling() | Load the next sibling of this element, within a structure. Structures only. |
getOwner() | Return the element that “owns” a nested element. Nested elements only. |
getParent() | Returns the element’s parent. Structures only. |
getPrev(criteria) | Load the previous element relative to this one, given a set of criteria. |
getPrevSibling() | Load the previous sibling of this element, within a structure. Structures only. |
getRef() | Builds the part of a reference tag unique to the element. |
getSiblings() | Load siblings within the element’s structure. Structures only. |
getSite() | Returns the craft\models\Site (opens new window) the element was loaded for. |
getStatus() | Returns a plain-text representation of the element’s status, which may be synthesized from a number of other attributes. |
getUrl() | Builds a complete front-end URL based on the element’s URI. |
The full list of element properties and methods can be found in the craft\base\Element
class reference (opens new window), or individual element types.