Planet Drupal

Subscribe to Planet Drupal feed - aggregated feeds in category Planet Drupal
Updated: 43 min 5 sec ago

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

Tue, 11/08/2015 - 09:09

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: Elsewhere

InternetDevels: Using PDF on Your Drupal Website

Tue, 11/08/2015 - 08:55

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: Elsewhere

DrupalCon News: Session Spotlight: Dries is requesting your feedback

Tue, 11/08/2015 - 07:00

After four years in the making, Drupal 8 is right around the corner and Dries’ Retrospective at DrupalCon Barcelona will be dedicated to looking back at what we did and how we did it. With countless new features and improvements, getting Drupal 8 ready for release has been a huge community effort, and in his session, Dries would like to highlight feedback about the process in his Core Conversations talk.

Categories: Elsewhere

Chen Hui Jing: Drupal 101: Getting started with Drupal 7 theming

Tue, 11/08/2015 - 02:00

With Drupal 8 just around the corner, it may seem odd that I would write a post about Drupal 7 theming, but I figured it would take some time for Drupal 8 to really become mainstream. Also, when I do write that Drupal 8 theming post (coming soon), we can do some one to one comparisons on the things that have changed. Trust me, there are a lot of differences between the two.

A theme is like the skin for your website. Drupal 7 theming may seem complicated at first. Peeking into a theme folder reveals a bunch of folders littered with PHP files, stylesheets and who knows what else. The easiest way to wrap your head around things is...

Categories: Elsewhere

Steve Purkiss: What is Drupal?

Tue, 11/08/2015 - 01:08
Tuesday, 11th August 2015What is Drupal?

Drupal is people. Drupal is figuring out people. Drupal is figuring out how to make things better. Drupal is about feeding yourself and your family. Drupal is about feeding other people's families. Drupal is about going to places you'd never considered going to. Drupal is about laying in the lake and watching the stars at night. Drupal is about making money for your business. Drupal is about making things easier. Drupal is about accessiblity for all. Drupal is about opportunity for all. Drupal will tell you what you need to know. Drupal is there for you to tell and show. Drupal is the push and the struggle. Drupal is the hook. Drupal is about taking those moments to really get your teeth into something you're passionate about and feel like you're maybe making a difference. Drupal is about escapism. Drupal is firing up the laptop and tethering before you get on the plane so you can git clone the latest dev release to take a look through the code until you're sleepy just to show off a bit more Drupal to fellow passengers who may take a glance but also learn something at the time. Drupal is about sharing your costs. Drupal is there to learn how to share. Drupal is there to provide a path to follow. Drupal is about sharing your thoughts and visions. Drupal is finding out where the line is when you didn't even know there was a line. Drupal is finding out the magic of everyone. Drupal is about survival. Drupal is tolerance. Drupal is about sustainability. Drupal is opportunity for all. Drupal is forcing you to face up to your conditions. Drupal is understanding. Drupal is a battle, an upheal struggle. Drupal is simple. Drupal is about sharing. Drupal is about caring. Drupal is hugging. Drupal is your voice. Drupal is special. You are special. 

Drupal is your True Pal.


tags: Drupal PlanetPlanet DrupalWhat is Drupaldrupal
Categories: Elsewhere

Red Crackle: Creating the simplest headless Drupal 7 site

Mon, 10/08/2015 - 22:25
In What is headless Drupal post, you learned what exactly is headless Drupal. In this post, you will create the simplest headless Drupal application possible in less than 15 minutes. By the end of this post, you will have a simple HTML page. On loading this page, JS will send a request to Drupal. Drupal will generate a random number and send it back to the JS. JS will render it on the HTML page.
Categories: Elsewhere

Four Kitchens: REST Easy Part 2: Sub Property Boogaloo

Mon, 10/08/2015 - 22:10

This week we’ll continue where we left off after doing the ground work of creating a basic endpoint with the RESTful Drupal module. We skipped one crucial part: the body field. This week’s installment will cover our missing field, which requires extra care when used within a RESTful endpoint.

Categories: Elsewhere

Promet Source: Feature Branch Workflow the Promet Way

