Planet Drupal

Subscribe to Planet Drupal feed - aggregated feeds in category Planet Drupal
Updated: 56 min 34 sec ago

Chromatic: Drupal 8 Deployments with Jenkins, GitHub & Slack

Fri, 17/06/2016 - 01:06

We recently launched our first Drupal 8 site--actually it’s this very site that you’re reading! While this wasn’t our first time using or developing for Drupal 8, it was our first full site build and launch on the new platform. As such, it was the first time we needed to handle Drupal 8 code deployments. While I’ve previously covered the benefits of using Jenkins, this post will take you through the steps to create a proper Drupal 8 deployment and how to integrate GitHub and Slack along the way. In other words, you’ll see our current recipe for deploying code automatically, consistently and transparently.

First Things First: Some Assumptions

This post assumes you already have a Jenkins server up and running with the following plugins installed:

If you don’t yet have these things ready to go, getting a Jenkins server setup is well documented here. As is how to install Jenkins plugins. For us, we typically use a Linode instance running Ubuntu LTS for our Jenkins servers. This post also assumes that the external environment you’re trying to deploy to already has Drush for Drupal 8 installed.

Example Deployment Script with Drush

Before we dive into setting up the Jenkins job to facilitate code deployments, I’d like to take a look at what exactly we’re trying to automate or delegate to our good friend Jenkins. At the heart of virtually any of our Drupal deployments (be them Drupal 7, 8 or otherwise) is a simple bash script that executes Drush command in succession. At a macro level, this typically means doing the following, regardless of version:

  1. SSH to the server
  2. Change directory to repository docroot
  3. Pull down latest code on the master branch
  4. Clear Drush cache
  5. Run database updates
  6. Update production configuration
  7. Clear Drupal caches

In Drupal 7, where we relied heavily on Features to deploy configuration, we would typically do something like this:

echo "" echo "Switching to project docroot." cd /var/www/drupal-7-project/docroot echo "" echo "Pulling down latest code." git pull origin master echo "" echo "Clearing drush cache" drush cc drush echo "" echo "Run database updates." drush updb -y echo "" echo "Reverting features modules." drush fra -y echo "" echo "Clearing caches." echo "" drush cc all echo "" echo "Deployment complete."

In Drupal 8, we have the magical unicorn that is the Configuration Management System, so our deployments scripts now look something like this:

If you’re familiar with creating Jenkins jobs already and are just looking for a Drupal 8 deploy script, these next lines are for you.

echo "" echo "Switching to project docroot." cd /var/www/ echo "" echo "Pulling down the latest code." git pull origin master echo "" echo "Clearing drush caches." drush cache-clear drush echo "" echo "Running database updates." drush updb -y echo "" echo "Importing configuration." drush config-import -y echo "" echo "Clearing caches." drush cr echo "" echo "Deployment complete."

Seriously, configuration management in Drupal 8 is amazing. Hat tip to all of those who worked on it. Bravo.

Another notable difference is that with Drupal 8, clearing caches uses the cache-rebuild Drush command or drush cr for short. drush cc all has been deprecated. R.I.P. little buddy. ⚰

If you have a site that needs to be put into "Maintenance mode" during deployments, you can handle that in Drupal 8 with drush sset system.maintenance_mode 1 to enable and drush sset system.maintenance_mode 0 to disable.

Creating our Jenkins Slave & Job

Now that we’ve covered what it is we want Jenkins to handle automatically for us, let’s quickly run down the punch list of things we want to accomplish with our deployment before we dive into the actual how-to:

  1. Automatically kickoff our deployment script when merges to the master branch occur in GitHub
  2. Run our deployment script from above (deploys latest code, imports config, clears caches, etc.)
  3. Report deployment results back to Slack (success, failure, etc.)
Create Your Jenkins Slave

For Jenkins to orchestrate anything on a remote box, it first needs to know about said box. In Jenkins parlance, this is known as a "node". In our case, since we’re connecting to a remote machine, we’ll use a “Dumb Slave”. Navigate to Manage Jenkins > Manage Nodes > New Node

At Chromatic our naming convention matches whatever we’ve named the machine in Ansible. For the purposes of this article, you can just name this something that makes sense to you. Example:** Drupal-Prod-01**

As part of the creation of this node, you’ll need to specify the Host and the Credentials Jenkins should use to access the box remotely. If you don’t yet have credentials added to Jenkins, you can do so at Jenkins > Credentials > Global credentials (unrestricted). From there things are pretty self-explanatory.

Setup the Basics for our Jenkins Job

Now that we have a way for Jenkins to target a specific server (our slave node) we can start building our deployment job from scratch. Start by navigating to: Jenkins > New Item > Freestyle Project.

From there press "OK" and move on to setting up some basic information about your job, including Project Name, Description and the URL to your GitHub repository. Pro tip: take the time to add as much detail here, especially in the Description field as you can. You’ll thank yourself later when you have loads of jobs.

Configure Slack Notification Settings (optional)

Assuming you’re interested in tying your deployment status messages to Slack and you’ve installed the Slack Notification Plugin, the next step is to tell Jenkins how/where to report to Slack. You do this under the Slack Notifications options area. As far as notifications go, we prefer to use only the "Notify Failure", “Notify Success” and “Notify Back To Normal” options. This is the right mix of useful information without becoming noisy. To allow Jenkins to connect to your Slack channels, you’ll need to follow these steps for adding a Jenkins integration. Then just fill in your Slack domain, the integration token from Slack and the channel you’d like to post to. These settings are hidden under “Advanced…”.

