The Bones of Drupal 8 Media Support

The Bones of Drupal 8 Media Support

Tanner Heffner, Developer
#Drupal 8 | Posted

If you’re using a content management system like Drupal, your content will likely include different types of media entities — images, videos, documents, tweets, etc. Thanks to the new Entity Browser paradigm in Drupal 8, creating a robust and accessible interface for content authors and editors to manage various media entities has never been smoother.

The Drupal Media Team gave the Drupal community a wonderful gift in the form of the Entity Browser module. This is the cornerstone of the new Entity Browser paradigm. In their words, the Entity Browser module “provides a generic entity browser/picker/selector. It can be used in any context where one needs to select few entities and do something with them.”

There are many existing implementations that provide media handling right out of the box already, but they can be very opinionated about what media you’re uploading, how and where you’ll use your media, or include extra bells and whistles you may not want. Seeing as how the Entity Browser module was designed with flexibility in mind, we’ll be creating a very un-opinionated browser, configured entirely through the admin UI. That configuration can then be exported to a custom module, either through the CMI tool or as a Features package. A future post will elaborate on how to create a custom media bundle & integrate it into an existing Entity Browser implementation with code.

Our implementation of Entity Browser is going to need these 3 modules at minimum:

Entity Browser

Inline Entity Form

Media Entity

For this example, we’ll also be using the Image and Document provider modules to get a head start on creating our media bundles.

Entity Browser integrates seamlessly with Inline Entity Form thanks to the widget provided by the included entity_browser_entity_form  submodule.

All of that, plus their dependencies, results in this relatively small makefile:

api: 2
core: 8.x

# Set some reasonable defaults
    subdir: "contrib"
    type: "module"

  drupal: 8.1.8
    version: 3.0-alpha27
    version: 1.0-alpha3
    version: 1.0-alpha9
    version: 1.0-alpha6
    version: 1.5
    version: 1.2
    version: 1.1

By the end of this walkthrough, we’ll have configured some media bundles, an entity browser with multiple widgets, a view with displays for managing media entities both in and out of the entity browser interface, and at least one field using the entity browser.

Configuring Media Bundles

We’re going to start by creating our media bundles. This can be found at /admin/structure/media. I’m going to make two bundles — one for each type provider plugin I have. Each bundle will need at least an upload field (file or image, respectively), but we’ll also be adding a plain text field for storing the MIME Type separately.

bundle fields

First, we create the bundle, selecting a type provider, but ignoring the type provider configuration and field mapping dropdowns for now, because the fields don’t exist yet. Once we add our fields, we can then go back and map them appropriately. Use the same textfield for the MIME Type mapping on both bundles, this will come into play when we create our view.

bundle settings

For document uploads, the file upload field is where you’ll set your valid document extensions. Generally something like: txt pdf xls ppt doc docx  allows for PDFs, Microsoft Office files, and other text files.

Do the same for the image bundle, but with the valid image extensions: jpg jpeggif png  etc.

Configuring the View

This part stinks, but it has to be done before we can get to the entity browser setup. It could be a lot worse, but media_entity  gives us a pretty good base media view to build from, and we only need to make a few tweaks.

First, I’m going to strip out some of the existing filters to create my own, leveraging the MIME Type field we created earlier. The only filters I want to keep are Publishing status and Media name. You can keep more or less, these are really personal preferences.

Under FIELDS  we’re going to add the MIME Type field we created, but keep it hidden. This is because we’re going to use it to create a grouped filter, in the FILTER CRITERIA  section. To accomplish that, we’re going to need to create a contextual filter in the ADVANCED  section. Sounds harder than it is. Just select the same MIME Type field with “Display all results for the specified field” selected. That’s it.

Now for the filter, add MIME Type one more time, expose the filter, and set it as “Grouped”. It’s optional, with whatever label you prefer. I’m calling mine “File Type”. Now at the bottom, you’ll see some empty rows with your group options. You can go as specific or generic as you like here. For brevity, I’ll only be filling out the 3 items it defaults to.

filter settings

Now that our settings look somewhat similar to this:

media view

We can hit the magic button:

magic view

This duplicates all existing settings into a new display for the same view. We need to clean up a bit further for the Entity Browser’s sake, but we’re almost there!

For the entity browser display, be sure you’re applying settings only to this display (overrides), not all displays! You don’t want to have to reconfigure the other display again.

Switch the format to a Grid with 4 columns. Some fields shown, but a lot fewer than the table display. Also, hide the labels on the fields this time. Hopefully you can tell which piece is the thumbnail and which is the title. One additional field is needed: Entity browser bulk select form . No settings are needed for the field, just the field itself.

We’re also changing the filter criteria on publishing status to only show published items inside an entity browser. If you’re using Views Infinite Scroll, it can be nice to switch the pager in this view to that as well. If your View’s settings for entity browser displays look similar, we’re good to go:

eb view

Configuring Entity Browser

Now that we have the “boring” stuff out of the way, let’s configure our entity browser. Entity Browser configuration is located over at admin/config/content/entity_browser .

This example is going to use the ‘Modal’ display plugin, ‘Tabs’ as the widget selector plugin, and no selection display plugin. You may find a different combination that works better for your use cases, but I’ve found these settings work well with no fuss.

eb settings

Hit next, and clear the height and width values on Display to ensure your modal is responsive. The next two tabs have no configuration options with our setup, so let’s move onto Widgets.

This browser is going to need 2 widgets — one to view existing media entities and another to upload new ones.

The first widget should always be the view widget, so the library of existing media entities is shown first. Select “Media: Entity browser” (or however you titled your view’s browser display) as the display to use.

After the view widget is there, add the upload widget. There are a few options here. For more fine-tuned configuration, as well as the ability to upload files to custom media bundles, use the generic Entity Form widget. If you’re using the provider plugins from earlier, special upload widgets are added here as well. Any of these are acceptable choices, often your browser will have a combination of upload forms for various bundles / embeddable objects. We’re going to keep it simple for now and just use the generic “Upload” widget. When you’ve added all the widgets you want, hit “Finish.”

eb widgets

Entity Browser in Action

The last step we need to do to see this in action is add a field that uses the damn thing!

For the sake of brevity, I’m going to add an entity reference field to the default Basic Page content type, referencing Other. On the field settings page, specify the type of content being referenced as “Media.” Finally, in the reference type section, select your image media bundle.

field type

On the form display settings for that field, switch it to use our Entity Browser, and display as a rendered entity.

field settings

For the display settings, also change that field to Rendered entity. You can keep the label or not. I like to hide them, but you definitely want to see the rendered image.

Whew, that was a lot. But we’re done! Go create a piece of content using that field, and watch the magic!

eb in action

Tanner Heffner

Tanner Heffner