Mon, 10/08/2015 - 21:50

When you’re wrangling a slightly larger team of devs as we do here at Promet, the importance of strict naming conventions becomes apparent pretty quickly. Take the commonly referenced Git workflow from Victor Driessen, for example.

Categories: Elsewhere Happy birthday to me and Devel form debug module to you all

Mon, 10/08/2015 - 20:06
I’m turning 32 today. People love birthdays, to me it’s just another line number in a messed stack trace output (philosophy mode enabled).   Two years ago I released a drupal module called Get form id (deprecated from now on) that does one small task - it tells you any form's id ...

Read now

Categories: Elsewhere

Lullabot: Write Unit Tests for Your Drupal 7 Code (part 2)

Mon, 10/08/2015 - 19:12

This article is a continuation of Write Unit Tests for Your Drupal 7 Code (part 1), where I wrote about how important it is to have unit tests in your codebase and how you can start writing OOP code in Drupal 7 that can be tested with PHPUnit.

In this article I show you how this can be applied to a real life example.


I encourage you to start testing your code. Here are the most important points of the article:

Dependency Injection and Service Container

Jeremy Miller defines dependency injection as:

[...] In a nutshell, dependency injection just means that a given class or system is no longer responsible for instantiating their own dependencies.

In our MyClass we avoided instantiating CacheController by passing it through the constructor. This is a basic form of dependency injection. Acoording to Martin Fowler:

There are three main styles of dependency injection. The names I'm using for them are Constructor Injection, Setter Injection, and Interface Injection.

As long as you are injecting your dependencies, you will be able to swap those objects out with  their test doubles in your unit tests.

An effective way to pass objects into other objects is by using dependency injection via a service container. The service container will be in charge of giving the receiving class all the needed objects. Then, the receiving object will only need to get the service container. In our System Under Test (SUT), the service container will yield the actual objects, while in the unit test domain it will deliver mocked objects. Using a service container can be a little bit confusing at first, or even daunting, but it makes your API more stable and robust.

Using the service container, our example is changed to:

class MyClass implements MyClassInterface { // ... public function __construct(ContainerInterface $service_container) { $this->cacheController = $service_container->get('cache_controller'); $this->anotherService = $service_container->get('my_services.another_one'); } // ... public function myMethod() { $cache = $this->cacheController->cacheGet('cache_key'); // Here starts the logic we want to test. // ... } // ... }

Note that if you need to use a new service called 'my_services.another_one', the constructor signature remains unchanged. The services need to be declared separately in the service providers.

Dependency injection and service encapsulation is not only useful for mocking purposes, but also to help you to encapsulate your components –and services–. Borrowing, again, Jeremy Miller’s words:

Making sure that any new code that depends on undesirable legacy code uses Dependency Injection leaves an easier migration path to eliminate the legacy code later with all new code.

If you encapsulate your legacy dependencies you can ultimately write a new version and swap them out. Just like you do for your tests, but with the new implementation.

Just like with almost everything, there are several modules that will help you with these tasks:

