Creating Custom Content
Audience
This documentation is primarily intended for developers experienced in object-oriented PHP, Drupal 6 or Drupal 7, and for those looking to explore the principles of Drupal 8.
The guide to creating a content entity type in Drupal 8 contains a full list of available options.
Building a Bundle-less Content Type in Drupal 8
In this case, we are creating a Drupal 8 content entity that does not have any bundles.
The entity does not implement the Field API, so it remains in code only. Nevertheless, it can serve as a useful framework for building content entities, especially as we import more complex data later.
Where applicable, I’ll reference relevant OOP concepts and documentation.
Background
Our module is named advertiser
.
Our content entity type is also called advertiser
.
Our new Drupal 8 content entity advertiser
will have the following fields:
- UUID
- ID
Defining the Content Entity in Drupal 8
First, all custom modules now reside in modules/custom
instead of sites/all/modules/custom
.
Inside our custom module, the file structure will look like this:
modules/custom/advertiser$ ├── advertiser.info.yml └── src └── Entity └── Advertiser.php
For reference, you can check out a complete Advertiser entity implementation including tests and constraint plugins, though we’ll keep it simpler here.
Info File
We start by defining our module in advertiser.info.yml
:
name: Advertiser type: module description: 'Barebones advertiser entity' package: custom core: 8.x
Entity Skeleton
The basic Advertiser
entity class and its schema are defined in src/Entity/Advertiser.php
.
First, we define the namespace:
namespace Drupal\advertiser\Entity;
Then we define the entity using annotations:
This is the actual definition of the entity type. Drupal reads and caches this, so remember to clear the cache after any changes.
/** * Defines the Advertiser entity. * * @ingroup advertiser * * @ContentEntityType( * id = "advertiser", * label = @Translation("Advertiser"), * base_table = "advertiser", * entity_keys = { * "id" = "id", * "uuid" = "uuid", * }, * ) */
Since this is a minimal entity, we only use a few properties, without handlers like AccessControlHandler.
We now have a functional module defining a custom content entity, but you’ll notice that the advertiser
table hasn’t yet been created in the database.
$ drush sql-cli mysql> SHOW TABLES;
This is because our class doesn’t yet include methods that interact with the database directly. We must define the minimum methods required for proper entity-database interaction.
ContentEntityBase
We import ContentEntityBase
to gain essential DB-related methods by adding the following use statement:
use Drupal\Core\Entity\ContentEntityBase;
Then, we extend ContentEntityBase
and implement ContentEntityInterface
:
class Advertiser extends ContentEntityBase implements ContentEntityInterface {
Now we need to use some built-in methods to store data. Let’s define the basic fields for our entity.
baseFieldDefinitions
The baseFieldDefinitions
method comes from ContentEntityBase
and expects one argument:
Entity type definition. Useful when a class is reused for multiple (possibly dynamic) entity types.
It returns:
An array of base field definitions keyed by field name.
Our implementation might look like this:
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('ID')) ->setDescription(t('The ID of the Advertiser entity.')) ->setReadOnly(TRUE); $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The UUID of the Advertiser entity.')) ->setReadOnly(TRUE); return $fields; }
Recap: Full Entity Class
setLabel(t('ID')) ->setDescription(t('The ID of the Advertiser entity.')) ->setReadOnly(TRUE); $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The UUID of the Advertiser entity.')) ->setReadOnly(TRUE); return $fields; } }
After installing your module, you should see the advertiser
table added to the database:
drush sql-cli mysql> SHOW TABLES;
or:
drush sqlq "show tables like 'advertiser'" drush sqlq "describe advertiser"
If your module is already installed, you’ll need to run an entity update.
In issue #2976035: CRUD operations should use latest entity type and field storage definitions, remote update ability was removed. See the corresponding change record for details.
Also consider using the Devel Entity Updates module.
?>Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.