Set Front Page from settings[.local].php in Drupal 8

When working on Drupal projects I usually need to set a static front page by referencing a Node’s ID. When working with different environments chances are high that Node ID varies from environment to environment.

Luckily we can easily override any configuration value in the settings file and thus have different values in settings.php than in settings.local.php. It’s simple as that: $config['']['page']['front'] = '/node/1';

Home Office Monday

Lunch break happens here today, thanks to #HomeOfficeMonday at @nimius 🙂 Smells like a pine forest in southern France 🌲


Drupal: Add Body Class when Tabs are displayed

I had the urge to style various elements differently in case tabs (the ones generated by menu_local_tasks) are present on the page. Out of the box $tabs array isn’t available in html.tpl.php so I had to implement ‘ hook_preprocess_html’ and add my desired class to my array of body classes. Yay!

function THEMENAME_preprocess_html(&$vars, $hook) {
  // Make tabs available on html tpl
  $vars['tabs'] = menu_local_tabs();
  // if we have primary tabs, add an accoring body class
  if (!empty($vars['tabs']['#primary'])) {
    $vars['classes_array'][] = 'has-tabs';

Unmaintainable Block Admin Page in Drupal

When you have more than 100 Blocks things get messy on Drupal’s Block Admin Interface. If you ever went crazy because of weird issues when dragging and dropping blocks to change their weight and/or region you probably have hit Drupal’s internal limit of handling weights from -50 to +50 or otherwise said, 100 items.

It can be fixed by setting the variable drupal_weight_select_max to a higher value. This can be done in various ways, here’s how its implemented in a deploy script.

function dgm_deploy_update_7011() {
  variable_set('drupal_weight_select_max', 250);

Programmatically manipulate a Node’s field value upon saving 

For a recent project we needed to automatically change a Node’s field value upon saving with a computed value. For an unrelated reason we needed this value to be in a regular text field, so using Computed Field was off the table.

It turned out to be really simple to accomlish with a minimal amount of custom code.

 * Changes the value of field_marker to a string made up of the
 * Node's type and the value of it's category taxonomy term
 * Slashes will be replaced with deshes, spaces get removed
 * Must make sure that the following exists:
 *  - text field "field_marker"
 *  - node types "gesuch" and "angebot"
 *  - taxonomy reference field "field_category"

// Helper function to keep our code
function save_marker_category($node) {
  if($node->type == 'gesuch' || $node->type == 'angebot') {

    $find = array('/', ' ');
    $replace = array('-', '');

    $category_object = taxonomy_term_load($node->field_category['und'][0]['tid']);
    $category =  trim(strtolower(str_replace($find, $replace, $category_object->name)));

    $type = $node->type;
    $node->field_marker['und'][0]['value'] = $type.'_'.$category;

    // Save the new value
    field_attach_update('node', $node);

function MYMODULE_node_update($node) {

function MYMODULE_node_insert($node) {

Slick Slider inside Table Display

Today I ran into an issue when trying to use Slick Slider within an element that has display: table. The layout broke almost completely and in all browsers on small width viewports. Simply adding table-layout: fixed; to the element that has display: table solved it.

HTML Template per Node Type

In case you need a different html.tpl.php on a per content type basis in Drupal 7

function THEME_preprocess_html(&$vars) {
  $node = menu_get_object();
  if ($node && $node->nid) {
    $vars['theme_hook_suggestions'][] = 'html__' . $node->type;

Custom Drupal Views Template breaks AJAX (updated)

I often create custom Views templates for my Drupal sites, for example to freely reposition exposed filters. Unfortunately, AJAX exposed filters in Views works only with a very strict markup hierarchy, and if your markup doesn’t match that scheme (.view-[view:id] > .view-filters > filters) it won’t work anymore

diff --git a/js/ajax_view.js b/js/ajax_view.js
index 7d54c67..f7f7ba9 100644
--- a/js/ajax_view.js
+++ b/js/ajax_view.js
@@ -57,7 +57,7 @@ Drupal.views.ajaxView = function(settings) {
   this.settings = settings;

   // Add the ajax to exposed forms.
-  this.$exposed_form = this.$view.children('.view-filters').children('form');
+  this.$exposed_form = this.$view.find('.view-filters form');
   this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this));

   // Add the ajax to pagers.



Thanks to this patch that removed the selector dependence this is not needed anymore

Remove fields form content type programatically

Say you want to remove the body field from the page content type. Putting this code inside an updatescript will get the job done. Remember not to use field_delete_field() if you’re not sure if you still want to use the field anywhere else. It’s way safer to rely on field_delete_instance. Setting the second parameter to TRUE means it’s automatically going to clean up the field anyway if it is found to be the last instance.

$instance = field_info_instance('node', 'body', 'page');
field_delete_instance($instance, TRUE);

Sync Brackets Extensions & Config

  1. Find your Brackets user folder (usually ~/Library/Application Support/Brackets) and move brackets.json and extensions/ to a shared folder (e.g. Dropbox)

  2. Add a symlinks to the moved file and folder:
    cd ~/Library/Application Support/Brackets
    ln -s ~/Library/Mobile\ Documents/com~apple~CloudDocs/config/Brackets/extensions/
    ln -s ~/Library/Mobile\ Documents/com~apple~CloudDocs/config/Brackets/brackets.json

  3. On your other machine make sure your config folder is done syncing, delete brackets.json and extensions/ from your Brackets user folder and setup your symlinks in the same way. Done \o/

PS: If you think: but why not syncing the entire Brackets user folder: I did that but I was bugged by the fact that Brackets was constantly complaining about not finding recently opened files and folders, which are saved in state.json. So I made sure that this file won’t be synced. 

Translate Drupal Strings Programatically

One of the many issues one has to face when trying to do some proper deployment with Drupal (only up to version 7, that is) is custom localized strings. Fear no more! Instead of translating strings in the admin interface (/admin/config/regional/translate/translate) we can make use of the great Update Script Processor, thus put all our custom translations into code and happily version and deploy them. Yay!

  1. Install Update Script Processor
  2. A update Script that contains your localizations, e.G. $this->setLanguageWording('de', 'Telephone number', 'Telefonnummer');
  3. run drush updatescripts

Obviously, you should put that under version control and make sure your deployment process runs drush updatescripts after deploying to another environment.

Here’s a full example that translate the original strings Telephone number and Fax number to their German counterparts:

 * @file   0060-update-localization-string-test.php
 * @author Daniel Wentsch

$this->setAuthor('Daniel Wentsch');
$this->setDescription('Update localization string (test)');

// Put your updatescript code here!
$this->setLanguageWording('de', 'Telephone number', 'Telefonnummer');
$this->setLanguageWording('de', 'Fax number', 'Faxnummer');


Generate new Drupal 7 Password Hash

If you find yourself locked out of your own Drupal installation and are unlucky enough to not receive any password-restore emails (or your server not being able to send them) you need to set a new password directly in the database. As Drupal stores a salted sha512 hash (and no plain passwords, of course) you need to encrypt your new password before you can store it in your database.

To do this you can either use the Shell script called provided in the scripts folder of any Drupal installation. In case you don’t have access to a shell you can also use the user_hash_password function in PHP:

This could be put in your index.php temporarily after bootstrapping Drupal. After visiting your site a string will be displayed. Replace your admin’s password in the users table in the database with that string and you can now log in with YourNewPassword.

require_once 'includes/';
echo user_hash_password('YourNewPassword'); 

Get Youtube ID from URL using PHP

  Get Youtube ID
  @param $url string
  returns the ID of a Youtube Video URL
function get_youtube_id($url) {
  parse_str( parse_url( $url, PHP_URL_QUERY ), $query_string );



Run Drupal Cronjobs on Strato Hosting

If you’re unlucky and have to run a Drupal site on one of the crappiest hosting companies available ( you might have troubles getting cronjobs working properly.

My workaround is calling wget silently and trash the ouput (find your secret key on your status report page):

curl -silent

Bootstrap Dropdown on Hover

An unofficial Bootstrap plugin to enable Bootstrap dropdowns to activate on hover and provide a nice user experience.