  • Registry autoload will help you to structure your object oriented code by giving you autoloading if you follow the PSR-0 or PSR-4 standards.
  • Service container will provide you with a service container, with the added benefit that is very similar to the one that Drupal 8 will ship with.
  • XAutoload will give you both autoloading and a dependency injection container.

With these strategies, you will write code that can have it’s dependencies mocked. In the previous article I showed how to use fake classes or dummies for that. Now I want to show you how you can simplify that by using Mockery.

Mock your objects

Mockery is geared towards providing even more flexibility when creating mocks. Mockery is not tied to any test framework which makes it useful even if you decided to move away from PHPUnit.
In our previous example the test case would be:

// Called from the test case. $fake_cache_response = (object) array('data' => 1234); $cache_controller_fake = \Mockery::mock('CacheControllerInterface'); $cache_controller_fake->shouldReceive('cacheGet')->andReturn($fake_cache_response); $object = new MyClass($cache_controller_fake); $object->myMethod();

Here, I did not need to write a CacheControllerFake only for our test, I used Mockery instead.
PHPUnit comes with a great mock builder as well. Check its documentation to explore the possibilities. Sometimes you will want to use one or the other depending on how you want to mock your dependency, and the tools both frameworks offer. See the same example using PHPUnit instead of Mockery:

// Called from the test case. $fake_cache_response = (object) array('data' => 1234); $cache_controller_fake = $this ->getMockBuilder('CacheControllerInterface') ->getMock(); $cache_controller_fake->method('cacheGet')->willReturn($fake_cache_response); $object = new MyClass($cache_controller_fake); $object->myMethod();

Mocking your dependencies can be hard –but valuable– work. An alternative is to include the real dependency, if it does not break the test runner. The next section explains how to save some time using Drupal Unit Autoload.

Cutting corners

Sometimes writing tests for your code makes you realize that you need to use a class from another Drupal module. The first instinct would be, «no problem, let’s create a mock and inject it in place of the real object». That is a very good approach. However, it can be tedious to create and maintain all these mocks, especially for classes that don’t depend on a bootstrap. That code could just be required in your test case.

Since your unit test can be considered a standalone PHP script that executes some code –and makes some assertions– you could just use the require_once statement. This would include the code that contains the class definitions that your code needs. However, a better way of achieving this is by using Composer’s autoloader. An example composer.json in your tests directory would be:

{ "require-dev": { "phpunit/phpunit": "4.7.*", "mockery/mockery": "0.9.*" }, "autoload": { "psr-0": { "Drupal\\Component\\": "lib/" }, "psr-4": { "Drupal\\typed_entity\\": "../src/" } } }

With the previous example, your unit test script would know how to load any class in the Drupal\Component and Drupal\typed_entity namespaces. This will save you from writing test doubles for classes that you don’t have to mock.

At this point, you will be tempted to add classes from your module’s dependencies. The big problem is that every drupal module can be installed in a different location, so a simple ../../contrib/modulename will not do. That would only work for your installation, but not for others. This is one of the reasons why I wrote with Christian Lopez (penyaskito) the Drupal Unit Autoload. By adding Drupal Unit Autoload to your composer.json you can add references to Drupal core and other contributed modules. The following example speaks for itself:

{ "require-dev": { "phpunit/phpunit": "4.7.*", "mockery/mockery": "0.9.*", "mateu-aguilo-bosch/drupal-unit-autoload": "0.1.*" }, "autoload": { "psr-0": { "Drupal\\Component\\": "lib/", "Symfony\\": ["DRUPAL_CONTRIB<service_container>/lib"] }, "psr-4": { "Drupal\\typed_entity\\": "../src/", "Drupal\\service_container\\": ["DRUPAL_CONTRIB<service_container>/src"] }, "class-location": { "\\DrupalCacheInterface": "DRUPAL_ROOT/includes/", "\\ServiceContainer": "DRUPAL_CONTRIB<service_container>/lib/ServiceContainer.php" } } }

We added mateu-aguilo-bosch/drupal-unit-autoload to the testing setup, so we can include Drupal aware autoloading options to our composer.json.

Striving for the green

One of the most interesting possibilities that PHPUnit offers is code coverage. Code coverage is a measure used to describe the degree to which the methods are tested. Having a high coverage reduces the number of bugs in your code greatly. Moreover, adding new code with test coverage will help you ensure that you are not introducing any bugs along with the new code.

PhpStorm coverage integration.

A test harness with coverage information is a valuable tool to include in your CI tool. One way to execute all your PHPUnit cases is by adding a phpunit.xml file describing where the tests are located and other integrations. Running the phpunit command in that folder will execute all the tests.

Another good 3rd party service is coveralls. It will tell your CI tool how the coverage of your code will change with the pull request –or patch– in question; since Coveralls knows about most of the major CI tools almost no configuration is needed. Coveralls also provides a web UI to see what parts of the code are covered and the ones that are not. dashboard.

Write tests until you get 100% test coverage, or a satisfactory number. The higher the number the higher the confidence that the code is bug free.

Read the next section to see all these tools in action in contributed Drupal 7 module.

A real life example

I applied the tips of this article to the TypedEntity module. TypedEntity is a nice little module that helps you get your code organized around your Drupal entities and bundles, as first class PHP objects. This module will help you to change your mindset.
Make sure to check the contents of the tests/ directory. In there you will see real life examples of a composer.json and test cases. To run the tests follow these steps:

