Skip to Content


Commerce Guys: The Apple Store discovers the Power of Content

Planet Drupal - 11 August 2015 - 5:19am
At Commerce Guys we know the value of content-driven commerce. It’s the reason our founders built Drupal Commerce, to enable the seamless blending of content management and robust commerce within a single software platform. We are thrilled to see more and more people talking about this continued transformation in the eCommerce market.

On Friday, Apple Inc., one of the largest companies in the world, announced what they see as a major shift in their eCommerce operations via a post on their website titled "A new way to learn and shop on": Content and Commerce are two sides to the same coin. Without Content, no one knows what you're selling. Without Commerce, how does your website help your business grow? A powerful platform that allows for seamless blending of the two can make a business grow by strengthening its ability to attract new customers and effortlessly convert browsers into buyers.

Most eCommerce platforms do a great job at transactional eCommerce, but in today's ever changing online landscape, a business needs more than just a checkout experience to attract and engage prospects and turn them into customers. A flexible framework like Drupal Commerce allows companies to build a web experience with a single software that controls both sides of the coin. Content that engages and attracts customers and feature rich eCommerce which improves conversion rates.

As Apple stated “Now you can shop everywhere across and purchase products right where you learn about them.” Now that Apple has seen the value of blending rich product information with eCommerce, something that Commerce Guys already embraced, perhaps you should consider making similar improvements to your eCommerce strategy by taking a look at Drupal Commerce.
Categories: Drupal

Google Product Taxonomy

New Drupal Modules - 11 August 2015 - 5:11am

Google Product Taxonomy module provides the following features:

Categories: Drupal

Drupalize.Me: Configure Search API Solr to Use Stopwords When Indexing Content

Planet Drupal - 11 August 2015 - 5:02am

Most written text has a lot of functional words, like "a", "the", or "is" which are important to the person reading the content as they help it flow in a cohesive manner, but aren't necessary as important to someone searching the content of your site. In this tutorial we'll look at ways to ignore those words in our search index.

Categories: Drupal

Deeson: Executing Drupal Behat tests on Vagrant from within PHPStorm

Planet Drupal - 11 August 2015 - 12:00am

If you've made it past the title, congratulations! There are lots of concepts discussed in this article, I'll mention Vagrant and Behat very briefly, but won't go into details as I'll provide better places to find information on getting started with those tools. This article is mainly for people who use Vagrant for Drupal development, have at least some idea as to how to make a Behat test run on their Vagrant box and want to run those tests from within the PHPStorm IDE.


Vagrant is a tool for creating consistent and portable development environments. The intention is to give all your developers the tools they need to do their job in a single package such as a database and web server. There is work involved in initially setting it up, but once you have a workable receipe you can pass that round to all your developers so they have the consistent development environment. All the tools run from within a Virtual Box, a complete operating system which can be made to be much more like the production environment.

Some helpful people have already done most of the hard work for you so you can start with what they have already done. Popular choices are VLAD and VDD. At Deeson, we tooled the base VDD recipe and added to it to build our own environment which uses a 64 bit version of Ubuntu Trusty64 as well as solr, nginx and a load of other tools. You can find Deeson's VDD recipe at

Drupal Behat Tests with Drupalextension

Behat is a PHP tool for creating and running functional tests and, potentially, engaging in something called behaviour driven development (BDD). A functional test describes some function of the finished website. This differs from unit tests, in that a unit test should test some small piece of the code in isolation, whereas a functional test will test a complete path through the system potentially touching many parts of the codebase.

If you are using the Deeson version of VDD linked above then you already have a globally installed copy of Behat. If you are using your own Vagrant box then you will need to add Behat and the Drupal extension to it. The instructions for installing Behat and the Drupalextension can be found at

System configuration

I am assuming you have followed the instruction on the Drupalextension site linked above to get a Behat test running on the command line on your Vagrant box. For the rest of the article, I will also assume the following variables, you should subsitute these with you own values where appropriate:

  • Project root on the Vagrant box is at /var/www/vhosts/
  • Drupal docroot is within the project root on the Vagrant box at /var/www/vhosts/
  • Behat tests are on the Vagrant box at /var/www/vhosts/ with the behat.yml configuration file at /var/www/vhosts/
  • The project root is also on your local computer at ~/Sites/ such that the drupal docroot is therefore at ~/Sites/ (Windows users, your milage may vary)
  • Your VagrantFile is located on your local computer at ~/Applications/vdd. This is the directory you checked out VDD or the Deeson equivalent if thats what you are using for Vagrant. The VagrantFile is a file in that directory which describes how your Vagrant is configured.