Configure Where this Job Can Run

This is where we instruct Jenkins on which nodes the job is allowed to run. In this case, we’ll limit our job to the slave we created in step one: Drupal-8-Prod-01. This ensures that the job can’t run, even accidentally, on any other nodes that Jenkins knows about. Jenkins allows this to be one node, multiple nodes, or a group.

Configure GitHub Repository Integration

Under "Source Code Management" we’ll specify our version control system, where are repository lives, the credentials used to access the repo and the branches to “listen” to. In our example, the settings look like this:

Here we’re using a jenkins system user on our servers that has read access on our GitHub repositories. You’ll want to configure credentials that make sense for your architecture. Our "Branch Specifier" (*/master) tells Jenkins to look for changes on the master branch or any remote name by using the wildcard, “*”.

Configure Your Build Triggers

This is where the rubber meets the road in terms automation. At Chromatic, we typically opt for smaller, more frequent deployments instead of larger releases where there is a higher probability of regressions. Since we rely heavily on the GitHub pull request model, we often have many merges to master on any given day of development for an active project. So we configure our deployments to coincide with these merges. The following setup (provided via the GitHub Jenkins Plugin) allows us to automate this by selecting "Build when a change is pushed to GitHub".

Setup Your Deployment Script

Here’s where we’ll implement the example deployment script I wrote about earlier in the post. This is the meat and potatoes of our job, or simply put, this is what Jenkins is going to do now that it finally knows how/when to do it.

Under "Build" choose “Add build step” and select “Execute shell”. Depending on your installed plugins, your list of options might vary.

Then add your deployment script to the textarea that Jenkins exposed to you. If you want somewhere to start, here is a gist of my job from above. When you’ve added your script it should look something like this:

Last Step! Enable Slack Notifications

Although earlier in the job we configured our Slack integration, we still need to tell Jenkins to send any/all notifications back to Slack when a build is complete. You do this sort of thing under the "Add post-build action" menu. Select “Slack Notifications” and you’re good to go.

Our deployment job for Drupal 8 is now complete! Click "Save" and you should be able to start testing your deployments. To test the job itself, you can simply press “Build Now” on the following screen OR you can test your GitHub integration by making any change on the master branch (or whichever branch you configured). With the setup I’ve covered here, Jenkins will respond automatically to merges and hot-fix style commits to master. That is to say, when a PR is merged or when someone commits directly to master. Of course no one on your team would ever commit directly to master, would they?!

Wrapping Up

Assuming everything is setup properly, you should now have a robust automatic deployment system for your Drupal 8 project! Having your deployments automated in this way keeps them consistent and adds transparency to your entire team.

Categories: Elsewhere

Chromatic: The Anatomy of a Good Ticket

Fri, 17/06/2016 - 01:06

We previously wrote about how to write a great commit message, but before that commit message is ever written, there was (hopefully) a great ticket that was the impetus for the change. Whether or not a ticket is great is subjective, and it is often how well thought out the details are that makes the difference. The ticket might have everything a developer needs to complete the task, but not provide any insight into how to test the final product. Conversely, it might provide all the details the QA team needs to verify, but not provide any insight into the technical requirements for implementation.

Before we examine the specific things that make up a great ticket let’s first examine some of the best practices that further enhance communication and efficiency:

  • Having all stakeholders using the ticket management system and not allowing any communication of requirements via email or other communication tools that silo information.

  • Ensuring that requirements which are discussed one-on-one or during a meeting are added back into the ticket so nothing is lost or forgotten.

  • Having any message conversations in open channels that allow visibility into the decisions for others working on related issues.

  • Continuously keeping tickets updated with the current status so the whole team is aware of where everyone else is with their tasks.

  • Ensure everyone is familiar with the internal jargon and acronyms used, or ensure they are provided with the tools to decipher the terms.

With some ground rules established, let’s investigate the factors that make for a great ticket.

A User Story

A user story provides a high-level description of functionality from a user’s perspective, such as, "when a user logs in they should be able to see a list of past purchases." Great tickets often start with a user story that answers what is needed and why at a high level.

Clearly Defined Goals & Scope

Clearly stated goals from the business allows the ticket to be resourced correctly. Also, a full understanding of the requested change’s scope will inform what brands, sites, regions, pages, etc. a new feature or change will affect, and is crucial to planning a proper implementation.

Accurate Estimates

A well thought through estimation of the level of effort from developers and other stakeholders will make sprint planning/resourcing much more accurate and sprint reviews/evaluations more insightful.

Understanding of Priority

A clear understanding of the business priorities will ensure timely completion and allow the team to plan ahead, avoiding late nights and weekends.

Knowledge of Blockers

Exposing any potential barriers or blockers during the estimating of the ticket will allow them to be accounted for and even potentially solved before development starts.


Providing screenshots and adding arrows and text for clear communication that makes it very apparent what "this" and “that” are, thus avoiding pronoun trouble.

Documented Designs