  1. Download the latest version of the module in your Drupal site.
  2. Navigate to the typed_entity module directory.
  3. Execute tests/ in your terminal. You will need to have composer installed to run them.

This module executes both PHPUnit and Simpletest tests on every commit using Travis CI configured through .travis.yml and phpunit.xml.

Another great example, this one with a very high test coverage, is the Amazon S3 module. A new release of this useful module was created recently by fellow Lullabot Andrew Berry, and he added unit tests!

Do you do things differently in your Drupal 7 modules? Leave your thoughts in the comments!

Categories: Elsewhere

SitePoint PHP Drupal: Drupal 8 Theming Revamped – Updates and New Features

Mon, 10/08/2015 - 18:00

If you are a Drupal developer who has dabbled in theming older versions of Drupal (5, 6, 7) you understand why frustration is the trusty companion of any Drupal themer. Luckily, though, Drupal 8 promises so many improvements that even the Angry Themer is happy for a change. It is only natural we jump in […]

Continue reading %Drupal 8 Theming Revamped – Updates and New Features%

Categories: Elsewhere

Appnovation Technologies: Overriding queue classes used in the Batch API in Drupal 7

Mon, 10/08/2015 - 17:04
There are lots of benefits in working with a platform such as Drupal, that come packed full of goodies for developers like myself and my colleagues, that enable us to build intelligent and innovative solutions.
Categories: Elsewhere

Nuvole: Drupal 8 Configuration Management: beware of pitfalls

Mon, 10/08/2015 - 16:35
Nuvole's Configuration Management workshop at Drupalaton 2015 in Hungary

Drupalaton in Hungary last weekend gave the opportunity for a 90 minutes workshop about Configuration Management (CMI) and how it changes a Drupal developers work flow with the coming Drupal 8.

CMI allows you to have the whole site configuration under control and that is a great improvement. But it also comes with its pitfalls. Developers have to be more vigilant when sharing configuration with each other: mindless exporting configuration may override the configuration shared by others, mindless importing may override one's own work and forgetting to import merged configuration leads to ignoring the work of your co-developers at a later stage.

CMI, while it is much more awesome than anything we have in Drupal 7, is also much more unforgiving. So it would be all too easy to not use it properly and what it was designed for and then wonder why you can't have nice things.

Fortunately, a methodical git workflow can help recover from mistakes (except importing configuration before exporting it first). So don't forget the order of the steps:

