Subscribe to feed Planet Drupal - aggregated feeds in category Planet Drupal
Bijgewerkt: 11 uur 59 min geleden

Microserve: Setting Up Drupal Bootstrap

ma, 2015/06/15 - 6:02pm

For those looking for a reliable, responsive front-end framework to base their website/drupal theme upon, Twitter Bootstrap can be hard to beat. Luckily there is an existing, contributed theme available to take out the hard work of integrating Bootstrap and Drupal... Well nearly all the hard work.

This step by step tutorial hopes to serve as an extension to existing documentation for Drupal Bootstrap and strives to fill in a few blanks and signpost the odd 'gotcha' that can potentially leave the novice banging their head against their monitor. It assumes you already have a decent grasp of the drupal folder structure and a knowledge of LESS CSS preprocessor.

Drupal Bootstrap Theme

Download the latest version of the Bootstrap Drupal Theme.

Unzip the contents into the sites/all/themes/ folder of your drupal site.

Copy the folder 'bootstrap_subtheme' and place the copy in the root of your regular sites/all/themes/ folder (You should now have two separate theme folders 'Bootstrap' and 'bootstrap_subtheme' at the same level in your theme folder structure).

Before anything else, rename the 'subtheme' copy to reflect the project you are working on. (for the purposes of this tutorial we'll name ours 'mytheme')

Bootstrap Editable Source Files

Bootstrap Drupal Theme provides the core framework to use bootstrap within Drupal, but we still need to include the latest working distribution of the editable bootstrap source files themselves.

In the future this should be possible using drush, but for now there are two methods for including these files. Either via link to the CDN, which is convenient, but does not give us full editability of LESS files, or by downloading the files to our theme to be used locally. Further info:

We want to choose the second method...

  1. Download the latest distribution of bootstrap from: (Choose the second, 'SOURCE CODE' version.)
  2. Download to the root of your new sub_theme (mytheme).
  3. Unzip and rename the unzipped folder 'bootstrap'. (Yep this is where it can seem confusing, you will now have a new folder called 'bootstrap' inside your new bootstrap sub_theme)
  4. Inside your new subtheme edit the .info file. On the first line change 'name =' value to match your new theme name ('mytheme' in this instance).
  5. Now we need to tell the theme which method to use for including the Bootstrap distribution. Towards the bottom of the  .info file, uncomment all lines under the heading 'METHOD 1: Bootstrap Source Files'  (yes, all those JS files.)
LESS Preprocessor Method

Although you can run a (very restrictive) installation of Bootstrap using standard CSS, it's unlikely you'll want to pass up access to the wealth of in-built variables and mixins available in the core LESS files, so now we need to choose which method of LESS compilation we want to use.

If you wish to install and use a local LESS compiler, you can leave the .info file set to use /css/style.css and then set your preprocessor to compile all LESS files to this file.

*I recommend however using the Drupal LESS module, to let Drupal do the compiling for you in browser. For this method, change the 'Stylesheets' entry in .info to point directly to /less/style.less

For this method to work, you will need to download and install the drupal Less module here:

Secondly download the Preprocessor library (lessphp) from:

to > /sites/all/libraries/ unzip and rename the folder to 'lessphp'

Enable the LESS module (if you haven't already) and go to /admin/config/development/less in the Drupal admin menu.

Choose 'less.php' as your LESS engine and turn on 'Developer Mode'. (This will ensure LESS files are recompiled on each page load.) - *Make sure this is turned OFF before site goes live.

Turn On The Theme

If you haven't already, enable your sub_theme and make it the default theme.

Disable the main Bootstrap theme (it doesn't need to be enabled for the subtheme to work.)

Clear your drupal cache and you should be good to go.

JQuery Update

For boostrap to run properly, you will have to have JQuery installed and running at atleast version 1.7. Make sure you have the JQuery Update module installed and set to 1.7 or above. (I've run bootstrap on 1.10 without problems.) 

You can change the version on the JQuery Update config page, or specifically for the theme, you can switch the version on your bootstrap sub_theme's theme settings page. 

*If you have selected a version of JQuery 1.7 or above and you're still getting drupal errors complaining that Bootstrap requires this version, you can choose to 'Suppress jQuery version error message' under Advanced on the sub_theme settings page. 

Missing Variable Errors?

Sometimes the Drupal Bootstrap theme can fall out of sync with the latest Bootstrap version.

If after enabling the subtheme you get lots of red errors about missing variables, do the following:

Inside your subtheme:

Make a COPY of the latest variables.less from the distribution files (mytheme/bootstrap/less/variables.less) and use it to REPLACE the version in your theme's custom files (mytheme/less/variables.less)

This should stop bootstrap looking for out of date variables.

Page Templates

While you 'could' copy the page.tpl.php and html.tpl.php templates from the Drupal core and set about adding all the necessary bootstrap classes and regions to them, It makes much more sense to start off by making copies of the versions supplied inside the main Bootstrap parent theme, where most of the ground work has been done for you.

You can find templates at: bootstrap/theme/ (where 'bootstrap' is the main parent theme installed from the page and html templates are inside the 'system' sub folder.

Copy the templates you need, to you sub_theme's template folder. (Create one if there isn't one already.)

Bootstrap LESS Files

In your sub_theme, you will initially have the following LESS files:

  • bootstrap.less 
    Never edit this. It's only purpose is to import all of bootstrap's core less files - the integral part of the framework.
  • overrides.less
    You will sometimes want edit some values in this file. It mainly contains drupal specific resets and 'overrides'.
  • variables.less
    This is where you can change the values of default bootstrap variables to set site wide typography, form styles, grid styles, branding etc. VERY USEFUL
  • styles.less
    This is initially empty other than a few import declarations. This like a normal style.css or .less file, is where you will put the bulk of your project specific custom LESS code.
  • header.less, content.less, footer.less
    I don't personally tend to find any use for these region specific files. These can safely be deleted if you don't intend to use them. If you do delete them, also make sure to delete their import declarations from the top of 'style.less'.
Custom Variables

You could create a new LESS file for your own custom variables, but I find a lot of my custom variables can be additions to existing bootstrap variable structures (for instance there is already a @brand-primary color value in variables.less and I nearly always add a @brand-secondary color), so it makes sense to include them in the same file and flow. So I add my variables to the existing file, making one consolidated, semantic file.

Custom Mixins

Mixins are a little different. You can just include them in style.less. You can also include them in the bottom of the existing overrides.less file. (You can include them anywhere really, but as you will often want to use variables within your mixins, it's advisable to call them after all variables have been imported from bootstrap and your own custom files.) I think the neatest way is to create new custom LESS file and keep all the custom mixins separate. For instance, on my current project, i've created a ‘custom-mixins.less’ file and imported it into style.less straight AFTER the existing imports like so:

// Bootstrap library. @import 'bootstrap.less'; // Base-theme overrides. @import 'overrides.less'; // Theme specific. @import 'custom-mixins.less';

Wait!? Where was variables.less in those import declarations? 

Well, one thing to be careful of is that you don't want to import the same file into more than one other less file directly. This would in essence mean the entire file would be imported twice. So because variables.less has already been imported into overrides.less, it's content will be inherited through importing override.less into the above file.

Here's a diagram to try and better explain the bootstrap .less inheritance flow, mentioned above: 

In Conclusion

Hopefully these tips will be of use and help navigate the initially daunting landscape of getting Drupal and Bootstrap to play nice together.

This guide is based on the worflow I have personally found most logical and efficient, but if you have other methods or further tips to 'share with the class', feel free to leave a comment below.

My closing 'top tip' to developing with Bootstrap, Drupal or otherwise is to always have the Bootstrap site open in a tab, for easy reference of it's existng grid structure, variables, mixins, js plugins and info.

Martin White

Acquia: Build Your Drupal 8 Team: The Forrester Digital Maturity Model

ma, 2015/06/15 - 4:46pm

In business, technology is a means to an end, and using it effectively to achieve that end requires planning and strategy.

The Capability Maturity Model, designed for assessing the formality of a software development process, was initially described back in 1989. The Forrester Digital Maturity Model is one of several models that update the CMM for modern software development in the age of e-commerce and mobile development, when digital capability isn't an add-on but rather is fundamental to business success. The model emphasizes communicating strategy while putting management and control processes into place.

Organizations that are further along within the maturity model are more likely to repeatedly achieve successful completion of their projects.

Let's take a look at the stages of this model, as the final post in our Build Your Drupal 8 Team series.

Here are the four stages:

Stage 1 is ad hoc development. When companies begin e-commerce development, there is no defined strategy, and the companies' products are not integrated with other systems. Most products are released in isolation and managed independently.

Stage 2 organizations follow a defined process model. The company is still reactive and managing projects individually, but the desired digital strategy has been identified.

Stage 3 is when the digital strategy and implementation is managed. An overall environment supportive for web and e-commerce development exists, and products are created within the context of that environment.

In Stage 4, the digital business needs are integrated. Products aren't defined in isolation, but rather are part of an overall strategic approach to online business. The company has a process for planning and developing the products and is focused on both deployment and ongoing support.

The final capability level, Stage 5, is when digital development is optimized. Cross-channel products are developed and do more than integrate: they are optimized for performance. The company is able to focus on optimizing the development team as well, with continuous improvement and agile development providing a competitive advantage.

Understanding where your company currently finds itself on the maturity scale can help you plan how you will integrate and adapt the new functionality of Drupal 8 into your development organization.

If you are an ad hoc development shop, adopting Drupal 8 and achieving its benefits may be very challenging for you. You may need to work with your team to move up at least one maturity level before you try to bring in the new technology.

In contrast, if your team is at stage 5, you can work on understanding how Drupal 8 will benefit not just your specific upcoming project, but also everything else that is going on within your organization.


  • A comprehensive SlideShare presentation on Digital Maturity Models.
  • A blog post by Forrester's Martin Gill that mentions the Digital Maturity Model in the context of digital acceleration.
Tags:  acquia drupal planet

Annertech: Web Development on Fire? Smoke testing a Drupal Website

ma, 2015/06/15 - 12:57pm
Web Development on Fire? Smoke testing a Drupal Website

Documenting code 10 years ago was always something that I wanted to do, but, let's face it: clients didn't give a damn, so unless you did it for free, it rarely happened. And I felt very sorry for the developer that had to fix any bugs without documentation (yes, even my code contains bugs from time to time!).


Drupal core announcements: Recording from June 12th 2015 Drupal 8 critical issues discussion

ma, 2015/06/15 - 11:56am

It came up multiple times at recent events that it would be very helpful for people significantly working on Drupal 8 critical issues to get together more often to talk about the issues and unblock each other on things where discussion is needed. While these do not by any means replace the issue queue discussions (much like in-person meetings at events are not), they do help to unblock things much more quickly. We also don't believe that the number of or the concrete people working on critical issues should be limited, so we did not want to keep the discussions closed. After our second meeting last week, here is the recording of the third meeting from today in the hope that it helps more than just those who were on the meeting:

Unfortunately not all people invited made it this time. If you also have significant time to work on critical issues in Drupal 8 and we did not include you, let me know as soon as possible.

The issues mentioned were as follows:

Alex Pott
Rebuilding service container results in endless stampede:
Twig placeholder filter should not map to raw filter:

Francesco Placella[]=Open&priorities[]=400&version[]=8.x&component[]=entity+system&component[]=field+system&component[]=language+system&component[]=content_translation.module&component[]=language.module&component[]=views.module&issue_tags_op=%3D
FieldItemInterface methods are only invoked for SQL storage and are inconsistent with hooks:

Lee Rowlands
Make block context faster by removing onBlock event and replace it with loading from a BlockContextManager:

Francesco Placella
FieldItemInterface methods are only invoked for SQL storage and are inconsistent with hooks:

Alex Pott
Rewrite \Drupal\file\Controller\FileWidgetAjaxController::upload() to not rely on form cache

Gábor Hojtsy
Twig placeholder filter should not map to raw filter:

Daniel Wehner
drupal_html_id() considered harmful; remove ajax_html_ids to use GET (not POST) AJAX requests:

Francesco Placella
Node revisions cannot be reverted per translation:[]=Open&priorities[]=400&version[]=8.x&issue_tags_op=%3D&issue_tags=D8+upgrade+path

Daniel Wehner
SA-CORE-2014-002 forward port only checks internal cache:

Francesco Placella
Nat: it would be good to have your feedback on the proposed solution the translation revisions issue aside from its criticality (see and following)

Fabian Franz
[PP-2] Remove support for #ajax['url'] and $form_state->setCached() for GET requests:
Condition plugins should provide cache contexts AND cacheability metadata needs to be exposed:
Make block context faster by removing onBlock event and replace it with loading from a BlockContextManager:

Alex Pott
[meta] Identify necessary performance optimizations for common profiling scenarios:

Nathaniel Catchpole
Core profiling scenarios:
Node::isPublished() and Node:getOwnerId() are expensive:
And User:getAnonymousUser() takes 13ms due to ContentEntityBase::setDefaultLangcode() ( is similar.


Jim Birch: Using CKFinder to organize image uploads by Content type in Drupal 7

ma, 2015/06/15 - 11:00am

As you may have noticed, /sites/default/files can quickly become a pretty busy place in your Drupal installation.  When creating image or file fields, we can add folders in the Drupal UI to organize the uploads.  But when we allow users to upload using the CKEditor WYSIWYG Editor, we have to work a bit harder to organize those uploads.

I am currently working on a project where we want to organize the uploads by content type.  Certain users have access to certain content types.  We want to be able to keep the separation going with the files.  Our goal is to have the wysiwyg uploads in the same folder as the "featured image" field on each content type, which is in /sites/default/files/[content-type].

What I quickly learned, was that IMCE is great in so many ways, and part of our normal Drupal install, but there is no obvious way to do this.  You can use IMCE to organize in a variety of different ways, like php date based folders and user id folders.  You could even have a roles based system, by creating an IMCE profile per role.  But I couldn't figure out a way to organize by field, or Content Type.

CKFinder to the rescue.  CKFinder is a premium file manager plugin for CKEditor.  When integrated with the CKEditor Drupal Module, both can be customized right in the Drupal UI.

Read more


PreviousNext: How to index panelizer node pages using Drupal Apache Solr module

ma, 2015/06/15 - 9:44am

Apache Solr Search is a great module for integrating your Drupal site with the powerful Apache Solr search tool. Out of the box it can index nodes and their fields, but Panelizer pages won't be indexed. In this post I show how you can get around this by indexing the rendered HTML of a panelizer node page.


Web Omelette: Drupal 8: custom data on configuration entities using the ThirdPartySettingsInterface

ma, 2015/06/15 - 9:00am

In this article we are going to look at how to use the ThirdPartySettingsInterface to add some extra data to existing configuration entities. For example, if you ever need to store some config together with a node type or a taxonomy vocabulary, there is a great way to do so using this interface. Today we are going to see an example of this and add an extra field to the menu definition and store the value in this way.

There are a number of steps involved in this process. First, we need to alter the form with which the entity configuration data is added and saved. In the case of the menu entity there are two forms (one for adding and one for editing) so we need to alter them both. We can do something like this:

/** * Implements hook_form_alter(). */ function my_module_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { if ($form_id === 'menu_add_form' || $form_id === 'menu_edit_form') { my_module_alter_menu_forms($form, $form_state, $form_id); } }

Inside this general hook_form_alter() implementation we delegate the logic to a custom function if the form is one of the two we need. Alternatively you can also implement hook_form_FORM_ID_alter() for both those forms and delegate from each. That would limit a bit on the function calls. But let's see our custom function:

/** * Handles the form alter for the menu_add_form and menu_edit_form forms. */ function my_module_alter_menu_forms(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { $menu = $form_state->getFormObject()->getEntity(); $form['my_text_field'] = array( '#type' => 'textfield', '#title' => t('My text field'), '#description' => t('This is some extra data'), '#default_value' => $menu->getThirdPartySetting('my_module', 'my_text_field'), '#weight' => 1 ); if (isset($form['links'])) { $form['links']['#weight'] = 2; } $form['#entity_builders'][] = 'my_module_form_menu_add_form_builder'; }

In here we do a couple of things. First, we retrieve the configuration entity object which the form is currently editing. Then, we define a new textfield and add it to the form. Next, we check if the form has menu links on it (meaning that it's probably the edit form) in which case we make its weight higher than one of our new field (just so that the form looks nicer). And last, we add a new #entity_builder to the form which will be triggered when the form is submitted.

The getThirdPartySetting() method on the entity object is provided by the ThirdPartySettingsInterface which all configuration entities have by default if they extend from the ConfigEntityBase class. With this method we simply retrieve a value that is stored as third party for a given module (my_module in this case). It will return NULL if none is set so we don't even need to provide a default in this case.

Let us now turn to our #entity_builder which gets called when the form is submitted and is responsible for mapping data to the entity:

/** * Entity builder for the menu configuration entity. */ function my_module_form_menu_add_form_builder($entity_type, \Drupal\system\Entity\Menu $menu, &$form, \Drupal\Core\Form\FormStateInterface $form_state) { if ($form_state->getValue('my_text_field')) { $menu->setThirdPartySetting('my_module', 'my_text_field', $form_state->getValue('my_text_field')); return; } $type->unsetThirdPartySetting('my_module', 'my_text_field'); }

Inside we check if our textfield was filled in and set it to the third party setting we can access from the config entity object that is passed as an argument. If the form value is empty we reset the third party setting to remove lingering data in case there is something there.

And that's pretty much it for the business logic. We can clear the cache and try this out by creating/editing a menu and storing new data with it. However, our job is not quite finished. We need to add our configuration schema so that it becomes translatable. Inside the /config/schema/my_module.schema.yml file of our module we need to add this:*.third_party.my_module: type: mapping label: 'My module textfield' mapping: my_text_field: type: text label: 'My textfield'

With this schema definition we are basically appending to the schema of the config entity by specifying some metadata about the third party settings our module provides. For more information on config schemas be sure to check out the docs on

Now if we reinstall our module and turn on configuration translation, we can translate the values users add to my_text_field. You go to admin/config/regional/config-translation/menu, select a menu and when translating in a different language you see a new Third Party Settings fieldset containing all the translatable values defined in the schema.

Hope this helps.

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

Chen Hui Jing: Developing Drupal sites as a team

ma, 2015/06/15 - 2:00am

A lot of people, myself included, start out with Drupal on their own, developing and building everything as a one-person operation. When we’re working by ourselves, there will be certain good practices that we neglect, either out of convenience (there’s no point doing X since I’m the only one touching this project), or out of ignorance (wow, I had no idea that was how Y was supposed to be used).

Working with a team of people to build a Drupal site (or any other development project) requires more structure and discipline to ensure the project doesn’t descend into a pile of spaghetti code. I’m going to try to summarise the processes that worked for my team thus far. I...


Code Karate: How to A/B test your Drupal Site

zo, 2015/06/14 - 3:48pm
Episode Number: 208

Are you testing your site? Until recently, we weren’t and it was costing us. Every element on your website should have a meaning and if you aren’t testing it against something else how can you be sure that you are maximizing your results!

Tags: DrupalDrupal 7Site BuildingDrupal PlanetTips and TricksUI/DesignJavascript