Storage Entities: More Elegant Content Modelling Through the Drupal UI

By mandclu, Sat, 04/03/2021 - 07:33

One of the strengths of Drupal has long been its ability to easily model complex content architectures. The ability to quickly configure and manage a variety of content types with distinct collections of fields and other configurations makes Drupal an excellent choice for structured and robust handling of a multitude of different kinds of data.

But sometimes, we don't want that information to be accessed directly. For example, my website might have contacts that are associated with events. I might not want those contacts to have their own "pages" within the site, because I'm only including a small amount of information. If I define these contacts as a content type, then each contact becomes a node and will have its own URL where it can be accessed and potentially indexed by search engines, and more. I could use  the excellent Rabbit Hole module to prevent direct access, but if we need to use that to prevent access for all nodes of one or more types, then we likely shouldn't really be storing them as nodes to begin with. By default content types also show up in the "Add content" menu and various other places in the admin UI, which may not be what we want, especially for data that isn't meant to be displayed or managed on its own.

Some sites use the Paragraphs module for this, and if your sites needs Paragraphs for more than this simple use case, then it can certainly be configured to handle a scenario like we've described for our contacts. That said, Paragraphs is a substantial set of code, and also has a sizeable list of requirements, so it's overkill if we only need a better way to model our content.

Another approach is to create a custom entity to hold the data you want to store. Drupal core's excellent Entity API provides a robust feature set for building you own entity types, giving you complete control over every aspect of how your new entity type will collect, store, and display data. That said, this approach is not for the feint of heart or casual site builder. Even leveraging an excellent tool like Drupal Console you'll end up needing to write a fair bit of your own code to get everything working properly, and custom code (even when created by Drupal Console) should be understood as technical debt, that will require ongoing maintenance, for example to ensure Drupal 10 compatibility.

I've also used the Entity Construction Kit (ECK) to simplify the process creating custom entities. It works well, allowing you to use the Drupal UI to specify and build out your own entity types, each of which can have their own bundles, the equivalent of content types for nodes, each of which can have their own fields and other configuration. While I like ECK, it does trouble me that it has yet to have a stable release, in nearly 10 years as a module on Drupal.org, nor has it opted into security coverage. Also, while ECK's system of being able to dynamically create both entity types and bundles is extremely robust, it's likely overkill for many common uses cases like the contacts we've said we want to use with our website's events.

I got thinking that for content modelling purposes, many sites would find a single entity type enough, with the ability to create whatever bundles are needed to effectively store the data they want to manage without making them nodes. I recently created the Storage Entities module to provide this simpler approach. Once installed, within the Structure menu you'll see a new option for Storage types, equivalent to core's Content types. The interface for managing the data is in the Content menu, effectively a new tab in the set that for many sites will already include Content, Files, Media, and possibly others.

The Storage Types admin page

By design the interface for Storage Entities mimics that of Drupal core's Node module, though with an aim to simplify the experience wherever possible. Currently, when defining a new storage type, there are only three fields, and the only one that requires input is the name for the type.

Adding a new Storage type

The interface for viewing, creating, and editing storage data is similarly simplified as much as possible, for instance fields which determine the author of the data its published state are hidden by default, but can be exposed if needed. That said, most often I suspect people will want to manage storage entities most often directly within the parent entities with which they will be associated, using a solution like Inline Entity Form.

Embedded contact form with the Inline Entity Form simple widget

Above we can see Inline Entity Form's simple widget. Particularly if a storage entity (e.g. contact) can be associated with more than one parent, it's often more useful to use the complex widget, which allows an editor to select from existing entities.

Inline Entity Form's complex widget can allow an editor to create a new or choose an existing contact

If you click from there to add a new contact, you see a somewhat different version of the same form.

Inline Entity Form's complex widget open to create a new contact

Now if you click to create the contact, you'll see its label and some options.

Inline Entity Form's complex widget showing the contact label and edit and remove actions

Finally, if we save our node, we see the structured content of our contact displayed.

An article node with our contact information displayed

Does every Drupal site need a solution like Storage Entities? Definitely not. But when you find you do need store content that isn't well suited to nodes, I hope this module will save you some time, and make your site easier to manage.

Have an idea on how the module could be better? Leave a comment below or open a feature request in the issue queue!

Comments 1

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.

johnzzon (not verified)

4 months 1 week ago

Interesting module! I've often just created a custom entity for this requirement, but this would be a lot easier when I only want to store data and don't have any logic in the entity class. I'll definitely follow the progress of this project!