Providing detailed requirements with exact values, sizes, states, etc. with considerations for edge cases will make any developer forever grateful. Style guides with documented font names, sizes, weights, etc. are another tool that will improve design workflow efficiency. Additionally, designs can provide:

  • Where every piece of information comes from.

  • How items should appear if a given field or other information source is empty.

  • How long or short variants of a given data point are handled and what logic controls programmatic truncation if applicable.

Contact Information

Providing the names and contact information for other team members who may hold key pieces of information that didn’t make it onto the ticket will prevent blockers and help new developers learn which team members have expertise in other areas. Additionally, providing contact information for external parties when working on third-party integrations will prevent communication gaps and middlemen. Sending a quick introduction when rolling a new person into the mix will get you bonus points.

Code Context

Taking the first step is the hardest part, but often a lead developer will know right where and how to proceed. Providing other developers with the names of functions or files to look for from someone with deeper knowledge of the codebase can save an immense amount of time up front and avoids potential refactoring down the road. It also reduces guesswork and more importantly, might reinforce a best practice when there are multiple approaches that would technically work. Examples of previous implementations or before-and-after code samples are also great things to consider providing.

Reliable Information

Up-to-date acceptance criteria that is verified as accurate and updated if/when requirements changed, and the ability for a developer to have 100% confidence in this information makes everyone’s life better.

Complete Logical Requirements

Thinking through default values or fallback values/logic if a given piece of data is empty by default, instead of treating it as an edge case, allows for cleaner code and reduces emergencies and "bugs" down the road.

Component Driven Separation

Giving everyone on the team discrete chunks of work that can be documented, developed, tested, and completed will allow everyone to feel much better about the progress of the project. Providing clearly defined subtasks that allow chunks of the work to be checked off and delineated clearly when working on larger tickets will help with this. Another key to success is having properly managed dependencies for blocking work so effort is not wasted until all blockers are resolved.

This can be accomplished by separating tickets by components, not pages. For example, "social share bar" and "comment widget" tickets that probably appear on every content type rather than a "article page" ticket that includes building and styling all of those components before it can be considered complete.

Exact URLs

When possible, always provide the exact URLs of pages where the offending bug can be found or the new functionality should be placed. This keeps anyone from making assumptions and when properly paired with a nice screenshot, it really takes the guesswork out of recreating bugs or finding where new features should live.

Reproducible Steps

In addition to exact URLs, a thorough lists of steps to reproduce the bug, the expected result, and the actual result will all help a developer quickly pinpoint and understand a problem. It is just as important for developers to provide QA and business stakeholders with steps to test functionality that is not intuitive or simple to test.

Assumptions & Changes

Finally, not all developers are the same. If you ask two developers to solve the same problem, you might get very different solutions, but the more details you provide them, the better the chance of a successful outcome. Additionally, a developer with a wealth of institutional knowledge might need significantly less information to have a clear picture of what needs to be done, while a new hire, internal transfer or external contractor will likely need more information.

However, I would argue that regardless of the expected assignee’s knowledge, the extra time spent to write a good ticket is rarely wasted. Tickets often get passed around as people take vacations, flat tires happen, and children get sick. When these things inevitably occur, we don’t want to rely upon assumptions, which, no matter how good, only need to be wrong once to cause potentially large amounts of wasted time, embarrassment, liability, etc.

Ways to Work This Into Your Project
  • Create a blocked status for your Agile or Kanban boards and utilize it liberally to ensure high visibility into the unknowns and show others how much time is lost due to blockers.

  • Loop project managers into conversations with the person who filed the initial ticket so they see first hand the level of effort required to track down answers.

  • Talk through the issues during sprint review and review what did and did not go well.

  • Allow developers to review and estimate issues before they are included in a sprint and require clear requirements before accepting a ticket.

  • Don’t just complain; be a part of the solution. Educate stakeholders on the structure you want to see for requirements and provide them with tools to help communicate more clearly such as logic maps, data flow diagramming tools, etc.

What Now?

I encourage you to think of a good ticket not just as a means to an end; be that a fixed bug, a new feature, or new design. Instead, treat it as an opportunity to show respect to each of the many professionals that will touch the ticket through its lifecycle by providing them the information and tools they need to perform their job to the best of their abilities. This respect goes in all directions, from ensuring good requirements for developers, to writing good testing instructions for QA, writing quality code for a great product and providing stable hosting infrastructure. This all culminates in a well-built project that shows respect to what this is ultimately all about: the user.

Categories: Elsewhere

Cheeky Monkey Media: D8 You’re Great! My first experience with Drupal 8

Fri, 17/06/2016 - 00:35
D8 You’re Great! My first experience with Drupal 8 shabana Thu, 06/16/2016 - 22:35

This is one of the blogs that I was really thrilled to write because I got to document my first ever installation of the production version of Drupal 8.  And boy, was I excited!  As you know, Drupal has made some significant changes under the hood in this version. I am not going to go over those changes in this feature, but I thought, I would give an overview of some of the superficial changes that it has undergone.  More than anything, as a developer, I was really interested to see how much it has changed in terms of the UI and operability.

Setting Up

I setup Drupal 8 on my Windows 10 machine running Acquia Dev Desktop (yes, you read that right!).  The installation was pretty straight forward and appeared to be somewhat quicker than all the versions I have tried before.  Once I got it setup, the front page looked extremely familiar, with it running Bartik as the default theme.  But right off the bat, I noticed the nice admin toolbar across the top of the page with pretty much the same menu links that we're accustomed to.  The one new change, 'Modules' is now called 'Extend'.