PHPStorm Vagrant Configuration

With the scene set we finally arrive at how to configure your PHPStorm. Within PHPStorm, we want all the tests to execute when we press the play button. Because the tests are running on the remote Vagrant box we need to setup a remote PHP interpreter within PHPStorm and tell PHPStorm this is accessible via Vagrant.

  1. PHPStorm -> Preferences
  2. Tools -> Vagrant

In the configuration for Vagrant you should set the path to your VagrantFile. This file describes your Vagrant configuration and would be in the folder you checked out VDD or the Deeson equivalent into. My settings are shown below.

PHPStorm PHP Interpreter Configuration

Next you need to tell PHPStorm that PHP is running on the Vagrant instance and can be used to run code with.

  1. PHPStorm -> Preferences
  2. Languages and Frameworks -> PHP
  3. On the Interpreter line click the triple dots button to open the Interpreters configuration screen. 
  4. Click the plus (top left) to add a new interpreter
  5. Give it a name (e.g. Vagrant PHP)
  6. Choose Vagrant
  7. Specify the locationt to your VagrantFile (again)
  8. Specify the location of PHP on the Vagrant box (e.g. /usr/bin/php). Note that clicking the Reload button here may make PHPStorm work it out for you.

VDD users may get an error about unmatched paths when configuring the Interpreter. You are using a dynamically mounting VagrantFile, and PHPStorm is unable to work out how you project directory maps from your local computer to the Vagrant box. You will need to specify the mappings on a per project basis in your VagrantFile as follows.

Under Vagrant.configure("2") do |config| add the following lines, remebering to replace the local path to the correct path for your system. You'll note that this code will never get run when the VagrantFile is properly used as it is inside an impossible block of code. However, it provides the information PHPStorm needs to work out the mappings from local computer to Vagrant box paths for the project.

