Apr 10 2019
Apr 10

Lots of people in the Drupal community are eager to learn React these days, following Dries's announcement that React is coming to Drupal.

At NEDCamp in 2018 I presented on how to dip your toe into embedding a react application into a Drupal framework (video on drupal.tv).

This is the long-delayed blog post to follow up to the presentation.

Our approach was fundamentally this:

  • we wanted to possibly embed multiple React apps on the site eventually, so we wanted to treat our base React libraries as common across the site.
  • we needed to marry React routing and Drupal routing so that we could occupy a whole "namespace" of the site
  • we wanted Drupal to store all the entities managed by the front-end, so we had to settle on storage and an API

React Libraries

We wrote a small react_libraries module to expose the libraries for React that we thought we would use everywhere and wanted consistent on every site.

Besides the .info.yml file for the module, the only other thing in the module is the libraries' definitions.

# react_libraries.libraries.yml react: js: https://unpkg.com/[email protected]/umd/react.production.min.js: external: true https://unpkg.com/[email protected]/umd/react-dom.production.min.js: external: true react-dev: js: https://unpkg.com/[email protected]/umd/react.development.js: external: true https://unpkg.com/[email protected]/umd/react-dom.development.js: external: true

All this does is suck in the libraries from CDN, including a prod (react) version and a dev (react-dev) version.

