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:

Other features are specific to a type—like Assets’ tie to files, or Entries’ nesting capability.

# Fields and Content

In a fresh installation, element types are distinguished only by a handful of native features. The identity and utility of an element is often defined by the custom fields attached to it via a field layout: elements and their custom field values are collectively referred to as content.

Craft is adamantly agnostic about your content model, and comes with no predefined notion of what a “page” or “post” should be. Instead, it treats all your content as data, and provides the means to use it how you see fit—whether that’s as HTML accessible via public URLs, a private database, GraphQL for a decoupled or statically-generated front-end, or even a CSV to populate a printed document.

Content can be a great deal more than text, too! Craft has a number of built-in field types that provide a highly-customizable authoring and developer experience.

# 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.

my-craft-project.ddev.site/categories/species
Customizing element sources
Customizing element sources.

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:

my-craft-project.ddev.site/categories/species
Craft’s condition builder
Using the condition builder to narrow results.

Similarly, they can customize which columns appear in the table (and how the results are ordered) with the View menu:

my-craft-project.ddev.site/categories/species
Customizing element index columns and sorting

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 quality 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

Drag-and-drop handle icon
their row in an element index. Reordering is still possible, even when the structure is limited to a single level.

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

icon in the footer (like Delete). Actions may be hidden or disabled when they don’t apply to the selection or source.

# 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!

An element “chip” with a title, thumbnail, and label indicated it has been modified.

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 a combination of the field layout and customizable card attributes 5.5.0+; additional features like colorization and icons are supported by entries.

Two element “cards” in the Craft control panel, show thumbnails, titles, and statuses.

# Custom Card Attributes 5.5.0+

The attributes and fields displayed on element cards is ultimately determined by the interface below each field layout designer:

Element card attribute customization interface.

An element’s Title and Status are always visible, and the presence of a thumbnail is determined by the field layout itself (by selecting Use for element thumbnails in the field layout element’s

Ellipses
action menu). Additional attributes not present in the field layout can be enabled in the card customization interface; those that are part of the field layout will indicate when they are enabled with an “eye” icon.

# Nested Elements

Craft ships with two native nested element implementations, which provide unique authoring or administrative experiences:

While relationships are supported by every element type, only addresses and entries are eligible for nesting. Plugins may use the nested element interface to provide other functionality, like Commerce’s product and variant system.

# Element Partials New!

Every element has a render() method, which you can call from a template to get an HTML representation of the object.

The CKEditor plugin (opens new window) uses the .render() method to convert each nested entry (opens new window) from a placeholder to a rich, personalized block—while remaining exactly where the author placed it in the editor.

This is not the only way to output your elements’ content, though! Any time you have access to an element, you are free to use its attributes and field values, directly.

Without any configuration, this will typically be the element’s 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 partial template is comprised of:

  • The element’s type or refHandle: Typically its lower-cased, singular name—entry or address, for instance. The refHandle 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 or element collection.

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 #}
{{ entry.title }}

{% if entry.field and entry.field.handle == 'nutritionHighlights' %}
  {{ 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!

Users and addresses don’t have field layout providers, and therefore do not support element partials.

# Parameters

Each partial 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 or null-coalesce operator (??):

{# _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.
ownerId int|null ID of the element that “owns” this element. Nested elements 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.