if 1 > 2 config.vm.synced_folder "/Users/johnennew/Sites/", "/var/www/vhosts/" end Configuring Behat for PHPStorm
  1. PHPStorm -> Preferences
  2. Languages & Frameworks -> PHP -> Behat
  3. Click the plus (top left)
  4. Choose the Vagrant PHP Intepreter
  5. Specify where behat executable is located within the Vagrant box. If you followed the instructions for drupalextension to install Behat globally then this will be /usr/local/bin/behat
  6. Press the reload button (two circular arrows) to have PHPStorm verify the path to Behat is correct
  7. Tick Default configuration file
  8. Find your behat.yml file in your project locally (for me this is ~/Sites/
Configuring PHPStorm Run Configuration

We are now ready to configure the run mode in PHPStorm so that the green play button becomes available and pressing it executes the tests

  1. Run -> Edit configurations ...
  2. Click the plus (top left) then Behat
  3. Name: Behat tests
  4. Test scope: Defined in configuration file

Press the green play button in PHPStorm and in theory your tests will now be executed on the Vagrant box and the results sent to PHPStorm.

If you would like to just test part of the suite of tests you can do so by tagging the tests and then creating a new Run configuration which specifies which tags to run. Lets say you have tagged some of your scenarios as @justthis

  1. Run -> Edit configurations...
  2. Press the plus symbol (top left) to add a new configuration and choose Behat
  3. Name: Just this
  4. Test scope: Defined in the configuration file
  5. Test runner options: --tags="justthis"
  6. Click OK

Now you have a dropdown choice next to the play button in PHPStorm to choose either Behat tests or Just this. Choose Just this and press play and only the scenarios tagged @justthis will be run.

Happy testing!

Categories: Drupal

PreviousNext: Over the Waterfall: The future is Agile

Planet Drupal - 10 August 2015 - 11:44pm

I recently attained the Certified Scrum Professional (CSP) certification and found the process a good opportunity to reflect on what led me to Scrum. It was also a chance to take pause and consider our  industry approach to project management.

Categories: Drupal

Wunderkraut blog: Stylus with Gulp: a fantastically fast front-end workflow.

Planet Drupal - 10 August 2015 - 11:09pm

Modern CSS preprocessors are hardly a surprise to anybody these days, SASS and LESS have polarized the developer ecosystem and workflow tools like Grunt and Gulp have become welcome additions to both camps. Not so welcome additions to this new reality are compile times that in complex projects can stretch into seconds, sometimes in the double digits, and multiple dependency trees. How does a compile time of milliseconds with exactly one dependency sound? Intrigued? Then keep reading!

In this post we'll be taking a look at one solution to the aforementioned problem: slow compile times and multiple dependencies.

First, lets take a look at the most obious solution to speeding things up: eliminating layers in our workflow stack. Say, we use Grunt (who doesn't!) or even better, Gulp (awesome!). What dependency is required to run those awesome things? Node.js, of course. Now, wouldn't it be great if our preprocessor also ran on Node, and maybe its extensions and packages too? Never fear, Stylus is here!

Stylus is the underdog and player number three in what at first glance appears to be a two-horse race.

While Stylus does not have as large a collection of extensions as the other two, the ones that are available are top-notch and cover all the bases. There's the nib library for all things CSS3, Rupture for media query handling, and an absolutely fantastic Jeet for a grid system amongs others.

Stylus won't strongarm you into any kind of a specific syntax style. You can use standard CSS syntax on one extreme, or white-space delimited syntax on the other and everything in between. With great power, of course, comes great responsibility, so unless you enforce a certain discipline, there is potential for some not-so-pretty code.

Next thing, Grunt or Gulp? If neither of those words evoke a strong sense of tribal belonging, then go with Gulp, otherwise... look into Gulp and see if you can live with it.  We'll be setting up a killer workflow based on Gulp right here.

So lets get right down to business: lets set up a real-world Drupal theme development environment that you'll be able to use right away.

tl;dr scroll down to the bottom and download a package that contains everything described here, otherwise:

  1. Remember that single dependency? What does it mean exactly? It means that there is only one file to maintain for versioning all our packages and tools: node's package.json, here is mine: { "name": "project_name", "version": "0.0.0", "dependencies": { "stylus": "^0.52.0", "stylus-type-utils": "0.0.3" }, "devDependencies": { "bower": "^1.4.1", "browser-sync": "^2.8.1", "gulp": "^3.9.0", "gulp-autoprefixer": "^2.3.1", "gulp-concat": "^2.6.0", "gulp-jshint": "^1.11.2", "gulp-rename": "^1.2.2", "gulp-sourcemaps": "^1.5.2", "gulp-strip-debug": "^1.0.2", "gulp-stylus": "^2.0.4", "gulp-uglify": "^1.2.0", "jeet": "^6.1.2", "jshint-stylish": "^2.0.1", "nib": "^1.1.0", "rupture": "^0.6.1", "yargs": "^3.18.0" }, "scripts": { "postinstall": "find node_modules/ -name '*.info' -type f -delete" } } Place this in your theme's root (name it package.json).
  2. Configure Gulp: gulpfile.js, here is mine: 'use strict'; var gulp = require('gulp'); var prefix = require('gulp-autoprefixer'); var uglify = require('gulp-uglify'); var jshint = require('gulp-jshint'); var concat = require('gulp-concat'); var stylish = require('jshint-stylish'); var rename = require('gulp-rename'); var stripDebug = require('gulp-strip-debug'); var browserSync = require('browser-sync').create(); var stylus = require('gulp-stylus'); var sourcemaps = require('gulp-sourcemaps'); var reload = browserSync.reload; var args = require('yargs').argv; var nib = require('nib'); var serverUrl = args.proxy; if (!serverUrl) { serverUrl = ''; } // Confingure our directories var paths = { js: 'js/**/*.js', jsDest: 'aggregated-js', css: 'css', styles: 'styles', ds: 'ds_layouts', panels: 'panel_layouts', img: 'img', }; ////////////////////////////// // Begin Script Tasks ////////////////////////////// gulp.task('lint', function () { return gulp.src([ paths.js ]) .pipe(jshint()) .pipe(jshint.reporter(stylish)) }); gulp.task('scripts', function() { return gulp.src(paths.js) // Concatenate everything within the JavaScript folder. .pipe(concat('scripts.js')) .pipe(gulp.dest(paths.jsDest)) .pipe(rename('scripts.min.js')) // Strip all debugger code out. .pipe(stripDebug()) // Minify the JavaScript. .pipe(uglify()) .pipe(gulp.dest(paths.jsDest)); }); ////////////////////////////// // Stylus Tasks ////////////////////////////// gulp.task('styles', function () { gulp.src(paths.styles + '/*.styl') .pipe(sourcemaps.init()) .pipe(stylus({ paths: ['node_modules', 'styles/globals'], import: ['jeet/stylus/jeet', 'stylus-type-utils', 'nib', 'rupture/rupture', 'variables', 'mixins'], use: [nib()], 'include css': true })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest(paths.css)) .pipe(; }); gulp.task('ds', function () { gulp.src(paths.ds + '/**/*.styl') .pipe(sourcemaps.init()) .pipe(stylus({ paths: ['node_modules', 'styles/globals'], import: ['jeet/stylus/jeet', 'stylus-type-utils', 'nib', 'rupture/rupture', 'variables', 'mixins'], use: [nib()] })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest(paths.ds)) .pipe(; }); gulp.task('panels', function () { gulp.src(paths.panels + '/**/*.styl') .pipe(sourcemaps.init()) .pipe(stylus({ paths: ['node_modules', 'styles/globals'], import: ['jeet/stylus/jeet', 'stylus-type-utils', 'nib', 'rupture/rupture', 'variables', 'mixins'], use: [nib()] })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest(paths.panels)) .pipe(; }); ////////////////////////////// // Autoprefixer Tasks ////////////////////////////// gulp.task('prefix', function () { gulp.src(paths.css + '/*.css') .pipe(prefix(["last 8 version", "> 1%", "ie 8"])) .pipe(gulp.dest(paths.css)); }); ////////////////////////////// // Watch ////////////////////////////// gulp.task('watch', function () {, ['lint', 'scripts']); + '/**/*.styl', ['styles']); + '/**/*.styl', ['ds']); + '/**/*.styl', ['panels']); + '/globals/**/*.styl', ['styles', 'ds', 'panels']); }); ////////////////////////////// // BrowserSync Task ////////////////////////////// gulp.task('browserSync', function () { browserSync.init({ proxy: serverUrl }); }); ////////////////////////////// // Server Tasks ////////////////////////////// gulp.task('default', ['scripts', 'watch', 'prefix']); gulp.task('serve', ['scripts', 'watch', 'prefix', 'browserSync']) Place it in your theme's root, name it gulpfile.js

  3. Now, the gulpfile.js above expects things to be in certain places, let's not disappoint it!
    Create a file structure like this: (if you download the package at the bottom of the page, you'll have it all set)

    theme_name |\ | ds_layouts |\ | panel_layouts |\ | aggregated_js |\ | js |\ | css |\ | img |\ | styles | |\ | | globals | |\ | | modules | \ | includes | style.styl \

    You'll notice that in this case I'm using a couple of assumptions.

    1. You'll be using Display Suite (because you should!)
    2. You'll be using Panels (because why not)
    While Display Suite, once enabled, will look for a folder named ds_layouts in your theme, Panels needs to be informed of our panel_layouts directory. To do so, add this line somewhere near the bottom of your file:  plugins[panels][layouts] = panel_layouts

    The rest of the directory structure is as follows:
    1. aggregated_js
      Gulp will lint, concatenate and uglify whatever scripts it finds in the js folder (or its subfolders) into a neat little file called scripts.min.js and place that here.
    2. js
      See point 1.
    3. css
      Destination directory for compiled .styl files and sourcemaps. The Gulp workflow will autoprefix the compiled files to be compatible with browser versions as specified in the gulp file (at the moment, 8 versions back from current, see prefix task definition in the gulpfile.js)
    4. img
      We'll keep theme image files here.
    5. styles
      Sources for stylus.

      Files with the extension .styl found immediately inside the styles directory will result in their respective compiled equivalents in CSS form in the css directory, anything in the globals subdirectory will be included during compile time with any .styl file (even the files in ds_layouts and panels_layouts! Do you see where this is going?) so naturally it's a good spot to put our variable definitions, mixins, extendables and such things. Modules subdirectory contains partials to be included in the main file(s) (in our case, style.styl), they won't be included automatically, so style.styl file must contain the following at its beginning (and ideally, that would be all it contains):

      @import 'includes/*.css' @import 'modules/**/*.styl' Includes subdirectory will have any pre-compiled css files (such as html5reset.css) which will be rolled as the first thing into compiled css. You can organize the structure in the modules subdirectory whichever way you please, incuding creating your own subdirectories for ease of use or reading, they will all be automatically incuded at compile time.
  4. Now that we've done the preparatory work, how do we actually make this whole thing work?
    1. From the theme root directory run: npm install (assuming you have Node.js already installed on your system)
    2. From the theme root, run: gulp
      Gulp will now listen for changes to your js or styl files and promptly compile them into css and minimized js for you! Congratulations!
    3. Additionally, you could take advantage of the awesome BrowserSync and run: gulp serve
      This will do the same as point number 2 above, but will also run a BrowserSync server which will reload the browsers (and other devices connected to the site) upon detecting a change to your CSS or JS files and will sync events on page (including scrolling and hovering!). By default, it will proxy a default site found at "" and re-broadcast it, if you will, at localhost:3000. You can change the default proxy by modifyling relevant line of gulpfile.js (search for, it is there only once), or you can specify your own proxy like this: gulp serve
    4. What about those ds_layouts and panel_layouts directories, what do those have to do with stylus you ask? They are there to make your life easier when working with ds and panels templates. Both of those have an option to include css file with the template, and if you were to place a stylus file with the appropriate filename in the template subdirectory, Gulp will compile that file using the global includes (so your mixins, variables, your grid and breakpoint will all be available to you!), and place it in the same place as source for you to include in the template! This will make the styles defined there availabe to both front, and back ends. You'll be able to view the layout of your page in its near compelted form when working with page manager, for example.

If you've managed to follow along and everthing worked, wonderful! I've used node version 0.12.7 with latest available versions of all node packages to write this setup. If something does not work, download and extract the package below. It is a barebones Drupal theme ready to be set as a subtheme of an existing theme or act as standalone. It is also possible that Gulp wants to be installed globally, in that case, simply run npm install -g gulp from the theme root.

Categories: Drupal

The RPGnet Newsletter: RPGnet Newsletter #16

RPGNet - 10 August 2015 - 11:00pm
Star Trek, women,and more.
Categories: Game Theory & Design

Idea Emporium: Norse Mythos, Part One

RPGNet - 10 August 2015 - 11:00pm
Lovecraft, with inspiration from the Norse.
Categories: Game Theory & Design

InternetDevels: Using PDF on Your Drupal Website

Planet Drupal - 10 August 2015 - 10:55pm

Drupal web development is at its peak so you can get a cutting-edge website by hiring a great Drupal team. However, if you want to try and build a Drupal website by yourself, we hope some tips from our guest blogger Jack Dawson, founder of Big Drop Inc., will be useful to you. So let us give him the floor.

Read more
Categories: Drupal

C# memory and performance tips for Unity, part 2 - by Robert Zubek Blogs - 10 August 2015 - 9:53pm
A collection of C# performance tips for Unity, focusing on identifying and removing unnecessary memory allocations.
Categories: Game Theory & Design

Death, Readability and 'Hard' vs 'Unfair' - by Asher Einhorn Blogs - 10 August 2015 - 9:53pm
With design that strongly pushes on readable threats, players can be challenged more, but die less.
Categories: Game Theory & Design

The Two User Acquisition Tactics That Got Us Half a Million Players - by Gabriel Stürmer Blogs - 10 August 2015 - 9:53pm
Gabriel Stürmer, CMO of Cupcake Sweet Entertainment talks about what they did to get half a million users in their two casual games, Letters of Gold and Words of Gold.
Categories: Game Theory & Design

Body Parts and Motion Sickness in VR - by Matthew White Blogs - 10 August 2015 - 9:53pm
An investigation into some of the causes of motion sickness when using VR technology previously revealed that simulating a nose can mitigate some of the unpleasantness associated with this phenomenon. Turns out, legs can have a similar effect!
Categories: Game Theory & Design

Basic Illumination for Games, Part 1: Applying art concepts on interactive media - by Jorge Veloso Blogs - 10 August 2015 - 9:53pm
This articles explores the basic anatomy of visual information, reviews the famous 3-point lighting technique used in film and photography, and provides examples of how it translates to interactive media, mainly in abstract and side-scrolling games.
Categories: Game Theory & Design

Google AdMob implementation with GameMaker: Studio - by Nicholas Doane Blogs - 10 August 2015 - 9:53pm
Join us as we review what we have learned about implementing Google AdMob using GameMaker: Studio. We discuss preloading advertisements as well as making sure they are positioned perfectly for various iPad screen sizes, and provide a step-by-step guide.
Categories: Game Theory & Design

How data scientists slashed early churn in Top Eleven - by Milos Milosevic Blogs - 10 August 2015 - 9:32pm
Early user churn can destroy even the best games. Here’s how Nordeus, makers of the most played online sports game in the world, Top Eleven, identified early churners and turned them into valuable daily players.
Categories: Game Theory & Design
Syndicate content

about seo