Our smaller apps just depend on this module and then attach the react_libraries/react(-dev) libraries as needed (you'll see that next).

One lesson learned is that we started with create-react-app, so to make this work we had to eject from that and remove the libraries that are normally in the build app bundle. Next time, we will build our app up from scratch rather than using the scaffolding.

Routing

The way React apps work is that they handle the routing by changing the URL with JavaScript and allow the app to deal with what to do given that route. But, as the page isn't refreshing, it's all just one path to Drupal. The problem comes in when a user bookmarks a URL and expects it to work (and it should). To handle this scenario, we assumed a 'namespace' in the routing by declaring /my-react-app/* to belong to our React app. In Drupal 7, this would've "just worked," as any path registered auto-assumes that anything appearing on the URL after that are just arguments to the route. In Drupal 8, this is no longer true, so we have to sort of fake that old behavior.

To do that, we need a custom module. As part of that module, we can define routing--and we tell our route that there is a single argument passed ({react_route}), and we set the default value of that parameter to "" if it is not passed at all (i.e., you navigate to /my-react-app by itself).

# my_react_app.routing.yml my_react_app.overview: path: /my-react-app/{react_route} defaults: _controller: \Drupal\my_react_app\Controller\MyReactAppController::overview _title: 'My React App' react_route: ''

But, alas - this does not match the path /my-react-app/pathpart1/pathpart2 - so this is not complete yet.

Next, we need to create an Inbound Path Processor, by dropping a new class in our module's src/PathProcessor/ folder.

namespace Drupal\my_react_app\PathProcessor; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Symfony\Component\HttpFoundation\Request; class MyReactAppPathProcessor implements InboundPathProcessorInterface { public function processInbound($path, Request $request) { if (strpos($path, '/my-react-app/') === 0) { $names = preg_replace('|^\/my-react-app\/|', '', $path); $names = str_replace('/',':', $names); return "/savant-tools/$names"; } return $path; } }

What the above code does is strip out the "namespace" part of our route, and then replace all the forward-slashes with colons so that it appears as a single route parameter. Essentially, PHP is just throwing this out anyway, since it's the front-end that will be using this route information in JavaScript.

The Controller

The final missing piece is - well, what DOES Drupal actually serve up for markup when we hit anything at my-react-app/*? That's defined by the Controller that your routing.yml file refers to. Your routing class gets dropped in your module's src/Controller folder.

<?php namespace Drupal\savant_tools\Controller; use Drupal\Core\Controller\ControllerBase; /** * Controller for My React App. */ class MyReactAppController extends ControllerBase { /** * Renders the react app. * * @return array * The render array. */ public function overview() { $build = []; // @TODO - do dev / prod here. (/react or /react-dev) // Ideally, make this configurable somehow. $build['#attached']['library'][] = 'react_libraries/react-dev'; // This is where you attach the additional library from your // module that contains the non-React-libraries code $build['#attached']['library'][] = 'my_react_app/actualapp'; // Finally, drop your main mount point for React. // This ID can be whatever you use in your app. $build['#markup'] = '<div id="root"></div>'; return $build; } }

Fin!

At this point, you're now free to write that whole slick frontend!

One last thing to mention, another alternative to this is to mount a React application onto a node. Using JD Flynn's module React Mount Node you can simply specify a node, the div ID, and the library you've registered with your React App in it. You will need React fully bundled, or you'll need to attach your react_libraries on every page or through some other mechanism, and the routing isn't handled with as much elegance - but if you have simpler needs, this is a great way to go!

Nov 15 2018
Nov 15
vertical_align_center

November 15, 2018

Chris

It's almost time for NEDCamp, and I can't wait!

Redfin will be presenting a session there on our toe-dipping foray into the world of "progressively decoupling" Drupal.

Recently, I was on an episode of Talking Drupal to explore a little bit more about React and Drupal together--this shoudl whet your appetite for the session at NEDCamp. Give it a listen!

At the presentation, you can expect a deeper dive into some of the code and the real implementation that wires these two technologies together. I look forward to seeing you there!

Mar 29 2018
Mar 29

It all started with an innocent tweet:

https://twitter.com/mirisuzanne/status/948637526612324352

"Excited to announce our new open-source, Sass-driven pattern-library generator! Go design some systems!"

I follow Miriam on Twitter because I love everything she's ever done. At Redfin, we were huge fans of Susy, right up until she told us not to use it any more. And, like everyone else in the Drupal community and web developer community at large, we're hearing more and more about Atomic Design and the use of pattern libraries to build websites. We're encouraged to build and use canonical and living style guides. Many tools have come forward and, in the Drupal world, it looks like Pattern Lab has been a big winner.

At Redfin, we've tried a number of these tools, including Sam Richard's Style Prototyping approach, and attended trainings for Pattern Lab. We've also experimented with KSS for documenting Sass and generating a style guide.

Why Herman

What attracted me to Herman was the common predicament of the small-to-medium project and its budget's ability (or inability) to deliver on these prototypes. From the Herman announcement on Oddbird:

Creating the beautiful Salesforce Lightning Design System requires an ongoing full-time dedicated team. Those of us doing agency work don't often have that luxury, but our clients still need a system that will work for them.

So how can we make design systems part of an agile process – growing slowly along-side the application, the same way we write and maintain test-coverage as part of any project? How do we make documentation and design consistency the path of least resistance?

I'm a big believer in systems. That is, I'm a big believer in systems that work. If a human doesn't want to use a system because it's too much of a hurdle, the system has failed, not the human. So, the idea of "the path of least resistance" is appealing to me (or perhaps I'm just lazy but, nonetheless, systems should be built for the lazy).

So, Herman came along with all this promise and sparkle and I decided to give it a whirl. For starters, Herman is based largely in the foundations of SassDoc. SassDoc shares a similar purpose with KSS, though, having now played with it, I find its syntax just a bit easier to understand. Perhaps, since I've learned PHP Annotations for Drupal, the annotations in SassDoc feel natural.

Getting Started with SassDoc

To this end, Herman is actually just a "theme" for SassDoc. So, to get started, you are going to initialize a new SassDoc project. Like most of the front-end world today, new front-end projects are initialized using a tool like Yarn or NPM. At Redfin, we use Yarn, so we initialized our project using "yarn init" and answering the questions as appropriate.

Once we were initialized, we added in our two dependencies - SassDoc and the Herman theme:

yarn add sassdoc sassdoc-theme-herman

Once that finishes, you have scaffolded out a Herman project… kind of. What you now need is all your Sass! Create a sass folder to get started and put a style.scss file in there. We'll start with something simple:

.button { border-radius: 5px; background-color: green; color: white; font-weight: bold; }

Here's our first simple component we'd like to document. Maybe, if you were lucky, you had SOME kind of note in there before, like // typical button styles or something.

SassDoc uses a "three-slash" syntax to pull comments in as documentation. So, let's enhance that a bit.

/// Components: small, re-useable components used on the site. /// @group components /// @name Button /// @group components /// @example html /// <a href="#" class="button">Click me</a> %button { border-radius: 5px; background-color: green; color: white; font-weight: bold; }

The first comment, which is offset by a newline from the rest, is called a "free-floating comment." It's just "out there," and not attached to anything. However, note that using the "group" annotation (@group components) I was able to assign it to belong to a group. Using other annotations, like name and example, I'm able to generate my style guide (at the end of the day, just a static site).

To generate, you need to be in the root of your project and run:

node_modules/sassdoc/bin/sassdoc sass --theme=herman

And this gives you the following static site (find it by visiting /sassdoc/index.html off your site's root):

Moving On

Let's get something different put together, a little more advanced. Let's throw in a mixin.

@mixin embed-container($width, $height) { $ratio: ($height / $width) * 100%; position: relative; padding-bottom: $ratio; height: 0; overflow: hidden; max-width: 100%; iframe, object, embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } }

This mixin is inspired by Smashing Magazine's timeless article on the subject.

Now, let's annotate! Put this directly above your mixin.

/// Mixins: custom re-useable but configurable tools we use. /// @group Mixins /// Helper mixin to drop on the wrapper for an iframe /// that you would like to be responsive. /// /// @group Mixins /// @author Smashing Magazine /// /// @param {Length} $width - Element's width /// @param {Length} $height - Element's height /// @output CSS for the wrapper and the inner iframe that maintains the aspect /// ratio as it is resized. /// /// @example scss - /// .embed-container { /// @include embed-container(400px, 300px); /// }

The above documentation introduces us to the @parameter annotation, which allows us to document a parameter, its type, the name, a default value, and a description, using the syntax:

/// @param {type} $name [default value] - description

Also, note that we're not displaying markup here for our @example annotation; rather, we're using scss for the syntax to output. For mixins, this is incredibly helpful as it can show us what the compiled CSS is as a result of using this mixin! Let's go ahead and compile again (node_modules/sassdoc/bin/sassdoc sass --theme=herman).

UH-OH!

» [WARNING] Error compiling @example scss: no mixin named embed-container Backtrace: stdin:2 .embed-container { @include embed-container(400px, 300px); }

SIDE NOTE: In addition to being confused, I bet you're already tired of specifying --theme=herman on the command line every time, huh? Let's kill two birds with one stone.

Rather than specifying your Herman parameters every time on the command line, you can specify them in a JSON or YAML file. In that way, you then only specify -c /path/to/config every time. Of course, at this point, you're just robbing Peter to pay Paul. Switch one command line option out for another.

There's an even better option. Just name your config file .sassdocrc and put it in the root of your project and it will be automatically used. The entirety of that file (so far):

theme: herman

However, we haven't yet solved the problem of "no mixin named." See, the @example annotation from SassDoc doesn't natively support compiling Sass into its CSS counterpart. That's a gift from Herman. In order for Herman to compile the SCSS into CSS, though, each @example must be able to stand on its own, and this was the one area that really tripped me up. Thankfully, Miriam was there to help out.

To make this work, one option is to import the Sass file that we need in order for the example to stand on its own. Change your example to this:

/// @example scss - /// @import "style.scss" /// .embed-container { /// @include embed-container(400px, 300px); /// }

I'll save you some time before you run off ahead and compile--this still won't work. But, it's easy to fix. Go back to your .sassdocrc and specify a "herman" object with some configuration. (Full details on the herman object configuration.)

Make your .sassdocrc like this now:

theme: herman herman: sass: includepaths: - 'sass'

The includepaths directive is important so that Herman can resolve your import statements. Want to do one better? You can auto-import a path (or paths) using another declaration but, beware--nothing you auto-include should generate any actual Sass output or it will show up in EVERY example. This is best used for your utility files, like _extends.scss, _mixins.scss, etc. (Refer to our own Bundler Shell theme to see how we lay this out.) For example:

theme: herman herman: sass: includepaths: - 'sass' includes: - 'util/mixins'

If you auto-include your util/mixins (really ./sass/util/_mixins.scss) then you can make use of your mixins without needing to put the @import in every @example!

Another Side Note: README

If you are feeling harassed by "[WARNING] Description file not found: `./README.md` given." It's probably best to have a README.md for your project. This shows up as the text of the index.html page for the top-level of your SassDoc project. I just went ahead and created a simple one. This is a SassDoc configuration value, and if you'd rather create an introduction to your style guide that is separate from the main README for your project, you can set descriptionPath in your .sassdocrc file.

Level Up

This is all great but, we need to level up. What else does Herman offer?

No one can say it better than their own README:

In addition to the core SassDoc annotations, our @icons annotation allows you to display SVG icons from a given folder, and we extend the core @example annotation to display compiled Sass/Nunjucks output and render sample components. We also provide a @font annotation for displaying font-specimens, and @colors, @sizes, and @ratios annotations for displaying color-palettes, text and spacing sizes, and modular ratios."

Icons

This one is easy so we'll start here. Add a comment and use @icons \<path-to-icons-relative-to-project-root> and you're there! It auto-generates your icon previews with filenames, even optimizing them as it goes. (Bear in mind your SVG's should specify a viewBox or they will likely be very, very tiny in the preview.) It expects a folder with individual SVG files per icon.

Font Stack Previews

Things start to get a little trickier starting here. For the fonts, colors, ratios, and sizes annotations, you will need to generate some JSON that the front-end JavaScript/templates can use. There's a plugin called sass-json that is doing this for you--taking sass maps and writing them out to encoded JSON--but you need to export your data in order to do this. So, let's dissect the font annotation first.

/// @font key (styles, to, show)

In this case, the ‘key' is the variable name of the Sass map holding the information about your font style, and the (styles, to, show) are a list of font weights/styles that you would like to display, for example: (regular, bold, bold italic).

Note that, at least for Google Fonts, the numbers are a more consistent thing to use when outside of the normal keywords of bold and regular. I didn't have success with previews using things like "semibold" or "light." (This is because they only support valid CSS values for font-weight - though there's discussion around that: https://github.com/oddbird/sassdoc-theme-herman/issues/250 ).

Finally, the second line is indented, to show that it's still part of the @font annotation, and it consists of any markup needed for the font to render correctly (JavaScript tag, link tag, etc).

So, in real life, this looks like:

/// @font sans-stack (300, 300 italic, regular, 600) /// <link href="https://fonts.googleapis.com/css?family=Work+Sans:300,400,600" rel="stylesheet"> $sans-stack: ( 'name': 'Work Sans', 'source': 'https://fonts.google.com/specimen/Work+Sans', 'stack': ("Helvetica Neue", "Lucida Grande"), );

For a web font like this, we use the name (that is, the actual font name you would use if you were to display it in a font-family property), source (this renders as an external link when the preview displays), and stack (which are the fallbacks you've chosen when this font is not available).

Getting that to render, though...

This is all the annotation related to the font, specifically, but now we need to include this Sass map into the "herman" map more globally. There's a handy mixin that Herman provides, called "herman-add" which we can use to do that. After the map, I put:

@include herman-add(‘fonts', ‘sans-stack', $sans-stack);

In order to use this herman-add mixin, you will need to include Herman's utilities (where this mixin is defined), so at the top of my file I put:

@import "../node_modules/sassdoc-theme-herman/scss/utilities/_utilities.scss";

Finally, we need to do a final export of the Herman map into JSON. At the bottom of my Sass file, I put:

@include herman-export;

This ensures that the herman map is exported to JSON so the front-end can pick it up. The Herman team is currently working on improving this process but, for now, this is still a pretty clean way to handle it. If you get a little cuter than I did with your partials, you can have a Sass file that only outputs the herman map JSON so you don't need to pollute your regular CSS with it if you don't want to.

Keep this pattern in mind, because most of Herman's awesomeness depends on it. You'll see as we move on.

Colors

Now that we've established a pattern, we're keen to keep following it. For color palettes to be generated in your SassDoc static site, we'll follow a similar pattern. First, the annotation:

/// @group colors /// @colors demo-colors $demo-colors: ( 'alto': #d8d8d8, 'scorpion': #5b5b5b, 'tree-poppy': #f36c38, 'white': white, 'wild-sand': #f5f5f5, 'grey-light': #d5dbe4, ); @include herman-add('colors', 'demo-colors', $demo-colors);

First, I use the @group annotation to put this in the ‘colors' navigation over at the left. Then, the actual @colors annotation puts the map key you're going to use to add to the Herman map. We add those colors in a map, and then finally use herman-add to map $demo-colors into $herman. In this way, the herman-export we call at the very end will ALSO now include this color palette in the static site.

Sizes

For text sizes, a great preview can be generated to show you the various headings or sizes you want to use. Sense a pattern yet? Let's look:

/// All the sizes that we have. /// @group sizing /// @sizes font-sizes {text} $font-sizes: ( 'base': 16px, 'important': 1.8rem, 'largest': 3rem, ); @include herman-add('sizes', 'font-sizes', $font-sizes);

Ratios

Ratios behave nearly identically:

/// Ratios we are using. /// @group sizing /// @ratios my-ratios $my-ratios: ( 'line-height': 1.4, 'gutter': 0.5, ); @include herman-add('ratios', 'my-ratios', $my-ratios);

The only thing to know is that you can optionally display text sizes (or spacing sizes, or page sizes) as rulers, though the default is to display a text preview. To do this, add the optional "{rulers}" or "{rulers-large}" after the sizes annotation (rather than "{text}" - which is the default).

Nunjucks - Martial arts the templates up a notch

For markup that is more complicated than some simple HTML, you can write a Nunjucks template to generate output for a preview. Let's enhance our button example with a Nunjucks template.

/// @group components /// @name buttonset /// @example njk /// {% set items = [{"name": "do something", "label": "open"}, {"name": "do something else", "label": "close"}] %} /// {% include 'buttonlist.njk' %} /// .buttonset { li { display: inline-block; list-style-type: none; margin-right: 1em; } a { display: inline-block; @extend %button; } }

You'll notice I still put this in the components group but I've turned my regular button into a buttonset. You'll also notice immediately the @example annotation this time specifies the "njk" syntax, meaning "compile Nunjucks code." When using njk in an annotation, you are required to specify a templatepath in your config. (Alternatively, you can specify an entire Nunjucks environment, but to do that you must be using the Node API version, which I am not.) Add this to your .sassdocrc inside herman:

nunjucks: templatepath: './templates'

So, I created a "templates" folder off the root of my project and put a simple buttonset.njk file in it. (Dear Drupalists, don't be scared of Nunjucks--it's Django/Jinja-based templates for JavaScript, just the same way Twig is Django/Jinja-based templates for PHP!)

{% block content %} <ul class="buttonset"> {% for item in items %} <li><a class="button" title="{{ item.name }}">{{ item.label }}</a></li> {% endfor %}` </ul> {% endblock %}

Now that I've configured a templates directory, and my syntax for using the templates is all set up, I get a fully rendered example. It includes (a) the Nunjucks language used to generate it, (b) the fully compiled HTML markup, and (c) a fully rendered example with all of my styles!

For bonus points, check out Nunjucks macros, which should help you further componentize your markup into easily-reproduced snippets. If we do it this way, we can sort of reverse the order. First, we import our njk file which defines our macro:

/// @name buttonset /// @example njk /// {% import 'buttonset.macro.njk' as mymacro %} /// {{ mymacro.buttonset([{"name": "do something", "label": "open"}, {"name": "do something else", "label": "close"}]) }}

...and our Nunjucks template is slightly different, wrapping the block with a macro call. A macro is similar to a "function."

{% macro buttonset(items) %} <ul class="buttonset"> {% for item in items %} <li><a class="button" title="{{ item.name }}">{{ item.label }}</a></li> {% endfor %} </ul> {% endmacro %}

The Power

So, by combining all of these elements directly into the Sass you're writing for your agile site, you can document on the fly and have an easy way to:

  • Reference and document your mixins
  • Display typography stacks and document when you should use each
  • Show heading sizes and spacing ratios for vertical rhythm
  • Discuss branding color palettes and describe how each should be used
  • Demonstrate the icon set available to the application quickly
  • ...and so much more!

The Review

So what do I like and dislike about this? What did I learn?

For someone like me, a lot of this was actually quite new coming in. Not just the fundamental concepts that Herman brought, but all of it. I had never used SassDoc before, though I'd played briefly with KSS. I'd never even heard of Nunjucks before, though I had used Twig. But also, the concepts that give Herman its power also add complexity to an already complex stack. You need to remember that, in a sense, everything is compiling twice. Once, it's compiling your Sass to be output (and then you're bringing that output into the static site via custom CSS), but it's also compiling all the SassDoc comments into a static site as well. These two different steps are nonetheless sourced largely from the same files, so all the pieces of the puzzle feel like they need to fit together just right for everything to work in harmony. Once that was fundamentally understood, the idea of the JSON encoding actually made total sense, and was OK to understand.

I also spent a lot of time getting bit by the Ruby bug. At Redfin, we sort of skipped over the whole Gulp / Node API thing. We used a lot of Ruby Sass and Compass and Bundler, until we recently switched to a stack based on Dart-Sass. While trying to learn, I tried to strip everything down to its fundamental elements, and that actually got me a few times. I should've started with a modern stack and used the node-sass implementation that I installed with my yarn install, and I wouldn't have had such issues. (With that said, we never would've improved Herman to support Ruby Sass!)

Overall, I believe that this is definitely good enough to go into our next project. Beyond that, I am confident in the Herman team that if I find any bugs as we use it, they will be responded to swiftly, which is hugely important for adoption of something kind of new like this.

UPDATE 04-09-2018: Added additional clarifications from Miriam.

Nov 20 2017
Nov 20

This past weekend, I was honored to be able to present a session at 2017's New England Drupal Camp (NEDCamp) about Drupal 8's Migrate API. Redfin has implemented many Drupal 8 migrations to date both from CSV data sources and legacy Drupal sites (Drupal 6 and 7). As a result, we want to share with you what we've learned in hopes of saving you the time often spent in the trials and errors of data migration.

My Master's degree is in Technology Education, so I understand that people learn things differently. Some people are auditory or visual learners while others like to read. To that end, I wanted to summarize our session here. If you are an audio or visual learner, please check out these resources:

Otherwise, let's peek at the concepts...

The overall process is:

  1. Scaffold out a module (.info.yml file). You can use Drupal Console for this.
  2. Write YAML files to define your migrations.
  3. Set up any global configuration if needed (your legacy database connection credentials in settings.php, a folder for your CSV files, etc).
  4. Extend/alter/write any custom plugins or code to support those migrations.

While you can use the Drupal Migrate UI to do this, I recommend building your Drupal 8 site the way you want (maybe taking advantage of newer paradigms like paragraphs, for example), and then worry about your migrations. There are four main modules that come in to play when not using the UI. Two are in core--migrate, and migrate_drupal. "migrate" lets you get anything into Drupal 8, while "migrate_drupal" extends and supports that to enhance your experience when migrating IN from a Drupal 6 or 7 (or 8!) site.

Two modules in the contrib space help you above and beyond what is provided in core. Migrate Tools provides Drush command integration for managing your migrations, while Migrate Plus provides loads of enhancements for migrating your data (additional plugins, etc). It's important to make sure you're using the right version of the module for your version of Drupal, by the way--but that's easy since you're using Composer, right?

Write Some Migrations

You will need to drop a migration YAML file in your module's /migrations folder. Generally, the yaml file is named after the id you specify for your migration plugin. As a full example, see core's d7_node.yml migration.

The Migrate API follows a traditional software design pattern called Extract, Transform, Load. To avoid some confusion with the concept of "Load" (in this case meaning loading data INTO your Drupal database), there's some different terminology used in Migrate:

  • Extract == Source
  • Transform == Process
  • Load == Destination

One thing that Migrate Plus provides is the concept of a "Migration Group." This allows multiple migrations to share some configuration across all of them. For example, if all migrations are coming from the same MySQL database (say, a Drupal 6 database), then that shared configuration can go into the migration group configuration once rather than into each individual migration.

There's some global configuration that goes into each individual migration, for example its "id" key (the unique ID of this migration), and its "label" (friendly name in the UI / Drush).

One thing you can specify also are "dependencies" - for example to a module. You can also enforce "migration_dependencies," which means that before THIS migration is run, THAT one needs to run. This is a great way to ensure references (like entity references, or taxonomy terms) are migrated into the site before anything that uses them.

Each migration then should specify three unique sections--source, process, and destination (sound familiar?).

Source

The source section specifies which plugin to use. These plugins are usually found in the module involved. For example, if you want to migrate data in from Drupal 7 nodes, take a look in core/modules/node/src/Plugin/migrate/source for the implementation / plugin id to use. Often, though, you'll actually find yourself writing a new Class in your own module which extends this one.

Each different source plugin might have some additional configuration that goes along with it. For example, with "plugin: d7_node" you might also specify "node_type: page" to migrate in only basic pages from your Drupal 7 site. You might also specify "key" here to say which database key from the $databases array in settings to use (if that wasn't specified globally in your migration group!).

The purpose of all source plugins is to provide a Row object (core/modules/migrate/src/Row.php) that is uniform and can be consumed by the next part of the process.

If you do write your own migration plugin, two methods I find myself frequently overriding are query() (so I can add conditions to the typical source query, for example - like only grabbing the last year's worth of blog posts), and prepareRow(). The method prepareRow() is your hook-like opportunity to manipulate the Row object that's about to be transformed and loaded into the database. You can add additionally-queried information, or translate certain values into others, or anything you need in prepareRow(). The only thing to beware of is every Row becomes a destination entity, so if you're doing something like joining on taxonomy terms, you're better to do that in prepareRow and add a new property to it with setSourceProperty() rather than, say, LEFT JOINing it on in the query.

Destination (yes, I skipped Process)

The destination plugins work largely the same way. You simply specify what entity (usually) you're migrating into. For example, you might have destination: 'entity:node' and any additional configuration related to that destination. One example for entity:node is to add default_bundle: page here so that you don't need to set bundle: 'page' in your process section (which we're about to get to). Similarly, if migrating files, you can specify source_base_path: 'https://example.org' to automatically download images from that path when importing!

Like source plugins, destination plugins have additional configuration here that is tied to the plugin.

There are so many things that are entities in Drupal 8, the possibilities are vast here - you can migrate nodes, users, comments, files, sure. But you can also migrate configuration, form display, entity view modules, anything in contrib, or your own legacy code! Migrate Plus also provides a "Table" destination so you can migrate directly into MySQL tables inside of Drupal (note that this is generally not best practice if you're migrating into entities--you're better off using the entity:whatever plugin so you take full advantage of the entity API).

Process

This is where all the real magic happens, in my opinion. To keep this blog post short (is it too late for that?), I won't go too deep into all the process plugins available, but I will talk about a few special cases and then encourage you to check out the documentation for yourself.

The "get" plugin is the most basic of all. It simply means "take the value off the Row object for property x, and map it to value y." In your real migration's yml file it would look like destVal: sourceVal - which simply means "take what's in $row->sourceVal and put it in the destination's "destVal" property.

The "migration_lookup" plugin goes one simple step further than get and translates the incoming ID to the new ID value on the new site. For example, if you have a migration that migrates person nodes and the nid was 65 for John Smith on the Drupal 6 site, but is 907 on the new Drupal 8 site, a reference to that person (say on the "authors" field of your "Research" content type) would also need to be translated. This plugin transforms the incoming 65 to the correct 907 by referencing a migration that has already been run (remember the migration_dependencies key?).

Multiple plugins can even be chained together to form a "pipeline" of transformations that can happen in order. For example, if your old database only had usernames as "Chris Wells" and "Patrick Corbett," but you wanted to make usernames, you could run that through the machine_name plugin to change it to "chris_wells" instead. But, what if there was already a "chris_wells" user? Well, you can then run the new value through dedupe_entity to append an "1" or "2" etc until it's unique. You can create fairly complex pipelines here in the yml file without having to touch any PHP code.

Sometimes a field in Drupal has a "nested value," like the body or link fields. The body field has a "value" and a "format" on it. To map these, you use a slash (/) to separate the field and the sub-field, like 'body/value': description and 'body/format': format -- just be sure and use those "ticks" (apostrophes, single-quotes, whatever you call them) around these types of keys.

Feel free to check out all the core process plugins, and even ones provided by contrib, like: get, migration_lookup, machine_name, dedupe_entity, default_value, concat, explode, flatten, static_map, substr, skip_on_empty, skip_row_if_not_set, menu_link_parent, callback, entity_generate, and entity_lookup!

There's one more special one, formerly known as "iterator" and now called "sub_process." This lets you create multi-step a pipeline against an array of structured data arrays. Make sure to pay some special attention to that one.

Put it all together

So by now you've created your shiny new Drupal 8 site just how you want and you've written a module (.info.yml file, really). You've placed all these migrations in it. You can place them in config/install and they will be read in as configuration. You can then edit them as needed using drush config-edit or similar in Drupal Console. You could also uninstall and reinstall your module each time you alter the yml files.

Alternatively, you can also place them in /migrations (off your module root) and instead they will be loaded as plugins instead of configuration. This way is likely preferred since you can just flush the plugin cache when you make changes to the YML file.

Once you also have your source set up (database, CSV files, XML, whatever), you can start to run your migrations with Drush!

The most commonly-used Drush commands for migrating (in my world) are:

  • migrate-status - where are things at?
  • migrate-import - run a migration (single or whole group)
  • migrate-rollback - "un-run" a migration
  • migrate-reset-status - used to reset a migration to "Idle" state if the PHP code you're writing bombs out or you press Ctrl-C in frustration.

Others I don't use as frequently are:

  • migrate-stop - stops a running migration and resets it to idle (I usually press Ctrl-C and then do a drush mrs (migrate-reset-status))
  • migrate-fields-source - list all the available properties on Row to import (I usually just inspect this in the debugger in prepareRow())
  • migrate-messages - display messages captured during migration (PHP warnings, etc) (I usually just look at the database table where these are stored instead of printing them in terminal)

WHOA.

So there you have it. Migration in a nutshell! Please do feel free to leave comments and questions below or reach out to us at Redfin if you need help migrating data into your shiny new Drupal 8 site.

Sep 21 2017
Sep 21
shopping_cart

September 21, 2017

Chris

Redfin is happy to announce that thanks to the efforts of vetchneons, we have at long last released a -dev version of the CashNET module for Ubercart in Drupal 7. CashNET is a payment processor used by a lot of institutions in the higher education realm.

We would love for any folks using Ubercart in 7 to test it out, so the module can be promoted to a stable release. 

And of course, if anyone wants to also port this to Drupal Commerce, they'd be more than welcome. :)

Head on down to the UC CashNET project page and give it a download!

Jul 10 2017
Jul 10

Drupal 8 has garnered significant community support over the last year. Many of our favorite Drupal 7 contributed modules now have stable Drupal 8 releases, making the transition to Drupal 8 a smoother and beneficial decision for many organizations. As the spring of 2017 ended, Google search traffic for Drupal 8 also surpassed that of Drupal 7. Certainly not definitive, but another telling clue for those considering transitioning to the latest release.

Google Trends: Drupal 7 vs Drupal 8 in 2017

Let's get started with Drupal 8 basics by performing the core install. Then, we'll setup a single community contributed module.

Setting up a Drupal 8 Environment

I'm going to assume that folks reading this tutorial are familiar with a previous iteration of Drupal (ideally 7). If not, there's many ways to setup the pieces and parts on your workstation necessary to start local development. The details aren't in the scope of this tutorial. In short, you could:

  1. Individually setup a Linux, Apache, MySQL, and PHP (LAMP) environment on your local Windows, Linux, or Mac OS system
  2. Use a cloud-based server that is LAMP ready
  3. Leverage the Acquia Dev Desktop software to automate the environment setup process

As a team, Daymuse uses Acquia Dev Desktop to manage our local development environments. That's what I'd recommend you do as well. The software is simple to install. It automates several installation and management processes. It'll keep up with repository updates so you can quickly create Drupal sites with the latest distributions available. It also provides integration with Acquia enterprise services. This tutorial will proceed from the point of having Acquia Dev Desktop installed, working from Mac OS.

Drupal 8 Install

Let's create our first Drupal 8 install on our local workstation with Acquia Dev Desktop.

  1. Open the Acquia Dev Desktop app
  2. Select the plus ('+') symbol on the bottom left
    Acquia Dev Desktop, Create a Site
  3. Click "New Drupal Site..."
    New Drupal Site Acquia Dev Desktop
  4. Select the latest Drupal 8 version (8.3.5 at the time of writing)
    Drupal 8.3.5 install

This will begin the file download and installation process of Drupal 8. This will send you over to your web browser to complete the configuration. Follow the prompts: select language, your install profile (Standard generally), confirm your system meets requirements, let Drupal configure a new database, and finally configure the site.

Drupal 8 configure your site after install

This information can be changed later. Don't worry about having a great site name or ideal email address just yet.

Once this process completes, you should wind up logged into your new Drupal 8 site.

Drupal 8 post install landing page

If you've had any trouble working through these initial Drupal 8 core steps, feel free to reach out to me on Twitter @chrisrcooper. Once you've poked around your install, which should look surprisingly like our generally recommended admin design for Drupal 7, let's begin the process of installing a contributed module.

Setup a Contributed Module to Extend Drupal 8

Our most popular blog regarding a single contributed module is our installation and setup of Simple FB Connect in Drupal 7. Let's work through installing Simple FB Connect in Drupal 8. The configuration process of the contributed module is quite similar as it is in Drupal 7. The download and installation process is quite different since we cannot rely on Drush to do as much of the heavy lifting. In order to install Simple FB Connect, Composer -- a PHP dependency manager -- is required. This article isn't focused on the details of setting up Composer which may be different depending on your environment. However, if you're on Mac OS and are comfortable with the command line, here's the TL;DR version of other Composer tutorials:

Install and Configure Composer PHP Dependency Manager for Drupal 8

Download via Terminal and cURL:

curl -sS https://getcomposer.org/installer | php

Results should read:
Install Composer on Mac OS Results

We don't want to only use Composer for this single project. Let's make the composer command global:

  1. Copy:
    sudo mv composer.phar /usr/local/bin/
    
  2. Edit your local Bash config:
    vim ~/.bash_profile
    
  3. Add Composer alias:
    composer="php /usr/local/bin/composer.phar"
    
  4. Relaunch Terminal
  5. composer command should operate now (outputs command list)
  6. Tell Composer where Drupal repositories are (be sure you're working from your Drupal install directory):
    composer config repositories.drupal composer https://packages.drupal.org/8
    

Composer is now installed on your workstation, available throughout Bash, and configured to work with Drupal 8 repositories. Let's use Composer to quickly install Simple FB Connect and all of its various dependencies.

Use Composer to Install Simple FB Connect Drupal 8 Module and Dependencies

Use composer command in Terminal to install the version 3 Simple FB Connect module:

composer require "drupal/simple_fb_connect:~3.0"

This may take some time as Composer initializes the Drupal repositories, results should read:

Drupal 8 composer install repository

As you can see from the results, Composer did a lot of heavy lifting in installing various external dependencies that Simple FB Connect has. Phew! Take a break.

Configure a Drupal 8 Module

Now, let's enable and configure the Simple FB Connect module in our Drupal 8 installation.

Use Drush to enable the new module (or do so from your Extend page /admin/modules):

drush en simple_fb_connect -y

Confirm the module is enabled. Go to your Extend page: /admin/modules. You should see:

Simple FB Connect installed on Extend page

Clear the site's cache so that configuration options will be visible: 

  1. Via Drush cache rebuild (note: "drush cc all" no longer works as in Drupal 7):
    drush cr
    
  2. Or via the Performance page (/admin/config/development/performance) and "Clear all caches" button

Confirm that the Simple FB Connect module permissions are configured correctly on the Permissions page (/admin/people/permissions).

Permissions for Simple FB Connect

Now you will need to configure Simple FB Connect's module configuration options. Our Drupal 7 tutorial for Simple FB Connect walked through the process of creating a Facebook App which is required for this module to connect to. The process hasn't changed. You can follow the Create Facebook App portion of the old tutorial if you don't already have a Facebook App to use. Once you've setup a Facebook App, you can use the credentials to fill out the module configuration.

Module configuration page (/admin/config/people/simple-fb-connect):

Simple FB Connect configuration page

Allow Anonymous Visitors to Login with Facebook in Drupal 8

You'll want to allow Visitors (anonymous users) to login with their Facebook accounts in order to test the module and your Facebook app. Enable Visitors for Registration and Cancelation on the Account Settings page (/admin/config/people/accounts).

Allow Anonymous users to login to Drupal 8 with Facebook

Visit the login page from a fresh browser. Attempt to login with your own Facebook account.

Drupal 8 facebook login on user page

Once you've entered your Facebook login info, if you're successful, you should see your account logged into the Drupal site with your Facebook account name.

logged-in-fb-user-account-d8.png

Congratulations! You've setup a development environment compatible with Drupal 8, Drupal 8 itself, and a contributed module to extend the capabilities of the CMS. You've also setup Composer which will be a useful tool as you work with other complicated PHP projects or Drupal contributed modules.

User Experience and Social Media Logins in Drupal 8

The primary reason you're integrating Facebook's login system is to improve the user experience. You may need to manually prune your user accounts for spam, but it may be worth it to continue to allow users to login (and register) with their Facebook accounts without approval. If a user has to wait for manual administrator approval, they may never bother to return once you've approved them.

We're working to develop tutorials to integrating Facebook throughout your Drupal 8 site. In the meantime, have a look at our Drupal 7 tutorials regarding Facebook:

  1. Drupal Facebook Comments
  2. Drupal Facebook Login

If you're interested in thoroughly integrating Facebook with your Drupal website strategy through professional services, reach out. Think this tutorial is useful? Don't forget to share!

May 02 2017
May 02

Recently, one of our Enterprise clients asked for some help installing SSL certificates on their Acquia-hosted Stage and Development environments. This is not something that Acquia seems to provide (they do provide basic SSL on dev/stage environments, but not with hostname matching), so we set out to get them set up. They use their dev and staging environments to demonstrate new content and features to stakeholders, and some were getting scared off by the SSL certificate warnings.

Rather than pay, we decided to try it out with Let's Encrypt, which if you haven't heard, is the amazing and relatively-new Certificate Authority that provides FREE CERTIFICATES, and has a mission of enabling SSL everywhere.

encrypt all the things!Get Certbot

The first thing you need to do is download certbot. Certbot is a command line tool from the EFF for managing SSL certificates with Let's Encrypt. At Redfin, we use Macs with Homebrew, so the easiest way to get the tool was to enter `brew install certbot` into a terminal. Now, there's a "certbot" global executable to use.

If you follow the "download certbot" link above, and for example enter "Apache" and "Ubuntu 14.04," you'll get instructions for how to install certbot on other platforms.

Once you have certbot downloaded, you need to run the "manual" method of validation. This feels like the old familiar way of verifying site ownership--adding some files to a particular directory. Let's Encrypt then calls out to that URL, and if it finds you put the right thing there, then it assumes you have control of that website, and provides you with the certificate.

On your local machine, run the certbot command that does manual verification: `sudo certbot certonly --manual -d SITEstg.prod.acquia-sites.com -d  SITEdev.prod.acquia-sites.com` (where SITE is dependent on your specific Acquia setup). You'll keep this command running as you perform the next steps.

The "certonly" and the "--manual" are the main influencers here. Note that you can add as many -d's and domains as you need. If you have more dev environments than the standard stage/dev in Acquia (my client did), you can just keep adding the -d's. Note that also on my Mac I had to run this with 'sudo' in front of it, because it writes to /etc. You can also specify some additional parameters on the command to put these files in a separate location if you need.

Allow in .htaccess

This starts the process of verifying your sites. As you step through, it will give you some long, hash-y looking text strings that need to be available at a particular URL. According to the spec, this is at a .well-known/ folder off your site root. In order to allow Drupal to see this, you may need some changes to your .htaccess file. 

If you're using a Drupal 8.3.x site (newer than Feb 9 2017), the issue has already been fixed. See https://www.drupal.org/node/2408321 for more information.

If you're using Drupal 7, then as of this writing it has not been fixed in core. See https://www.drupal.org/node/2847325 for more information. Essentially you need to allow .well-known in the FilesMatch directive at the top of .htaccess, and then exclude it from the main RewriteRule later down in the file.

Make verification "file" visible

The next thought you might have is, "OK, now I need to put all the files that need to be visible in that .well-known/acme-challenges/ry784yfy7...fdhj directory." Except, you don't really. (Pro tip: you do not need to enable live development mode on 4 environments at once and crash the server.)

The reason why not? The fabulous Let's Encrypt Challenge module. This lets you use the Drupal UI to enter your challenge information, or upload files to sites/default/files to answer the challenges. Download that module and push it to a branch, and set all of the Acquia environments your enabling Let's Encrypt SSL for, to use that branch. Enable the module on each dev/stage site, and as you walk through the certbot command (it gives you a challenge for each domain), log in to the site, enter the challenge, and hit save. You can then pull up the URL that certbot gives you, in order to verify that the module is doing what it promises. (Important note here, if you accidentally pull up the URL before you've changed .htaccess or enabled it, Acquia's Varnish is going to cache the bogus response and validation won't work. If you accidentally do this, be sure and flush the Varnish caches at Acquia for the environment where you got an itchy trigger finger.)

When the certbot process completes, it will tell you where you can find the certificate files needed. These are stored locally on the machine where you run certbot, in the case of a Mac with certbot installed with Homebrew, in /etc/letsencrypt/live/FIRSTDOMAIN (where FIRSTDOMAIN is the first domain you passed into your certbot command, above). 

Tell Acquia You Got the Goods

This is a two-part process. By logging into your Acquia console, you must go to each individual environment and go to the SSL section, in the nav at the left hand side. From there, you can click "Install SSL Certificate" at the top. You will be prompted to enter four pieces of information: (1) a name for your certificate (ex.g. "LE 05022017" because it's Let's Encrypt and the day it was created), (2) the private key for the certificate (use privkey.pem from the folder above, where certbot put all this info), (3) the certificate itself (use cert.pem), and (4) the "chain" certificate (often called "intermediate" certificate), which establishes security from your certificate all the way to a Root Certification Authority (use chain.pem). NOTE: with Acquia, you will not use fullchain.pem. This is simply a file that concatenates all the information together into a single certificate file.

The second part of this process is to click "Activate" next to the certificate once the "installing" activity is completed.

Again, this needs to be repeated for each environment, but with the same certificate information.

In the below screenshot I've tried to call attention to some relevant parts of the SSL screen in the Acquia console:

the Acquia console with a Let's Encrypt certificate successfully installed and activatedNote the SSL navigation on the left column, the name of the certificate "LE 05022017," the "Deactivate" link (this is where you would find the "Activate" link after the certificate installs), and the "Install SSL certificate" link at the top.

We hope this proves helpful in getting some basic SSL certificates installed in your own Acquia environments!

May 02 2017
May 02

Recently, one of our Enterprise clients asked for some help installing SSL certificates on their Acquia-hosted Stage and Development environments. This is not something that Acquia seems to provide (they do provide basic SSL on dev/stage environments, but not with hostname matching), so we set out to get them set up. They use their dev and staging environments to demonstrate new content and features to stakeholders, and some were getting scared off by the SSL certificate warnings.

Rather than pay, we decided to try it out with Let's Encrypt, which if you haven't heard, is the amazing and relatively-new Certificate Authority that provides FREE CERTIFICATES, and has a mission of enabling SSL everywhere.

encrypt all the things!Get Certbot

The first thing you need to do is download certbot. Certbot is a command line tool from the EFF for managing SSL certificates with Let's Encrypt. At Redfin, we use Macs with Homebrew, so the easiest way to get the tool was to enter `brew install certbot` into a terminal. Now, there's a "certbot" global executable to use.

If you follow the "download certbot" link above, and for example enter "Apache" and "Ubuntu 14.04," you'll get instructions for how to install certbot on other platforms.

Once you have certbot downloaded, you need to run the "manual" method of validation. This feels like the old familiar way of verifying site ownership--adding some files to a particular directory. Let's Encrypt then calls out to that URL, and if it finds you put the right thing there, then it assumes you have control of that website, and provides you with the certificate.

On your local machine, run the certbot command that does manual verification: `sudo certbot certonly --manual -d SITEstg.prod.acquia-sites.com -d  SITEdev.prod.acquia-sites.com` (where SITE is dependent on your specific Acquia setup). You'll keep this command running as you perform the next steps.

The "certonly" and the "--manual" are the main influencers here. Note that you can add as many -d's and domains as you need. If you have more dev environments than the standard stage/dev in Acquia (my client did), you can just keep adding the -d's. Note that also on my Mac I had to run this with 'sudo' in front of it, because it writes to /etc. You can also specify some additional parameters on the command to put these files in a separate location if you need.

Allow in .htaccess

This starts the process of verifying your sites. As you step through, it will give you some long, hash-y looking text strings that need to be available at a particular URL. According to the spec, this is at a .well-known/ folder off your site root. In order to allow Drupal to see this, you may need some changes to your .htaccess file. 

If you're using a Drupal 8.3.x site (newer than Feb 9 2017), the issue has already been fixed. See https://www.drupal.org/node/2408321 for more information.

If you're using Drupal 7, then as of this writing it has not been fixed in core. See https://www.drupal.org/node/2847325 for more information. Essentially you need to allow .well-known in the FilesMatch directive at the top of .htaccess, and then exclude it from the main RewriteRule later down in the file.

Make verification "file" visible

The next thought you might have is, "OK, now I need to put all the files that need to be visible in that .well-known/acme-challenges/ry784yfy7...fdhj directory." Except, you don't really. (Pro tip: you do not need to enable live development mode on 4 environments at once and crash the server.)

The reason why not? The fabulous Let's Encrypt Challenge module. This lets you use the Drupal UI to enter your challenge information, or upload files to sites/default/files to answer the challenges. Download that module and push it to a branch, and set all of the Acquia environments your enabling Let's Encrypt SSL for, to use that branch. Enable the module on each dev/stage site, and as you walk through the certbot command (it gives you a challenge for each domain), log in to the site, enter the challenge, and hit save. You can then pull up the URL that certbot gives you, in order to verify that the module is doing what it promises. (Important note here, if you accidentally pull up the URL before you've changed .htaccess or enabled it, Acquia's Varnish is going to cache the bogus response and validation won't work. If you accidentally do this, be sure and flush the Varnish caches at Acquia for the environment where you got an itchy trigger finger.)

When the certbot process completes, it will tell you where you can find the certificate files needed. These are stored locally on the machine where you run certbot, in the case of a Mac with certbot installed with Homebrew, in /etc/letsencrypt/live/FIRSTDOMAIN (where FIRSTDOMAIN is the first domain you passed into your certbot command, above). 

Tell Acquia You Got the Goods

This is a two-part process. By logging into your Acquia console, you must go to each individual environment and go to the SSL section, in the nav at the left hand side. From there, you can click "Install SSL Certificate" at the top. You will be prompted to enter four pieces of information: (1) a name for your certificate (ex.g. "LE 05022017" because it's Let's Encrypt and the day it was created), (2) the private key for the certificate (use privkey.pem from the folder above, where certbot put all this info), (3) the certificate itself (use cert.pem), and (4) the "chain" certificate (often called "intermediate" certificate), which establishes security from your certificate all the way to a Root Certification Authority (use chain.pem). NOTE: with Acquia, you will not use fullchain.pem. This is simply a file that concatenates all the information together into a single certificate file.

The second part of this process is to click "Activate" next to the certificate once the "installing" activity is completed.

Again, this needs to be repeated for each environment, but with the same certificate information.

In the below screenshot I've tried to call attention to some relevant parts of the SSL screen in the Acquia console:

the Acquia console with a Let's Encrypt certificate successfully installed and activatedNote the SSL navigation on the left column, the name of the certificate "LE 05022017," the "Deactivate" link (this is where you would find the "Activate" link after the certificate installs), and the "Install SSL certificate" link at the top.

We hope this proves helpful in getting some basic SSL certificates installed in your own Acquia environments!

Nov 16 2016
Nov 16

While we at Redfin don't really yet have a full on base theme for every project, one thing we do use is our "bundler shell." This forms the basis of any Drupal 7 or 8 theme we build, and in fact, is really just the framework for the front-end (that is, this shell is useful outside of the realm of Drupal, actually).

First things first - here's the code.

Let's go ahead and begin the dissection...

The Gemfile

The Gemfile comes from Bundler, which is an amazing dependency management tool for front-end stuff, namely Ruby Gems. Here, we mention the repository we need, and which gems to get. You can then run bundle install in order to install the requisite version of gems specified in the Gemfile.lock. (If you're at all familiar with Composer, this should sound familiar, because Bundler was a huge inspiration for Composer.) Then, we can start our normal compass commands by adding bundle exec in front of them, and it will ensure you've installed everything correctly before it starts to watch the sass folder, and compile to the css folder. 

bundle exec compass watch

The 'sass' folder

Our Sass folder structure leans on a single but simple style.scss, which includes a number of things. 

Up top, we include any compass imports, followed by any external vendor imports, namely Formalize and Susy. Combining Susy with Breakpoint we can rapidly build responsive layouts that just make sense.

We use Chris Eppstein's sass globbing plugin to import an entire folder of partials with one line.

@import "folder/*";

In this way, we then allow the project to grow folders out organically. Typically we end up with folders like:

  • nodes
  • views
  • paragraphs
  • misc (or "components")
  • regions

Even as I write this, we're discussing how to better standardize this list.

Configuration

The last thing to check out is the config.rb file. This is a standard sass/compass file that you need, but I do want to call particular attention to the last line, where we mention sourcemap=true.

This little bit of magic gives your Chrome Inspector (or other Dev Tool of choice) the ability to identify which line of the sass partial--not the compiled css--the styles are coming from, so you know right where to go to change them.

Leveling Up

The last piece of our front-end stack is Browsersync, which we'll cover in a future post!

Nov 27 2015
Nov 27

CKEditor is a superb WYSIWYG text editor and when used together with the CKEditor module for Drupal, it's a great solution for enabling editors to easily add HTML to content. A common issue site builders seems to have is changing the list of styles that are available in the Styles drop down combo. Here's a salient tip for getting it working!

Photo of Chris Maiden Fri, 2015-11-27 07:26By chris

CKEditor comes with a Styles drop down combo that enables editors to select some text and then decorate it by selecting from a list of available styles:

Screenshot of CKEditor showing Styles drop down

These styles might be everything you need in which case, you're home and dry!

In my case, I wanted editors to be able to pick from just the following styles: paragraph, heading 3 through heading 6. That's all.

The method for customising the styles presented in the drop down combo is to copy the ckeditor.styles.js (or styles.js) file from the CKEditor library to your theme (or somewhere else) and to configure the Drupal CKEditor profile settings to pick up the new file:

Screenshot showing CKEditor profile set to use styles from the theme

If you, like me, have taken the styles.js file from the CKEditor library itself (CKEditor version 4.5.4) and have placed this in your theme directory, you might have got the following blank styles drop down:

Screenshot showing the blank styles dropdown

What's going on? Well, the solution is easy, once you know it!

All that is needed is to edit the JavaScript file you've copied to your theme and change the following line:

CKEDITOR.stylesSet.add( 'default', [

to

CKEDITOR.stylesSet.add( 'drupal', [

and that's it. Oh, you might need to clear your browser cache or alternatively append a query string to the JavaScript file to bust the browser cache and that is actually it!

Oct 30 2015
Oct 30

Like many Drupal developers out there, I spend a lot of time traveling. It's one of the benefits of doing knowledge work: you can make your location independent from your work. Handling your email and most communication with a mobile device is straightforward and well supported. It's still rare for developers to do technical work while on the road with anything other than a traditional laptop. The reason is simple: it's hard to run a web server stack and write code without a full blown operating system.

Toting a modern lightweight laptop around the world is doable, but it's not easy. They're somewhat fragile, have a large power brick, and limited battery life. A travel laptop is yet-another-device to maintain to go along with your home workstation, tablet, and smartphone. They're also rather expensive.

What if it was possible to do your standard Drupal development work from the tablet you already own? I wanted to see if this was possible with the current scheme of apps and services available. I ran across a story by Mark O'Connor, a programmer, who had the same thought. He worked out a solution that would offload the heavy lifting to a remote server and had success with it. I wonder: Why can't we do this with Drupal, too? So, I decided to skip the laptop on my next trip and cut down on my baggage.

Despite only having a 28 liter Deuter backpack, I brought along an entire development workstation with me on a recent three weeks in Europe. Mind you, that small backpack also contained the rest of my clothes and needs for the trip. "How?" you might ask.

Tools and Tricks for Drupal Web Development from Anywhere

1) Apple iPad

iPad for mobile Drupal development traveling

Before the Android and Windows folks string me up by my toes, I'm sure this is all possible with other platforms. That said, I had a Retina iPad handy and I appreciate a challenge. With that in mind, a lot of the details in this post will revolve around iOS. I'm sure you'll manage to apply the key concepts and solutions to your own platform solution. I haven't attempted any of this on other platforms, so I can't compare or speak to them.

The primary advantage I see in the iPad is the variety of accessories, and application choice. You may do fine with a generic Bluetooth keyboard that's compatible with any tablet, but having a Smart Cover style keyboard can really help with ease of use while traveling. Similarly, you're going to be chasing down edge case uses of the platform which means having a huge library of Apps to leverage is beneficial. Still, it's worth looking at other tablet options that may suit your specific needs better. A mixed tablet/desktop device like Surface can have access to the entire Windows x86 application library, though those generally aren't mobile optimized.

For me, reliability was also a key need. Apple's walled garden can be an advantage if you have a supported use case and are doing real work. You want your system to reliably function and the last issue you want to deal with is a finicky OS, update, or application. Following this train of thought, I wanted hardware that was easy to simply replace. I don't mean working on the internals. I mean throwing the whole tablet away and starting fresh. Apple's cloud backup and app data storage systems mean that the underlying hardware becomes irrelevant. If the iPad should be stolen, lost, or broken, I could simply walk into the ubiquitous Apple stores or resellers and replace it with a clone. From there, it's just a matter of restoring a cloud backup and a bit of time. This removes the concern of lost luggage, thieves, or a horrendous downpour eliminating my ability to work for the remainder of the trip.

The platform itself also has a bright future with the iPad Pro expected to debut this November. The larger screen and more powerful multi-tasking system is specifically targeted at creative professionals. Putting aside the unknown that is an unreleased device, it's good to see that Apple has plans and a future for the iPad line as a professional's work device.

2) Logitech Ultrathin Keyboard Cover

Traveling Mobile Web Development Keyboard for iPad

For any web developer trying to make due on a tablet, the first accessory they should purchase is a compatible physical keyboard. Onscreen touch keyboards are quite usable for short stints, but try typing out a few thousand words or hundreds of lines of code on one. You'll add a solid 12 ounces (~350g) to your pack, but it's worth the weight.

I had three requirements for a physical keyboard alongside the iPad:

  1. Use the iPad's magnet attachment as a cover
  2. Support iPad specific shortcuts
  3. Double as a stand for the iPad

The Logitech Ultrathin Keyboard Cover meets these three key requirements. It connects wirelessly via Bluetooth which means you could also connect it to a smartphone if needed. It charges via micro-USB with a built-in battery. I purchased a used one off Amazon in near new condition for under $20. It was cheap enough that if it didn't work out, I wasn't losing much.

I've been using this slim keyboard now for months and can say that I type nearly as quickly as I can on my favorite full size keyboard. I can't do so for as long of periods, but my speed isn't handicapped. While it's quite a bit smaller, the key travel and placement is thoughtful. The keyboard's support for iOS shortcuts really helps boost productivity: a double-press of the dedicated home button brings up the app switcher, cut/copy/paste shortcuts work, there's a dedicated function key for Spotlight search, etc.

3) Smartphone with tethering capability

Have an iPad with cellular built-in? Skip this section.

You're going to need to connect to the Internet in order to do any development work. For now, there's no way I know of that'll let you run a local development environment on a tablet (perhaps a rooted Android device or a jailbroken iPad?). You'll need Internet access to utilize a remote environment. You can subsist on WiFi if you're confident you'll always have access.

You can also leverage the cellular in your smartphone. To do this, you'll need to connect your iPad to your smartphone by way of tethering. Your carrier and device will dictate how you can do this, but most carriers and smartphones offer a built-in way of doing so. If not, it's possible to do so with a jailbroken iPhone and a dedicated tethering app on the Cydia store. If you want to avoid jailbreaking, you might have luck with one of those apps with a hidden tethering capability that sneak onto the App Store once in a while.

If you're jailbreaking or otherwise bypassing your carrier's separate tethering plan, be wary: users have been caught and back-billed for a tethering plan.

One way or another, your iPad is going to need a connection to the Internet.

4) Mobile-friendly Drupal Administration

Some of your routine Drupal work will still be within the actual Drupal admin. You'll still be creating Views, editing Content Types, and exporting your changes to Features. It's important that the administration theme is compatible with your iPad's screen size. You'll also want to consider how using your finger rather than a mouse pointer will change the interaction with the administration elements.

We wrote up a dedicated post to creating a mobile-friendly Drupal administration environment, recently. That tutorial applies perfectly here. Drupal's mobile-friendly admin themes still have room to improve, but following our tutorial will put your Drupal administration into a state that will work well with an iPad.

5) Development Web Server Environment

Without the ability to natively run a Drupal development environment (web server and database), we need a remote one. The idea being, we can remotely run a development Drupal environment and feed our changes to it. You can do this by running an environment on your desktop workstation that you setup to connect remotely to, or you can create one in the "cloud" as I do.

I mentioned in the web services recommendations post that I generally prefer AWS for on-demand servers. Setup an instance that'll support a Drupal install. Configure the instance to have access to your Git version control system. Now it's a simple matter of accessing this remote development environment from your iPad, making your changes in-place, then following your normal commit and deployment process to your dev/stage/production environments for your project.

The development instance can also act as an application provider for your mobile device. You'll be able to access all the command line utilities through your mobile deice that are on your development server. You can perform basic text editing with Vim, commit code with Git, and fire off Drupal commands with Drush.

One of the great parts about having this instance always on and independent from the device you're accessing it from is that it'll always be in the same state as where you left off. Even if your iPad is destroyed in your travels, you can replace it, restore your device, and pickup your development work right where you left off. This also means it's possible, though difficult, to get some work done via a smartphone in a pinch as all you'll need is a shell connection to your development environment.

6) iOS Web Development and Project Apps

Of course, you're going to need lots of apps to handle various tasks. These app suggestions bring together earlier parts of this series on web services and desktop applications, as they're intended to all work together. Your mobile workstation becomes similar and synced with your desktop workstation.

Drupal Development Apps for iPad and iOS

Image Editing: Pixelmator

​If you need to do a bit of design work here or there, Pixelmator is an inexpensive, PSD compatible iOS app. The key here is Photoshop compatibility with a simple interface and a solid track record of updates. You want an app that'll keep pace with changes to the primary file format design work is saved to. Photoshop is the standard and Pixelmator offers a similar experience along with compatibility. 

SSH: Serverauditor

​Serverauditor is an SSH app for mobile devices. The app offers one key feature over similar apps: it'll maintain a background connection to a server. If you app switch to Mail to review change requests, Serverauditor will maintain its server connection in the background. A lot of the other SSH options do not do this. Serverauditor is also free. Panic makes a very well reviewed SSH app, Prompt, but I've not jumped on the bandwagon just yet since Serverauditor fulfills my needs while Prompt is fairly expensive.

Whatever your SSH app choice, it'll likely be the most important app choice you make for your mobile workstation. Much of your work will be within the shell on your remote development server: making quick text changes with Vim, committing changes with Git, executing deployment scripts, etc.

Code Editor: Coda for iOS

Again, this choice works with my recommended desktop code editor. If you need to write some serious code, Vim may not be enough for you. Coda for iOS is a full-featured code editor: syntax highlighting, local/remote file management, previewing and of course much more. It also provides an integrated terminal for SSH. If you're comfortable with Vim, you may be able to get away with ignoring a local code editor altogether.

Communications, Project Management, Billing

Keeping pace with the web services I recommended previously, mobile apps are available to support your billing, PM, and communication needs. Slack has a solid team chat app. Skype offers a mobile app with full video and audio calling as well as instant messaging. Basecamp's iPad offering cuts down on the noise so much it's almost a better solution than the desktop web app. Freshbooks' iPad app enables mobile time tracking and invoicing. These apps themselves are all free.

The idea here is that your "normal" workflow can be followed while you're traveling. Keeping consistent services and apps means that the jump between your home workstation and your tablet will be less jarring and generally in sync.

Miscellaneous

​I mentioned Evernote and Things as recommended applications for your desktop. Those work here, too. That'll help you keep your notes and task lists in sync across devices. If you're going to be doing some word processing, Pages, which is now free with iOS devices, is a fine solution. Your general productivity apps are covered between Microsoft, Google, and Apple's offerings.

I should also mention that you may want to consider tunneling your traffic over a VPN while you're traveling. Depending on the sensitivity of your development work and the security of the connections you use while you're away from home, securing your connection with a known VPN provider can help keep prying eyes away from your packets.

Lastly, you'll want something that'll keep your mobile workstation reasonably safe without adding too much heft to your baggage. There's loads of iPad cases, sleeves, and battery extending enclosures available. I opted for a more DIY approach. My iPad and keyboard fit together in a very snazzy recycled blue jean iPad sleeve that my more creative half made.

DIY iPad Sleeve with Recycled Blue Jeans

The Pro's and Con's of Working from an iPad

At the end of the day, while it's possible to do most of a typical Drupal developer's work from an iPad, it's not as efficient as on a desktop workstation or powerful laptop. If you do a lot of frontend development, we're still a long ways off of having a competent DOM inspector and effective process to produce graphical elements from images on an iPad. However, there's nothing stopping you here from writing CSS and JS. The trouble is in the details: debugging and inspecting. The same generally applies to the PHP side of things. You won't have much trouble making edits to theme files, writing simple scripts and hooks, or installing modules thanks to Drush. What you will have trouble with is debugging and other more complex tasks. You'll be able to handle the MySQL side of things with some combination of the MySQL command line and phpMyAdmin. The iPad workflow will also be dependent on the quality of your Internet connection. A slow or inconsistent connection means your work is going to be frustrating when you're trying to tackle things through a remote server.

On the positive side, and what I found to be most important is: I can do almost all my routine work from an iPad. What this means is that I can rely on an iPad to do most of my work from anywhere in the world. It doesn't have to be a grand tour of Europe, either. It can be as simple as deciding to take an extended lunch break at a park and finishing up a View change under leafy shade away from the stale feel of an office. An iPad is much easier to just grab and go with compared to a laptop. That's the biggest benefit: I can take my work with me, at any time, on a whim. The iPad extends my "office" to all the parks and coffee shops within a short walk around my office. That makes for a lovely change of scenery and a happier life.

Looking for more in our series on building a web developer toolkit, perfect for freelance Drupal developers, consultants, and agencies?

Did you like this post and want to see more on building your toolkit? Share it!

Oct 28 2015
Oct 28

This week, we're continuing our Drupal Developer Toolkit series with ten desktop and mobile applications to support your Drupal workflow. These tools can make your day-to-day Drupal development routine more effective. If you've got your own hidden gem to add to this list, let us know!

10 Applications Every Drupal Web Developer Needs

This is my list of local, native applications I use and recommend during my day-to-day Drupal development work. Some of them are certainly applicable to general web developers, but I find them to be especially relevant to a Drupal developer whether a consultant or part of a company. When reviewing the list, consider that I do most of my Drupal development work from a Mac workstation though most of these applications are cross-platform. 

1. Code Editor: Coda

Let's just start this list off with one of the more controversial topics: code editors or integrated development environment (IDE). This is certainly subjective. I've been using Coda now for years and enjoy it quite a bit. It integrates a shell to quickly hop to the command line. For your file transfer needs (FTP, SFTP, etc), a version of the excellent Transmit is integrated. Coda also connects with loads of plugins and version control systems like Git. The interface is generally sparse, not terribly distracting.

I feel like Coda has just what's needed for the average web developer along with some lovely integrations to handle server-side work. It's not as light as what Vim enthusiasts desire. It doesn't have as strong of a code autocomplete as something like Visual Studio. It's not as customizable as Sublime. However, it does hit the basics of all these things, fitting most needs. Most Drupal devs work with Git for version control, here's an excellent write-up on integrating Coda with Git.

IDE Alternative: PhpStorm

​If you do serious PHP development work—creating custom modules from scratch, for example—you may want a dedicated PHP IDE. PhpStorm brings the focus of your editor to PHP with stronger code completion, rich debugging tools, and deep framework integration. PhpStorm also works well the other code you'll run into doing Drupal development, too. There's full support for CSS, JavaScript, and HTML.

2. Local Development Environment for Drupal: Acquia Dev Desktop

Our primary work is in Drupal development and support. For sometime, if you want to run a local development environment to test or work locally on Drupal, you would use a stack of Apache, MySQL, and PHP installs. Eventually, these were combined in a single local application specific to your operating system (see: LAMP, WAMP, MAMP). Eventually, a Drupal-specific environment came about, created by the behemoth Drupal company: Acquia. Their version of a local *AMP stack includes tools specific to Drupal such as Drush. It provides a GUI to help quickly setup local Drupal installs and even integrates with Acquia's version control system to make environment migrations a bit easier if you're in their environment.

Dev Desktop makes spinning up a local Drupal install quick and painless. It's how we get started with all of our new projects, testing ideas and beginning implementation locally.

3. Notes: Evernote

​Web Developers constantly take notes. Meeting? Write down requirements details being addressed. Reviewing a technical issue? Map out the processes firing as they relate to the issue. Notes, notes, and more notes.

You'll want to have those notes at hand whenever you may need to review or edit them. Evernote provides a cross-platform note taking system. It's like an amped up version of Notepad. The WYSIWYG provides enough design ability to handle any sort of note taking needs you can throw at it. It syncs across all your devices: you'll have the note you just started writing on your smartphone in a meeting available on your workstation or their web app ready to be reviewed. If you're still stuck paper and pencil note taking, Evernote offers an excellent camera/scanning system that will OCR the text from your notes. It's possible to add media, categorization, and share notes with colleagues.

I've been using Evernote for years to house a variety of life information that I can offload from my brain. Evernote is also a note taking tool for Drupal developers.

4. Chat: Skype

While you should keep the bulk of business communication to project management tools like Basecamp or Slack, now and again you'll want to send a quick message. Maybe you want to have a short conversation about a feature or quick review. Email isn't always light enough to handle something minor and can be frustratingly slow. Instant messaging is a great communication method to fire a quick question off to a colleague. There's a lot of platforms out there for this. However, Skype does a good job of encompassing the needs of a quick one-on-one communication. It offers a fine platform for instant messaging, offering a cross-platform application. It provides a way to initiate file transfers, screen sharing, audio calls, and video calls within that instant messaging interface. All these base features are free.

Often, I'll want to show a multi-step interaction to a colleague that's too much for a screenshot or screen recording, and Skype's quick screen sharing system is an excellent solution. It's a great way for Drupal developers to walk through an interaction or system with other developers.

More than anything, I'd suggest keeping your business communications within a specific instant messenger, no matter which app that is.

5. To-do Task List: Things

Basecamp is an excellent tool for creating project-level, shared task lists. However, you probably have a bunch of tasks you need to complete that aren't things you need to share with the team. Maybe you need to update your local Drupal development stack, perform an OS update, or order a new keyboard. Keeping all of this in your head is a terrible use of your memory and attention. Get it out of your head and into a task list.

I'm a big fan of the minimal Things to-do list app. There's a desktop and mobile app that syncs your tasks. Unfortunately, it is Apple-centric. If you need something similar that's cross platform, take a look at Wunderlist.

6. SEO Deep Dive: Screaming Frog SEO Spider

Let's say you have a Drupal site with thousands of pages. You're leveraging the Metatag module to handle SEO-related data. How do you know all those thousands of pages properly have the right data snippets in place?

SEO Spider allows you to run a local app that'll crawl and index data search engines are interested in across your pages and site. This will help you identify weak points and missing data across the site without having to manually view the source on a bunch of pages to perform a manual analysis.

7. MySQL Database Management: Sequel Pro

While phpMyAdmin was probably your first introduction to GUI-style management of MySQL databases, Sequel Pro is the first step into professional MySQL use. This powerful, native client for Mac OS X is totally free. The app has the features you may expect: a powerful query editor, full CRUD support within the UI, and strong backwards compatibility. It also has a few you may not: multi-window and multi-tab options to manage your remote connections, favorite host saving, several connection methods (including SSH tunneling), and a lovely interface to browse contents and structure.

If you're not happy in living in the mysql cli, Sequel Pro offers a fast and flexible native app to handle your database management.

8. DOM Inspector: Firebug

Firebug is the original Document Object Model (DOM) inspector. It's a free plugin for the Firefox web browser. DOM inspectors allow developers to view the frontend source code that a web server delivers to a browser. It also allows developers to review some other data provided by the web server like HTTP Headers.

Other Drupal developers might use similar tools integrated with Chrome or Safari. However, Firebug is a dedicated tool for this purpose and continues to get updates to help make the life of web developers easier.

9. Animated Screen Grab (GIF): RecordIt

​If you have a short, visual interaction you want to show a client or colleague, sometimes an animated GIF is the perfect solution. Screenshots are static, so they're no good for animations or multi-step interactions. Setting up a screenshare can be too much for a simple question or process review. RecordIt is a free, cross-platform app to quickly select a portion of your screen and record several seconds of it to an animated GIF file. RecordIt provides a public link to share that file so others can review it. Quick, simple, and free.

10. "​Wireframes": Balsamiq Mockups

If you need to produce a quick mockup for a design or user interaction and you're not a designer, I'm a big fan of Balsamiq Mockups. It's a very simple tool for laying out user interface elements and exporting them to shareable visuals (JPG, PNG, etc). It's miles from the complexity of a proper wireframe tool like Adobe's InDesign. It's a great tool for Drupal developers that want to produce a quick user interface for a client or colleague to review that doesn't take a degree in design to use.

Mockups provides interface elements that are for both desktop scaled designs or mobile scaled elements.

BONUSES 

​Save Your Eyes with f.lux

f.lux is not a Drupal developer specific tool, but it's the one application on this list that I think literally every computer user should have installed. Its purpose is fairly simple but its effect can genuinely improve your life. f.lux manages the display color on your monitor, adjusting the color to match the sun's trajectory over the course of the day. f.lux adjusts its color based on time of day and your location. As the sun goes down, f.lux will lower the intensity of colors, making those whites much less bright. These adjustments can really help save your eyes, reducing eye strain as your stare endlessly into that backlit monitor. It's free and cross-platform.

If you're wondering if f.lux really makes a difference, install it, use it for an hour or two after the sun as gone down, then quit the application. This will revert the color output to default on your monitor as you shield your eyes from sudden glare of your monitor. If you use a computer, install f.lux.

File Sharing with Dropbox

​There's lots of competing file sharing apps and services out there. Cloud file storage in itself is a pretty simple thing: it's just a place to store files that aren't on your local disk. The key reason I recommend Dropbox versus other options is simply that, in my experience, other businesses tend to use Dropbox. When working with clients, the way they'll often share larger files is via Dropbox.

If you as a Drupal developer also use Dropbox, you'll be ready to utilize shared folders and file systems from clients and colleagues without having to install yet another app when they do. This choice is primarily about reducing friction in your day-to-day. Dropbox itself is a fine file sharing service, offering cross-platform apps and a usable free account level.

Building a Drupal Developer Toolkit Series

Native, local applications serve as another key tool for Drupal development teams. These are your bread and butter tools: they provide the primary way for you to do your work as a Drupal developer. What applications mentioned could help you be more productive?

Looking for more in our series on building a web developer toolkit, perfect for freelance Drupal developers, consultants, and agencies?

Did you like this post and want to see more on building your toolkit? Share it!

Oct 22 2015
Oct 22

This week, we're continuing our Drupal Developer Toolkit series with eight lightweight web apps. These tools will make your day-to-day Drupal development routine more effective. If you've got your own hidden gem to add to this list, let us know!

8 Best Web Tools for your Drupal Workflow List

These are some of the key web apps we use for singular tasks throughout our web development work. These are the quick, single-use quality of life improvement tools. They aren't intended to be deep, high-end professional tools. There's bound to be other professional, purpose-built, comprehensive tools for the uses cases supporting these web apps. We're not pursuing deep, complex systems in this list. Instead, these are the lightweight tools that follow the Pareto principal. All of these web apps are free or freemium.

1. Code Cleanup and Formatting: Tabifier

​Once you've worked with a team of other web developers, one of the things you'll notice about their code is differing methods of to create indents. Some developers like to add two spaces, a tab, or several spaces to form an indent level. There's practically a holy war on web forums about which one of these methods are correct. Often, different methods cause different effects in different code editors. Some of your fellow developers might be in Windows using Visual Studio while another is rocking Vim from the command line on a Linux server.

Code formatting web app tool spacing tabbing indents

The best way to handle this is to set a standard for your team to work against. Discuss and agree to use a single format. While indenting is one of the most discussed code formatting issues, there's others: when to break curly bracket code to a new line, spacing within comma delimited lists, comment formatting, etc. This may seem like a fairly minor thing, but consistently formatted code helps make it more scannable. This can reduce effort neeeded to accomplish tasks for everyone on the team, paying dividends over time. It doesn't matter what format is chosen so much as everyone follows the same format.

If you've got a mess of code and want to quickly clean it up without having to do so manually (and your Integrated Development Environment (IDE) doesn't have its own method), there's a great, free, simple, web app to handle this: Tabifier. Copy your code into the WYSIWYG, select the code syntax to follow, hit format, and copy your newly formatted code back to your editor.

2. Code Comparisons and Difference Identifying: Diff Checker

Web tool for code comparison difference diff checking

I've got two blocks of code and I want to quickly compare them, finding the differences. For whatever reason, the code isn't in an IDE that'll make it easy for me to quick compare two files. Maybe I want to check if a file was changed from an original, and more specifically, what was changed. Perhaps I just want to compare a Drupal core update to settings.php (hint hint) to see what the differences are from the last version. Maybe a client emailed me a revised Word doc that has no revision history but they've changed an unknown amount of the document.

This is where a quick A-B difference checker can be a great tool to have handy. A 'diff' will compare two sets of text and identify the differences or changes between the two. Diff Checker is an excellent, simple tool to do this with as few options as possible. All I've got to do is copy and paste into version A and B into two text boxes and hit compare. The differences are highlighted for you so you can see exactly what has been changed.

3. Writing Blogs, Documentation, Proposals: Hemingway Editor

Writing Analysis Web App Tool Free Grading

Writing deep technical documentation sometimes means I let my English composition fall by the wayside. Explaining technical concepts requires forming a complex mental model that can push out the basics of writing. Suddenly, my document is chock-full of run-on sentences, complicated phrase structures, and inconsistent voice. For my readers, it's difficult enough to follow new technical concepts. There's no need to complicate that with grammatical complexity, too.

Hemingway Editor scans your text for reading difficulty, adverb use, simplicity, and consistent voice. The app will also provide a "readability" score which represents reading difficulty. Hemingway Editor does this with a simple WYSIWYG interface and highlights issues inline. The clean interface helps me stay focused with simple visual cues to identify problems. Give it a shot to improve the readability of your own articles, proposals, or documentation. There's a lot of Drupal.org docs that would benefit from a quick cleanup!

4. Monitoring Search Engine Page Ranks (SEO): Pro Rank Tracker

​I like to keep track of search engine result rankings for particular URLs. In the case of this site, I want to keep an eye on how we rank on Google for local search results plus our various services. A good search phrase example would be: "Richmond Drupal developer". If our ranking drops, I want to see if a new, local competitor is outshining us in some way. Or worse, something has happened to our domain and Google is penalizing our result ranking (for example, comment spam could cause this).

Heading off to Google every morning at 9AM for a quick scanning of results isn't viable, though. Google's guess at your location and other meta data can affect the results, too. Instead, consider a web app that'll track this result ranking for you over time. Typically, you need only feed it a URL and search terms. I've been using Pro Rank Tracker for this for a while but they've recently drastically cut back the usefulness of their free service level. Dear Reader, if you have a better app suggestion for tracking page ranks over time, shoot us a tweet.

5. Search Engine-friendly Page Testing (SEO): ​Varvy (previously Feed the Bot)

Back in April of this year, Google rolled out the Mobilegeddon update that added weight to mobile-friendly display for websites in search results. Basically, page rankings could be lowered a bit if they weren't considered "mobile-friendly" by Google. This was another kick in the pants for web developers, webmasters, and site owners to configure websites for optimized display on smartphones and mobile devices.

There's several web apps that'll test a particular URL for mobile-friendly display, but none are as simple yet comprehensive as Varvy's in my experience. It tests the full gamut of good website practices, beyond simply testing for a "mobile-friendly" display (which Google can do quite well). Varvy will check for robots.txt issues, a sitemap, solid HTML practices, HTTP headers, and much more. The test results also provide suggestions and jumping off points for fixing issues. It's an excellent way to do a high level check of website best practices that search engines care about.

6. Domain Health Monitoring (SEO): Majestic

Search Engine Result Ranking Tracker Web App Tool Free

Search Engine Optimization (SEO) is a deep rabbit hole of educated guessing into the black box that is search engine algorithms. One of the more basic concepts is that a domain (daymuse.com, for example) has a strength score as a whole. In addition, every individual web page (URL) has a strength score. Think of them as multipliers: a solid domain can help a weak page rank well in the same way that a really great page can standout from a weak domain. The actual strength of a domain or page comes down to some combination of content (quality and quantity), other URLs which link to it (backlinks), age, and other smaller factors.

The general goal of any website owner should be to strengthen the score, or authority, of their overall domain if organic search traffic is important for the organization. It's a bit of a chicken and egg problem as strong domain authority usually raises search results which raise traffic which tend to generate more backlinks and greater authority. The only way to get this positive feedback loop started is to do so manually. Reach out for relevant backlinks, write quality, link-friendly content, and make sure search crawlers can index your content easily. The details aren't within the scope of this post, but if you're not already using Google Webmaster Tools (WMT) to their fullest extent—that's the best place to start. With all that effort, however, you'll want to keep track of overall domain authority over time. There's a handful of web apps that do this, but I've found Majestic keeps the freshest index of pages and backlinks with lots of features at the free account level.

7. Social Media Tracking: SumAll

​Drupal freelancers, small firms, and agencies probably have half a dozen social media accounts. While a great tool like Buffer can help you manage and post content across social media platforms, it doesn't keep track of "stats". Which of your social media campaigns are most effective, generating the most user interaction or advocacy? You could dedicate a block on your calendar to manually login to each platform and record these stats. But, you wouldn't do that, right? You're a systems thinker. You listen to Cortex. You devise solutions that automate routine tasks for you.

SumAll is your social media statistical roundup tool. Connect it to all your platforms and get an email update that rounds out all the stats for you and tracks them over time. SumAll's UI, while still evolving, does a great job of trying to deliver loads of statistical data across lots of metrics and platforms. Their free account level is plenty sufficient for small shops.

8. Testing Drupal Modules: simplytest.me

​Did you just read about a new Drupal module that might solve an issue for you on /r/Drupal's contrib Wednesday thread? Did you spot an interesting use case for a module from this week's TheWeeklyDrop? Perhaps you were browsing around Drupal.org's module listing and wanted to try something new out.

Rather than going to the length of firing up a clean local development environment and installing the module, you can leverage simplytest.me. It's a free resource for testing Drupal modules. The web app lets you select a module name and fire up a copy of Drupal core with the module. You've got 30 minutes to do what you need to and then it's gone, into the ether. It's the ideal quick test platform.

Building a Drupal Developer Toolkit Series

Web apps serve as another key tool for Drupal development teams. These simple, always-available, free web apps can cut surprising amounts of tedium from your schedule. They can make you more effective at your work. What web apps mentioned could help you be more productive?

Looking for more in our series on building a web developer toolkit, perfect for freelance Drupal developers, consultants, and agencies?

Did you like this post and want to see more on building your toolkit? Share it!

Oct 20 2015
Oct 20

Migrating away from legacy content management systems (CMS) can sometimes throw up some interesting technical challenges. Recently we were involved in a migration from a CMS where URL’s contained no word boundaries... here’s how we transformed these unfriendly URL’s and improved search engine optimisation.

Photo of Chris Maiden Tue, 2015-10-20 13:39By chris

I'm sure we're all aware that human-readable URL's are a good thing, not only for us but for search engines too. Take, for example, the following URL:

/topsubjects/businessandintellectualproperty/businessandmanagementstudies/yourstudyprogram

Whilst it's readable (with effort), it's quite unfriendly and does nothing to promote the content of the page.

Initially I thought it an impossible (or at least very complicated) task to programmatically split a word such as "businessandintellectualproperty" into its component parts: "business and intellectual property". There were literally thousands of URL's so it was an impossible task to do manually.

The exported data from the legacy CMS contained human-readable page titles and the HTML of the body content so at least I had the option of using the page titles to generate the "your study program" part of the URL but what about the component parts of the URL? How could "businessandmanagementstudies" be transformed to "business-and-management-studies"?

Enter Wordbreaker! Wordbreaker (and Indexer) are utilities that are packaged with Sphinx (since version 2.1.1), an open source full text search server. Given that you have some useful data somewhere (in my case, the combined HTML body content of all of the pages in the CMS), Indexer can be used to create a frequency dictionary which in turn is passed into Wordbreaker along with the string you want to split, such as "businessandmanagementstudies" and lo and behold, out pops "business and management studies". It's magic, let me explain how to use both Indexer and Wordbreaker!

Creating a frequency dictionary with Indexer

The first thing you need to do is to identify the most useful data you have from which to create a frequency dictionary. A frequency dictionary is essentially a list of unique words found in a body of data with a frequency count of how often each word appears. Common words appear often so have a high frequency count whilst un-common words appear less frequently and thus have a low frequency count. Wordbreaker uses a frequency dictionary to determine the likelihood of the words it finds in the string actually being the words you want.

To give you an idea of what a frequency dictionary looks like, I've created one using the content of this blog post, here's a snippet:

the 51
to 30
of 27
a 23
frequency 16
you 13
in 12
dictionary 11
content 11
and 9

Clearly then, the richness of your source data and its relevance to the strings you're trying to split is an important factor in how successful the word splitting will be. In my migration, I used the combined content of the entire website to create a frequency dictionary which thankfully proved to be quite successful. What would have been potentially days of mind-numbing editing of URL's was reduced to a few hours of reviewing and fixing the few unsuccessful cases.

So, now you've identified your data, how do you create a frequency dictionary?

To use Indexer, you'll first need to create a Sphinx configuration file. This example shows how you can configure Sphinx to index data from an XML file:

source demo
{
  type = xmlpipe2
  xmlpipe_command = cat source.xml
  xmlpipe_fixup_utf8 = 1
}

index demo
{
  source = demo
  path = /tmp/demo
}

indexer
{
  mem_limit = 128M
}

Here we have Sphinx indexing the content of source.xml but it could easily be configured to index content from a MySQL or PostgreSQL database. See the sphinx.dist.conf file that comes with Sphinx for examples of how to do this.

Now let's take a look at the content of the source.xml file:

<?xml version="1.0" encoding="utf-8"?>
<sphinx:docset>
    
  <sphinx:schema>
  <sphinx:field name="content"/>
  </sphinx:schema>
  
  <sphinx:document id="1">
    <content><![CDATA[Document content here]]></content>
  </sphinx:document>
  <sphinx:document id="2">
    <content><![CDATA[More content here]]></content>
  </sphinx:document>

  <sphinx:killlist>
    <id>1</id>
    <id>2</id>
  </sphinx:killlist>
  
</sphinx:docset>

For conciseness, the example contains only two documents with hardly any content, in reality you'd want much more source content with which to generate a rich frequency dictionary.

Now, assuming you've installed Sphinx already, the command for producing the frequency dictionary is:

$ indexer --buildstops demo.dict 100000 --buildfreqs demo -c sphinx.conf

The --buildstops flag tells indexer to stop short of actually producing an index and to just produce the list of words. The --buildfreqs flag tells indexer to add the frequency count.

demo.dict is the name of the resulting frequency dictionary file.

demo is the name of the source to use (referred to in sphinx.conf, the configuration file to use for this operation).

We've now got everthing we need to start splitting strings into their component words.

Using Wordbreaker

The command for doing so is:

$ echo businessandmanagementstudies | wordbreaker --dict demo.dict split

And the result:

business and management studies

I think that's pretty amazing and more importantly, so did our client! We were able to pass each section of the URL to Wordbreaker, replace spaces in the string that Wordbreaker returned and transform URL's like this:

/topsubjects/businessandintellectualproperty/businessandmanagementstudies/yourstudyprogram

Into URL's like this:

/top-subjects/business-and-intellectual-property/business-and-management-studies/your-study-program

I did a lightening talk at the October North West Drupal User group, here are the slides - http://slides.com/matason/wordbreaker

And here's the blog post from Sphinx about Wordbreaker - http://sphinxsearch.com/blog/2013/01/29/a-new-tool-in-the-trunk-wordbrea...

Oct 05 2015
Oct 05

Last week I started a series with you all: Upgrading Your Drupal Developer Toolkit. In today's tutorial post, we'll work through web services that any freelance Drupal developer, small consultancy, or agency will find useful within their tool set of outsourcing methods.

Web services that focus on software-as-a-service (SaaS) are often excellent returns on investment for small business. They help eliminate the need for internal expertise that otherwise might have to be provided for by an employee, contractor, or partnership often underutilized. Daymuse is a successful web development consultancy, but we couldn't reasonably hire a full time accountant with our current workload. This struggle, where small business may have workers who "wear many hats", is apparent in industries outside of Drupal and web development. However, there's several industry-specific services that I think may help you reduce costs and frustration. Let an external web service reduce the weight of some of those hats. I'd like to shed some light on our experiences with web services and what we've been using happily over our last seven years of experimentation.

10 Web Services to support your Drupal Business

My service recommendations come from the point of view of a relatively small web development company. They won't be for everyone, but I find they work well for us. Of course, they can be useful outside the realm of the Drupal content management system (CMS), too! Tweet us your own recommendations and feedback!

1. Team Communication: Slack

Slack sits somewhere between email and instant messaging. It's a sort of expanded IRC with a slick interface. You can easily attach files and share links (with teasers embedded). You can group conversations by channels: a channel for each project or client so that a conversation will retain context as you switch between them. Slack is abundantly cross platform with a quality desktop, mobile, and web app. The free pricing level has suited our needs so far just fine.

Slack is the newest addition to our team's arsenal of tools, but it's already become part of our routine.

2. Project Planning: Basecamp

​If you're too small to have a dedicated project manager sporting a slick PMP, Basecamp is about as close as you're going to get to having your team internally manage projects efficiently. The simplistic, web-based tool allows teams to create projects, task lists, assign priorities, and comment on topics. Think of combining forum software with a checklist and then adding some project management specific niceties.

I've been using Basecamp for years. Competitors have come and gone and there's plenty of competition in the service offering. There's no useful free option for Basecamp, but the $20 per month level does provide for several ongoing projects and a small team to collaborate. Most importantly, external parties (think clients) can handle using Basecamp without much training. Basecamp also offers an excellent, free, mobile app. If you're still managing projects via email and spreadsheets, Basecamp offers an excellent boost to your team's productivity.

Basecamp is simple project management because that's all it needs to be. Watch out for complicating this process more than need be.

3. Accounting and Payments: Freshbooks

When Daymuse first started, I'd track time on projects with a stopwatch and a spreadsheet. When I wanted to send an invoice to a client, the process would look something like this:

  1. Call up an invoice template in Word
  2. Frustration begins modifying content as I break the layout
  3. Contemplate why we're still using Tables for layout in Word docs, frustration rises
  4. Send email, forget to attach invoice
  5. Cry and repeat

I'd forget who I sent an invoice to and when. I tried keeping track via a calendar app, one more thing to deal with. I couldn't easily accept credit cards without creating a PayPal invoice. The layout of the invoices was somewhat haphazard and the emails themselves were similarly inconsistent. It was unprofessional.

If I ever wanted to gather statistics for how the business was doing: profit, expenses, time-to-pay per client, and so on—I'd have to fire up a spreadsheet and lose a bunch of time doing that instead of real work.

Freshbooks changed all of that. Time tracking is now a simple process of clicking start/stop and selecting an appropriate project/task. Invoices are cloned and modified in minutes. Payment reminders are automatically sent and customizable. Clients can pay with credit cards directly from the invoice. I can bring up reports on just about any financial aspect for the business and monitor trends. All of this can be easily shared with external tax professionals. Freshbooks also offers a lovely mobile app and can sync with Basecamp.

Freshbooks made everything to do with money, easier. Their plans start as low as $108/year. Ignoring all the headache and time saving, making the process of time tracking easier will make up for the cost by helping you properly bill for your Drupal expertise.

4. Payroll: Gusto (previously ZenPayroll)

If you've taken on Payroll as a small business, you already know what a difficult process it can be. Good luck setting up all the necessary tax payment processes, following all the dates to make sure money goes to all the right places at the right time. There's also serious implications to making mistakes here: fines and interest add up. Keep being a Drupal expert and avoid becoming a Payroll expert. We switched from a local provider of Payroll services (who did a fine job) to an online provider to better fit our processes.

After reviewing several options, Gusto seemed to be the best choice. Their custom service is excellent. Every time I've had a question or issue, they're easily available via phone or email. We also saved money as Gusto's pricing is very competitive. Gusto offers an excellent mobile app and syncs with Freshbooks.

5. Cloud Hardware, Website Hosting: ​Amazon Web Services (AWS)

We reviewed all the major "cloud" hardware providers before choosing AWS to build out our infrastructure. All of our services exist within the systems provided by AWS. Our data backups are stored in AWS snapshots. We use RDS for our databases, which provides MySQL as a service with automatic regional failover. Virtualized, easily scalable hardware means it's easy to spin up an additional Varnish instance as anonymous traffic grows or Memcache instances to protect your MySQL backends from unnecessary repeated selects. We route client emails over SMTP (well supported Drupal module) through Amazon's Simple Email Service (SES). This lets us avoid worry about spam and yet another support need. If you do technical work on the web, Amazon likely offers software-as-a-service solutions to make your life easier, outsourcing one of the technical balls you're trying to juggle internally.

We've also been experimenting with Digital Ocean for certain, smaller, one-off projects. Their pricing starts at $5/month for a service we've found to handle a basic Drupal or Wordpress instance largely because all of Digital Ocean's offerings are SSD based. The least expensive plan only has 512MB of memory which is admittedly too little for all but the most basic Drupal sites, but the $10/month plan kicks it up to 1GB which will certainly support most small or local business informational Drupal websites. Like AWS, Digital Ocean generally targets technically savvy users: this isn't a service that I would recommend non-technical small business owners to try to DIY your own Drupal with. Digital Ocean does offer one-click Drupal installs (as well as Wordpress and other popular CMS), though.

Drupal Cloud Website Hosting

I would be remiss not to mention the two big players that provide Drupal-specific web hosting: Pantheon and Acquia. Pantheon provides a more developer-centric platform with an excellent GUI for managing development environments and migrations. Their backend is Rackpace. Acquia targets larger organizations, with its bread-and-butter being larger corporations looking to offload all Drupal-related web management. Acquia's backend is Amazon and is corporate arm of Drupal's founder.

While Daymuse competes with both Pantheon and Acquia for managed hosting customers generally, they both operate at higher volume levels and are more hands off. We've worked with both Acquia and Pantheon at every level of their service offerings with various clients, often acting as experts supporting the clients' interests when evaluating options. I think Pantheon is an excellent solution for a savvy freelance Drupal developer or small firm that wants to offer hosting as part of their package without building out an infrastructure. Acquia's managed hosting can be a good (though expensive) solution to outsource a large chunk of an internal IT offering, avoiding an in-house team of SysAdmins, DevOps, etc for large organizations.

If you're a small-medium business, non-profit, higher ed., or regional government: consider looking into small-medium agencies that specialize in your software and offer managed hosting. Often, they'll be able to offer you the one-on-one attention you need while providing managed hosting services at reasonable costs. That's exactly what we do.

6. Domain Services and Registration: Dreamhost

Domain registration has become one of the more mundane tasks in a web developer's life. Years ago, it was incredibly expensive to purchase your own dot com. Now, there are dozens of registrars available that provide low-cost registration. There's also a lot more choice in domain extensions: more than just .com, .net, .org and the restricted .gov, .edu, or country-specific extensions. The newest top-level domains (TLDs) are more descriptive and niche. Down the street from my office is the Virginia Museum of Fine Arts which with their latest redesign moved to http://vmfa.museum. These newer TLDs should reveal an immediate expectation for users when browsing, but it is a significant change on the web and hasn't really caught on just yet. The envy of the web world is still short dot coms.

All of Daymuse's domain registrations have been through Dreamhost for the last several years. They aren't the least expensive registrar, but they do provide quality, direct customer service and include private registration for the domain. Private registration allows domain registrars to obfuscate the WHOIS information for the domain owner, keeping contact information, name, and mailing addresses hidden from public view. We've been pretty happy with Dreamhost. Their domain registration rates haven't seen an increase in quite some time and annual renewals don't tend to be anymore expensive than the initial registration which is sometimes a "gotcha" with other registrars.

In recent months, I've also heard great things about Hover, though I nor Daymuse have ever used them. The general consensus seems to be that they target the slightly less tech savvy folks who'd like to register a domain and not have to understand all the intricacies of DNS and the like. The impression I get is that they help guide you through that process and assist in transfers or associations. Have you had experience with Hover? Tweet me what you've thought about the experience!

7. Email and Calendar Hosting: Google Apps

Our email and calendar system has been provided for by Google Apps since it was first released as a public service and associable with domains. Since then, Google Apps has come out of beta and the baseline account costs about $50 per year per user. Google Apps offers more than just email and calendar, but for those two services, I think business should generally err on the side of caution. Google is a big name and will likely be around for a while yet to come. That's something you want with your email and calendar services. Google Apps is also strongly cross-platform: whether mobile or desktop, Apple or Windows Phone, you'll be to access your email.

We work with a number of healthcare industry clients where HIPAA compliance is an issue. Google Apps does offer HIPAA compliance when dealing with PHI data, but only through their paid accounts. If you're under one of the grandfathered free accounts, you're out of luck.

8. Virtual Conference Calls: Uberconference

[embedded content]

​Love it or hate it, conference calls are still a thing. Even if you're a disciple of the Rework mentality of avoiding them, if you want to do business, you'll run into a need for conference calls. For quite some time, I tried to make sure Daymuse would outright avoid them or relegate them to a more leisurely Skype call. Too often, it became more trouble than it was worth: no Skype accounts on the other end of the conversation or the need to call in via a landline. We went hunting for a virtualized conference call solution and found just what we needed about a year ago: Uberconference.

They offer a free pricing tier that I suspect will work for most small business. The service offers digital connection (mic and headphones over the web), call in via a provided number, and screensharing. They also have lots of other nice features such as: SMS reminders, call recording, and mobile apps. Of the several conference call services I've tried, Uberconference is easily the winner for small business like us. They also have hilarious hold music.

9. Web and Application Uptime Monitoring: ​Pingdom

​Do you need to monitor a client's web project uptime to meet an SLA? Want to be notified if a website you support or work with becomes unavailable? Perhaps you just want to know what average uptime on a particular domain is. Pingdom offers this type of domain monitoring service.

Pingdom can go much further than simple up/down monitoring:

  • Are certain pages performing poorly?
  • Do certain interactions (login, then select a nav item, then create a report) running slowly?
  • Is site performance trending towards slower performance?

The service has a lot to offer. At its heart, the easy to configure and free domain uptime monitoring with notifications is hard to beat. It's incredibly useful for just about any freelance web developer or Drupal consultant.

10. Newsletter and Mailing Lists: ​Mailchimp

​Email marketing and the classic newsletter concept has seen a resurgence in recent years. While social media and mobile web initially seemed like a death knell for traditional email, its actually been propping up one of the Internet's original use cases. Email is now available for us on our smartphones, complete with instant notifications, 24/7. All your apps, services, and contacts have a central, default location to reach you: your email.

For that reason, most web properties will want to have some sort of email outreach for users or customers. We've been recommending Mailchimp now for years to clients to solve the problem of handling automated email generation, sending, and subscription handling for large subscriber sets. Mailchimp's free account level is plenty functional for most small business and is the service we use internally for newsletters. While there is a place for custom-designed email templates, Mailchimp offers cross-platform compatible designs which help avoid the incredibly painful process of designing cross-platform emails. Mailchimp is also well-supported in Drupal or Wordpress.

Building a Web Developer Toolkit Series

Web Services serve as another key tool on a Drupal web developer's toolkit. They can help cut out some of those extra hats you've been wearing and balls you've been trying to juggle. Not only can they reduce this effort on non-core competency work (i.e. your web development work), but they can even create a boost in productivity and revenue. Making it easier for your team to track billable time, manage projects, and get work done means a boost in efficiency: more work, more money. What web service mentioned could help you be more productive?

Looking for more in our series on building a web developer toolkit, perfect for freelance Drupal developers, consultants, and agencies?

Did you like this post and want to see more on building your toolkit? Share it!

Oct 01 2015
Oct 01

Somehow we're nearly at the end of September. School is back in session and the summer "break" has ended. Daymuse's hometown of Richmond hosted more than a half million bike race spectators. Drupal's major event, Drupalcon, was a smashing success in Barcelona. Now we're looking forward to New Orleans next year. 

You may have noticed a long stretch since our last post on the Daymuse blog. Summer sent me gallivanting across Europe, turning the tables on my grandparents whom were my guides when I was younger. The rest of Daymuse had to pickup the slack and so we haven't written anything new around here recently. Traveling with limited hardware also let me put a lot of these tools to the test. If you're just getting back into the swing of things too, what better way to stretch your Drupal muscles with the latest and greatest tools for your work?

It doesn't matter if you're still in Drupal training or you're a Drupal expert: there's always new tools that can make your Drupal work faster, better, or cheaper. There's a lot of ground to cover here as this article originally surpassed 5,000 words rather quickly. Instead of a single monster post on Drupal tools, I'm going to break this up into a tutorial series of five posts over the coming days covering different subtopics:

  1. Drupal-specific Modules and Tools for Developers (that's this one!)
  2. Web Services for Drupal Developers and Consultants
  3. Workflow Web Apps for Drupal Developer Quality of Life
  4. Go-to Applications every Drupal Developer Needs
  5. The Cutting Mobile Edge: Do Drupal Development from Anywhere

Each new post in this Drupal Developer Toolkit tutorial series will highlight different day-to-day tasks a Drupal developer may run into and tools to help solve problems. Let's get right into Drupal-specific Modules and Tools for Developers today. Have your own idea to add? Take to Twitter!

Drupal Development Tools: Expand your Developer Toolkit

With the standout exception of Drush, the "tools" mentioned below are really Drupal modules. The reason I'm defining them as useful day-to-day tools is that they don't actually do anything on their own. They add no particular functionality to a Drupal implementation themselves. Instead they give you, the developer, a bit more of an overview and more reporting options. They're better thought of as extensions of the "Status Report" page. These are excellent tools to add to your Drupal developer toolkit.

Security Review Module

​Before we launch any new Drupal site, we run through this module's checklist. It will verify each condition is met and provide suggestions on how to solve unmet conditions. The module runs a gamut of tests, from file permission checks to .htaccess verifications.

It's important to consider that merely passing "all green" on this checklist doesn't mean the site is 100% safe. Instead, think of it as an excellent starting point. Once you've gone through the process on a few sites, you'll get into the habit of taking care of unmet conditions before you even run the test. That's a great habit to build.

SEO Checklist Module

Just like Security Review above, this module serves as a task list for making sure our work meets the basic needs of search engines and their understanding. Incidentally, strong search engine understanding correlates with accessibility on the web. Even if you don't care too much about search engine optimization (SEO) or page rankings, you should care about your user's ability to read and understand your website. This module doesn't have anything to do with page-level ranking improvement: it will not help you build backlinks, test keyword strength, or write well. That's still up to you and your content contributors.

Within the realm of Drupal, there's nothing that really compares to Wordpress' infamous Yoast SEO plugin which does focus on content-level optimization. Drupal does have a cobbling of modules (that are severely outdated and bloated) which attempt to replicate Yoast's functionality but fail. I see room for a module developer to carve out quite the user base for a new module! Update: A reader wrote in to let us know they just posted a comparison article of the SEO compliance suite of modules mentioned here with the new—drumroll—Drupal Yoast SEO module just released to beta! That's very exciting for the content side of Drupal; we'll be doing our own testing with this SEO toolkit soon! 

Hacked! Module

You didn't modify Core, right? That's the cardinal rule. I'm going to assume you didn't modify Core.

Drupal Meme: Never Hack Core or Cat Dies

But, if you did, or you're afraid someone else with code access did, Hacked! can tell you. What you're more likely to run into is a modification to a module or theme. Often this is a module patch you applied in the past and then forgot about. That can be a real pain in the butt for a Drupal developer: which module was patched by whom to do what? Hopefully, you're tracking your patch files in your version control system. Running a test with this tool will identify which contributed modules have been modified and even diff the changes for you.

Hacked! helps you avoid upgrading a module and overwriting module changes via patches or modifications to cure a problem or solve an edge case issue. It's also an incredibly useful tool if you're new to a project or a client and want to verify the integrity of the Drupal codebase.

Drush command-line Utility for Drupal

This is the do-everything swiss-army knife command-line utility of Drupal. I hesitated even including it here because it should be a given, but just in case: Drush, you need it. At the simplest level, Drush just gives you the ability to do nearly everything you can do in the Drupal GUI via the command-line. That may not sound like a big deal, and though it's a huge time saver simply by being command-line driven once it's in your workflow, the real power of Drush comes from bulk processing tasks. Want to run a database update across several sites at once? You can do that in one command and Drush will keep plodding along while you do something else. Want to sync the /files directory across multiple environments (dev, stage, prod)? One line.

Drush is the power user shell for Drupal workers. If you're not using Drush already, and you do something that even resembles Drupal development work, this tool carries the single biggest impact on this list for your life.

Honorable Mentions: A Better Drupal Administration Experience and Broken Link Checker

Drupal 7's administration experience out of the box has grown long in the tooth. That's alright because Drupal's community has created an incredibly powerful set of modules that combine to create a responsive, intuitive, and user friendly administration experience. I wanted to give an "honorable mention" to our post detailing how to put together such an experience.

You should keep an eye out for broken links within your Drupal site. Rather than make this a manual process (or having to watch logs for 404 errors), the community offers an excellent module, Link checker, which will create a report of broken links in your content. This makes the process more proactive and automated. We wrote up a tutorial detailing a complete strategy of how to avoid broken links, too.

In the next post for this series, we'll be tackling web services. These are especially important for small Drupal firms, consultants, or freelancers as they help makeup for low headcount and lack of business expertise. Summer has set and we're off to another exciting season of Drupal and web development on the Daymuse blog. Stay tuned.

Did you like this post and want to see more on Drupal tools? Share it!

Jul 09 2015
Jul 09

Drupal 7's administration interface and theme leaves much to be desired. The Seven administration theme, part of Drupal Core, has shown its age since Drupal 7's introduction years ago. Mobile devices have taken a large chunk of web traffic: webmasters want to be able to administer their Drupal sites from smaller screened devices like Tablets and Smartphones.

I have something to tell you.

I'm writing this very post from an iPad. Not only do our clients often want to have the ability for users to browse the anonymous, public portion of the website from mobile devices, but often they need to be able to add or edit content from one as well. The Daymuse website itself is in fact one such needy customer.

Drupal administration from any device

One of the greatest features of modern CMS is the ability to administer the system over the web from any location (which also happens to be its greatest security concern). Whether you're a traveling online entrepreneur, or just a hands-on executive who needs to be able to make minor content edits from a meeting on your phone, it's possible to setup Drupal 7 to work with your mobile device administration needs.

The combination of admin tools we use to provide mobile Drupal administration also happens to make the user interface far more approachable. It modernizes the design style, simplifies several common workflow processes, and generally stays out of the way of the real work: adding and editing content. This package of modules, theme, and libraries we use is nearly consistent across the sites we manage (Drupal 6 is still clinging on in some places).

Forward thinking administration for Drupal 8

We've curated this combination of systems with an eye for the Drupal 8 administration experience. That means, where possible, we attempt to utilize tools which are backports or offer similar experiences to the administration system within Drupal 8. In this way, the teams we work with, will be more prepared and familiar with Drupal 8 once the inevitable migrations occur from Drupal 7.

Let's get down to the meat of it and start with the core part of this elegant Drupal administration solution: the admin theme.

Ember: mobile friendly Drupal admin theme

Drupal's Ember Administration Theme

Ember is part of the Spark distribution, a Drupal distro specifically built in attempt to bring Drupal 8 features to Drupal 7. Unfortunately, the distribution as a whole, hasn't been updated much since its initial creation years ago. A few of the modules and tools within it, however, have blossomed on their own. Ember is one such piece.

The Ember admin theme replaces the Seven admin theme as the style and design presented to site administrators. It's been built from the ground up with responsive design. Ember has maintained its focus on being an excellent, mobile administration theme with similarities to the Drupal 8 administration theme. With each update, Ember continues to blaze the trail for a mobile friendly, quality user experience in Drupal 7 administration.

Mobile Drupal Administration with Ember Theme

Ember Support: contributed module interface tweaks

If you've spent time using Drupal contributed modules, you'll have undoubtedly noticed that several modules diverge drastically from the style of the core admin theme, Seven, for their administration. Most module developers will test their module-specific administration experience against Seven. However, with Ember's incorporation of responsive design and a vast array of style changes, this can break edge case module administration experiences.

Rather than constantly add one-off module-specific tweaks and fixes to the Ember theme, a separate module has been created. Ember Support solves a variety of module-specific style issues. We recommend adding it to any Drupal site utilizing the Ember administration theme to ward off the more common module-specific issues, especially sites using the Panels module.

Mobile-friendly admin navigation with Navbar for Drupal 7

As much as we're fans of Ember for its mobile-friendly approach to Drupal administration, this doesn't solve a primary mobile device issue in the admin: navigation.

Here's one of the first sets of commands I would run on nearly every fresh Drupal 7 sites only a few years ago:

drush dis toolbar &amp;&amp; drush en admin_menu -y

The very basic Drupal core Toolbar module had to go. It lacked any power features. At the time, Administration Menu (admin_menu) was nearly a given on any Drupal site we'd run across and any we developed.

Administration Menu module began to show its age, though. 

Server hardware has become less and less expensive, meaning we have a little less concern for just how many modules are integrated with a particular implementation. We use all sorts of technically unnecessary contributed modules, but which make life easier for developers, editors, or administrators. Menu items within the administration navigation proliferated. Administration Menu's tiling dropdown menus became less and less useful, sometimes extending beyond the height of the screen, making it impossible to reach the absolute positioned bottom items.

As mobile devices continued to gain a larger share of web browsing, they also become more than just consumptive devices. More and more, folks on iPads and other Tablets wanted to manage their sites. Smartphone users wanted to be able to make quick edits. They wanted to be productive. Administration Menu face planted when used on a small screen device. It was mobile-unfriendly.

Drupal's Module page is hard to use

The use case where Administration Menu shined before, also began to become a problem spot. Desktop screen sizes, more specifically, resolutions have continued to increase. Where a 1024x768 resolution monitor was common even only a few years ago, 1080p ("HD") is commonplace now. Pricing for even higher resolution monitors has come down drastically. All this means that the small fonts and spacing used in Administration Menu to help alleviate the screen real estate restrictions of an era of 1024x768 yield tiny fonts and difficult click targets on our Retina-era screens. 

Enabling the optional Administration Menu Toolbar Style module brought the menu back to the design style of the Drupal core Toolbar module. This brought back quick access to Shortcuts. It did help with larger fonts and click targets, but then didn’t mesh well with the tiling dropdowns. Even with this style, fonts and click targets which are static pixel sizes, continue to become a problem as screen resolutions increase.

Advantages of Drupal's mobile-friendly Navbar menu module

It was time to replace the aging Administration Menu module with a modern, mobile-friendly navigation system. The Navbar module, sprung to life from the Spark distribution initiative, brings a highly responsive, customizable navigation system to Drupal 7. 

The look and feel of Navbar is a direct backport of the Drupal 8 navigation system. Moving from Drupal 7 to Drupal 8 will be easier if site users are already familiar with Drupal 8’s navigation via Navbar in Drupal 7.

Navbar Requirements

The Navbar module has multiple JavaScript library dependencies. The Libraries module makes it easier to manage JavaScript libraries within Drupal for contributed modules. Libraries is also a dependency.

  • Libraries module (version >= 2.0)
  • Backbone JavaScript library (version >= 1.0)
  • Underscore JavaScript library (version >= 1.5)
  • Modernizr custom build (version >= 2.6.2)

Simplified workflow and process recognition with Navbar’s design

One of the first things you’ll notice about Navbar is its visual design. The iconography used is an attempt to create quick visual recognition of what each link represents for your site users. While you, as a frequent Drupal site builder, may have the Structure navigation system and location memorized, having a massive list of links with odd textual names is one of the turn-offs that new Drupal users experience. Users have two options for displaying Navbar’s sub-navigation elements.

1. Horizontal Navigation: They can be to display as a horizontal, left-right link list.

Drupal Navbar admin menu: horizontal menu

2. Vertical Navigation: They can also be displayed as a more traditional, left-aligned, top-bottom, list of links. In this configuration, further navigational children can be expanded with a click.

Drupal Navbar admin menu: vertical menu

This conscious choice of viewing navigational items is a consistent theme throughout Navbar. Administration Menu could produce scary looking, tiling, massive, dropdown navigational items as you scan the nav and children populate with hovers. Navbar requires a conscious decision to expand the menu tree.

This is where visual design can make a system more approachable. Larger fonts make each navigation item more readable. Spacing around the navigation items help make them more clickable (or tappable).

An aside for diehard Administration Menu users

If Administration Menu will be pried from your cold, dead hands but you want to have some sort of mobile-friendly experience, it's possible to combine the two. The Admin Menu Navbar project exists to provide the Administration Menu module for large screens and Navbar for small screens. Check it out to combine the best of both worlds.

Administration Menu's search plugin can help make exploring the menu system a bit easier. Be sure to enable it in the module's configuration to give yourself access to a quick menu search tool.

Workflow with Drupal Shortcuts

One of the features of the core Toolbar module I missed when converting to Administration Menu, is the visual focus on Shortcuts. While it’s certainly possible to use Shortcuts with Administration Menu, they’re second-class citizens within the navigation hierarchy. Toolbar gave Shortcuts a space to live in on the right side of the navigation. It’s not the most intuitive location for something that, by their very purpose, should be used frequently, but at least it highlights them. Administration Menu doesn’t even make them available by default. Shortcuts don’t get much love, and I think that’s because their accessibility and focus made them slower or difficult to use with incredibly popular Administration Menu.

Enter Navbar.

Drupal Navbar focus on Shortcuts menu

Navbar takes the treatment of Shortcuts and moves them up to first-class citizens within the navigation hierarchy. They’re front and [left aligned]. Shortcut’s iconography in Navbar instantly draws attention for non-technical content contributors; typical Internet users. That star icon calls to them:

What’s in this drawer? Is it an aptly named set of useful tools for me?

Ember works in concert with Navbar and Shortcuts. Administration pages and edit pages provide for a quick one-click button to add the page to the shortcuts listing. Just click the Star icon on the right to add the page to your shortcuts.

Drupal Ember theme quick add Shortcuts

Customize the Drupal administration experience for your clients and users. Put those bookmark-style frequently used links into the Shortcuts system. Will your editors need to constantly access the menu system, block system, or a specific node for their workflow? Perhaps they’ll frequently need to review a draft content queue. Add a Shortcut! This is where you can add value to the folks using the system you build: make their life easier. It’s a simple, yet often overlooked step.

Extras: manage modules, fields, and menus simply

While Ember and Navbar make up the backbone of a modern, mobile-friendly, Drupal 7 administration experience, there are a few extras we always include.

Disable the Drupal core Overlay module

You either love or hate Overlay.

drush dis overlay

This is one of the first commands I run on a new Drupal install, so I think you know where I stand. Sure, the idea that I can edit the site configuration from my current content page, may sound nice. I make my edits, I return to the content page I was on.

In practice, this doesn’t really work as planned. As I’m navigating through the configuration pages, making changes, clearing caches, submitting forms, the DOM ends having to be fully reloaded. That means that the configuration page reloads but also the content page under the overlay. You end up causing two page reloads, slowing down your work and adding some extra work to the server.

I don’t know about you, but I end up working in multiple browser tabs, anyway. This eliminates the use case for Overlay anyway. I end up refreshing the content page I started from (where I probably ran across an issue) in a separate tab, this way I can control when the refresh occurs and I can make a proper comparison.

In addition, Overlay, which is an AJAX-dependent (JavaScript) process, is known to cause issues with a variety of contributed modules that are JavaScript-heavy.

Disable Overlay.

Make browsing Drupal Modules easier with Module Filter

More serious Drupal developers rarely find themselves on the Modules page as they’re doing any module-related work with Drush in the command line. However, not everyone is a serious Drupal developer.

System Administrators and general Web Developers are often the folks who maintain Drupal systems. As much as we, as Drupal Developers, will push for the use of Drush, that Module list page will be used often.

The Modules page has a terrible user experience.

Drupal's Module page is hard to use

It’s information overload. There’s summary data (version, description, requirements) for every Drupal module available to the implementation. Larger implementations will have hundreds of these. Have you found yourself hitting CTRL+F (or, ⌘+F) to text search the page for the module name you’re looking for? Make your life easier. Help your colleagues.

Install Module Filter, a Drupal module.

What are the benefits of Module Filter?

  • JavaScript-powered instant text search
  • Filtering: show/hide Modules that are enabled, disabled, required, and more
  • Show recently added Modules
  • A more approachable, scan friendly list of basic Module information

Drupal's Module Filter module user experience

Improve the Drupal Field UI

This tweak is really for site builders as I suspect your site editors aren’t often going to be mucking with the Field UI.

I always found it irritating that Fields had an edit page and also a field settings page. Why not merge these two things? That’s exactly what Backports module does, a change backported from Drupal 8. It removes an extra step for you as you’re creating and editing your Content Type’s Fields.

Goodbye, Field Settings.

Simplify Drupal's Field UI with Backports Module from Drupal 8

Simplify Drupal Menu Administration

The Menu UI, just like the Field UI, seems to have a totally unnecessary extra step. When selecting edit menu why in the world can’t you edit the menu links? Really, how often are you changing the Menu name (which is what edit menu provides by default)?

The Simplified Menu Administration module merges the edit menu and list links options together. The merged edit menu page provides for naming as well as link resorting and modification.

Drupal 7 Edit Menu, Links with Simplified Menu Admin

The space that used to contain list links now provides a direct add link option for the specific menu.

Drupal 7 Quick Add Link with Simplified Menu Admin

If the site you’re building or editing has a large menu system, simplifying the Menu UI workflow can cut significant effort and frustration off your workflow. Combine this with a solid internal link strategy and you'll be in a good place managing your link strategy.

Modernize Drupal 7’s Administration System

Combining all these tools together, we create a modern Drupal 7 administration experience. This system of theme, modules, and libraries will improve site user workflow, expand device support, and generally make the system more approachable to site users.

Let’s bring it all together with a series of Drush commands:

drush dis overlay toolbar -y; drush vset admin_theme ember; drush en ember_support navbar backports module_filter simplified_menu_admin -y

With a quick copy+paste and enter, you’re on the way to creating value for the folks that pay the bills in the projects you build: the managers, contributors, and editors. As the man behind the Macintosh interface said:

As far as the customer is concerned, the interface is the product.
-Jef Raskin

Save them time, give them a better experience. Bring them a step closer to their inevitable Drupal 8 migrations, reduce that future heartache. Give them the ability to use the systems you build from more devices, simply.

Did you like this article or know a team in need of help with their Drupal administration workflow? Share it! Want to take Drupal administration and workflow to the next level? Hire our Drupal team for a completely customized experience!

Jul 09 2015
Jul 09

Drupal 7's administration interface and theme leaves much to be desired. The Seven administration theme, part of Drupal Core, has shown its age since Drupal 7's introduction years ago. Mobile devices have taken a large chunk of web traffic: webmasters want to be able to administer their Drupal sites from smaller screened devices like Tablets and Smartphones. You need a modern Drupal admin theme.

I have something to tell you.

I'm writing this very post from an iPad. Not only do our clients often want to have the ability for users to browse the anonymous, public portion of the website from mobile devices, but often they need to be able to add or edit content from one as well. The Daymuse website itself is in fact one such needy customer.

Drupal administration from any device

One of the greatest features of modern CMS is the ability to administer the system over the web from any location (which also happens to be its greatest security concern). Whether you're a traveling online entrepreneur, or just a hands-on executive who needs to be able to make minor content edits from a meeting on your phone, it's possible to setup Drupal 7 to work with your mobile device administration needs.

The combination of Drupal admin theme tools we use to provide mobile administration also happens to make the user interface far more approachable. It modernizes the design style, simplifies several common workflow processes, and generally stays out of the way of the real work: adding and editing content. This package of modules, theme, and libraries we use is nearly consistent across the sites we manage (Drupal 6 is still clinging on in some places).

Forward thinking administration for Drupal 8

We've curated this combination of systems with an eye for the Drupal 8 administration experience. That means, where possible, we attempt to utilize tools which are backports or offer similar experiences to the administration system within Drupal 8. In this way, the teams we work with, will be more prepared and familiar with Drupal 8 once the inevitable migrations occur from Drupal 7.

Let's get down to the meat of it and start with the core part of this elegant administration solution: the Drupal admin theme.

Ember: mobile friendly Drupal admin theme

Drupal admin theme - Ember

Ember is part of the Spark distribution, a Drupal distro specifically built in attempt to bring Drupal 8 features to the Drupal admin theme in 7. Unfortunately, the distribution as a whole, hasn't been updated much since its initial creation years ago. A few of the modules and tools within it, however, have blossomed on their own. Ember is one such piece.

The Ember Drupal admin theme replaces the Seven Drupal admin theme as the style and design presented to site administrators. It's been built from the ground up with responsive design. Ember has maintained its focus on being an excellent, mobile administration theme with similarities to the Drupal 8 administration theme. With each update, Ember continues to blaze the trail for a mobile friendly, quality user experience and Drupal admin theme.

Mobile Drupal Administration with Ember Theme

Ember Support: contributed module interface tweaks

If you've spent time using Drupal contributed modules, you'll have undoubtedly noticed that several modules diverge drastically from the style of the core admin theme, Seven, for their administration. Most module developers will test their module-specific administration experience against Seven. However, with Ember's incorporation of responsive design and a vast array of style changes, this can break edge case module administration experiences.

Rather than constantly add one-off module-specific tweaks and fixes to the Ember theme, a separate module has been created. Ember Support solves a variety of module-specific style issues. We recommend adding it to any Drupal site utilizing the Ember administration theme to ward off the more common module-specific issues, especially sites using the Panels module.

Mobile-friendly admin navigation with Navbar for Drupal 7

As much as we're fans of Ember for its mobile-friendly approach to Drupal administration, this doesn't solve a primary mobile device issue in the admin: navigation.

Here's one of the first sets of commands I would run on nearly every fresh Drupal 7 sites only a few years ago:

drush dis toolbar &amp;&amp; drush en admin_menu -y

The very basic Drupal core Toolbar module had to go. It lacked any power features. At the time, Administration Menu (admin_menu) was nearly a given on any Drupal site we'd run across and any we developed.

Administration Menu module began to show its age, though. 

Server hardware has become less and less expensive, meaning we have a little less concern for just how many modules are integrated with a particular implementation. We use all sorts of technically unnecessary contributed modules, but which make life easier for developers, editors, or administrators. Menu items within the administration navigation proliferated. Administration Menu's tiling dropdown menus became less and less useful, sometimes extending beyond the height of the screen, making it impossible to reach the absolute positioned bottom items.

As mobile devices continued to gain a larger share of web browsing, they also become more than just consumptive devices. More and more, folks on iPads and other Tablets wanted to manage their sites. Smartphone users wanted to be able to make quick edits. They wanted to be productive. Administration Menu face planted when used on a small screen device. It was mobile-unfriendly.

Drupal's Module page is hard to use

The use case where Administration Menu shined before, also began to become a problem spot. Desktop screen sizes, more specifically, resolutions have continued to increase. Where a 1024x768 resolution monitor was common even only a few years ago, 1080p ("HD") is commonplace now. Pricing for even higher resolution monitors has come down drastically. All this means that the small fonts and spacing used in Administration Menu to help alleviate the screen real estate restrictions of an era of 1024x768 yield tiny fonts and difficult click targets on our Retina-era screens. 

Enabling the optional Administration Menu Toolbar Style module brought the menu back to the design style of the Drupal core Toolbar module. This brought back quick access to Shortcuts. It did help with larger fonts and click targets, but then didn’t mesh well with the tiling dropdowns. Even with this style, fonts and click targets which are static pixel sizes, continue to become a problem as screen resolutions increase.

Advantages of Drupal's mobile-friendly Navbar menu module

It was time to replace the aging Administration Menu module with a modern, mobile-friendly navigation system. The Navbar module, sprung to life from the Spark distribution initiative, brings a highly responsive, customizable navigation system to Drupal 7. 

The look and feel of Navbar is a direct backport of the Drupal 8 navigation system. Moving from Drupal 7 to Drupal 8 will be easier if site users are already familiar with Drupal 8’s navigation via Navbar in Drupal 7.

Navbar Requirements

The Navbar module has multiple JavaScript library dependencies. The Libraries module makes it easier to manage JavaScript libraries within Drupal for contributed modules. Libraries is also a dependency.

  • Libraries module (version >= 2.0)
  • Backbone JavaScript library (version >= 1.0)
  • Underscore JavaScript library (version >= 1.5)
  • Modernizr custom build (version >= 2.6.2)

Simplified workflow and process recognition with Navbar’s design

One of the first things you’ll notice about Navbar is its visual design. The iconography used is an attempt to create quick visual recognition of what each link represents for your site users. While you, as a frequent Drupal site builder, may have the Structure navigation system and location memorized, having a massive list of links with odd textual names is one of the turn-offs that new Drupal users experience. Users have two options for displaying Navbar’s sub-navigation elements.

1. Horizontal Navigation: They can be to display as a horizontal, left-right link list.

Drupal Navbar admin menu: horizontal menu

2. Vertical Navigation: They can also be displayed as a more traditional, left-aligned, top-bottom, list of links. In this configuration, further navigational children can be expanded with a click.

Drupal Navbar admin menu: vertical menu

This conscious choice of viewing navigational items is a consistent theme throughout Navbar. Administration Menu could produce scary looking, tiling, massive, dropdown navigational items as you scan the nav and children populate with hovers. Navbar requires a conscious decision to expand the menu tree.

This is where visual design can make a system more approachable. Larger fonts make each navigation item more readable. Spacing around the navigation items help make them more clickable (or tappable).

An aside for diehard Administration Menu users

If Administration Menu will be pried from your cold, dead hands but you want to have some sort of mobile-friendly experience, it's possible to combine the two. The Admin Menu Navbar project exists to provide the Administration Menu module for large screens and Navbar for small screens. Check it out to combine the best of both worlds.

Administration Menu's search plugin can help make exploring the menu system a bit easier. Be sure to enable it in the module's configuration to give yourself access to a quick menu search tool.

Workflow with Drupal Shortcuts

One of the features of the core Toolbar module I missed when converting to Administration Menu, is the visual focus on Shortcuts. While it’s certainly possible to use Shortcuts with Administration Menu, they’re second-class citizens within the navigation hierarchy. Toolbar gave Shortcuts a space to live in on the right side of the navigation. It’s not the most intuitive location for something that, by their very purpose, should be used frequently, but at least it highlights them. Administration Menu doesn’t even make them available by default. Shortcuts don’t get much love, and I think that’s because their accessibility and focus made them slower or difficult to use with incredibly popular Administration Menu.

Enter Navbar.

Drupal Navbar focus on Shortcuts menu

Navbar takes the treatment of Shortcuts and moves them up to first-class citizens within the navigation hierarchy. They’re front and [left aligned]. Shortcut’s iconography in Navbar instantly draws attention for non-technical content contributors; typical Internet users. That star icon calls to them:

What’s in this drawer? Is it an aptly named set of useful tools for me?

Ember works in concert with Navbar and Shortcuts. Administration pages and edit pages provide for a quick one-click button to add the page to the shortcuts listing. Just click the Star icon on the right to add the page to your shortcuts.

Drupal Ember theme quick add Shortcuts

Customize the Drupal administration experience for your clients and users. Put those bookmark-style frequently used links into the Shortcuts system. Will your editors need to constantly access the menu system, block system, or a specific node for their workflow? Perhaps they’ll frequently need to review a draft content queue. Add a Shortcut! This is where you can add value to the folks using the system you build: make their life easier. It’s a simple, yet often overlooked step.

Extras: manage modules, fields, and menus simply

While Ember and Navbar make up the backbone of a modern, mobile-friendly, Drupal 7 administration experience, there are a few extras we always include.

Disable the Drupal core Overlay module

You either love or hate Overlay.

drush dis overlay

This is one of the first commands I run on a new Drupal install, so I think you know where I stand. Sure, the idea that I can edit the site configuration from my current content page, may sound nice. I make my edits, I return to the content page I was on.

In practice, this doesn’t really work as planned. As I’m navigating through the configuration pages, making changes, clearing caches, submitting forms, the DOM ends having to be fully reloaded. That means that the configuration page reloads but also the content page under the overlay. You end up causing two page reloads, slowing down your work and adding some extra work to the server.

I don’t know about you, but I end up working in multiple browser tabs, anyway. This eliminates the use case for Overlay anyway. I end up refreshing the content page I started from (where I probably ran across an issue) in a separate tab, this way I can control when the refresh occurs and I can make a proper comparison.

In addition, Overlay, which is an AJAX-dependent (JavaScript) process, is known to cause issues with a variety of contributed modules that are JavaScript-heavy.

Disable Overlay.

Make browsing Drupal Modules easier with Module Filter

More serious Drupal developers rarely find themselves on the Modules page as they’re doing any module-related work with Drush in the command line. However, not everyone is a serious Drupal developer.

System Administrators and general Web Developers are often the folks who maintain Drupal systems. As much as we, as Drupal Developers, will push for the use of Drush, that Module list page will be used often.

The Modules page has a terrible user experience.

Drupal's Module page is hard to use

It’s information overload. There’s summary data (version, description, requirements) for every Drupal module available to the implementation. Larger implementations will have hundreds of these. Have you found yourself hitting CTRL+F (or, ⌘+F) to text search the page for the module name you’re looking for? Make your life easier. Help your colleagues.

Install Module Filter, a Drupal module.

What are the benefits of Module Filter?

  • JavaScript-powered instant text search
  • Filtering: show/hide Modules that are enabled, disabled, required, and more
  • Show recently added Modules
  • A more approachable, scan friendly list of basic Module information

Drupal's Module Filter module user experience

Improve the Drupal Field UI

This tweak is really for site builders as I suspect your site editors aren’t often going to be mucking with the Field UI.

I always found it irritating that Fields had an edit page and also a field settings page. Why not merge these two things? That’s exactly what Backports module does, a change backported from Drupal 8. It removes an extra step for you as you’re creating and editing your Content Type’s Fields.

Goodbye, Field Settings.

Simplify Drupal's Field UI with Backports Module from Drupal 8

Simplify Drupal Menu Administration

The Menu UI, just like the Field UI, seems to have a totally unnecessary extra step. When selecting edit menu why in the world can’t you edit the menu links? Really, how often are you changing the Menu name (which is what edit menu provides by default)?

The Simplified Menu Administration module merges the edit menu and list links options together. The merged edit menu page provides for naming as well as link resorting and modification.

Drupal 7 Edit Menu, Links with Simplified Menu Admin

The space that used to contain list links now provides a direct add link option for the specific menu.

Drupal 7 Quick Add Link with Simplified Menu Admin

If the site you’re building or editing has a large menu system, simplifying the Menu UI workflow can cut significant effort and frustration off your workflow. Combine this with a solid internal link strategy and you'll be in a good place managing your link strategy.

Modernize Drupal 7’s Administration System

Combining all these tools together, we create a modern Drupal admin theme experience. This system of theme, modules, and libraries will improve site user workflow, expand device support, and generally make the system more approachable to site users.

Let’s bring it all together with a series of Drush commands:

drush dis overlay toolbar -y; drush vset admin_theme ember; drush en ember_support navbar backports module_filter simplified_menu_admin -y

With a quick copy+paste and enter, you’re on the way to creating value for the folks that pay the bills in the projects you build: the managers, contributors, and editors. As the man behind the Macintosh interface said:

As far as the customer is concerned, the interface is the product.
-Jef Raskin

Save them time, give them a better experience. Bring them a step closer to their inevitable Drupal 8 migrations, reduce that future heartache. Give them the ability to use the systems you build from more devices, simply.

Did you like this article or know a team in need of help with their Drupal administration workflow? Share it! Want to take Drupal administration and workflow to the next level? Hire our Drupal team for a completely customized experience!

Jun 09 2015
Jun 09

Last week's tutorial on Drupal Facebook comments integration lead our blog to traffic records and a mention on TheWeeklyDrop among other places. There's a lot of demand from Drupal website owners and managers to integrate Facebook with their website platform. Today, we're going to work through another of the most requested Facebook integration needs: login and connect.

One of the experiences that most irritate users of your website is having to create yet another account just to access your website or key functionality of it. The user now has to keep track of another username or email and password combination. If you require a unique login to your website, you're going to discourage some users from using your website.

Make it easy for your Drupal users: login with Facebook

A common solution to this poor experience in recent years is to suggest the user logs in via an account on a third-party website. Commonly, this is a social media account: Twitter, Google+, Facebook, etc. Most internet users have one of these accounts, and, among them, Facebook has the largest user base. Allowing users to login with their Facebook account is often the first third-party login system website owners or managers wish to integrate with their Drupal websites.

The negative side of allowing users to login with a third-party account, such as Facebook, is that their login has now become dependent on a third-party. As unlikely as it is for Facebook to go belly up anytime soon, it is possible. Massive social networks have collapsed quickly in the past (see: MySpace). 

The Drupal Content Management System (CMS) provides multiple methods to authenticate Drupal users with Facebook accounts through contributed modules. Let's work through what I think is the best candidate for setting up a simple Drupal Facebook login: Simple FB Connect module.

Drupal user authentication with Facebook using Simple FB Connect module

To integrate a simple Facebook login and authentication system for Drupal, my choice for this tutorial is the appropriately named Simple FB Connect module. The module operates under the premise that all you want to do with it is allow users to login with their Facebook accounts: nothing more, nothing less. This module has very few configuration options and certainly doesn't integrate as deeply with Facebook and Drupal as some other login-related modules do. There's no way to pull additional account details from Facebook and add their data to custom user fields in Drupal here. 

The Simple FB Connect module simply allows users to click a login link which syncs their Facebook data (after authentication) with a new Drupal user account. Their Facebook email address and profile photo will be added to their Drupal user account. The module works with the Drupal core account settings options of allowing users to create accounts with or without a secondary verification email or acceptance from an administrator account. Disabling a second verification level means that users can login with their Facebook account instantly and have access to your site.

Support for Simple FB Connect and Drupal 8

Updated July 7, 2017

One of the key reasons I'm using the Simple FB Connect module in this tutorial is that it is well supported with recent updates and rising usage statistics. In addition, the module supports Drupal 8 and has a full release available. I'll discuss alternative modules for Facebook authentication later in this tutorial.

The process outlined below is for Drupal 7 but is quite similar regarding the Drupal 8 release of Simple FB Connect. The key difference is in the installation process which is dependent on Composer. Our first Drupal 8 based tutorial revolves around the installation of Simple FB Connect and helps outline the specific details.

Setup Simple FB Connect module for Drupal Facebook login

Let's work through the steps of integrating the Simple FB Connect module with your Drupal website to allow Facebook user account authentication. First, we need to download our module and related dependencies.

  1. Download the Simple FB Connect module from its Drupal project page
    Note: I would suggest using the 7.x-2.x version which is in Beta at the time of writing; the 2.x branch integrates the latest Facebook Connect API
  2. Download and enable the dependencies (required for the 7.x-2.x+ versions of Simple FB Connect): 
    1. X Autoload module from its Drupal project page
    2. Libraries API module from its Drupal project page
    3. Facebook PHP SDK version 4.0.x PHP library from its Github project page
      Note: put the library in a "sites/all/libraries/facebook-php-sdk-v4" folder; I'm using version 4.0.23 in this tutorial

After enabling the module and dependencies, head to the config page (/admin/config/people/simple-fb-connect​) for Simple FB Connect.

Simple FB Connect Module Configuration

Phew, for a module with "Simple" in the title, it sure has a lot of dependencies! Integrating with third-party services is rarely straightforward. It might be time for a drink, there's more to do.

On the configuration page, you'll notice a few blank fields which are required (and I've filled in the above screenshot). You'll need a Facebook App ID and App Secret. You'll want to setup a Facebook Connect URL as well for security purposes. The field should be pre-filled on the configuration page with your site URL. We'll use this later. As the help text suggests, you'll need to create a Facebook App in order to get these pieces of data.

I have to create an entire Facebook App just to setup Drupal login for Facebook users?!

I know, it sounds like a lot of work. Fortunately, it's just a couple of steps. You can create the App with a personal Facebook account or a public Facebook page. Follow the link on the configuration page above to the Facebook app starter.

Create a Facebook App to support your Drupal Facebook login module

Let's run through creating the necessary basic app to allow Drupal website logins with Facebook. It's only a few steps. From the starter page, hit "Create a New App". You'll be prompted to fill out some basic App information. Here's how I filled out the App fields for this tutorial:

Create a Facebook App for a Drupal website

Hit "Create App ID" and you'll be prompted with a security question and/or Facebook verification process. You may need to add a credit card or walk through a mobile phone verification process to prove to Facebook you're a real person. As an additional step, I had the pleasure of proving my humanity by clicking on fireworks photos. I suppose Independence Day is less than a month away in the U.S., but I digress.

The subsequent landing page will show a dashboard which contains your App ID and App Secret (hidden). It will also reveal the API Version of your app which may be useful to be sure your module is compatible with the Facebook App.

Facebook App ID and App Secret for Drupal

Show the App Secret and paste these two data points into your Simple FB Connect configuration page's appropriate fields.

Next, hit "Settings" in the left menu panel of the Facebook App. On the Settings page, add a new Website platform.

Facebook App Connect URL Settings for Drupal Simple FB Connect module tutorial 

After adding the new Website platform, two fields will appear:

  1. Site URL
  2. Mobile Site URL

Fill both of these fields with the URL from the Simple FB Connect module's configuration page's "Connect url" field data as I did in the screenshot. Save your changes.

Configure your Drupal website to accept Facebook logins

Now we have our Facebook login module installed and setup alongside our Facebook app. The last major step to having a working Facebook login system on your Drupal website is to configure your account settings appropriate to your goals. For this tutorial, I just want users to be able to instantly sign in with their Facebook account, creating a Drupal account automatically with their Facebook credentials in the background.

  1. Go to Drupal's Account settings page (/admin/config/people/accounts).
  2. Under Registration and cancelation → "Who can register accounts?", tic the "Visitors" option
  3. Hit "Save configuration" at the bottom of the page

Facebook User Account Settings config for Drupal login

This will allow any anonymous visitor to create an account on your Drupal website without approval from an administrator. The "Require e-mail verification" option will not force Facebook users to also authorize an email, so you can leave this checked to help keep out the auto registration spam bots (hopefully you're doing a few other things to keep the spammers out, too).

You can keep the "administrator approval is required" option active if you wish, but you will have to manually unblock every Facebook user account before they can use your site. This will generally discourage new users from making using of your member section, take this into consideration for your website strategy.

Login to your Drupal website with your Facebook account

Now that all the pieces are in place, test your Facebook login process with your own account credentials. Logout of your administrator account and visit your Drupal login page (/user). You should see a new tab or link to "Register/Login with FB".

 Register or Login with Facebook

Hit the link to begin the Drupal login with Facebook process. If you don't see this link, try clearing your Drupal website's cache. If you still don't, double check you've completed all the above steps correctly. If there's a warning or error message shown, it will offer up some clues as to what you might have missed. If you still can't get it working, feel free to ping us on Twitter or consider hiring the experts to integrate Facebook with your Drupal website.

Be sure you're logged into your own Facebook account in the browser session you're testing with. If all goes well, you should see a pop-up on Facebook requesting authorization to associate your account with the Facebook App you created earlier.

Facebook App authorize Drupal login

Hit "Okay" and you should be redirected back to your Drupal website user page, logged in. The username should be populated with your Facebook name, your email appropriately synced, and your picture shown as your Drupal profile photo.

Facebook data fields on Drupal user profile

While the module is called "Simple FB Connect", there are a lot of steps to setting up the Facebook authentication and login system as a whole. You'll need to not only configure the module and related dependencies, but also a Facebook App and your website's user account settings.

Once done, you'll be able to offer your users a seamless login and account creation service for those that wish to use their Facebook account details to login. This can dramatically improve the user experience as opposed to requiring them to create yet another user profile on yet another website.

Alternative Drupal Facebook login modules

The Simple FB Connect Drupal module is one of the easier, modernized, Drupal and Facebook login integration modules available. There are of course several other choices:

  1. Facebook OAuth (FBOAuth)
  2. Facebook Connect
  3. OAuth Connector
  4. Hybrid Auth Social Login

I wanted to talk about a few of these as they each have interesting differences. Depending on your use case, one may be a much better choices for your implementation—especially if you intend to integrate other social network login systems.

Drupal's Facebook OAuth (FBOAuth) module

This module deserves special attention. In many ways, FBOAuth actually offers a simpler setup process than Simple FB Connect. It has less dependencies (well, none). It'll even work with a few profile related modules so that you can integrate Facebook user data fields further with your own custom user data fields in Drupal.

FBOAuth's setup process is very similar to Simple FB Connect: install the module, setup a Facebook app, copy the Facebook app credentials into the module configuration, and you're nearly off and running. All you really need to do beyond that is setup a location for the actual login button which can be a block or some PHP to print the button in a template file. Here's a screenshot of how I setup FBOAuth on the same website after disabling the Simple FB Connect module and adding the FBOAuth's login block to the content area:

FBOAuth module for Drupal Facebook login authentication

Note the "F Connect" blue button under the "Log in" button. The FBOAuth module is quite easy to setup, especially after already going through the process of creating a Facebook App. It may fit your use case better if you need to integrate a few custom user fields with Facebook data (perhaps importing the Facebook user's "About" details to a custom "Bio" field for Drupal users).

The primary reason I didn't base this tutorial around FBOAuth is that Simple FB Connect, for the purpose of merely offering a Facebook login process in Drupal, seems to be aiming towards future compatibility. FBOAuth doesn't yet have a roadmap for Drupal 8 support. In addition, while it makes the setup process slightly harder, the Simple FB Connect relies upon Facebook's PHP library. Hopefully this means the module team will be able to keep pace with Facebook API changes. This has been evident with their release history and presumably the team will continue to keep up.

Still, the FBOAuth module is backed by a very well known Drupal-focused company and the module has been around for some time. It has additional features and is quick to setup. Don't be afraid to give it a whirl if it fits your use case better. The move to Drupal 8 production sites is still probably years away for the majority of the Drupal web.

Multiple social media accounts with Hybrid Auth Social Login or OAuth Connector modules

If you just want to add a single additional login system (perhaps Twitter), you still might be best off with sticking to Simple FB Connect or FBOAuth plus a related Twitter login module. Beyond that, consider a more multi-purpose tool. If your intention is to integrate other social media platforms as addition login options, it's probably best to utilize a non-Facebook focused module.

I've setup OAuth Connector a few times in recent projects and I can tell you it's a difficult process. It works, and it's flexible to allow logins with several social networks that support OAuth, but it really can be a pain to configure the credentials and integration points for each platform. OAuth Connector is the best choice for a more flexible login integration system or for platforms that aren't supported by other modules.

Use Hybrid Auth Social Login module for multi-login Drupal

Hybrid Auth Social Login module for Drupal - Facebook

For multiple social network login Drupal setups, I tend to implement Hybrid Auth Social Login module. The team behind it have done an amazing job of keeping all the related social network login integration up to date as APIs have changed over the years. We have sites that have been using Hybrid Auth for years without trouble, even as platforms update and deprecate API versions.

If there's interest, I may do a tutorial on Hybrid Auth Social Login module in the future. I think it's a great tool. Ping us on Twitter if you'd like that.

Improving User Experience with Third Party Drupal Logins like Facebook

Remember, the primary reason you're integrating any social media login system is to improve the user experience for your users. Keep this in mind as you're considering how to configure the related user permissions and workflow. If you're attempting to build a community around your Drupal website or app, keep that at the forefront of your decisions. A little more effort maintaining systems and avoiding spam on your end can go a long way to giving users the quick login experience they expect.

Your Drupal Facebook login process should be part of your larger strategy to integrating the social network. Read our tutorial on setting up Facebook commenting integration from last week and keep an eye out for more Drupal Facebook integration tutorials coming.

  1. Drupal Facebook Comments
  2. Drupal Facebook Login
  3. Drupal Facebook Feed
  4. Drupal Facebook Like

If you're interested in thoroughly integrating Facebook with your Drupal website strategy through professional services, reach out. Think this tutorial is useful? Don't forget to share!

Jun 02 2015
Jun 02

There's a confusing array of comment or discussion modules available for Drupal. While the core Comment module is functional for a basic website, it does require further work to prevent spam, apply your design style, and adapt for mobile use. This can be avoided by using one of the many social media based comment modules. These modules allow integration of Drupal comments with an existing social media platform. One of the most popular is, of course, Facebook. It's fairly straightforward to setup Facebook Comments on a Drupal website.

Why use Facebook Comments on a Drupal website?

We like the Disqus module integration for comments on Drupal websites at Daymuse. However, it lacks a key value proposition that Facebook Comments offer and that's sharing. Facebook Comments allow (and set by default) users to share their website comments with their friends.

Unless the commenter alters the default setting, any comment on a website will be shared with the commenter's friends along with a link to the relevant page. Their comment and your website may appear in their friend's News Feed. That's a big boon for increasing your website's reach if you have an active audience.

Drupal Facebook Website Comments Share to News Feed

The downside is of course that if you solely use Facebook Comments as your discussion platform on your website (and it may be awkward to use multiple commenting systems), you'll limit your commenting audience to Facebook members. While most internet users do have Facebook accounts—limiting the downside to this requirement—only a subset will willingly comment using their personal identities on public websites. This is the cost of using Facebook as your Drupal website commenting system.

Drupal Facebook Comments Social Plugin Module

Facebook allows developers to integrate a comment discussion thread on webpages by way of the Comments Plugin. The plugin allows Facebook users to comment on webpages using their Facebook account. In addition, the plugin allows the comment (and webpage which was commented on) to be shared to their friends' News Feed.

Facebook's Comments Plugin also contains moderation tools that can be utilized through the Facebook site. There's some customization of how the Comments Plugin will appear on your webpages, too.

This Comments Plugin can be integrated with Drupal by way of a few different Drupal modules. I've tested these modules over the years and have settled on the Facebook Comments Social Plugin module as my go-to solution for Facebook comments in Drupal. The Facebook Comments Plugin and Facebook's APIs change frequently which means ideally Drupal would have a module available that kept pace with the updates. Unfortunately, the Drupal Facebook-related modules tend to be rarely updated. Still, the Facebook Comments Social Plugin module tics the necessary boxes to get Facebook comments running on your site. It will integrate comments with certain Content Types, allow configuration changes, and adjust the appearance of the comments. It provides a basic Facebook commenting solution.

Facebook Comments Social Plugin module configuration

Let's look at the install and setup process for the Facebook Comments Social Plugin Drupal module.

Download and install the module from the Drupal project page for Facebook Comments Social Plugin. There are no dependency modules. In order to create mobile friendly, responsive design comment threads, I'm using the dev version of the module. If you need responsive comment threads, be sure to use the dev version. The stable/suggested version, as of the time of writing, doesn't yet correctly support responsive design or mobile friendly comment threads.

Here's a one-liner for Drush to grab the stable/suggested version:

drush en facebook_comments -y

The dev version I am using in this tutorial is 7.x-1.0-beta2+6-dev. After installing, head to the config page (/admin/config/content/facebook-comments). 

Reconfigure the settings options to match your use case. Let's review some of the options and what they mean along with some advice for each.

Color Scheme

The color scheme option allows you to align the display of the comments with the general colors of your Drupal theme.

Light Color Scheme

Most folks are going to stick with the Light color scheme. It looks like the comment threads you've most likely seen. It's primarily white based with a light gray box and a dash of Facebook's blue.

Drupal Facebook Comments Light Color Scheme

Dark Color Scheme

The dark color scheme is more rarely used—I've yet to run across it on a production Drupal site. A bit of a tangent, but it's a shame that so many websites focus on white color schemes as it's so harsh on the eyes at night. The module's Dark color scheme is great if you offer an inverse or nighttime mode on your site. You could activate the color scheme through some JavaScript alongside your normal nighttime mode activation process.

Drupal Facebook Comments Dark Color Scheme

View mode

The View mode option allows you to set where or when the Facebook comments will display. Most likely you'll want this set to "Full node". This means that the Facebook comments will only display on a full node page (e.g. /node/23). You can also display the comments on Teaser view modes or both Teasers and Full nodes. Rarely do you want to display comments on something like a listing page that has a several node teasers, but it's an option.

Facebook comment plugin width (nodes)

If you've opted for the dev version of the module, now is the time to setup a fluid width to support your responsive design. Despite the help text suggesting a pixel-based width, enter "100%". You'll also want to tic the checkbox just below the width entry: "Fluid Facebook comment plugin width (nodes)".

If you need the comments box to be a static width, set the total pixel width desired for the comment thread area.

Facebook comment plugin width (block)

Follow the same process as you did for the nodes width above for the blocks. This is only relevant if you intend to show Facebook comments within blocks. Leave the default setting if you're not.

Be sure to set the total comment count to display in the block with the "Amount of comments to display (block)" option directly below, too.

If you intend to have mobile friendly Facebook comments through responsive design, you will have trouble displaying them on individual node pages by way of a block. Instead, use the nodes option above.

Facebook App ID

This step is unnecessary if you just want to get started with integrating Facebook comments in Drupal. Later, you can create a Facebook App and then set the App ID here in order to group moderate comments through Facebook itself. Without doing so, comment moderation within Facebook will be more manual and slower, but it's one less thing to get bogged down with while you're just trying to get started.

Facebook Comment App Moderation

If you really want to create a Facebook App, you can get started with a Facebook website app (www App). You'll just need the App ID after creation.

Facebook comment default Content Types

Presumably you're adding comments to an existing Drupal website with existing Content Types. Tic each Content Type you wish to have Facebook Comments appear with.

Important: in order for Facebook Comments to appear on existing content, be sure to tic the "Enable Facebook comments on existing content for the selected content types" option. This will process some database updates on save to apply the comments on existing content. The box itself will not remain checked when you revisit the config page.

Enable Facebook Comments Display on Nodes or Blocks

Once you've sorted out your config options, hit save.

Navigate to each content type you've enabled Facebook comments on and their Manage Display option. Be sure the Facebook comments field appears visible for the Content Type.

Drupal Facebook Comments Hidden or Visible on Nodes via Content Type

If you're using Facebook comments in blocks, be sure to navigate to the block configuration page. Set the now accessible block display into a region of your theme.

Similarly, if you're using the Context module to administer block display, be sure to add the newly available Facebook Comments block to the applicable Context display.

Facebook Comments Testing

If you've added comments to existing nodes, navigate to a node of a Content Type you've enabled and verify the comment thread is appearing. If they're not, double check your settings.

Sometimes clearing your Drupal site's cache is needed. If you're still having trouble, we do offer Drupal consulting services.

Facebook Comments in Templates (TPL Files) and Theme

You can control Facebook comments on nodes within a node.tpl.php file. Depending on your theme, the process will vary a bit but generally you control the output of the comments so as to manually display them within a particular section of your node.tpl.php template. Facebook comment styling can also be controlled, somewhat, through your CSS.

If you want to control the output of the Facebook Comments section with your node.tpl.php you can use this code:

&lt;?php if (isset($content['facebook_comments'])): ?&gt;
&lt;div class="clearfix facebook-comment-wrapper"&gt;
&lt;?php print render($content['facebook_comments']); ?&gt;
&lt;/div&gt;
&lt;?php endif; ?&gt;

This PHP code will give you a good baseline to get started with more advanced control of the Facebook Comments integration on nodes through your template. I've added two unnecessary CSS classes to the wrapping element: clearfix and facebook-comment-wrapper. If your theme has a clearfix class (and most modern ones do, we love Omega for responsive design), this will help set your comments in the right position relative to your content and prevent overlapping sections. Feel free to experiment with removing it. You can use the facebook-comment-wrapper class to apply relevant CSS to the container. Both of these classes are technically unnecessary.

This code will first check to see if the Facebook Comments array value is set and then render them if they are. This should be added to your node.tpl.php if you're manually outputting your fields on your nodes with a template file. Otherwise, the Manage Display field option mentioned earlier should handle the output of Facebook Comments on nodes.

Facebook Comments alternative Drupal Modules

There's more than just the Facebook Comments Social Plugin module to integrate Drupal with Facebook Comments. The Facebook Comments Box module provides similar functionality. However, I ran into some integration issues. Unfortunately, both of the two major Facebook Comments modules for Drupal haven't been update in a long while.

Drupal Facebook Integration Tutorial Series

Integrating Facebook comments on your site can offer great value to your users: if they're already logged in to Facebook, they can quickly comment on your articles and pages. If they wish, they can share the comment (and your page) to their friends, which can help share your content and generate traffic. The downside is of course that it requires your readers to have a Facebook account in order to comment.

Remember, commenting is primarily to help build a community and a running discussion on your website. Think about your users and the type of platforms they're likely on before opting to integrate comments. Facebook comments are best integrated on website that cater to a casual, friendly audience where individual personalities can shine through.

This post is the first in a series on integrating Facebook with your Drupal website. We'll also be working through:

  1. Drupal Facebook Comments
  2. Drupal Facebook Login
  3. Drupal Facebook Feed
  4. Drupal Facebook Like

Stay tuned for more!

If you're interested in thoroughly integrating Facebook with your Drupal website strategy through professional services, reach out. Think this tutorial is useful? Don't forget to share!

May 21 2015
May 21

Broken links suck. It's incredibly frustrating to read a great article that links to an external resource that covers a subtopic in detail only to find the link is broken. In that moment I curse whatever developer or webmaster of the external site didn't think that creating a 301 redirect was worth the effort. I end up going to the root domain to hunt for the article by topic, hopefully the link text or URL slug gives enough topic or keyword clues to find it. Sometimes the external resource is gone completely and then I'm off to Archive.org to try to find a cached copy.

You know what's worse than a broken external link for your Drupal site? A broken internal link.

A broken internal link is a slap in the face for user experience. You didn't create a 301 redirect from the old URL to a relevant new URL. You didn't update the link you have control over. Do you care about your reader's experience at all? I want to help you prevent broken internal links in your Drupal sites and show you a process to automate link updates. Don't slap your users, follow this process!

What are internal links

Internal links are simply links which are to URLs on the same domain or website. For example, this is an internal link to our Drupal CMS guides. The link is to a page on the Daymuse.com domain from a page on the Daymuse.com domain. We have full control over both the link href (an anchor attribute which creates a hyperlink, the link destination URL) and linking page. The opposite, external links, are simply links to a different domain. You don't have any control over the link destination.

Why internal links are important in Drupal

Inbound links (external links on other sites to your site) are important to build domain authority for SEO, improving search rankings. Similarly, internal links help create content relationships within your site and give context to content through their link text.

Sidenote: Search engines account for internal link anchor text. Ideally, you don't want anchor text to simply say "click here", "more", or some other non-contextual, non-descriptive anchor text.

How to create internal links in Drupal body text

The primary way you'll create Drupal internal links is through body text on pages. More than likely, your WYSIWYG offers a link button that'll pop-up a dialog to input a link URL. This gives you a few methods to create internal links.

Absolute internal links

If you create a link with a fully qualified URL (the complete http(s)://subdomain.domain.extension/page-name), that's an absolute link. No part of the link is "variable", its destination will forever be the exact URL you've input. If any part of the destination URL were to change in the future, your absolute links will become broken. You'll need to manually update them.

Relative internal links

You can create links that are relative to the linking page. There's a few methods of creating these relative internal links.

If you were to simply add the href of "page-name-2" to a link from a page at this URL:

http(s)://subdomain.domain.extension/topic/page-name

The href would be relative to the current location and so the link will actually go to:

http(s)://subdomain.domain.extension/topic/page-name​-2 

The link destination will retain the depth, and target a sibling page ("page-name-2" within /topic/).

You could also link to a page on the current domain from the top level by using a leading forward slash. If your link href was set to "/page-name-2" in the above example, with a leading forward slash, your destination would become: 

http(s)://subdomain.domain.extension/page-name​-2

The forward slash causes the hierarchy to collapse, leading from the top level domain: "/topic" is dropped.

There's some additional advanced methods of creating internal links in HTML documents, but this should give you an idea of how they work. In essence, they create variables so that your links will work when certain conditions change. If your domain name were to change but your content hierarchy remained the same, your relative links would still have destinations that match your hierarchy and become relative to the new domain name. This gives you more flexibility than absolute internal links, but it's still not the best method.

Canonical internal links

Drupal's internal URL scheme creates canonical locations for content. These are the "non-pretty" URLs. Drupal's node system is reflected in these internal URLs:

http://www.domain.com/node/&lt;nid&gt;

In this scheme, the <nid> represents the internal node ID (a unique identifying integer) for a particular piece of content. This works similarly for Drupal's taxonomy and term system:

http://www.domain.com/taxonomy/term/&lt;tid&gt;

The <tid> is the term ID, identifying a taxonomy term. Using our example above, this is the canonical URL to our Drupal CMS guides:

http://www.daymuse.com/taxonomy/term/23

The "Drupal CMS guides" term ID is 23. If you inspect or hover the actual link above, you'll see that the URL is pretty, human readable:

http://www.daymuse.com/guide/drupal

We've setup Drupal to have an alias for "/guide/drupal" to display our "Drupal CMS guides" term. Drupal creates these pretty aliases by default ("clean URLs"). 

However, this is the literal HTML code that Drupal stores for that body text internal link:

&lt;a href="https://www.daymuse.com/taxonomy/term/23"&gt;Drupal CMS guides&lt;/a&gt;

This is a relative internal link to a canonical URL. Our WYSIWYG is configured to translate these internal canonical URLs to their pretty aliases on the fly. This takes care of multiple issues:

  1. If we were to decide to change our domain or store this blog post on a subdomain, the relative link would automatically reflect the domain change
  2. If we were to alter the alias from "/guide/drupal" for this particular term to "/guides/cms/drupal", the canonical URL would point to the appropriate pretty URL

This works the same way for nodes: if we link to their canonical URL and their alias is updated, Drupal will automatically translate the canonical URL to the new pretty URL on the fly. Tracking down the canonical URL manually for each internal link can be a pain, though. We're getting to automating the internal link creation process, but first let's make sure we understand why it's important.

Why creating Drupal canonical internal links is important

As your Drupal website develops, you'll undoubtedly create more content: more nodes, more terms. You'll also come up with new URL strategies and ways to classify your content through the pieces of your URLs. Perhaps you'll decide to add a portion of the date within the URL, maybe a category the content resides in, or you just want to manually alter a piece of content's URL to make it shorter or better reflect the contents. This will happen over time. When it does, you don't want to either have to go back and update all your internal links to reflect the change, or even worse, cause broken links and leave them broken. Broken internal links will degrade your search engine performance two ways:

  1. You'll lose the internal link anchor text context and relationship between pages
  2. Search engines will devalue your content due to having broken links

Don't cause broken internal links. You have full control over fixing them and implementing a strategy to avoid them in Drupal. Let's automate the process.

Drupal Internal Link modules

What we want to do to automate internal link updates is simply make sure that all of our internal link destinations (hrefs) are to canonical URLs wherever possible. You can do this by tracking down the internal path and ID of every term or node you want to link to. That requires a lot of extra effort. There's a better way. Thankfully, Drupal's community of contributed modules comes to the rescue.

Drupal WYSIWYG Module and editor plugin (TinyMCE, etc)

If you're using the WYSIWYG module plus one of the editor plugins it supports, your best bet is the LinkIt module. LinkIt provides a button in the WYSIWYG and a dialog to search for content on your site to link to. Once you click the LinkIt button in your WYSIWYG, it's just a matter of following the prompts to create internal links:

Creating Internal Links in Drupal with LinkIt

LinkIt will automatically create your link with the relative canonical URL. You don't have to hunt down the content ID or fuss with the HTML of the anchor.

Drupal CKEditor Module and CKEditor Link Module

All of our Drupal projects now utilize the CKEditor module for a WYSIWYG. This is the direction Drupal 8 has gone and so we try to make sure the eventual progression will be seamless for our Drupal services clients.

The CKEditor module has an extension or submodule that performs similar work to LinkIt, the CKEditor Link module. This allows you to use the lovely CKEditor WYSIWYG to create internal paths quickly. We love it.

After following the module instructions to setup and configure CKEditor Link to work with CKEditor, you'll have a simple process to creating internal, canonical links. This is our internal link workflow using CKEditor and CKEditor Link modules:

CKEditor Link Workflow Internal Path Process How To

  1. Select the anchor text you wish to use in the WYSIWYG
  2. Click the CKEditor Link button
  3. Make sure the "Link type" in the dialog is "Internal path"
  4. Start typing the title of our content in the autocomplete text input, select the right suggestion

This process creates a link to the internal canonical Drupal path to the content.

CKEditor Link creates internal Drupal paths

If you ever change your domain or alter the destination page's alias pattern, this internal link will still work. Combining CKEditor and CKEditor Link modules is our favorite way to handle internal path and link creation within Drupal.

Checking for broken internal links

Now that you have a process to create proper internal links (if you haven't, make changes now), you may need to check for any broken internal links. Drupal offers an excellent module for broken link checking, but first let's look at Google's Webmaster Tools. The free tool offers excellent insight for broken links.

Using Google Webmaster Tools to check for broken internal links

You do have a Google Webmaster Tools account, right? If you don't, sign-up. If you're a manager or webmaster, ask your developer to follow these steps to check for broken links. It's quick, easy, and free. This is a great way to fix search issues, raise your ranking, and properly distribute your internal traffic. Don't slap your users with broken internal links.

After logging into the Google Webmaster Tools (GWT) and selecting your domain, find your broken internal links this way:

Use Google Webmaster Tools to find broken links

  1. Expand the "Crawl" menu
  2. Select "Crawl Errors"
  3. Select the "Not found" tab

This will provide you with a list of URLs with problems. You're interested in those that aren't found (404 errors). The URLs listed tell you which URLs Google has stumbled across and received a 404 error. These are great candidates for creating 301 redirects to the right, or at least relevant, content on your site. What you really want to check for though is where these broken URLs are linked from. Are they your own internal pages? GWT to the rescue again! Click any of the URLs listed:

Find the source of broken internal links with Google Webmaster Tools

The pop-up dialog will indicate the broken URL and where it is linked from. Go to those pages and fix your broken internal links.

Automate broken link checking in Drupal with Link Checker module

If you've got a large Drupal site, manually checking GWT for broken links may not be the most effective way to find them. Drupal's Link Checker module will automate this process for you. Setup the module and it will scan your new and existing content for links, follow them, and identify any problems with them through their HTTP status code. Fix any 403s or 404s! The Drupal Link Checker module works with both internal and external links.

Why are internal broken links bad for your Drupal site?

Search engine spiders or crawlers are very busy workers. There's an entire web worth of pages to crawl and re-crawl. When they run into a broken link, they may stop where they are and move onto the next page. Broken links are a negative signal to search crawlers. Don't give them a reason to devalue your page.

I'm sure you've run into a broken link or two in your life while reading a page on some website. I bet it may have tempted you to stop where you are on the page and try to find a more authoritative, updated page about what you were reading. If the page owner hasn't checked their content over time to verify the links work, what's to say the content is still accurate? Not only do broken links discourage search engines, but they discourage users. It's especially embarrassing where the links are internal because the webmaster has control over both the destination page and the linking page.

Broken internal links can easily be avoided. Create a workflow to utilize canonical, relative internal links. Automate your internal linking process as much as possible by following the steps above. Identify any existing broken links with GWT or Drupal's Link Checker module and setup a process to routinely check for broken internal links. Make sure to create 301 redirects if you update existing content paths to prevent external sites from linking to now nonexistent paths. Don't slap your users with broken links, they're quick to fix!

This post was inspired by reading Mike Gifford's spring cleaning tips for Drupal sites, be sure to show your Drupal site some love with routine maintenance! Did you like this article or know someone that needs some link workflow help? Share it! If you're still having trouble getting your links in order, you can hire our Drupal team!

May 04 2015
May 04

Drupal HTML5 is celebrated as a way for websites to become richer and more interactive: closing the gap on native apps with geolocation, video, games, and audio through asynchronous communication with local storage and dynamic web user interfaces. The Drupal 7 content management system (CMS) didn't ship with HTML5 support. If HTML5's technology is something you wish to integrate with your Drupal 7 website, read on for a primer on HTML5 and a guide to using HTML5 features in the CMS.

The State of HTML in Drupal 7: The Doctype

Drupal 7 shipped its release on January 5, 2011. Drupal 7's code freeze was September 1, 2009. W3C didn't propose a stable HTML5 spec recommendation until October, 2014 and much of HTML5 was still up in the air as late as 2012. Needless to say, Drupal 7 didn't ship with HTML5 as the frontend spec. Drupal 7 released instead with an XHTML 1.0 transitional document type declaration (doctype):

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

Fortunately, Drupal's adaptive nature as a platform means that HTML5 can be well-integrated in all key areas of the CMS.

Technically, all that needs to be done to change the doctype parameter of your Drupal website is to declare it on your first line of HTML:

&lt;!DOCTYPE html&gt;

This "empty" declaration will default to HTML5 for all browsers which support it.

What is Drupal HTML5 and How Does it Work?

So what's the trouble? That seems like a pretty simple line of HTML to change, doesn't it?

Understanding XHTML/HTML Compatibility with HTML5

You're about to speak to a stranger; think of when you're traveling. You don't know whether they speak your native language or not. What's the first thing you say to them? It's probably: "Do you speak English?" Perhaps they respond back that they do. Now, they've tuned their brain to be ready for you to say something in English. What would happen if you then started asking where the nearest bathroom was but instead added some Spanish, "¿Where is the baño?"

HTML5 Doctype Tag Element Support Meaning

This is how a doctype declaration works for HTML. The browser and the server are agreeing on what sort of language they're going to use with each other. This doesn't "translate" all the HTML that you're actually using though: you still need to update tags to meet their HTML5 specifications. If not, you might be throwing some Spanish into the middle of your HTML and hoping the browser will make a guess as to what you mean.

Deprecated HTML Tag Elements in HTML5

The good news is that most HTML tags won't need to be changed. The tags you use in old HTML/XHTML will still work, they'll just lack the additional features or context that HTML5 elements offer. (You're not using a <blink> tag right?)

Some HTML tags have been deprecated in HTML5:

  • <acronym>
  • <applet>
  • <basefont>
  • <big>
  • <center>
  • <dir>
  • <font>
  • <frame>
  • <frameset>
  • <isindex>
  • <noframes>
  • <s>
  • <strike>
  • <tt>
  • <u>

If you're still using any of these tags, you'll need to convert them to appropriate tags still supported. For example, <center> has been deprecated because it was used to visually center page elements. Visual layout is the purpose of Cascading Style Sheets (CSS). The CSS property, text-align, provides an option of center. You'd want to utilize this property and value to visually center elements on the page instead of the <center> HTML tag.

If your Drupal implementation has some inline HTML, perhaps through WYSIWYG content areas or Block content areas, you'll need to make sure no deprecated HTML tags are used.

New HTML5 Tag Elements

The new HTML5 elements I find myself using the most are actually semantic tags that further define classic div tags. A div is simply a block element which contains other elements (its opposite is the span which is an inline element container). Divs make up large quantities, if not most, of the tags used on any particular webpage. W3C wanted to offer further context through HTML5 to these div tags. Instead of just divs, we now have: nav, article, figure, aside, and section to work with. HTML5 Doctor offers an excellent flowchart to help visualize your decision as to which tag is most appropriate:

Which HTML5 Element to Use Instead of Divs

Of course, there's much more to the HTML5 spec than just these handful of new semantic tags. What's important to understand is that these new semantic tags are the basis of the HTML5 spec.

Semantic Tags

W3C defines the new semantic tag elements available within HTML5.

Tag Description <article> Defines an article in the document <aside> Defines content aside from the page content <bdi> Defines a part of text that might be formatted in a different direction from other text <details> Defines additional details that the user can view or hide <dialog> Defines a dialog box or window <figcaption> Defines a caption for a <figure> element <figure> Defines self-contained content, like illustrations, diagrams, photos, code listings, etc. <footer> Defines a footer for the document or a section <header> Defines a header for the document or a section <main> Defines the main content of a document <mark> Defines marked or highlighted text <menuitem> Defines a command/menu item that the user can invoke from a popup menu <meter> Defines a scalar measurement within a known range (a gauge) <nav> Defines navigation links in the document <progress> Defines the progress of a task <rp> Defines what to show in browsers that do not support ruby annotations <rt> Defines an explanation/pronunciation of characters (for East Asian typography) <ruby> Defines a ruby annotation (for East Asian typography) <section> Defines a section in the document <summary> Defines a visible heading for a <details> element <time> Defines a date/time <wbr> Defines a possible line-break

These semantic tags offer greater context to the elements which are contained within them.

Form Tags

The new spec also defines form elements that give greater context to fields and content within forms.

Tag Description <datalist> Defines pre-defined options for input controls <keygen> Defines a key-pair generator field (for forms) <output> Defines the result of a calculation

These new form tags can be used as a basis for richer data gathering through HTML forms.

Graphics Tags

As the web advances with more powerful browsers, rich graphics have become a core part of every web experience. HTML5 defines new graphic elements.

Tag Description <canvas> Defines graphic drawing using JavaScript <svg> Defines graphic drawing using SVG

These new graphics tags really shine when used with JavaScript libraries that boost their interactivity.

Media Tags

Greater connection speeds have rolled out around the world since the last major HTML specification was created. Broadband is standard in much of the developed world with mobile devices having incredible connection speeds compared to the days of the 56k dial-up modem. We now have media as part of nearly every webpage: video, audio, and images. The new spec gives media a set of tags and attributes appropriate to them.

Tag Description <audio> Defines sound or music content <embed> Defines containers for external applications (like plug-ins) <source> Defines sources for <video> and <audio> <track> Defines tracks for <video> and <audio> <video> Defines video or movie content

The HTML5 video tag is one of the most interesting HTML5 features. Video is a major part of the modern web but it's been implemented through the Adobe Flash plugin for years. Flash is generally not supported on mobile devices and can be a bit of an energy/performance hog. The HTML5 video tag, and related JavaScript libraries, promise to provide support for streaming video in native HTML.

HTML5 Input Types

HTML5 extends the <input> tag's type attribute to support man new forms of data gathering. New type options include:

  • search
  • email
  • url
  • tel
  • number
  • range
  • date
  • month
  • week
  • time
  • datetime
  • datetime-local
  • color

These new type options are handled in different ways across browsers.

What is Relevant in HTML5?

There's many other technologies that get conflated with HTML5 like CSS3, Websockets, or the Flash Killer: Canvas. CSS3 is a new specification for cascading style sheets, which does often go hand-in-hand with HTML5, but isn't actually under it. Websockets is an API that creates a bi-directional mode of communication over a single TCP connection (think of push/pull). As amazing as Canvas is, without a supporting JavaScript library, it's nothing more than another semantic tag further defining our old divs. If you'd like to check if a particular HTML5 tag or attribute is supported by a particular browser version, this tool will verify compatibility.

Semantic HTML: Further Context and Purpose to Your Content

What HTML5 offers as the core part of the spec is further context to your content. No longer does all content live inside div tags. Instead, the containing elements offer an extra layer of context to the content which resides within them. An article is intended to define your page's core information, content which could live by itself. This is the meat of any page. An aside is tangentially related information (perhaps even "related content"), links, and data. It's relevant to the article but not data which makes much sense by itself. Nav elements contain the menu or navigation system for your website.

Integrating Drupal HTML5 in Drupal 7

The primary way you'll upgrade your Drupal 7 website to HTML5 is actually through your theme. You won't need to rewrite everything if you can utilize an HTML5-based Drupal 7 theme. If you happened to use a base theme which has now migrated from XHTML to HTML5, the theme developer should provide an upgrade path. If you happen to be working with an older theme that hasn't upgraded to HTML5 or you have a custom theme, you may need to rewrite some of your template files to match the new spec. Nathan Smith offers an excellent guide to getting started rewriting these template/.tpl files. Themes generally override the core template files that Drupal provides. These template files contain the actual HTML which is output by the CMS. 

Drupal Modules for Drupal HTML5 Support and Integration

There's several Drupal modules that focus on providing compatibility and integration with HTML5 elements within Drupal's existing systems.

  • Elements - provides support for advanced form elements which are the core of Drupal fields
  • Video - handles various video file trouble with HTML5 video elements; codecs, streaming, thumbnails
  • Geolocation - gather the user's location or store latitude and longitude coordinates
  • HTML5 Tools - connects the Elements (above) fields to Drupal systems and primary modules like Views

The HTML5 Tools module for Drupal 7 helps make the new HTML5 input types standard and provides methods to utilize them within the CMS. These input types are mentioned above.

HTML5 JavaScript Compatibility Tools

Aside from adjusting tags to appropriately match the HTML5 spec, most HTML5 Drupal Themes will utilize JavaScript libraries to solve compatibility problems in older browsers that do not support the spec. The most important HTML5 JavaScript compatibility plugins are:

  • Modernizer - detects browser capability, provides capability indications within the DOM
  • HTML5 Shiv - provides support for HTML5 elements in older Internet Explorer browsers

Drupal 7 Themes built on HTML5

The best HTML5-based Drupal 7 themes we've found through several project builds are:

  • Base or Starter Themes:
    • Omega - developer focused, JavaScript compatibility libraries, page layout system
    • Zen - hugely popular, tons of choice and control from the admin interface
    • Adaptive - point-and-click interface for controlling device size media queries
    • Fusion - integrates well with grid/layout systems
  • Functional Themes:
    • Corporate Clean - popular starter design for professional sites
    • Business - clean grid starting design for business sites

Some of these Drupal Themes are compatible with version 6 or 8. If you're looking for HTML5-focussed themes for Drupal 6 or Drupal 8, these themes are also a great place to start.

Curious about what we use on a majority of our projects? It's Omega, a lovely base theme targeted to dev/designers ready to code. Out of the box, Omega reminds me of the clean slate offered by the HTML5 Boilerplate framework (sidenote: there is a Drupal theme based on this HTML framework, but it gets little activity or support). There's very little markup to fight from the start, and Omega does a great job of stripping unnecessary classes and markup as much as is possible within Drupal. Omega uses a flexible layout system (sort of like a sub-subtheme), and a mobile first design system. We love Omega.

Does my Drupal HTML5 Website Validate?

W3C offers an excellent validation tool that's been updated as the HTML5 spec is updated. You'll always be validating against the latest agreed requirements as long as you're using the W3C HTML Validator. The validation tool will give you errors and warnings that pertain to particular tags, syntax, or attributes. The tool also offers suggestions and direction to solve the problem area. Once you're ready to begin testing, plugin your URL to the W3C HTML Validator and be sure the doctype is detected automatically as HTML5. If you're having trouble configuring your Drupal site to match the HTML5 standard or want to integrate new technologies provided by the spec, we offer focussed Drupal implementation services.

The Future of Drupal HTML5 and Drupal 8

Drupal 7 wasn't built from scratch to support HTML5. However, Drupal 8 will ship with integrated support for HTML5, and at the time of writing Drupal 8 is in beta. The future is looking bright for Drupal and HTML5.

The reason you should care about HTML5 is that it leads the web towards a more defined standard for its information. This makes it easier for search engines, algorithms, APIs; any computer reading your content to better understand what it's about and the purpose. This makes for easier curation and stronger relevance. Delivering relevant information for what a user is seeking is a core part of the web as we know it, HTML5 is a step towards making that experience even better.

If you like this Drupal guide to HTML5, consider sharing it. Do you have suggestions for Drupal HTML5 integration? Corrections? Questions? Connect with us!

Apr 23 2015
Apr 23

Are you trying to add a block of related content to a node page in Drupal? Do you want to display other nodes which share terms with the currently displayed node?

Have you been getting frustrated searching D.O for an answer? Are you weeding through Stack Overflow or Drupal Exchange posts for this common use case?

I'm going to help you with Drupal related content using the Views module. If you just want to the highly actionable parts (building the View and contextual filters), use the video walkthrough. However, I strongly suggest reviewing the use case and logic below, first. This might even help you when you're working through requirements on your other projects.

Drupal Related Content

There's many ways to attempt to identify Drupal related content. You could even use an external service that incorporates "relevance" through an algorithm by way of Apache Solr for example. Or, maybe you want to show related content by word frequency among two nodes. You could even directly identify related content with a one-to-one relationship with an entity reference. Today, we're going to work through a bit simpler, more common method of deriving and displaying related content (side note: if you're actually looking for one of those more complex routes, we do offer Drupal consulting!). It's a frequent enough use case that I find myself repeating the steps for different projects, yet there's enough steps that I may need a refresher by Googling around a bit. Yet, every time, I see folks stumbling through this or apparently not able to find the way to do it. Let's do it right. Here's what you'll need and what I'm using:

Requirements to display Related Content by Taxonomy Terms:

  • Drupal Core 7.36+
  • Views module 3.10+

Basic stuff! Now, let's talk about the use case we're working against. You may need only a subset of the apparent functionality, and that's okay. Derive what you need from the fuller explanation.

Related Nodes by Terms Use Case

First, we should think about our content. Let's say we have seven nodes of a certain content type, titled:

  • Car
  • Boat
  • Bike
  • Bus
  • Train
  • Skateboard
  • Pogo Stick

Now, what about our classifications system? Let's say we add a taxonomy as a term reference field on the content type. It has terms:

  • Wheeled
  • Motored

We'll be logical and go ahead and add the right terms to each of our nodes as follows:

  • Car
    • Wheeled
    • Motored
  • Boat
  • Bike
  • Bus
    • Wheeled
    • Motored
  • Train
    • Wheeled
    • Motored
  • Skateboard
  • Pogo Stick

With this data, we want to display related content based on the terms that are applied to each node. Let's use a few examples and plain english to flesh out requirements:

What Other Nodes Should be Related and Shown for:

Bike

Any idea? Well, node Bike has term Wheeled. Let's just show the nodes with that term. These nodes have term Wheeled and should be shown: Car, Bus, Train, Skateboard, Bike. That's pretty simple, but there's already a bit more going on you may not realize right away. For example, Bike, should not be shown even though it does have term Wheeled. Why? The user doesn't want to see the node they're already looking at. We'll want to add a requirement based on this:

1) The related content should not show the current node.

Car

Node Car has two terms: Wheeled, Motored. Now we'll need to decide what to do with two terms. Do we show only the nodes that have both terms or do we show any node that has either term? For our use case, we're going to go with the more difficult example:

2) The related content should show nodes matching any term.

Ok, so let's take each term and query our node list, Wheeled first: Car (eliminated by requirement 1), Bike, Bus, Train, Skateboard. Now, let's query our second term, Motored: Car, Boat, Bus, Train. So, we have our output when put together: Bike, Bus, Train, Skateboard, Boat, Bus, Train. Wait! We have duplicates! The user doesn't want to see the same thing twice. Time for a new requirement:

3) The related content should not contain any duplicate nodes.

Where does that leave us? Our requirements for our related content by term in Drupal functionality are that the related content should:

  • Not show the current node
  • Show nodes matching any term
  • Not contain any duplicate nodes

Is that what you want to build? Let's do it! Got your nodes, taxonomy, and terms together? Excellent! I bet you want to walkthrough the View. This is a great time to go ahead and hit the video on this post.

Review Creating a Drupal related content Block with Views

Make sure you've created your nodes. Then, add a taxonomy and terms. Then, create a View->Block. Let's walkthrough the other major points in screenshots:

Add a Contextual Filter->Has Taxonomy Term ID

Drupal Related Content with Contextual Filters

Remove Duplicates with the Contextual Filter

Avoiding Duplicates with Views Contextual Filters

Add another Contextual Filter but with Content: NID

Remove the Current Node with Contextual Filter

Remove the Current Node with the Contextual Filter

Exclusions in Taxonomy Term Related Content

Need more help? If you're seeing Pogo Sticks, something broke! Feel free to ping us on Twitter, subscribe on YouTube for more, or follow us on social media. We have a lot more planned. Think this guide is useful? Don't forget to share!

Mar 24 2015
Mar 24

In years past, website design started with wireframes or visuals that focussed on a median screen size on a desktop display. Perhaps it was 1024x768 resolution. There's a lot more variation in screen sizes as mobile devices capable of displaying websites in rich accuracy have become prevalent. This means that our strategy for website design has to evolve from focussing on desktop displays with haphazard "fixes" in order for the pages to work on mobile, to beginning with a mobile first strategy. I'm going to walk you through mobile first strategy and its implementation within the Drupal CMS with this guide.

Drupal Mobile First Strategy

Mobile First Design means iterating a design with a start from the smallest target device screen size. Once the smallest screen size display is worked out, you move on to the next major target screen size and adjust your display as necessary to fit the new size. Perhaps your smallest screen size is a smartphone (though soon that may be a smartwatch). Most likely your design on a narrow smartphone won't incorporate columns of content. Instead, information that may usually reside in a sidebar would display before or after your primary content. Moving up to your second target screen size, perhaps a tablet, you may have enough space to incorporate an additional column. This layering can continue as more screen real-estate is afforded and your design alters to fit.

Drupal Mobile First Website Design Explained, Simply

Drupal Mobile First Strategy Explained

Are you confused by Mobile First Strategy? Let me offer up an explanation that might be more easily digested. 

The best visual description I've heard of this is to think of the different levels as stained glass. The bottom layer of stained glass would represent the mobile design. From there, you might add a tablet-based design - this second level of stained glass could have a slightly different design from the bottom layer. These design changes would naturally cover-up the bottom layer as the different colors and shapes within the stained glass would block out the light from hitting the bottom layer in the same way, producing a different result. Of course, some of the light would indeed make it through to the bottom layer which means the layers of stained glass would look different by themselves, but also when stacked.

This stacking process would continue onto each new layer, showing different designs through and all based upon eachother.

Drupal Responsive Design

A key part of a mobile first strategy, from a technical point of view, is the use of responsive website design. This is the process by which code read by the browser detects screen sizes and adjusts layouts to match a particular screen size. In technical terms, this is done through the concept of media queries. Media queries are cascading style sheet (CSS) code which is able to detect a pre-set screen width and then apply encapsulated code which only runs at that particular size or larger (or smaller).

Adaptive Design vs. Responsive Design

Responsive design principles also dictate that the design should constantly respond to varying screen sizes. That means that your "tablet" target design should work with a variety of screen sizes close to a single target size. This is because there's variety in device category screen sizes; not all tablets have the same screen size. Design code which dictates static layouts based on singular screen size breakpoints is known as Adaptive Design and is less flexible (though less complex) than Responsive Design. 

A History Mobile Websites

Before responsive (and adaptive) design concepts were widely accepted, systems were in place to detect literal mobile devices (as opposed to screen sizes) and adjust design based on which devices was accessing the website. As you might imagine, as more and more mobile products have come into existence, this was not a scalable approach. It was unreasonable to constantly update mobile device detection methods whenever a new device became popular. An approach of adjusting design based on screen sizes was far more practical.

Prior to having device detection available as a mobile web design strategy, separate mobile websites were the primary method to dealing with mobile users. You may recall seeing redirects to mobile subdomains (http://m.domain.com for example). This method utilized an almost entirely separate website that was displayed to mobile users. An separate theme or template would need to be maintained and sometimes even separate (or duplicate) copies of content.

Drupal Mobile First Design Strategy for Websites

I'm a huge fan of the HTML5 Boilerplate, a generic frontend web framework. It's an amazing tool for starting out new web projects, as we've become more involved with Drupal, I set out to find a solid theme that would support a lot of the same principles and function well with Drupal. Our primary Drupal projects are all in version 7, so we've limited our theme reviewing and process development to Drupal 7.

Pitfalls in Drupal Mobile Themes

A primary concern we have for utilizing Drupal 7 themes is following a mobile first design approach. This means that we want base themes that follow a principle of adding larger "layers" of screen sizes with appropriate design adjustments atop the initial smallest screen size target. What we don't want is the reverse: themes which focus on removing elements from desktop designs and overriding desktop designs to fit small screens.

Recommended Drupal 7 Mobile Themes and Templates

We've used several different Drupal 7 themes here at Daymuse. Each provide varying degrees of mobile support. These include:

  • Adaptive Theme
  • Aurora
  • Bootstrap
  • Foundation
  • Omega
  • Radix
  • Zen

Each has their advantages and disadvantages. I recommend using this as a starting point to look further into the use cases for each theme. For example, Bootstrap is a fantastic theme (based on a fantastic framework) to quickly build out a rich design but has somewhat limited variation; it's more assembling pieces than an open landscape.

Our Favorite Mobile First supporting Drupal Theme

We tend to build client sites that start from a literal blank page, and for that we greatly prefer the Omega theme as a basis of our projects. It's similar in nature to the HTML5 Boilerplate frontend framework I mentioned earlier. When you first install Omega, you'll be greeted by a fully reset design: white background, default text. The styling resets provided by Omega mean that you'll be working from the same blank slate across all browsers; there shouldn't be variation in element styles. In addition, the CSS is setup to follow mobile first design principles: build the small screen design first, add additional layers of design alterations for each additional breakpoint. Omega incorporates responsive design as part of its core purpose.

Mobile Design in Drupal Administration

Drupal Mobile Friendly Administration Theme Ember

Generally when discussing mobile first design strategy for Drupal, we're referring to what the end user sees. Drupal sites actually utilize two separate themes: and end user theme that anonymous website visitors see through the Content Delivery Application portion of Drupal and an administration theme which logged in users typically see with the Content Management Application side of Drupal.

While our primary focus is in the end user experience, there's also concern for the administration side and mobile first design. Just like the end user theme, Drupal's administration themes are fully customizable and can be built from the ground-up using mobile first design principles. Typically, we utilize off the shelf Drupal administration themes as our clients find the administration interface to be secondary. We love using the Ember mobile-friendly administration theme with Drupal 7. Ember works perfectly alongside the Mobile Navbar menu module. Ember & Navbar mobile menu are some of our favorite mobile tools for Drupal. These two Drupal modules create a perfect starting point for mobile-friendly Drupal 7 administration. Even better, they follow the direction of Drupal 8—making it easier for your users to migrate to Drupal 8 in the future.

Drupal Mobile-Friendly Testing Tools

As of April, 2015, Google is placing and even greater emphasis on websites' mobile-friendliness. If your users are on a mobile device and searching Google, they're more likely find results which Google deems to be "mobile-friendly". There's several criteria to meeting this test, but follow best practices as outlined above with your Drupal site and basing it on a recommend Drupal mobile theme should have your site pass the test.

Mobile-Friendly Drupal Site Test Tool by Google

The Mobile-Friendly Test is a free tool offered by Google. Before you launch your site, be sure it meets the requirements to be mobile-friendly. Having a mobile-friendly Drupal site is one of the easiest ways to surpass your competitors who do not have sites which meet Google's mobile-friendly requirements in search results.

If you like this guide to mobile first strategy and responsive design with Drupal, consider sharing it. Ping us if you have questions, corrections, or think something should be included—we respond quickly!

If you or your company are seeking expert direction with incorporating a mobile first strategy or responsive design into your projects, we can help. Catch us on Twitter or other networks to connect with us.

Nov 13 2014
Nov 13

Following on from the first blog post in this series, An Introduction to Test Driven Development, Chris introduces the test harness so strap yourself in!

My first experience of work "in the real world" came through work experience. I was lucky enough to get one of only two placements with IBM at Havant and my assigment was to build to specification the wiring loom used to connect the IBM 3745/3746 communications controller to its test harness. These units had to be regularly and thoroughly tested throughout production and so periodically each unit was hooked up to a test harness by means of the aforementioned wiring loom so that a range of tests could be executed against the unit and pass/fail reports and data collated. My time at IBM provided a fabulous insight into engineering/testing and firmly cemented in my mind the concept of a test harness.

In software development, a test harness provides exactly the same functionality, it provides a means of executing tests against software and giving feedback on whether the software is behaving as expected.

The specific test harness you choose will likely vary from project to project and is dependant on a number of factors, the coding language of the project and experience of the developers and test engineers involved may have an impact on the decision making process, a Google search for "test harness for language x" will no doubt turn over a number of options for each language and whilst there’s no hard and fast rule that your test suite and project code language must match, the skillset of the team surely will play a part.

Another major consideration should be around the types of test you want to execute, (unit, integration, system, acceptance etc) as some test harness frameworks lend themselves more towards one or a subset of types. You can of course use more than one test harness if it makes sense for your project with each providing different elements of a test plan strategy: unit tests running on every build and full smoke and functional tests running on release for example.

Consideration also needs to be given to the development methodology being applied - perhaps PHPUnit is a best choice if a purely Test Driven approach is adopted, on the other hand, Behat is a clear winner for Behaviour Driven Development.

I'll leave the last key point for consideration till the end! First, let's briefly review 4 popular test frameworks.

SimpleTest

For those of us working with PHP (and specifically Drupal), there are a number of options. Coupled closely with Drupal is SimpleTest which was moved to core in Drupal 7. It's modeled on the open source SimpleTest unit test framework so those familar with its suite of assertions will be comfortable and will get the extra benefit of helper methods such as drupalLogin(), drupalLogout(), drupalCreateNode() and drupalCreateUser() for establishing fixture[1].

Here's an example of a user login test in SimpleTest taken from the user module and modified slightly for clarity:

<?php
  /**
   * User login test.
   */
  class UserLoginTestCase extends DrupalWebTestCase {
    public static function getInfo() {
      return array(
        'name' => 'User login',
        'description' => 'Ensure that login works as expected.',
        'group' => 'User',
      );
    }
    
    /**
     * Test that a user can login.
     */
    function testUserLogin() {
      $user = $this->drupalCreateUser(array());
      $this->drupalLogin($user);
    }
  }

As you can see, tests are expressed in PHP code and SimpleTest provides a number of assertions that can be used.

I won't go into much detail here about SimpleTest as many good blog posts already exist about its use and limitations (duration of test run being a major issue which SimpleTest Clone seeks to address, some have had success with switching to MyISAM for tests and others, along with Drupal Quality Assurance have adopted ramdisk with a mixed outcomes it seems.)

Code Enigma offers high performance Drupal hosting with built in support for running automated tests, see our hosting page for more information or get in touch if you'd like to talk it through.

PHPUnit

PHPUnit is a popular open source PHP test framework created and maintained by Sebastian Bergmann which, from its name, is a good choice for unit testing although you can combine it with other libraries, Guzzle and Selenium Server for example enabling browser automation for functional and acceptance testing.

I personally find PHPUnit invaluable and use it on a daily basic, tests are easy to read, write and are quick to run if you're actually doing true unit testing. Of course, that in itself raises a challenge when working with Drupal where dependencies are commonly requested rather than injected. Drupal 8 is heading in the right direction with Mark Sonnabaum leading the introduction of PHPUnit tests in the upcoming release. I recommend watching the video of his recent Drupalcon Portland session on the subject.

A really basic example PHPUnit unit test:

<?php
  /**
   * Adds two numbers and returns the result.
   */
  function add($a, $b) {
    return $a + $b;
  }

  class AddTest extends PHPUnit_Framework_TestCase {
    public function testadd() {
      $this->assertSame(3, add(1, 2));
    }
  }

Once again, tests are expressed in PHP code with PHPUnit providing perhaps a slightly richer set of assertions than you get with SimpleTest.

Behat

Created by Konstantin Kudryashov, Behat is the PHP Behaviour Driven Development enabler for PHP projects - it enables composition of human readable tests (in Gherkin) that Behat turns into executable acceptance tests. This is the beauty and strength of BDD (and Behat), together they provide a means whereby business owners, developers, project managers and testers can frame requirements in a common language, the language of the business domain and from there derive a suite of acceptance tests that indicate delivered value.

The DrupalExtension module provides additional step definitions for some of the basic operations normally performed on a Drupal site, in addition it provides support for regions defined in the theme layer for more accurate querying of the user interface.

I recently gave a talk about BDD and Behat at the North West Drupal user group - you may find my slides and code helpful.

An example feature and scenario:

Feature: Login
  As a visitor
  I want login
  So that I can manage my account

  Scenario: A user enters their credentials and logs in successfully
    Given I am on "/"
    And I fill in "admin" for "name"
    And I fill in "letmein" for "pass"
    When I press the "Log in" button
    Then I should see "My account"

Expressed in a structured language called Gherkin, Behat along with the Mink extension can take this feature and turn it into an executable acceptance test without the need to write any PHP code.

Codeception

Codeception is a PHP framework created and maintained by Michael Bodnarchuk. It enables acceptable, functional and unit testing which are created by expressing context, actions and expected behaviour in simple expressive PHP code.

At the time of writing, Codeception has switch on module support for a number of PHP projects such as Symfony, Laravel, Yii and ZF but unfortunately no-one has written the equivalent for Drupal yet. Keep an eye on Mike Bell and Paul Byrne who have both written very good blog posts about Codeception, Testing with Codeception and Drupal Projects and More testing with Codeception and Drupal projects

An example Codeception test:

<?php
  $I = new WebGuy($scenario);
  $I->wantTo('ensure that frontpage works');
  $I->amOnPage('/'); 
  $I->see('Home');

Tests are composed in simple expressive PHP code.

Conclusion

It's perhaps now apparent that whichever test framework you choose, the end result is much the same: tests are executed either directly against code (unit testing) or against the site itself (functional/acceptance testing through browser automation) and the failures are reported in some way. The key variant these frameworks offer, and in my book, the most important element for consideration is the input. Answering the following pivotal question helps:

How best can tests be expressed for this project and the people involved in its delivery?

Although not explicit, you might want to include the client when you consider the people involved!

Footnotes

1. A fixture is a known application state which tests will run against, establishing a fixture is the work you do to get to that know state, perhaps the creation of a user for example.

Jul 09 2013
Jul 09

Drupal's highest adrenaline event headed to Daytona Milton Keynes on Saturday 6th July for an exciting second round. The sun was out and the track was unbelievably hot but everyone had a great time. Thanks to IXIS and Pulsant for coming along this time, and sorry to everyone who couldn't make it! You missed out!

The format was 3 heats followed by a final. Chris Cohen (that's me!) took victory in races 1 and 2, putting him on pole for the final, and Pulsant's Chris Cowdry took victory in the final heat.

The final was a close affair but in the end Chris Cohen took victory and Chris Cowdry came home second, just 3.6 seconds back, with Pulsant's Steve Blow securing the final podium place.

Fastest lap was Chris Cohen's 1:11.294, with Chris Cowdry's 1:11.362 a very close second. IXIS's Matthew Proffitt suffered a fuel problem near the end of the final and had to retire, putting paid to what would have otherwise been a great finish!

After two rounds, the drivers' championship looks like this:

The (website) constructors' championship looks like this:

A big thanks to Daytona Milton Keynes for putting on a great event. Look out for the next Drupal Grand Prix in the near future, and if you are a Drupal company and want to organise the next one, please do get in touch and let us know!

We don't have all the details of everyone from the first round, so if your company or name is not correct in the standings, get in touch and let us know please!

Jun 10 2013
Jun 10

Following on from the first blog post in this series, An Introduction to Test Driven Development, Chris introduces the test harness so strap yourself in!

My first experience of work "in the real world" came through work experience. I was lucky enough to get one of only two placements with IBM at Havant and my assigment was to build to specification the wiring loom used to connect the IBM 3745/3746 communications controller to its test harness. These units had to be regularly and thoroughly tested throughout production and so periodically each unit was hooked up to a test harness by means of the aforementioned wiring loom so that a range of tests could be executed against the unit and pass/fail reports and data collated. My time at IBM provided a fabulous insight into engineering/testing and firmly cemented in my mind the concept of a test harness.

In software development, a test harness provides exactly the same functionality, it provides a means of executing tests against software and giving feedback on whether the software is behaving as expected.

The specific test harness you choose will likely vary from project to project and is dependant on a number of factors, the coding language of the project and experience of the developers and test engineers involved may have an impact on the decision making process, a Google search for "test harness for language x" will no doubt turn over a number of options for each language and whilst there’s no hard and fast rule that your test suite and project code language must match, the skillset of the team surely will play a part.

Another major consideration should be around the types of test you want to execute, (unit, integration, system, acceptance etc) as some test harness frameworks lend themselves more towards one or a subset of types. You can of course use more than one test harness if it makes sense for your project with each providing different elements of a test plan strategy: unit tests running on every build and full smoke and functional tests running on release for example.

Consideration also needs to be given to the development methodology being applied - perhaps PHPUnit is a best choice if a purely Test Driven approach is adopted, on the other hand, Behat is a clear winner for Behaviour Driven Development.

I'll leave the last key point for consideration till the end! First, let's briefly review 4 popular test frameworks.

SimpleTest

For those of us working with PHP (and specifically Drupal), there are a number of options. Coupled closely with Drupal is SimpleTest which was moved to core in Drupal 7. It's modeled on the open source SimpleTest unit test framework so those familar with its suite of assertions will be comfortable and will get the extra benefit of helper methods such as drupalLogin(), drupalLogout(), drupalCreateNode() and drupalCreateUser() for establishing fixture[1].

Here's an example of a user login test in SimpleTest taken from the user module and modified slightly for clarity:

<?php
  /**
   * User login test.
   */
  class UserLoginTestCase extends DrupalWebTestCase {
    public static function getInfo() {
      return array(
        'name' => 'User login',
        'description' => 'Ensure that login works as expected.',
        'group' => 'User',
      );
    }
    
    /**
     * Test that a user can login.
     */
    function testUserLogin() {
      $user = $this->drupalCreateUser(array());
      $this->drupalLogin($user);
    }
  }

As you can see, tests are expressed in PHP code and SimpleTest provides a number of assertions that can be used.

I won't go into much detail here about SimpleTest as many good blog posts already exist about its use and limitations (duration of test run being a major issue which SimpleTest Clone seeks to address, some have had success with switching to MyISAM for tests and others, along with Drupal Quality Assurance have adopted ramdisk with a mixed outcomes it seems.)

Code Enigma offers high performance Drupal hosting with built in support for running automated tests, see our hosting page for more information or get in touch if you'd like to talk it through.

PHPUnit

PHPUnit is a popular open source PHP test framework created and maintained by Sebastian Bergmann which, from its name, is a good choice for unit testing although you can combine it with other libraries, Guzzle and Selenium Server for example enabling browser automation for functional and acceptance testing.

I personally find PHPUnit invaluable and use it on a daily basic, tests are easy to read, write and are quick to run if you're actually doing true unit testing. Of course, that in itself raises a challenge when working with Drupal where dependencies are commonly requested rather than injected. Drupal 8 is heading in the right direction with Mark Sonnabaum leading the introduction of PHPUnit tests in the upcoming release. I recommend watching the video of his recent Drupalcon Portland session on the subject.

A really basic example PHPUnit unit test:

<?php
  /**
   * Adds two numbers and returns the result.
   */
  function add($a, $b) {
    return $a + $b;
  }

  class AddTest extends PHPUnit_Framework_TestCase {
    public function testadd() {
      $this->assertSame(3, add(1, 2));
    }
  }

Once again, tests are expressed in PHP code with PHPUnit providing perhaps a slightly richer set of assertions than you get with SimpleTest.

Behat

Created by Konstantin Kudryashov, Behat is the PHP Behaviour Driven Development enabler for PHP projects - it enables composition of human readable tests (in Gherkin) that Behat turns into executable acceptance tests. This is the beauty and strength of BDD (and Behat), together they provide a means whereby business owners, developers, project managers and testers can frame requirements in a common language, the language of the business domain and from there derive a suite of acceptance tests that indicate delivered value.

The DrupalExtension module provides additional step definitions for some of the basic operations normally performed on a Drupal site, in addition it provides support for regions defined in the theme layer for more accurate querying of the user interface.

I recently gave a talk about BDD and Behat at the North West Drupal user group - you may find my slides and code helpful.

An example feature and scenario:

Feature: Login
  As a visitor
  I want login
  So that I can manage my account

  Scenario: A user enters their credentials and logs in successfully
    Given I am on "/"
    And I fill in "admin" for "name"
    And I fill in "letmein" for "pass"
    When I press the "Log in" button
    Then I should see "My account"

Expressed in a structured language called Gherkin, Behat along with the Mink extension can take this feature and turn it into an executable acceptance test without the need to write any PHP code.

Codeception

Codeception is a PHP framework created and maintained by Michael Bodnarchuk. It enables acceptable, functional and unit testing which are created by expressing context, actions and expected behaviour in simple expressive PHP code.

At the time of writing, Codeception has switch on module support for a number of PHP projects such as Symfony, Laravel, Yii and ZF but unfortunately no-one has written the equivalent for Drupal yet. Keep an eye on Mike Bell and Paul Byrne who have both written very good blog posts about Codeception, Testing with Codeception and Drupal Projects and (Paul's blog is no longer live) More testing with Codeception and Drupal projects

An example Codeception test:

<?php
  $I = new WebGuy($scenario);
  $I->wantTo('ensure that frontpage works');
  $I->amOnPage('/'); 
  $I->see('Home');

Tests are composed in simple expressive PHP code.

Conclusion

It's perhaps now apparent that whichever test framework you choose, the end result is much the same: tests are executed either directly against code (unit testing) or against the site itself (functional/acceptance testing through browser automation) and the failures are reported in some way. The key variant these frameworks offer, and in my book, the most important element for consideration is the input. Answering the following pivotal question helps:

How best can tests be expressed for this project and the people involved in its delivery?

Although not explicit, you might want to include the client when you consider the people involved!

Footnotes

1. A fixture is a known application state which tests will run against, establishing a fixture is the work you do to get to that know state, perhaps the creation of a user for example.

May 24 2013
May 24

Round 2 of the Drupal Grand Prix will take place at Daytona Milton Keynes on Saturday 6th July. It's a great outdoor karting circuit that can host up to 35 drivers on the track at a time, and it's open to any UK Drupal companies and freelancers. (It's open to anyone outside the UK too, if you're up for the trip!)

The event starts at 2.15pm on Saturday 6th July, and registration is £80 per driver. The event consists of a warm-up, 3 heats, and a final, all of which will take about 2 hours, with the strong possibility of drinks afterwards. All drivers get to take part in every race! No experience necessary! It's suitable for anyone, even if you have never been karting before. Trophies will be awarded for first, second and third place overall.

We're looking for teams of 4, so if your Drupal company would like to enter a team, get in touch via the contact form on the site. If you can't manage 4 drivers, let us know how many places you'd like and we'll team you up with other like-minded Drupal racers! Spectators and official photographers are also welcome, if you want to come and cheer on your team.

Round 1, hosted by IXIS, took place in January and was a great success, with 19 drivers out on the track representing their Drupal companies from all over the country!

Due to the way the circuit handles bookings, fees are payable up front upon booking, and are not refundable (sorry!) As it's outdoors, it might rain! The event will take place in any weather, and waterproof race suits are available if it gets a bit wet. Please leave plenty of time to arrive. If you arrive after 2.15pm the venue will not allow you to drive and you will miss the entire event!

May 16 2013
May 16

Moving Drupal website clients to cloud hosting has been great as they're able to get high performance, scalable capacity at a pretty reasonable rate. However, we have discovered when clients offer an email sign-up, the emails that are generated from the cloud-hosted Drupal website are often rejected as spam. For those clients who have chosen the Rackspace cloud, here is a step-by-step solution to the problem.

To begin, you'll need to login to the Rackspace Cloud Tools Marketplace with your Rackspace Cloud username and password. Install the free SendGrid app; this will connect the Sendgrid email system to your cloud account. When you install the SendGrid app, you'll see a large link that says try the free edition. Click that box and then input your email address. An automated reply will be sent to you where you can create your SendGrid account using the Rackspace Cloud. Complete your registration and keep your SendGrid username and password handy.

Next, you'll need to install and configure the SMTP Authentication Module on your Drupal site for SMTP support. Once you've got the SMTP module installed, configure the SMTP Authentication with the following settings:

  • SMTP Server - smtp.sendgrid.net
  • SMTP Port - 587
  • Use Encrypted Protocol - No. If you want encryption choose “Use SSL” and set SMTP Port to 465
  • Username - SendGrid Username
  • Password - SendGrid Password

Once that's complete, you should be ready to send emails off your Rackspace Cloud server. You can test the setup using the test email box at the bottom of the configuration page and hitting save.

For more information on how to get SendGrid setup with Drupal, be sure to visit the website directly.

Have any questions about this tutorial? Leave us a comment below!

May 07 2013
May 07

I am sick and tired of hearing that the Drupal learning curve is much steeper than the WordPress learning curve. The reality is, both platforms are starting to converge in several areas.

If we're going to look at Wordpress vs Drupal, let's be fair. Drupal is a web content management framework that can be extended vastly. WordPress is the Best-of-Breed blogging platform that continues to evolve into an extensible content management system. Different? Absolutely. But as both platforms progress, both become closer in both capabilities, the ability to extend, ease of use, design and even...difficulty to learn.

I'll begin by giving a little background into my experience and then go from there. I have a degree in graphic design. If I'm going to use a web application, it's very important that little programming experience is needed because I have a limited skill set to troubleshoot bugs. That being said, I've built my own osCommerce sites nightmares and know the pain that comes with trying to search through lines of code to hack in a module or extra functionality. In addition, I also ran my own WordPress blog for at least 3 years, but migrated to Drupal once LevelTen moved to Drupal; needless to say I can shoe string something together if I must.

When we began using Drupal here at LevelTen, it took a good 6 months to really get my head wrapped around it. At the time, there weren't the excellent books, videos and other resources that exist now. Drupal training wasn't something you could find in a local class, but thankfully today, that's an option almost every day of the week. Plus, there's no need to start at ground zero and download Drupal out of the box; instead, start with one of the great Drupal distributions that are readily available to accelerate your development and learning time.

Personally, I've been using Drupal for 6 years now and I continue to learn every day. The web also changes every day and there's an ever expanding selection of modules to make Drupal better. Guess what? 99% of the clients I work with don't need to know about those changes; they just need their website to work and not be locked into a solution that can't grow with their business.

In the end, learning anything new is never an easy task, but if you use the tools that are available to your advantage you'll be able to get that simple WordPress learning curve on your super powerful Drupal website.

Do you find that Drupal is difficult to learn? When you look at Wordpress vs Drupal, what are your thoughts? Share your comments below!

May 02 2013
May 02

Twitter recently re-launched their blog and they chose Drupal over WordPress

I've been telling people for years that if you just want a blog, WordPress is a great option. Twitter's decision to use Drupal as a blog makes me wonder a bit. Why would a company with their development and technical expertise choose Drupal vs WordPress if they're just building a blog? 

Here are a few reasons why I think the decision was a no-brainer:

  1. Let's all agree that Twitter isn't some mommy blogger or small business, so their needs are probably a little different. Saying "It's just a blog" isn't true.
  2. They built dev.twitter.com on Drupal so they're already familiar with Drupal's ability to be customized and expanded; plus why introduce a new technology that team members have to learn?
  3. Drupal's security and protocols are a major plus over WordPress. Why else would WhiteHouse.gov have chosen it over other options? 
  4. Not that they need it, but Drupal offers Enterprise Class Support with Acquia. Where's that solution on WordPress?

Look, my goal here is not to bash WordPress. I've used it in the past and it has its place; but in the end decisions like this only help to reinforce the argument that Drupal is the superior open source platform.

Do you think it was a good decision for Twitter to use Drupal over WordPress? Let us know in the comments.

Mar 15 2013
Mar 15

Writing standards-compliant code in Drupal 7 doesn't have to be hard! Using the power of a modern IDE, it can help to show you where you're going wrong, and ensure that all your code is standards-compliant. Here, we'll take a look at setting up JetBrains PhpStorm (our favourite IDE) to show you coding standards problems, but any IDE with CodeSniffer support will be able to do this, so it's likely Eclipse, NetBeans, and others will also help you out in the same way.

Why bother?

Good question. It's important we're all writing code in the same way, as we all come from different programming backgrounds, different cultures, and all have different ways of doing things. If we all just wrote code however we felt like writing it, when you got hold of my code, you'd have to adjust to my way of coding when you looked at my code. If you needed to make changes to it, either you'd need to adjust to my way when you wrote your code, or you'd have to introduce another style of code in the same file, making it even harder for the next person.

Besides that, having everybody write code in the same way enhances the stability of the code and makes it less error-prone. You spend less time thinking about how the code is structured, since it's always the same, and you spend more time thinking about how the code actually works.

Prerequisites

Do bear in mind this is based on a Linux installation, but OSX and Windows both have PEAR available and both operate in the same way, so apart from minor path differences, this will work just fine.

Oh great, I have to install a bunch of crap first? Yes, fraid so. Luckily this is pretty painless. There's a number of ways to get PHP_CodeSniffer installed but we prefer the PEAR method. Just type pear install PHP_CodeSniffer at your friendly command line prompt. That's pretty much it. CodeSniffer's installed.

Next, you'll need the Drupal-specific coding standards in a format that CodeSniffer can understand. Luckily, the coder module provides these standards, so grab a copy of that. Note that you don't need to install or use the coder module on your site; it just contains the standards inside it.

Inside the archive you download, you'll find there's a coder_sniffer/Drupal subdirectory. You want to extract this subdirectory and move (or symlink) this to /usr/share/php/PHP/CodeSniffer/Standards/Drupal. This will vary based on your Linux distro or operating system, but this is generally the place where PEAR decides to install stuff. If you end up with a file at /usr/share/php/PHP/CodeSniffer/Standards/Drupal/ruleset.xml (or your equivalent path) and a bunch of subdirectories, you're good to go.

PhpStorm setup

Head to your PhpStorm settings and type 'sniff' into the search box. You will need to point PhpStorm to your CodeSniffer path. On Linux, this is just going to be /usr/bin/phpcs but on Windows, it will be different, and you're looking for phpcs.bat instead. Make sure you click 'validate' on this screen to get a confirmation that PhpStorm and CodeSniffer can talk to each other.

Now you've done that, head to your project and configure its inspections. A quick way of doing that is clicking the little icon that looks like a guy in a top hat in the bottom right of the main window. No, seriously, it's a guy in a top hat, I'm telling you!

In the inspections for PHP, turn on CodeSniffer validation, and then click on this particular validator. You'll notice a little drop-down with a selection of coding standards to use. Pick 'Drupal' from the list (you might need to hit the little refresh icon next to it first, otherwise Drupal might not appear). By default, the level of the warning is weak warning, but change this to warning. If things are weak warnings, you'll end up disregarding them altogether, and coding standards violations, while they won't stop your module from working, should be treated as things to fix right away while writing code.

Now, whenever you open a file in your project, you'll be presented with a whole load of warnings (unless you already write gleaming, standards-compliant code). Not that I'm picking on the bean module, because it's great, but it was the first one I had to hand that wasn't perfect. Here's what you'll see:

There's a few issues with the code here, but none are difficult to solve!

Clean margins!

What I mean by this is that the right margin shows a yellow or red stripe mark in PhpStorm whenever a line contains a warning or error. Internally, we operate a "clean margins" policy, which means that these stripes must be removed before committing any code. Weak warnings, such as unused variables, are acceptable (since you don't always use all the parameters in the function when you implement a hook, for example).

This is not an excuse to make everyone do a huge amount of extra work! Instead, what we find is that people's attitudes and styles change over time, while using CodeSniffer, and pretty soon, we're actually writing standards-compliant code first time, rather than having to go back through line by line and clean up.

YMMV

This is a specific example on how to set up PhpStorm and PHP_CodeSniffer to help with coding standards, and specifically on Linux, but if you have any experience using other IDEs where this is a possibility, or you operate things a little differently, we'd love to hear from you in the comments.

Feb 12 2013
Feb 12

It seems we're using an ever-increasing number of modules on our Drupal 7 sites, which are getting progressively more complex as clients (understandably) want more features, more eye candy and more value for their money. Some modules are downloaded from drupal.org, some are modified, some are written completely from scratch, and even features are modules. We've come up with a simple organisational method which we think ought to keep everything organised, and we thought we'd share this and let you have your say.

What to version

There's only one thing we think should be in your version control repository for a Drupal site: stuff you've written. Drupal itself can live outside version control, because you're not going to modify it (you're NOT going to MODIFY IT, right)?! The same goes for contributed modules downloaded from drupal.org. We shouldn't need to modify those at all.

Our argument is that since you don't need to modify these things, you don't need to version these, and doing so might make our jobs more complicated, as it makes it more complicated to do things like drush dl which can be used to provide module updates.

Therefore, we advocate only putting custom site code, such as the custom theme, and any custom modules, in version control.

Contrib, custom and features

We're suggesting making 3 subfolders inside your site's module folder:

contrib

This holds anything you've downloaded from drupal.org and not modified. This can be excluded from version control (using a .gitignore or similar) and while it still sits inside your site, doesn't need to get caught up in your repositories.

custom

This holds anything you've written yourself, such as custom modules that apply specifically to this site. Importantly, we also use this to contain any modified contrib modules. More on that below.

features

This holds all the site's features, which are automatically generated by the site (or drush) and don't typically contain code you would want to modify yourself.

Modifying contrib

Contrib is great. There's 63 billion modules and they're all fully operational and comply with coding standards, right? What do you mean 'not always'?! Depending on the contrib module, it might have bugs that prevent it from working on your site, or you might want to extend to suit your site, but the change is so unconventional it wouldn't be accepted into the official version, and it's not possible to write an addon module.

In the case of bugs, we always advise filing a patch. There's two good reasons for this: firstly, you've fixed the issue, so why not let others benefit? Secondly, using drush make or similar methods, these patches can be auto-applied when building a site, but only if they're posted online somewhere (okay, you could grab it from a private repo, but that's just stingy).

However, the patch might take some time to be applied and rolled into a new release. If this is the case, your site might need to go out before the new version is available, which means you're effectively running a custom version of that module. But wait, you have a place for custom modules already!

We'd advocate moving this module from the contrib folder to the custom folder. That way, when a nice sysadmin comes along to provide a security patch for the module, it's obvious that it has been modified, and in applying the latest security update, your modifications won't get wiped out by accident.

Your methods

While we've found this method ideal for our development, everyone has their own way of doing things, and if you can see particular problems with this approach, or you can suggest a better or alternate method we haven't touched upon, do let us know in the comments.

Sep 07 2012
Sep 07

When using contextual filters in Drupal's views module, you can get information from the page's URL, and use it to affect the view. This works fine if your view is a page, such as a page of blog posts, but what if your view is a block, embedded somewhere else?

For example, what if you want to add a 'recent posts' block to each user profile, to show the top 10 posts they have made recently? By default, you wouldn't be able to do this, as views 3 in Drupal 7 cannot 'see' the page URL if the view is inside a block. Luckily there's a way round this.

I'll assume you've already set up a view of nodes, representing your 'recent posts', and you've set up things like your sort order and how many nodes you'd like displayed.

I'll also assume you have aliased your user profile URLs, so that your user/1337 is actually displayed as users/pooslice or something similar in the browser.

Set up your contextual filter in the normal way. Here, we need to use the Content: author uid filter. Once you've chosen it, there's a set of radio buttons entitled When the filter value is NOT available. Set this to provide a default value and then, in this case, choose User ID from URL from the drop-down menu.

That's it.

We're just telling your view, when it's in a block, to explicitly pay attention to the page URL, where otherwise it would ignore it. Once it has the page URL, it's able to determine which bit of the URL is the user's uid, and pass it on to the contextual filter, so your view is correctly able to filter by user ID, even when it's in a block.

Bear in mind this is only going to work on user profile pages, so you will want to make sure that you're using the context module, or your block configuration is set up to only show the block on the appropriate pages.

Jun 25 2012
Jun 25

We just got back from DrupalCamp Oxford at the weekend, and there were a lot of good sessions. When you consider the ticket price was only £50 and included two 3-course lunches (both of which were way above and beyond the usual "Drupal event" food quality), it was a real bargain, but with so much information to take in, we thought we'd provide a quick summary of the key bits we took away from it.

Cool modules

We didn't know about the hacked module, which was mentioned by Hernani Borges de Freitas, and is really useful if you've acquired someone else's Drupal code, like a website, and want to know if anyone has hacked a module, or worse, hacked core, so it no longer matches the code on drupal.org

There's also the authcache module that can provide a certain degree of caching for authenticated users. This is useful for sites where the majority of users are authenticated, although probably not necessary for the vast majority of sites, which generally deal with anonymous users (you should still cache, although not using this module).

Another of Hernani's suggestions is the MySQL tuner, which is a PERL script that can be used to suggest some decent settings for your MySQL installation based on the specs of the machine it's running on.

Chicken in tarragon sauce!

Migration

Data migration is always a pain, so Johan Gant's session on the migrate module was great. It's not a magic fix for data migration projects, but it can help to ease the pain. The main points we took away from this were:

  • Make sure you can repeat your migration again and again and again because it will never go right first time.
  • Make sure you know the progress of the current migration, as when it takes a long time, you need to know where it's at and whether it's stuck.
  • Use realistic data, because if you use a small sample for testing which doesn't represent the rest of it, you'll run into problems when you try the real migration.
  • Don't migrate on a live environment until you know it will work. You knew that already, right?!

Johan gave a timescale of 5 days to import 400 nodes of a single type, which included the time needed to learn how to use the migrate module, and is very useful to anyone coming at a complicated migration for the first time, as it demonstrates this isn't a quick process, even when handled expertly.

Project management

Edward Kay's talk on project management was useful to us, especially as it outlined a lot of things we were already doing right. It's often useful to verify that your business process works the same or similar to other companies in your market, as otherwise it can suggest you've taken your eye off the ball.

Edward discussed how multitasking is deceptively ineffective and each individual should be kept on a single task. Jumping from task to task can feel productive, when really it is holding people back.

Edward also had some great suggestions about using spreadsheets to track the start, finish and sign-off dates for various parts of the project. He demonstrated some great-looking cumulative flow diagrams, but he didn't let us know how to make these, or give us any kind of template, so perhaps if Edward or his colleagues are reading this, we could get a link to those?

Aegir

We last took a serious look at Aegir in 2010, and it has come a long, long way since then. The main draw for a Drupal hosting provider like us is that the migration from one version of a module to another is seamless and automatic. If something goes wrong, the system will detect this and automatically roll the code back until you have a chance to fix the problem.

Combined with the fact that it can handle multiple remote systems and even non-Drupal projects (Wordpress, anyone?), we're now convinced it's mature enough and will be assessing it internally to see if it fits in with our deployment workflow.

The dining hall at St. Catherine's College

Everything else

It's a credit to St. Catherine's College that they were able to cater for 150 people and put out such great food. Unlike most other Drupal events, lunch was civilised, orderly, and most importantly, actually tasted great!

The Friday evening meal at Al-Shami was also brilliant, and the first time most of us Tigerfishes had tried Lebanese cuisine!

A big thanks to everyone from the Oxford Drupal User Group who worked very hard to put together an event on this scale.

Feb 05 2012
Feb 05

A routine part of a Drupal build spec is to create a touch or tap swipe compatible Drupal slider. This is also often referred to as a touch sensitive carousel or hero in Drupal design. This element offers an image rotator, providing a pre-defined set of images which slide through a list from left to right. With modern design incorporating touch features from the ground-up as mobile first for the wealth of mobile devices, it's more important than ever for touch swipe functionality to work. Views Slideshow, a module for Drupal CMS, enables slides of content to animate one to another; a Drupal slider. The module was originally created before touch features were vital to Drupal implementations and websites in general. There's a way to quickly add the functionality to a Drupal slider, though. Let's walk through making your own Drupal swiper.

Views Slideshow Touch Swipe Tutorial

Wouldn't it be neat if Drupal's Views Slideshow worked with a mobile device to enable tap-swiping to change the slideshow image?

Turns out it's possible. This turns your slider into a swiper. The user interaction changes from an activated slide by way of a click, to a gesture that the user is committing: a swipe. This feature is often referred to as a Drupal swiper.

Drupal Swiper

You could use the jQuery TouchSwipe plugin. Alas, that requires integrating yet another plugin library. What about writing up some custom JavaScript to integrate the basic touch sensing yourself, then integrating the reaction with Views Slideshow?

That's just what I needed to do on a project that had to keep using the Drupal module Views Slideshow. What I didn't want to do is attempt to rewrite or override an existing part of Views Slideshow. After all, the module already has all the pieces in place - I just needed to have a script capture the user's "touch" action and then apply an appropriate slide change. Here's just how to do that:

jQuery to Capture a Swipe and then Trigger a Slide Change

You can trigger a "next" or "previous" click event on a slideshow upon swipe to change the slide like this (you'll need to change the element classes as they relate to your slideshow):

/*
*  Assign handlers to the simple direction handlers.
*/
var swipeOptions= {
swipeLeft:swipeLeft,
swipeRight:swipeRight,
threshold:30
}

$(function() {
// Attach swiping event
$("div.slideshow").swipe( swipeOptions );
}
);
// Swipe handlers:
// The only arg passed is the original touch event object
function swipeLeft(event, direction) {
  $('#views_slideshow_controls_text_next_view_name a') .trigger('click');
}
function swipeRight(event, direction) {
  $('#views_slideshow_controls_text_previous_view_name a') .trigger('click');
}

Implementing this JavaScript (jQuery) code will give you a swipe compatible slider or swiper.

Drupal Slider with FlexSlider: Touch Swipe Sensitive Carousels

Turns out there's a better way though which is somewhat new. FlexSlider, a plugin to the Views Slideshow module might just make your day. The FlexSlider module has become a separate entity from the Views Slideshow module over the years; you can use as more than just a display plugin for Views Slideshow. FlexSlider offers its own Drupal slider carousel that can fit your needs without ever using Views Slideshow in some cases. FlexSlider offers swipe support for Drupal sliders. FlexSlider is a great way to make your own Drupal swiper.

Update: Drupal.org user kbasarab has turned this into a sandbox project if you'd like a more direct solution.

If you enjoyed this Drupal guide to image sliders with touch support, consider sharing it. If you're still having trouble, get in touch to hire the Drupal experts.

Jan 17 2012
Jan 17

Drupal 6 has a lot of database API commands, although one common task that continues to come up is how to get results out of a query more than once, without repeating the query. I've not seen this documented elsewhere so I thought it was worth noting.

Why bother?

Excellent question. Shouldn't I have written a better query? Our need was to go through the resultset from the db_query and work out the highest and lowest values, then, perform some complex maths on each row that depended on knowing the highest and lowest values.

One possibility was to perform an extra two queries, getting high and low values, but this turned out to be slow. Another would be to order the original query from lowest to highest and just cherry-pick the start and end values, although the ORDER BY on the query turned out to be slow enough to be cumbersome.

It's as easy as...

Assuming we have a $result as the result of a db_query(), we just need to $result->data_seek(0):

  1. $highest = 0;

  2. $lowest = NULL;

  3. // Determine high and low values from the query.

  4. while ($record = db_fetch_object($result)) {

  5.   if ($record->count > $highest) {

  6.     $highest = $record->count;

  7.   }

  8.   if ($lowest === NULL || $record->count < $lowest) {

  9.     $lowest = $record->count;

  10.   }

  11. }

  12. // Reset the pointer to the first row in the result set.

  13. $result->data_seek(0);

  14. while ($record = db_fetch_object($result)) {

  15.   // do complicated calculations to achieve world domination.

  16. }

Nice!

Jan 12 2012
Jan 12

Documenting your Drupal code using PHPDoc is part of building any kind of Drupal site that involves writing code, whether you're writing a mega-module like views, or just writing a quick front-end theme. This quick reference guide will get you going, or act as a simple refresher if you haven't done it for a while.

Why document?

To put it really simply, your code is not finished unless it is documented. Documentation helps other people understand your code, it helps you understand your own code once you've come back to it after 6 months, and it even helps you write better code, making you think about what you're writing. PHPDoc comments, in particular, which live at the beginning of funcitons, can automate the process of building the API for your code (this is what api.drupal.org uses).

However, I'm going to make the assumption you already want to document your code, otherwise you wouldn't have read this far, right?

What do I document?

Everything. No, seriously. Every function, class and method. If there is a function in your code that has no PHPDoc comment at the top, you should go back and write documentation for it.

When should I document?

As you're writing the code. If you write the code, and then go back to document it, the chances are you'll either give up because you can't be bothered, or your documentation will be worse because you won't remember as clearly what each individual function does. A good IDE (integrated development environment) will generate PHPDoc stubs, so you write the function signature (the line that starts "function" and has all the parameters) and the IDE will generate a blank PHPDoc block in the correct format. See our guide to setting up JetBrains PhpStorm if you want a recommendation on a solid IDE.

What if it's just a hook?

You don't need to fully explain what the hook does, but you still need to document it. Just write what hook you're implementing. The reader will then know to look in the API to find the definition for the hook. See Doxygen and comment formatting conventions for more.

  1. /**

  2.  * Implements hook_menu().

  3.  */

What if it's form API stuff?

You can just document it like this:

  1. /**

  2.  * Submission handler for mymodule_form().

  3.  */

  4. function mymodule_form_submit($form, &$form_state) {

  5.   // code here

  6. }

  7. /**

  8.  * Validation handler for mymodule_form().

  9.  */

  10. function mymodule_form_validate($form, &$form_state) {

  11.   // code here

  12. }

The function should be summarised on the first line

The first line of your PHPDoc block should contain a summary of the function's purpose.:

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  */

If you want to explain it in more detail, that's great. No, really, that's super that you want to write more than a single line! Do it! Leave a completely blank line between your summary and the rest of the PHPDoc block.

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * Will check to make sure that the foo's bar is correct before

  5.  * attempting to do anything, and calculates the baz ratio

  6.  * internally as it goes.

  7.  */

Always document the return value

Some functions don't return anything. That's fine, just say it returns void. Otherwise, give the type that it returns, and give a description of what the caller can expect to get out of the function:

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * @return string

  5.  *   The text describing the foo.

  6.  */

Note that the text describing what the function returns is indented by 2 spaces from the @return, and if it goes onto multiple lines, indent those too.

The comment block should never go beyond 80 characters in line length. All IDEs and most text editors can show you an 80-column "margin" or "print margin" which will let you know where to wrap comment lines.

Documenting parameters

You need to document every single parameter that gets passed into your function. You should use @param type $name (the type should come before the parameter name). Don't leave the type out! It helps massively in understanding what to give to the function.

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * @param int $foo_id

  5.  *   The numeric ID of the foo to be retrieved.

  6.  *

  7.  * @return string

  8.  *   The text describing the foo.

  9.  */

  10. function mymodule_retrieve_foo($foo_id) {

  11.   // code here

  12. }

Note how, in the example above, there is a blank line between the parameter listing and the return value.

For parameters that can accept more than one type, you can always write:

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * @param int|string $foo

  5.  *   The numeric ID or the machine-readable name of the foo to be retrieved.

  6.  *

  7.  * @return string

  8.  *   The text describing the foo.

  9.  */

  10. function mymodule_retrieve_foo($foo) {

  11.   // code here

  12. }

There are times when the parameter might be able to take so many types that you might want to write:

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * @param mixed $foo

  5.  *   The numeric ID, machine-readable name, or array representation

  6.  *   of the foo to be retrieved.

  7.  *

  8.  * @return string

  9.  *   The text describing the foo.

  10.  */

  11. function mymodule_retrieve_foo($foo_id) {

  12.   // code here

  13. }

Documenting arrays as parameters or return values

If the parameter or return value is an array, it's not enough to just declare that it's an array, you need to explain what keys are expected in the array, and what values they can have. Don't worry if your PHPDoc blocks are long. You're using a proper IDE, not Dreamweaver or notepad, right? So you have a function list and you can quickly jump to the definition of any function within your code? Of course you can, so you needn't worry about scrolling through loads of PHPDoc.

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * @param int $foo_id

  5.  *   The numeric ID of the foo to be retrieved.

  6.  *

  7.  * @return array

  8.  *   An array representing the foo, with these keys:

  9.  *   - id: the numeric ID of the foo.

  10.  *   - name: the machine-readable name of the foo.

  11.  *   - created: a UNIX timestamp representing the foo's creation date and time.

  12.  */

  13. function mymodule_retrieve_foo($foo_id) {

  14.   // code here

  15. }

What your documentation should say

Don't explain how PHP or Drupal works. Expect that the reader already knows this information. Explain, in human terms, what the code does, and highlight any unexpected behaviour. The reader should be able to understand how to call the function, what it does, and what it will give back, without having to read the code. The code is there, of course, but the element of human error can be reduced by properly documenting things.

A (more or less) complete example

  1. /**

  2.  * Retrieves a complete foo from the database.

  3.  *

  4.  * Will check to make sure that the foo's bar is correct before

  5.  * attempting to do anything, and calculates the baz ratio

  6.  * internally as it goes.

  7.  *

  8.  * @param int $foo_id

  9.  *   The numeric ID of the foo to be retrieved.

  10.  * @param array $options

  11.  *   An array of extra information used to retrieve the foo, with keys like this:

  12.  *   - color: a string representing the hex colour code for the foo.

  13.  *   - bar: a string representing the type of bar to be returned with the foo.

  14.  *   - html: TRUE or FALSE. Determines whether to return the foo as HTML or not.

  15.  *

  16.  * @return string

  17.  *   The foo represented as a string, surrounded by HTML if that option was provided.

  18.  */

  19. function mymodule_retrieve_foo($foo_id, $foo_type) {

  20.   // code here

  21. }

Your comments

I intend this to serve as a handy reference guide for anyone who quickly needs to see examples that aren't covered by the coding standards document, so do let me know about any corrections, or any additions you might like to see.

Dec 12 2011
Dec 12

Healthcare, love it or hate it, it's not going away and in fact the healthcare industry is booming and continues to grow. Almost daily we hear about some revolutionary break through in medicine that will help us to lead longer healthier lives. The web has made sharing knowledge and information easier and easier and the emergence of smart phones allows anyone to access years of historical data at their fingertips. The problem is that traditionally this data has been uploaded through systems that are archaic and quickly becoming obsolete thanks to the rapid emergence of open source tools like Drupal.

Over the past few years, we've seen Drupal's adoption in the arts and entertainment industry, government organizations, online publishing, social communities and now healthcare. At LevelTen we have had the opportunity to implement Drupal for numerous healthcare industry clients like: Caris Life Sciences, Health Market Science, Mission Pharmacal and McKesson to name a few. Just like those in other industries, the medical world is starting to realize the speed at which they can deploy new products and brand focused sites utilizing Drupal's intelligent framework.

The healthcare industry is extremely specialized and often times the information can be confusing or overwhelming to the end users. Utilizing Drupal, a website can be easily modified or changed based upon feedback from patients and site visitors, and ultimately continue to make the site better and more user-friendly over time as a result of that feedback. Plus, some of the more advanced features allow for easily sharing related information and content; in the long run those extra tools will equate to a greater visitor return rate and longer website visit times.

Maybe you're considering Drupal for your medical organization; here are just a couple of great points to consider:

  • Integration - Drupal has a very sophisticated structure and as such can be tied into almost any applications, applications with a solid API are even easier. The benefit of integration is a universal experience for all of your site users and visitors.
  • Customization - Drupal has over 8000 modules (extensions to add functionality) currently available and that list only continues to grow. The benefit speaks for it's self, but the more options available to choose from the faster your site can be deployed, ultimately lowering costs.
  • Easy to Update - Drupal is a CMS and a framework both; the CMS portion when combined with the right modules, makes it easy for non-technical staff to update and manage the website.

I could go on and on, but if you're in the healthcare industry and reading this then Drupal is probably already on your radar; either way I would love to speak with you about some of our past projects and approach to see how we might be able to help you.


Get Drupal help when you need it most! Find hundreds of great tutorials. Track, rate, comment and more. Create Account
Dec 01 2011
Dec 01

JetBrains PhpStorm, is, surprisingly, an incredible IDE, and works extremely well for Drupal development. We took some time to go through all the various custom settings and get things set up to obey Drupal's coding standards, so we thought we'd share.

First of all, JetBrains's PhpStorm IDE is payware. Second of all, I lost so many hours of my life to frustrations with Eclipse that I was quite happy to fork out the relatively low cost once I'd given it a trial. This is not a post to discuss IDEs or the merits of one platform above another, but suffice is to say that PhpStorm, against all odds, is now my preferred IDE on Linux. YMMV.

I'm going to assume you've set it up, you're using Ubuntu (mostly it won't matter what OS you're on for this blog post) and you're using the Sun version of Java. You are using the Sun version, right?!

Basic settings

Head into the settings from File > Settings.

First, go to Editor and in the Other section, set Strip trailing spaces on Save to All. Also, turn on Ensure blank line before end of file on Save.

Now, expand Editor and head to Editor > Apperance. Turn on Show line numbers unless you love not knowing what line you're on.

Head to Code Style > PHP and make sure Global settings is in use at the top, otherwise you'll have to set these options for each project you work on. Change Tab size to 2 (usually it defaults to 4) and also change Indent and Continuation indent to 2 too.

The rest of the settings in Code style > PHP are actually very sensible, and the only other thing you might want to consider is in the Other tab, turning on Indent code in PHP tags which is not a Drupal standards issue, but I do prefer code that way.

Next, check that under File encodings, the IDE encoding is on UTF-8. You will also want to make sure that under Code Style > General you have set Line separator (for new files) to Unix (this is especially important if you're using Windows) and set Right margin (columns) to 80.

Again, under Code Style > General, set Tab size, Indent, and Continuation indent to 2. Head into each section of Code Style, such as CSS, HTML, etc and make sure all indents are set to 2 on everything.

File types

Drupal has some unusual file extensions and you will need to configure these under PhpStorm to be able to edit them. Head to File Types, click PHP files in the upper pane, and add *.install, *.module, *.profile, *.test, and *.theme.

Inspections

Inspections are a really powerful way of letting you know you're writing crap code, and will often catch things that most humans will miss. You absolutely don't want inspections to be showing you any false positives if possible, since this will create a 'boy who cried wolf' effect where you won't notice things that are genuinely wrong because you're so accustomed to looking at 'wrong' inspections.

Head to Inspections. For me, it's best to set up the global inspections and use them for all projects, so that's what we'll cover here, although it's also possible to have different inspections for different projects. First, choose Default in the drop-down at the top left (not Project default) and click Share profile.

Turn off the Spelling inspection, unless you really enjoy your IDE telling you that function names are not valid English words! Alternatively you can open it up, choose the Typo inspection, and configure it to only spell check in comments, but I prefer to just disable it and spell things properly myself.

Open up PHP > PHPDoc. You will probably want to turn off Missing @return statement and PHPDoc comment matches function/method signature, and turn on Missing PHPDoc comment. The reason is that under Drupal standards, you don't need to fully document hook implementations. If you leave on those inspections, you will get a lot of errors. On the other hand, you should never have any function that has no documentation for it, even if it's just to say it's implementing a hook, so turning on that inspection will help you out.

Head to PHP > Undefined and turn off undefined variable and undefined field. The reason is that, for whatever reason, it was decided that Drupal should use stdClass objects as data stores, rather than arrays, so you end up with things like $node->title, which, since $node is an object of type stdClass, and not a proper object, generates an undefined field warning. You might need to turn off more of these, so try it out and see how it goes.

Project-specific

Once you've actually opened up a project (which should be as simple as opening a directory, as PhpStorm can detect things like whether it's under git source control), you will want to set up some include paths. This only applies if, like us, you run Drupal multi-site, and your project is just the site itself, rather than the entire Drupal installation. If you added the entire Drupal installation as your project, you needn't worry about this, as it's taken care of for you.

In the project panel, right-click where it says External Libraries and choose Configure Include Paths. Now, add 3 new include paths. These will be /path/to/drupal6/includes, /path/to/drupal6/modules, and /path/to/drupal6/sites/all/modules. This will allow PhpStorm to know about all Drupal's internal functions and any functions inside modules like views where these are stored outside of the current project.

Enjoy

That should be it. You're now good to go develop a Drupal site, module, theme or whatever it is you're doing using PhpStorm. If I did miss anything off this list, do let me know in the comments and I can add it in.

Quick update: Thanks to Timon Royer for letting us know about his PhpStorm and Drupal video which runs you through some of the ways PhpStorm makes your life as a Drupal developer easier. He seems to be a mac user, but we can overlook that, right? ;)

Pages

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