  1. config export
  2. git commit
  3. git merge
  4. config import

And do it often to keep the merges and failures simple and easy to resolve.

Please find the full Drupalaton 2015 workshop slides attached below.

Tags: Drupal PlanetDrupal 8Attachments:  CMI presentation Drupalaton 2015
Categories: Elsewhere

KnackForge: Solr Streaming Expressions

Mon, 10/08/2015 - 13:12

Solr 5.1 introduced a revolutionary Streaming API. With Solr 5.2, you get Streaming Expressions on top of it. Ever wondered on how to run nested queries in SOLR or running parallel computing capabilities, this could be the answer. 

Streaming Expressions provide a simple query language for SolrCloud that merges search with parallel computing. Under the covers Streaming Expressions are backed by a java Streaming API that provides a fast map/reduce implementation for SolrCloud. Streaming Expressions are composed of functions. All functions behave like Streams, which means that they don't hold all the data in memory at once. Read more about the basics here


Assuming a debian based system, say Ubuntu 12.04 or 14.04. If you have not installed Solr 5.2, go grap latest codebase (For eg, extract it. 

Setup Solr in cloud mode.

Cloud mode lets you create collection and nodes. See for more details. bin/solr -e cloud Enter the port and other details.

To start a single node, use,

bin/solr start -cloud -s example/cloud/node1/solr -p 8983

Streaming API:

Now comes the interesting part. We have the following streaming API functions, 

Categories: Elsewhere

OSTraining: New Video Class: Google Search Console

Mon, 10/08/2015 - 11:06

When it comes to getting your website noticed by the world, your best friend is Google. Many websites rely on Google for far over 50% of their traffic.

In this class, Topher introduces you to a fantastic set of tools called Google Search Console (formerly Google Webmaster Tools).

Whether you run a Drupal, WordPress or Joomla site, Google Search Console helps you understand how Google sees your site and gives you advanced warning of any problems.

Categories: Elsewhere

Tim Millwood: Composer in contrib: Step 2

Mon, 10/08/2015 - 10:45
Now that we have an initiative to get get a composer.json file in each contrib module, we cal start...
Categories: Elsewhere

Microserve: Getting Bootstrap Grid Classes Into Drupal 7 CMS Markup

Mon, 10/08/2015 - 10:10

Bootstrap is wonderfully useful and robust, mobile first framework for creating fully responsive, grid based web layouts.

The application of the Bootstrap framework relies on the principle of applying existing Bootstrap CSS classes to HTML mark-up, which in turn harness a suite of existing,  integrated LESS classes, mixins and variables as well as some useful, included JavaScript plugins to create Bootstrap layout.

When building HTML from scratch, the principle and practice is pretty straight forward. Once your Bootstrap library files are in the right place and working, you simply need to add Bootstrap classes to your mark-up as you go.

When developing with Drupal, it can be a challenge to 'crowbar' in the Bootstrap classes you need.

When developing with Drupal, things are not quite so straight forward out-of-the-box and it can be quite a challenge trying to 'get at' all of the code where you would need to crowbar in the Bootstrap classes you need.

Luckily there a number of ways to tackle this challenge, four of which are listed below. I've kept the neatest, life changing trick till last, because it's important to understand your options. (There's a time and place for all these approaches.)

1. PHP Templating!system!page.tpl.php/7

So tactic number 1 shouldn't come as massive surprise to most Drupal front enders and that is of course to harness the existing Drupal templating system to create templates containing Bootstrap specific mark-up.

The most obvious example of this (and the bare minimum required to even begin utilising the Bootstrap grid system) is good old page.tpl.php.  Here you'll most likely want to be applying Bootstrap classes to Drupal regions like the main content area and sidebars, so that they respond to screen size and probably 'stack' on top of each other at a smaller sizes.

Of course the above 'regions' example is a simple scenario (and If you're using the Drupal Bootstrap starter theme ( a lot of this basic, mark-up will already be in place.) but things will no doubt have to get a lot more fine grain than this and at some point It's a distinct possibility you'll also want to inject Bootstrap column classes into node templates, views templates etc. 

2. Helper Modules

One of my favourite 'helper modules' is Views Responsive Grid.

As the name suggests this module helps create responsive (div based) grid layouts for your views. By itself the module doesn't do anything to auto-magically  'Bootstrapize' your views, rather it gives you an extra view format (Responsive Grid) which at odds with the default Drupal, table based grid format, produces a simple set of nested divs and the ability to assign your own responsive classes to the view wrapper, rows and columns, all through the admin interface, without need for template editing.

In our case we'd use it to add Bootstrap classes, but because it's framework agnostic, you could just as easily use it on sites using omega or foundation themes or your own bespoke responsive approach.

3. Display Suite

Display Suite can be found here.

To people who are already advocates of Display Suite, this one should be a no-brainer.

The Display Suite module (DS) is the ultimate tool in customising Drupal layout through the front end admin interface.  Again no need for editing PHP templates directly.

If like me, you haven't used DS a massive amount in the past, Bootstrap presents a pretty good case for further investigation. 

Simply put, DS presents to you through the Drupal admin interface, every default and custom field of a content type, stripped of mark-up and allows you to create multiple view modes where you can choose to show or hide specific fields, re-arrange their order, group them together, create custom page regions, wrappers and assign custom classes, IDs and various other formatting options to each of these elements.  For all intents and purposes it lets you create complex node templates without necessarily writing a line of code.

So, say we have a 'case study' content type, for example, we could create a node view mode for presenting a single case study article, a teaser view mode to use in views listings where results should appear in a grid layout, and a second teaser view mode to use in views where results appear in a simple list format. We can show/hide whichever fields we like per view mode, group them together any way we choose and more importantly for us, we can use this method to insert all the Bootstrap mark-up and/or classes we require.

4. Bootstrap's Default Mixins

I said at the beginning of this blog, that I was saving the best till last and here it is.

This won't be news to everyone, but I'm willing to bet there are going to be a pretty large portion of bootstrap users, who, even though they have studied the Bootstrap documentation available on the getbootstrap site will have missed this nifty feature.

If you visit the CSS page of the Bootstrap site and specifically the 'grid' section, you will no doubt be familiar with the explanation and examples of the grid system itself and which classes to use where, but right at the bottom of this section (just before the section on 'Typography'), there's a sub-section on LESS mixins.

Now, far be it from me to advise Bootstrap on how to write their documentation, but this section seems to me to be ordered in a quite counter-intuitive manner.  There's a large section of very over complicated example code, showing mixins being used in conjunction with various media queries and LESS variables without seemingly explaining what any of the individual lines of code actually mean. Complicated and confusing enough for may visitors to give up trawling through before reaching the end of the section. And this is the crime, because here, right at the end of the section under the heading 'Example usage',  in one short example piece of code, the keys to the Bootstrap kingdom are presented:

.wrapper { .make-row(); } .content-main { .make-lg-column(8); } .content-secondary { .make-lg-column(3); .make-lg-column-offset(1); } <div class="wrapper"> <div class="content-main">...</div> <div class="content-secondary">...</div> </div> What does this mean?

Well it means, with a little thoughtful coding, you can create an entire Bootstrap layout without needing to physically insert classes into your HTML mark-up at all. You could in theory use just LESS mixins to style existing, non-Bootstrap markup elements to appear as if they had certain Bootstrap classes, without having to edit their HTML output directly.

The example code above would produce layout equivelent to the following HTML mark-up:

<div class="wrapper row"> <div class="content-main col-lg-8">...</div> <div class="content-secondary col-lg-3 col-lg-offset-1">...</div> </div> Further examples

For instance you have a wrapper div, which contains 6 child divs and you want those 6 children to appear as if they were 6 Bootstrap columns with a class of .col-sm-4. They should have a width of 100% on mobile and stack above each other and then at the 'sm' breakpoint of 768px screen width and above, each of the 6 columns should float left in  2 rows of 3 and have a width of 33.33333333%, or in other words ocuppy 4 of the default 12 Bootstrap columns.

*The below layout examples are best viewed on larger screens, so that you can  see the layout change as you resize the browser. (on mobile, layouts will all appear stacked at 100% as no 'xs' breakpoint has been declared.)

Col 1 Col 2 Col 3 Col 4 Col 5 Col 6

If you were editing the HTML directly, you would need to give the wrapper div a class of 'row' and each child div a class of '.col-sm-4'. Using the mixins available to Bootstrap you could do this indirectly, assigning the mixin .make-row(); to your wrapper and then the mixin of .make-sm-column(4); to each of the children. Bingo Bootstrap will now take care of the rest. 

div.wrapper { .make-row(); } div.child { .make-sm-column(4); }

You can also stack Bootstrap classes just like in HTML like so:

div.child { .make-sm-column(4); .make-md-column(6); }

Resulting in:

Col 1 Col 2 Col 3 Col 4 Col 5 Col 6

*Each child div will be 4 columns (33.33333333%) at the 'sm' breakpoint and above, until the 'md' breakpoint when each child div will be 6 columns (50%) wide. Because we haven't decared a specific number of columns at 'xs' (below the 'sm' breakpoint), the divs will revert to their 100% wide default and stack one on top of each other.

You can even add offsets like so:

div.child { .make-sm-column(4); .make-md-column(6); } div.thisclass { .make-sm-column-offset(4); .make-md-column-offset(6); } Col 1 Col 2 Col 3 Col 4 Col 5 Offset on larger screens

*In this example, at the 'md' breakpoint each div occupies 5 columns with an empty column to it's left. (5+1 = 6 cols - or 50% in total).


So there you go, there's my 4 favourite ways of getting Bootstrap into Drupal. You could exclusively use tactics 1,3 or 4 in isolation (2 is more of a 'bolt-on' to be harnessed by the others), depending on your preferred work flow and how much you want to 'get your hands dirty' by digging down into the code of Drupal, but in practice all methods should be viewed as complimentary tools available in a themer's toolbox, each with it own advantages and disadvantages in any one given situation.

Martin White
Categories: Elsewhere

Web Omelette: New contrib module: Info Plugins

Mon, 10/08/2015 - 09:02

Today I would like to introduce a new module that I released for the Drupal (developer) community to use and share: Info Plugins. This is for developers who are tired of implementing a bunch of messy _info hooks (and their corresponding callbacks), lumping together functionality that frankly shouldn't even touch. I'm talking about those ugly switch statements in which we have cases for the various extensions we provide. Don't get me wrong Drupal, I love your hook system.

With Info Plugins, much (and progressively more and more) of this becomes cleaner by exposing all those extension points to the cTools plugin system. What I mean by this is that using this module you will be able to declare things like Drupal blocks, filters, field formatters and more, as cTools plugins. This way, all the logic related to one plugin (block, filter or field formatter to continue with the above examples) resides neatly within one single plugin include file.

Let us look at an example a bit more in depth: the Drupal block. Instead of implementing up to 4 hooks (_info, _view, _configure and _save) to manage your blocks, you can now define a new core_block plugin within your cTools plugins folder like so:

$plugin = array( 'title' => t('Example block'), // Your own callback for building the display of the block (called by `hook_block_view()`) // Leaving this empty, the function name would default to `my_module_example_block_view()` 'view' => 'my_module_render_example_block', // Your own callback for building the config form for the block (called by `hook_block_configure()`) // Leaving this empty, the function name would default to `my_module_example_block_configure()` 'configure' => 'my_module_configure_example_block', // Your own callback for saving the config for the block (called by `hook_block_saved()`) // Leaving this empty, the function name would default to `my_module_example_block_save()` 'save' => 'my_module_save_example_block', // ... all other options you may want to pass to `hook_block_info()` ); /** * Returns a renderable array that represents the block content, i.e. * the same as you would return from `hook_block_view()`. * * @param $delta * The block delta */ function my_module_render_example_block($delta) { return array( '#type' => 'markup', '#markup' => 'My custom example block' ); } /** * Returns a form to be used as the block configuration form, i.e. the same * as you would return from `hook_block_configure()` * * @param $delta * The block delta */ function my_module_configure_example_block($delta) { $form = array(); $form['my_custom_field'] = array( '#type' => 'textfield', '#title' => t('My custom block field'), '#default_value' => variable_get($delta, '') ); return $form; } /** * Saves the block configuration, i.e. the same as you would do inside * `hook_block_save()` * * @param $block * An array of values representing the block with it's configuration, i.e. the * `$edit` array passed to `hook_block_save()` */ function my_module_save_example_block($block) { variable_set($block['delta'], $block['my_custom_field']); }

So as you can see, your block definition, render and configuration resides in one file. If you need more blocks, you just define more plugins and you are good to go. There is such a documentation oriented example inside the plugin_examples folder of the module for each available plugin type. Plus, don't forget the file.

Once you install the module, you will have only one administration screen at admin/config/info-plugins where you'll be able to select which plugin types you need. For example, if you need to define a custom block, enable the Core Block plugin type. If you need others, enable them as well. But I recommend you keep them disabled if you don't use them so that their logic doesn't get included in memory (all the relevant hooks and what not). My goal here is to keep a very low foot print.

To see which plugin types are available to use, please consult the project page. And keep checking back because I will add more. And if you want to contribute, please don't hesitate. Take it out for a spin, give it a test and please open issues to let me know of any bugs you find. I will be active on this for a while and want to hammer out all the potential problems before creating a stable release.


In Drupal var switchTo5x = true;stLight.options({"publisher":"dr-8de6c3c4-3462-9715-caaf-ce2c161a50c"});
Categories: Elsewhere