The Modules Page

Going to the modules page, we see that we have a module filter by default, making module searches a lot easier when our list starts building up. As we scroll down the list, we notice a couple of inclusions that are finally getting their dues, as you might already know, Views and Views UI are in Core!  The Views UI pretty much looks the same but the one thing I really liked is the ability to now clone a View display type as any other display type. To elaborate, in D7, if we wanted to clone a Page display, we were only allowed to clone to the same display type, ‘Page’.  However, the Views in D8, now allows us to clone a display type like Page, as any other display type like ‘Block’, ‘Entity Reference’, ‘Feed’, ‘Attachment’, etc (views.png). This is one change I’m really happy about because there has been one too many instances where I’ve had to fiddle with code after cloning a display to transform it to another display type.

More welcomed goodies in Core

The other noticeable changes: we've got CKEditor, Contextual Links, Quick Edit, and Configuration Manager all enabled and running as part of Core.  They've also added multilingual capabilities, and web services as part of the release.  These are definitely welcomed additions and makes Drupal much more relevant and powerful from the get-go.  One additional change that I noticed, the removal of the PHP Filter module.  It has now moved to a contributed module at

Display Modes with More Juice

Moving along, Drupal 8 now incorporates some of the functionality of Display Suite and offers us more control over the way nodes, user profiles, comments, taxonomies and blocks are displayed.  There is a new admin section under 'Structure' called 'Display Modes' from where we can add more display modes to control the look and feel of content as well as forms.  So not only can we easily manage the display that the end-user sees, but we can also modify the look of forms while data is inputted.

In-Place Content Editing

One of the other features that is in Core now is the ability to edit content in-place. In Drupal 7, this task was accomplished by contributed modules.  With the inclusion of it in Core now, it just makes life a lot easier for us, especially when we’ve got tons of stuff to edit and test.  There’s an ‘Edit’ button at the top of the toolbar and that displays all the places on the page that we can edit in-place.  Editing and displaying of the updated content is now a cinch.

Configurations made easier

As I began to delve further into the configuration section, the one thing that caught my eye was the new 'Configuration synchronization' section under Development.  I briefly played around with the feature  and my initial reaction is, it's a mild-dose of the Features module. Basically, this new feature allows us to export all the configuration changes made on a site into a nice little tar.gz file.  In the scenario above, I just created a new user role called 'Super User' and immediately exported my configurations. Once you extract the file, you can see that there are quite a few .yml format text files , and among them is a file called, 'user.role.super_user.yml', which is the config for my new role.  Basically, I can take this and import it into my Staging or Production site, provided they're the same site and share the same UUID.  As the Features modules allows us to bundle related configurations and re-use it on ANY site, Drupal's core configuration feature allows us to keep configuration consistent between different environments of the SAME site.  As you can see, it won't replace the Features module just yet, but it does offer a great starting step towards a cleaner and more reliable way to transfer and transport configuration among different environments and sites.

In conclusion

In a nutshell, my first encounter with Drupal 8 has been extremely positive. The guys at Drupal have taken stock of what users really need and have tried to incorporate those changes into this new version.  I've got lots of roads to traverse with Drupal 8 and I hope to share with you some of those experiences during my future trails.

Visit our Why Drupal 8? site!

  Categories Drupal Planet
Categories: Elsewhere

Cheeky Monkey Media: Working with Bootstrap’s New Responsive Utility Classes

Fri, 17/06/2016 - 00:34
Working with Bootstrap’s New Responsive Utility Classes denis Thu, 06/16/2016 - 22:34

As an html/css purist at heart, my school of thought has always been having your representational layer separated from your markup. Sites like CSS Zen Garden taught us that you should never have to mix your design styles inside your markup with the idea being that well structured html will never have to change even on a complete re-design.


2 years ago, I was forced to use a css framework for one of my project. Being the control freak that I am, I was reluctant to try new things and bloat my beautiful handmade custom css.

It took me a little over a year for me to embrace using a css framework and rely on existing css to style my markup, but I’ve learned so much by doing so from people a lot smaller than I am. And I’ve reduced more than half the need to write custom css as well as lowered production time.

Disclaimer: Some of these new classes will only work on the current alpha-2 release of bootstrap 4 and might change in the future since it’s still in heavy development. Use at your own risk.

Responsive Floats

Responsive floats are great for header elements among other things. I often come across designs that have search box right aligned on desktop, but are left aligned on tablet. Or main navigation that are floated to the left but move to the right and collapse on mobile.

Responsive floats works by using the pull-<breakpoint>-<direction> pattern.


  <form class=”pull-xs-left pull-md-right”>

     <input type="text" placeholder="Search">



The above code will float the search bar left until the screen width reaches the “md” breakpoint, floating it to the right.

In conjunction with other components from the framework like navbar, spacing and setting your own variables in sass, we can easily come very close to the original design mockups without writing a single line of custom css. Like I said earlier, it took me a while to develop using these concepts but it opened my mind to write my code in a more modular fashion and reuse these components on every site I work on.

Responsive Text Alignments

This one I use often for content. On Desktop, the design’s text is aligned center inside articles but on mobile this makes for a weird looking effect and we’de much rather have it left aligned.

