Skip to main content

The Cheeky Monkey Media Blog

A few words from the apes, monkeys, and various primates that make up the Cheeky Monkey Super Squad.

"Drupal and Masonry without the tears of frustration" by Micah Joyner - Cheeky Monkey Media

Drupal and Masonry, without the tears of Frustration

I recently had to create a new layout that mimicked the Pinterest layout. Masonry to the rescue! (sorta...) With Drupal already crapping out the content via views, we could just use the Masonry views plugin right? Sorta. Well, it worked. ... sorta. There were problems, and I don’t like problems, only solutions.

I like a very NON-hacky way of doing things. Masonry views worked for the desktop screen size but failed miserably for anything smaller. We were working with a responsive design, so it was unacceptable. There was simply just no amount of tweaking the options and CSS that it came with, that I was happy with. I’m also not a fan of CMS plugins controlling layout. There tend to be crappy implementations and far less control. I don’t speak for everything, of course, just my experience.

I wanted to control.. as much as I could. So I abandoned the views plugin, and just decided to use the raw jQuery plugin, and use my own CSS.

This assumes ya know how to use requireJS and jQuery plugins.

Step 1 - The view.

So, the view just had to output the HTML, nothing else. Set the output format for the view to ‘Unformatted list’. Nice, just simple, clean Drupal output.

Step 2 - Including the jQuery plugin code.

I’m also not a fan of including boatloads of JS on every page so that you can use it “at some point” on some page on the site. Unnecessary load times, for all other pages.

RequireJS happiness ensued.

The main.js config file:

  1. requirejs.config({
  2.   paths: {
  3. 	// vendor
  4. 	'masonry': 'vendor/masonry.pkgd.min',
  5.  
  6. 	// custom
  7. 'jquery': 'modules/jquery-global',
  8. 	'community': 'modules/community'
  9.   }
  10. });
  11.  
  12. require([
  13.   'jquery',
  14.   ], function ($) {
  15.   'use strict';
  16.  
  17.    // DOM ready
  18.   $(function() {
  19.  
  20. 	// js loaded only on community page
  21. 	if ($('body').hasClass('page-community')) {
  22.   	require(['community']);
  23. 	}
  24.  
  25.   }); // DOM ready
  26. });

We’re telling require where to find the libraries and specific module files, that has the code we need. Then when DOM has loaded, we check to see if we’re on a specific page, if so, load up the required JS. The ‘community’ page is where the masonry plugin is required. So, let's look at that file (community.js).

  1. /**
  2.  * Community
  3.  * @requires jquery, masonry
  4.  */
  5. define([
  6.   'jquery',
  7.   'masonry'
  8. ], function ($, masonry) {
  9.   'use strict';
  10.  
  11.   /**
  12.    * object constructor
  13.    */
  14.   var Community = function() {
  15. 	this.init();
  16.   };
  17.  
  18.   /**
  19.    * init community module
  20.    */
  21.   Community.prototype.init = function() {
  22. 	var self = this;
  23.  
  24. 	// init masonry
  25. 	$( '.view-community .view-content' ).masonry( { itemSelector: '.views-row' } );
  26.  
  27.   /**
  28.    * DOM ready
  29.    */
  30.   $(function () {
  31. 	var community = new Community();
  32.   });
  33. });

So now we have the masonry jQuery plugin only loading up on the community page. By inspecting the output of that view on the page, I was able to figure out which elements to target for masonry to know which is which regarding content. The ‘.view-row’ elements were each ‘element’ of content, while the “.view-community .view-content” was the parent.

That just gets the all the JS working, but will most likely still look like poo (technical monkey term). -- Time to start slinging that poo around until we have something nice to look at. Yes, we can actually polish a turd.

Step 3 - CSS(SCSS) Kung-Poo

  1. .view-community {
  2.   max-width: 100%;
  3.   margin: 0 auto;
  4.   .view-content {
  5. 	width: 100%;
  6. 	overflow: hidden;
  7. 	.views-row {
  8.   	width: 48%;
  9.   	margin: 0 1%;
  10.   	margin-bottom: rem-calc(20);
  11.    	overflow: hidden;
  12.   	border-radius: 15px;
  13.   	background: $white;
  14.   	font-size: rem-calc(12);
  15.   	line-height: rem-calc(18);
  16.   	@media #{$medium-up} {
  17.     	font-size: rem-calc(16);
  18.     	line-height: rem-calc(26);
  19.   	}
  20.   	@media #{$small-portrait-up} {
  21.     	margin: 0 1%;
  22.     	margin-bottom: rem-calc(20);
  23.     	width: 48%;
  24.   	}
  25.   	@media #{$medium-up} {
  26.     	margin: 0 1%;
  27.     	margin-bottom: rem-calc(20);
  28.     	width: 31%;
  29.   	}
  30.   	@media #{$large-up} {
  31.     	margin: 0 1%;
  32.     	margin-bottom: rem-calc(20);
  33.     	width: 23%;
  34.   	}

Okay, now we have something decent to look at.

  • So for mobile views, the elements take up 48% of the horizontal screen space, effectively having two elements per ‘row’.
  • Moving up from that, we just increase the font-size.
  • Then up from that, (a tablet layout), we have effectively 3 per row, and the for desktop we have 4 per row.
  • So this is much cleaner, leaner than having to fiddle with the views masonry plugin. It allows us to have much more control over the plugin itself, and the CSS.

Sometimes, it pays to just go back to doing things manually, especially if you want more control.

Web Development

Would you like to know more about what we do?

View Our Services

Graphic Design Cheeky Monkey

Have a look at some our client work

View Our Work

Cheeky Monkey Discovery

Learn more about Cheeky Monkey Media

About Us

Comments