A few months ago, Plank decided it was time to redesign our own website. Rather than just reskin our old WordPress site, we wanted to rebuild from the ground up. The Laravel project was chosen for the project as the it has recently become a favorite among our developers. In reimagining our website, we didn't just want to recreate what we had before. We sought to embark on a project that would allow us to innovate and come up with new tools that we could provide our clients.

Today, Plank is happy to open source one little piece of innovation that emerged from this exercise: Laravel-Mediable. Feel free to check out the code on GitHub or read on to learn a little but about how this new tool came to be.

Building a Media Management Interface

While building the CMS for the new plankdesign.com, we realized that we would need to come up with a way of handling the many media files that would be used throughout the site. The various content types that make up the site make use of thumbnails, banners, galleries, inline images, and even downloadable attachments. hardcoding links to the files in the public/webroot directory is not a sustainable solution.

Fortunately, over the years, we have experimented with numerous ready-made file management plugins, such as CKFinder, ELFinder, Filemanager, WordPress's Media Library, etc. This has given us plenty of time to get a sense of which features make programming easier and what kind of interfaces lead to a smooth user experiece. We came up with the following list of requirements.

After a few weeks of work, we came up with a system which met all of our requirements. Here is a little peek at the user interface that lives on the backend of plankdesign.com

The code that we are open sourcing today represents the backend component that we built this media management on top of. It sadly doesn't include the interface shown above, but could serve as a foundation for others to build something similar – or something completely innovative.

A Quick Tour

The Laravel-Mediable package consists of three main classes:

Example Usage

Upload a file to the server, and place it on the filesystem disk named "uploads". This will create a Media record that can be used to refer to the file


$media = MediaUploader::fromSource($request->file('thumb'))
	->toDestination('uploads', 'post/thumbnails')
	->upload();

Attach the Media to another eloquent model with one or more tags defining their relationship.


$post = Post::create($this->request->input());
$post->attachMedia($media, ['thumbnail']);

Retrieve the media from the model by its tag(s).

$post->getMedia('thumbnail')->first()->getUrl();

For more in-depth documentation and installation instructions, check out the readme page on github.

Comparing to Laravel-MediaLibrary

A popular Laravel package called Laravel-MediaLibrary released by the Belgian agency Spatie already attempts to do something very similar to our Laravel-Mediable package. We drew a lot of inspiration from this fantastic package, but found that it didn't quite meet all of our needs. Our package is a little bit more complex to use, but offers more flexibility. Here is a quick comparison to help you decide which package best suits your use case.

spatie/laravel-medialibrary plank/laravel-mediable
Relationship many-to-one polymorphic, each media record is owned by one related model many-to-many polymorphic, each media record can connect to any number of related models, and vice versa.
Filesystem Files are stored in directories named after the media id relative to the disk root Files can be stored anywhere on the disk
Association Identifier Each media record belongs to one "collection" Media can be attached to a model with any number of "tags"
Aggregate Types Support for images and pdfs Configurable support for any number of custom types
Miscellaneous Features Glide manipulations Synchronization commands