Bootstrap v4 introduces new responsive text alignment classes like this:

<article class=”text-md-center”>

 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit ex, semper quis eros sed,</p>


This will leave the text at its default left alignment on smaller breakpoints, but will align the text center on the medium breakpoint and up, removing the need to write a media query in your css.

If you prefer to have your text centered on all breakpoints you simply need to use text-xs-center


This is just the tip of the iceberg for new features that ships with the Bootstrap 4. Some other things that I’m really loving is the new card component and contextual colors and backgrounds creating custom ones is as easy as using the “bg-variant($parent, $color)” mixin.

If you haven’t already, I urge you to look at the documentation , but whatever css framework you chose to use, make sure you really dig in the documentation and use all the tools that are available to you. The investment will save you time in the long run.

  Categories Drupal Planet
Categories: Elsewhere

Cheeky Monkey Media: IntentionJS and RequireJS - How monkeys do it (the sfw edit)

Fri, 17/06/2016 - 00:32
IntentionJS and RequireJS - How monkeys do it (the sfw edit) micah Thu, 06/16/2016 - 22:32


  • RequireJS (and some knowledge of how to use it)
  • IntentionJS
  • A brain
  • Bananas

There are plenty of reasons you shouldn’t HAVE to use IntentionJS, but it’s just so good when you NEED your fix, of DOM manipulation.

Normally a responsive website should be designed so that when you expand or collapse the viewport (effective screen), the DOM elements flow naturally from left to right, and top to bottom. The order is preserved, and it was designed so that those elements follow that flow in terms of importance and usability.

Admittedly, this does limit us at times, and we need elements to be in completely different placements in the DOM, depending on the device used. Sure we can mess with duplicated content by hiding and showing the right elements based on the screen size [please don’t, it’s bad], or doing some fancy schmancy css floating and absolute positioning, but then you start to get other fun issues, that go beyond the scope of this banana log.

So, we’re left with manually moving the elements around. You could start using the append() and after() functions say, from jQuery, but that also gets complicated.. setting screen widths, window resize, or using (media query), etc. All messy in some form or another.

We like clean, even though we like poo, we still like clean.

Our Hero, IntentionJS

