Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Drupal and Masonry, without the tears of Frustration

Parent Feed: 

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.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web