our blog

How To: Add Media Objects to the Body of Your ExpressionEngine Entries

When I first started using ExpressionEngine — nearly four years ago — I quickly realized there wasn’t a great way to add media objects to the body copy of an article or post. I went through a few different options, but none of them really allowed the client much in terms of laying out these objects in the body copy. Jump forward to today and the problem really hasn’t been solved, or at least it hasn’t met my expectations.

The techniques I’m going to share with you are ones I initially learned three years ago and continuously improve upon. In this tutorial, we’ll be giving the client the ability to add images, videos, and embed code, but the sky is the limit on what you want to give them the ability to add. I’ve added functionality in the past to include image carousels, quotes, and related entries.

I use a handful of third party commercial and non-commercial EE add-ons in my configuration. I use the commercial options because I utilize them in other ways throughout the CMS. You should have no problem doing this with the non-commercial options in parenthesis; however, I will be using Matrix template tags throughout.

Assets ($99) by Pixel & Tonic (can be replaced by the native File fieldtype; however, you cannot add multiple files at once)
Matrix ($49) by Pixel & Tonic (can be replaced by the native Grid fieldtype)
Wygwam ($29) by Pixel & Tonic (can be replaced by the native Rich Text Editor or Textarea)
Low Variables ($49) by Low (can be replaced by native Snippets)

Antenna by Vector Media Group
Copee Pastee by Iain Urquhart
Entry Type by Rob Sanchez
Field Pack by Pixel and Tonic
Stash by Mark Croxton

Channel field setup

Firstly, let’s start with the channel fields we’ll be using. I namespace all channel fields with the initial channel they are paired with. In this case, the channel short name is “general.”


Field Label Short Name Fieldtype
Body general-body Rich Text Editor, Wygwam, Textarea, etc.
This is your typical body text editor; nothing fancy. I typically use the third party commercial add-on Wygwam from Pixel and Tonic in my setups for its UI and extra features.

Body Objects

Field Label Short Name Fieldtype
Body Objects general-body-object Entry Type
Fieldtype settings
Fieldtype Field Pack - Pill
Short Name Label Hide Fields
image Image Body Video, Body Embed
video Video Body Image, Body Embed
embed Embed Body Image, Body Video
Here, I’m using Rob Sanchez’s Entry Type add-on to show/hide my body object fields below. This will create options to select which field you want to show, and the other two will be hidden. More information on his Github page.

Body Images

Field Label Short Name Fieldtype
Body Images general-body-image Matrix
Fieldtype settings
Matrix Configuration
  Column 1 Column 2 Column 3 Column 4
Cell Type Copee Pastee Assets Field Pack - Pill Field Pack - Pill
Col Label Text Editor Code Image File(s) Image Alignment Image Grid
Col Name image-code image-file image-align image-grid
Celltype Options Label: image Allow multiple options: yes Pill Options:
EntryObject-unit--right : Right
EntryObject-unit--left : Left
Pill Options:
EntryObject--grid1 : 1 column
EntryObject--grid2 : 2 column
EntryObject--grid3 : 3 column
EntryObject--grid4 : 4 column
This field is a Matrix with four columns: The automated code to paste into the text editor; the field to select/upload image(s); alignment options; and if multiple images are chosen, the grid columns you want to use.

Body Video

Field Label Short Name Fieldtype
Body Video general-body-video Matrix
Fieldtype settings
Matrix Configuration
  Column 1 Column 2
Cell Type Copee Pastee Text
Col Label Text Editor Code Video URL
Col Name video-code video-url
Celltype Options Label: video Multiline?: no
This field is for video URL’s from popular video services. It consists of a Matrix with two columns: the automated code to paste into the text editor, and the field to paste in your video service URL. Note: the video URL’s can only be from YouTube, Vimeo, Wistia, or Viddler since we’ll be using Antenna to parse the URL and that’s the only services that add-on accepts for now.

Body Embed

Field Label Short Name Fieldtype
Body Embed general-body-embed Matrix
Fieldtype settings
Matrix Configuration
  Column 1 Column 2
Cell Type Copee Pastee Text
Col Label Text Editor Code Embed HTML
Col Name embed-code embed-html
Celltype Options Label: embed Multiline?: yes
This field is for embedding HTML, like Google Maps, Tweet embeds, Instagram embeds, etc. It consists of a Matrix with two fields: the automated code to paste into the text editor, and the textarea to hold the embed HTML.

Some of you may be asking yourself why you couldn’t just paste a YouTube embed code (instead of using the video field) or a Google Maps embed code (instead of using the embed field) straight into the text editor. You certainly can do that. However, the whole point of these body object fields is so we, as the developers and designers, can control the output on the front-end.

Add your channel fields to a channel and we’ll move to the front-end code.


I typically write my CSS in LESS, but for this example I’ve written it in plain CSS.  I’ve also included media queries for responsive development.

EE Tags

My ExpressionEngine tags are put into snippets, or in my case Low Variables, so we can use them throughout the site.

Snippet: Show the body objects

This might look like a mess, so let’s break it down.  The outer-most tags {general-body-image}, {general-body-video}, and {general-body-embed} were the Matrix fields we made earlier. They’re wrapped around a Stash tag, so each row in the Matrix will duplicate that Stash tag. The stash tag is turning our HTML into snippets, appending them with the Matrix row number and storing them for later use on the page.

Inside {general-body-image}, I’m using the values of the Image Alignment and Image Grid columns to fill in our class attributes where necessary.

When the body field parses at a later stage, those Stash snippets are injected where their matching text editor code was placed in the body copy.

Snippet: Hide the body objects

Sometimes you want to use the first few words or sentences of the body copy as a description somewhere on your website and you don’t want images or videos to show in those descriptions. So you go and remove the Matrix tags from the page. Unfortunately, you’ll still end up with our text editor code {image1}, {video1}, etc. showing. Here’s how you get rid of those:

Page Template

Now it’s time to bring it all together in the template.

There are two items here to discuss: 1.) Choose which snippet to use: the one that shows the objects or the one that hides them, and 2.) wrap your body tag with {exp:stash:parse process=”end”} so that you makes sure to parse your body tag last, allowing your snippets to parse first every time.

Whew! That was a lot to put on paper, but I can tell you with first-hand knowledge that clients love this. The ability to align images left, right, or full width; put images in a grid; add videos and maps that expand to the width of the container; and whatever else your imagination can create will all make their experience the best one they’ve had with a CMS.

If you have any questions about anything I’ve gone over, please direct them to @terrostar on Twitter.