From the mouths of the intentionJS magicians: (

“Intention.js offers a light-weight and clear way to dynamically restructure HTML in a responsive manner.”

Good right? riiight.

Okay, so we all have our own methods for including JS, and writing libraries and code. Here’s what we monkeys do.

Starting with RequireJS

We like using requireJS. A lot. In fact I get a banana every time I do. So in the main.js file loaded by require we have:

requirejs.config({ paths: { // vendor 'intention': 'vendor/intention', 'underscore': 'vendor/underscore-min', 'viewportsize': 'vendor/viewportSize-min', // custom 'jquery': 'modules/jquery-global', 'intentcontext': 'modules/intentcontext', 'homepage': 'modules/homepage', 'initintent': 'modules/initintent' }, });

Here we are just telling require where to find all our ‘required’ files when we ‘require’ them. Yeah.. there is probably a better way of saying that. *puts on deal with it glasses*

Intention requires underscore, so we’re including that. Also, we’re using a little library called ‘viewportsize’. Why? well because different browsers report different viewport sizes, based on whether or not it’s showing the scroll bar. That’s a problem, this fixes that problem. (

Then we include jQuery, cause we need it. Then comes some magical code with unicorns.. and monkeys.

require([ 'jquery', 'underscore', 'intentcontext', ], function ($, _, IntentContext) { 'use strict'; // DOM ready $(function() { // js loaded only on homepage if ($('body').hasClass('front')) { require(['homepage']); } if ($('html').length > 0) { require(['initintent']); } }); // DOM ready });

So here, we’re just including the needed libraries for the site in general, and then checking if we’re on the homepage, if so, include the homepage module. Then the very last that we include in the initialization of the intent. Think of it, as intentions’s big red “go” button. We’ll get to these a bit later. For now, just know, that we are making sure that the initinent file is included last, since we’re doing all ‘intention’ setup first. Since require loads these in ORDER, of the code inclusion, we’re able to do all the setup first, then lastly initialize it.


This is where we setup our ‘contexts’. A context is basically a ‘switch point’ - a point a which stuff is supposed to happen. Each ‘context’ is associated to a screen size (these values should match your CSS media queries for major layout changes)..

IntentContext.bp_desktop = 1025; IntentContext.bp_tabletlandscape = 769; IntentContext.bp_tablet = 641; IntentContext.bp_mobilelandscape = 321; IntentContext.bp_mobile = 0;

These are the breakpoints were major layout changes happen (for the purpose of this blog). Yours would match that of your CSS breakpoint values.

Next up, making our contexts. As you will see, each context has a name, and I’m setting the “min” value to the breakpoint value that I set in the above code. So basically, the ‘desktop’ context will get triggered every time the browser hits the “1025 pixel” viewport width or above. (It won’t keep re-triggering events though, as you increase viewport width above that, which is nice.) All the other ‘contexts’ will get triggered at their respective screen width values.

IntentContext.horizontal_axis = IntentContext.intent.responsive({ ID: 'width', contexts: [{ name: 'desktop', min: IntentContext.bp_desktop }, { name: 'tabletlandscape', min: IntentContext.bp_tabletlandscape }, { name: 'tablet', min: IntentContext.bp_tablet }, { name: 'mobilelandscape', min: IntentContext.bp_mobilelandscape }, { name: 'mobile', min: IntentContext.bp_mobile }], matcher: function (measure, context) { return measure >= context.min; }, measure: function () { IntentContext.v_width = viewportSize.getWidth(); return IntentContext.v_width; } });

So, there is a thing. It’s thing you may need. Normally intention won’t activate the context on first page load, which you may need. We will get to that. (This is what that initintent.js file is for).


Now we need to tell which elements where to be placed in the dom, according to whatever ‘context’ is triggered. You can either go directly in the HTML and add all the special intention attributes to the elements, or do it via JS. I like doing it in the JS, i find it cleaner.

So in our Homepage.prototype.intent = function () function:

var footer = $('.l-footer'); footer.attr('intent', ''); footer.attr('in-desktop-after', '.l-header'); footer.attr('in-tabletlandscape-after', '.l-main'); footer.attr('in-tablet-after', '.l-main'); footer.attr('in-mobilelandscape-after', '.l-header'); footer.attr('in-mobile-after', '.l-header'); IntentContext.intent.on('desktop', function() { footer.attr('style', 'border: 4px solid red;'); }); IntentContext.intent.on('tabletlandscape', function() { }); IntentContext.intent.on('tablet', function() { }); IntentContext.intent.on('mobilelandscape', function() { footer.attr('style', 'border: 4px solid white;'); }); IntentContext.intent.on('mobile', function() { footer.attr('style', 'border: 4px solid blue;'); });

First line we just get the element we want to target. The next lines are key.

I’m now manually adding all the required contexts on that elements, so for each ‘breakpoint’ context, we know where to place the footer. The syntax is as follows

footer.attr(‘in-[your-breakpoint-name]-[move-function], ‘[dom element]’)’

‘your-breakpoint-name’ is just the name you associated to the breakpoint, up in the IntentContext.js file.

‘move-function’ is the method in which you want to place that element. They work just like jQuery’s manipulation functions [append(), before(), after(), prepend()]

‘dom-element’ is just the element you are specifying to be “moved to”.

So in this case, when the browser hits the ‘desktop’ layout screen width, we are putting the ‘.l-footer’ element just after the ‘.l-header’ element in the DOM. The next lines all work the same and specify where the element needs to go, for whichever context (screen size).

Then, we have some more magical code.

IntentContext.intent.on('desktop', function() { footer.attr('style', 'border: 4px solid red;'); }); IntentContext.intent.on('tabletlandscape', function() { footer.attr('style', ''); });

So, for each context, we can run some custom code of any kind. In this case, every time we hit the ‘desktop’ context, we are going to add a border to the footer element. Everytime we hit the ‘tabletlandscape’ context, we make sure remove any lingering styles. Etc..

I normally like to use these methods to ‘reset’ certain things that may have been triggered on an alternate layout.

Lastly, the Initilization of Intent. This will allow us to use those .on() [in above code] functions on page load as well.

Know that all this will only happen on the homepage though. If you need this to happen on all pages, you can create a separate module that can handle site wide context changes, and just include it in the main.js require section.

InitIntent.js IntentContext.horizontal_axis.respond(); IntentContext.intent.elements(document); $(window).on('resize', IntentContext.horizontal_axis.respond);

So these 3 lines just get everything going. Check out the intention.js website for further detail, but suffice to know, they get intention up and running.

That should be it to have it all working nicely and being able to do some sexy DOM manipulation without to much pain.

Categories Drupal Planet
Categories: Elsewhere

Acquia Developer Center Blog: 5 Mistakes to Avoid on your Drupal Website - Number 2: Security

Thu, 16/06/2016 - 23:49

Good security practices protect your site from hacker attacks. In this article we'll look at some methods for reducing security risks on your site. 

Drupal Security Best Practices

Drupal has good security built in if used correctly. However, once you begin to configure your site you might introduce new security issues. Plan configuration so that only trusted users have permissions that involve security risks.

Tags: acquia drupal planet
Categories: Elsewhere

DrupalCon News: Sharing the secrets of your success!

Thu, 16/06/2016 - 23:07

Welcome to Dublin, stranger. Why don't you come and warm yourself round our campfire? There. That's better.

Help yourself to stew, it's all we have, but you're welcome to share it.

It's good stew, warms all the right parts in all the right ways. The only thing we ask in return is that you share with us your secrets. You know, the secrets of your success.

Don't be shy now, I can see from the way you walk that you're a superstar project manager. Seeing that sort of thing is just a gift of mine, I guess.

Categories: Elsewhere

ImageX Media: Higher Education Notes and Trends

Thu, 16/06/2016 - 22:47

In this week’s higher education notes and trends, predictive behavior technology comes to the education sector, for-profit schools see sharp declines and a closer look at how the University of Southern California is differentiating itself from other prestigious private schools by becoming a leader in recruiting minorities. 

Categories: Elsewhere

Lullabot: Lullabot Project Manager Roundtable

Thu, 16/06/2016 - 22:00
Matt & Mike sit around with several Lullabot project managers, and talks about the ins, outs, and hows of PMing.
Categories: Elsewhere

Acquia Developer Center Blog: The Risks and Rewards of Fully Decoupling Drupal

Thu, 16/06/2016 - 21:36

With the advent of web services in Drupal 8 core, decoupling Drupal — namely, using Drupal as a content repository to expose data for retrieval and manipulation by other applications — has never been easier. Now, with the REST module in core, you can transform Drupal into a data service without custom code or substantial configuration. But is it a good idea? What are some of the considerations you should scrutinize when opting for a fully decoupled project?

Tags: acquia drupal planet
Categories: Elsewhere

Darren Mothersele: PHP Framework in One Weekend

Thu, 16/06/2016 - 14:30

Earlier this year I set about creating a day of training for DrupalCamp London. It was based on a PHP Framework course I’d given, but reduced to fit into a day. We ended up focusing on Modern PHP, as that was most useful for the attendees in their transition from Drupal 7 to Drupal 8.

It was a really successful day, and I had some great feedback. I have since developed the idea into a two day training course, which looks at some of the core concepts behind most modern PHP apps.

Over the past couple of months I have worked hard to refine the content and edit it down into a short guide. I’ve released it (thanks to Leanpub) in the form of a book. It guides the reader through a weekend-long project to construct a simple PHP web framework.

“a weekend, the fundamental unit of coding self-improvement” - Peter Shirley

In particular, it uses Symfony Components, and some other popular PHP packages, to demonstrate the core features of web frameworks, like routing, templating, controllers, and dependency injection. Projects such as Drupal, phpBB, Laravel, eZ Publish, Joomla!, Magento, Piwik, and many more are using Symfony Components as a foundation on which to build. The book uses these, and more, to build our own PHP Framework in a weekend.

Here’s the full contents:

  • Getting Started
  • Managing Complexity
  • Testing
  • HTTP
  • Templating
  • Content
  • Routing
  • Controllers
  • Dependency Injection
  • Design and Layout
  • Reuse

Click the cover image below to get the book:

Drop me a line if you have any questions.


Categories: Elsewhere

Savas Labs: Using XHProf to profile your Drupal module

Thu, 16/06/2016 - 02:00

Second part in a series of how to use XHProf effectively within a VM for a Drupal website. Continue reading…

Categories: Elsewhere

Drupal Association News: Acknowledging the Drupal Association's Supporting Partners - Q2

Thu, 16/06/2016 - 00:20

There are so many amazing companies in the Drupal universe contributing their time and resources to the community and project right now. They’re taking the initiative to encourage their employees to contribute code. They’re sharing what they've learned while trying to provide clients with superior digital experiences. They’re donating their time to provide educational content to the community. And they’re doing a lot of it through their own internal operations.

Some of these businesses are also members of our Supporter Programs, which fund’s maintenance and improvements. And for that, we can’t thank them enough.

"Supporting Partners help us make a better home for our community. Their financial support is directly responsible for DrupalCI, the Issue Credits system, and all the other initiatives we've undertaken as a team. Take the Drupal 8 landing page as one example. Funding from Supporting Partners let us promote the release of Drupal 8 with a level of professionalism and finesse that no Drupal release has had before. Work like that builds a stronger ecosystem for our Supporters and for the wider community." - Tim Lehnen (hestenet), Drupal Association Project Manager

In this quarter alone, with financial support from the Supporting Partners, the tech team has been able to:

  • Launch the Alpha of their Composer façade
  • Update the Git Twisted daemon, which serves as the backend for the Git repositories and packaging process
  • Launch a new staging environment that more closely matches the production environment, optimizing the development workflow
  • Improve performance of the DrupalCon Events website
  • Deploy CKEditor to's Section, Page, and Post content types, which brings a more impressive editorial experience to
  • Bring PhantomJS testing to DrupalCI, so the Drupal project can now test at the JavaScript level

All of this happened while ensuring DrupalCI ran smoothly for DrupalCon New Orleans sprints, successfully launching registration for DrupalCon Dublin (get your tickets now!), and launching the DrupalCon Baltimore splash page. Needless to say, the team has been busy, and it wouldn’t have been possible without our Supporting Partners financial contributions.

Check out our recent update for more details on exactly what the team was able to accomplish this past quarter. And to see where the team is headed next, take a look at the team's working roadmap.

As a testament to the relentless support these companies continue to show, here’s a list of new or renewing partners just this quarter:

  1. EPAM Systems
  2. Aten Design Group
  3. Phase2 Technology
  4. Lullabot
  5. Digital Circus
  6. HS2 Solutions
  7. Cybage Software, Inc.
  8. The Cherry Hill Company
  9. Cheeky Monkey Media
  10. Access
  11. Message Agency
  12. Adapt A/S
  13. Unleashed Technologies, LLC
  14. Promet Source
  15. Digital Echidna
  16. ThinkShout Inc.
  17. Amazee Labs
  18. ImageX Media
  19. Four Kitchens
  20. Evolving Web
  21. Acro Media Inc
  22. Aquilent
  23. Facet Interactive
  24. Last Call Media
  25. QED42 Engineering Pvt Ltd.
  26. Bluehost
  27. Blackmesh
  28. OpsGenie
  29. Arvixe
  30. GreenGeeks
  31. JetBrains

If you want to give back to the Project and help fund this important work, please contact our Executive Director, Megan Sanicki, for details. Your participation will be much appreciated and your company will also be able to enjoy great benefits in return!

Categories: Elsewhere

Acquia Developer Center Blog: Drupal 8 Module of the Week: Rules

Wed, 15/06/2016 - 22:30

Each day, between migrations and new projects, more and more features are becoming available for Drupal 8, the Drupal community's latest major release. In this series, the Acquia Developer Center is profiling some prominent, useful, and interesting projects--modules, themes, distros, and more--available for Drupal 8. This week: Rules.

Tags: acquia drupal planetRulesworkflowintegration
Categories: Elsewhere Drupal 6 security update for Views!

Wed, 15/06/2016 - 22:29

As you may know, Drupal 6 has reached End-of-Life (EOL) which means the Drupal Security Team is no longer doing Security Advisories or working on security patches for Drupal 6 core or contrib modules - but the Drupal 6 LTS vendors are and we're one of them!

Today, there is a Moderately Critical security release for Views to fix an Access Bypass vulnerability.

An access bypass vulnerability exists in the Views module, where users without the "View content count" permission can see the number of hits collected by the Statistics module for results in the view.

This issue is mitigated by the fact that the view must be configured to show a "Content statistics" field, such as "Total views", "Views today" or "Last visit".

Download the patch for Views 6.x-2.x or 6.x-3.x.

If you have a Drupal 6 site using the Views module, we recommend you update immediately! We have already deployed the patch for all of our Drupal 6 Long-Term Support clients. :-)

If you'd like all your Drupal 6 modules to receive security updates and have the fixes deployed the same day they're released, please check out our D6LTS plans.

Note: if you use the myDropWizard module (totally free!), you'll be alerted to these and any future security updates, and will be able to use drush to install them (even though they won't necessarily have a release on

Categories: Elsewhere

Drupal Blog: Drupal 8.1.3 and 7.44 released

Wed, 15/06/2016 - 21:32

Drupal 8.1.3 and 7.44, maintenance releases which contain fixes for security vulnerabilities, are now available for download.

See the Drupal 8.1.3 and Drupal 7.44 release notes for further information.

Download Drupal 8.1.3 Download Drupal 7.44

Upgrading your existing Drupal 8 and 7 sites is strongly recommended. There are no new features or non-security-related bug fixes in these releases. For more information about the Drupal 8.1.x release series, consult the Drupal 8 overview. More information on the Drupal 7.x release series can be found in the Drupal 7.0 release announcement.

Security vulnerabilities

Drupal 8.1.3 and 7.44 were released in response to the discovery of security vulnerabilities. Details can be found in the official security advisory:

To fix the security vulnerabilities, please upgrade to either Drupal 8.1.3 or Drupal 7.44.

Change log

Drupal 8.1.3 is a security release only. For more details, see the 8.1.3 release notes. A complete list of all changes in the stable 8.1.x branch can be found in the git commit log.

Drupal 7.44 is a security release only. For more details, see the 7.44 release notes. A complete list of all changes in the stable 7.x branch can be found in the git commit log.

Update notes

See the 8.1.3 and 7.44 release notes for details on important changes in each release.

Known issues

See the 8.1.3 and 7.44 release notes for details on known issues affecting each release.

Security information

We have a security announcement mailing list and a history of all security advisories, as well as an RSS feed with the most recent security advisories. We strongly advise Drupal administrators to sign up for the list.

Drupal 8 and 7 include the built-in Update Manager module, which informs you about important updates to your modules and themes.

Bug reports

Both Drupal 8.1.x and 7.x are being maintained, so given enough bug fixes (not just bug reports) more maintenance releases will be made available, according to our monthly release cycle.

Categories: Elsewhere

Annertech: Reusable Media in Drupal 8 - it's a reality, here's how!

Wed, 15/06/2016 - 20:10
Reusable Media in Drupal 8 - it's a reality, here's how!

Adding media (for most people that means adding images) in Drupal has been an issue for a long time. Adding reusable media (upload an image once, use it on any page on your website) has been even trickier.

With the advent of Drupal 8 and the sterling work done by the media team, adding reusable media (in a very user friendly manner) is now a reality. This tutorial shows you how:

Categories: Elsewhere

Acquia Developer Center Blog: How to Develop a Multisite Platform with Acquia Cloud Site Factory

Wed, 15/06/2016 - 19:58

Leveraging a common Drupal codebase to power multiple Drupal sites provides compelling benefits, including faster site launches, reduced maintenance overhead, and centralized security updating.

However, in order to be successful and avoid typical traps, the use of a common Drupal codebase requires some extra design care and strategy.

Tags: acquia drupal planet
Categories: Elsewhere

Cryptic.Zone: Customer Chat: Live Customer Support for Drupal

Wed, 15/06/2016 - 17:47

E-commerce sites are more and more commonly offering live chat for their visitors as a way of customer support. There is a wide selection of modules for Drupal that can add this functionality. However, most, if not all, I found rely on third party chat services. A while ago, I decided to build a native live chat module in connection with a project of mine. The module has been released as Customer chat.

Categories: Elsewhere

Mediacurrent: Evaluating the security of Drupal contrib modules

Wed, 15/06/2016 - 17:01

At Mediacurrent, we take website security very seriously. Drupal has some security best practices baked into its APIs that let developers create their own modules, hopefully with secure code, to contribute back to the community. You contribute back, don’t you?

Categories: Elsewhere