HTML Template per Node Type

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

<?php
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.

Source: https://www.drupal.org/node/2477307

Update

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:

<?php
/**
 * @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');

$this->finished();

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 password-hash.sh 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/password.inc';
echo user_hash_password('YourNewPassword'); 
die(); 

Get Youtube ID from URL using PHP

<?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 );
  return($query_string['v']);
}

Usage:

get_youtube_id('https://www.youtube.com/watch?v=zWvvvGprR-o');

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 (Strato.de) 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 http://www.YOUR-SITE.com/cron.php?cron_key=YOUR_SECRET_KEY

Bootstrap Dropdown on Hover

An unofficial Bootstrap plugin to enable Bootstrap dropdowns to activate on hover and provide a nice user experience. http://cameronspear.com/demos/bootstrap-hover-dropdown/

https://github.com/CWSpear/bootstrap-hover-dropdown

Override Superfish’s Mobile Menu Trigger in Drupal

The Superfish integration for Drupal works nicely for all kinds of menus from Mega Dropdowns down to Mobile. What bothered me with Superfish’s Mobile Menu implementation is that the Button that opens the Mobile Accordion (.sf-accordion-toggle) is always named after the name of the actual menu and normally can’t be overridden.

One possible approach to overcome this is using plain CSS to hide the span and place something different inside the link tag using the content property. I don’t like that idea too much so instead I tried figuring out how to change this with JavaScript. Turned out it’s not possible to simply selecting the DOM element and changing its value because the original value gets re-assigned anytime you resize you browser windows. What does work is overriding the Superfish behavior. I just copied it over from superfish.js form the Superfish Module into my theme’s JS and there I set my desire value, like so: options.plugins.smallscreen.title = '<i class="glyphicon glyphicon-menu-hamburger "/><span>Menü</span>';

Here’s the entire function:

// Override the superfish Behevior to add our own 
// custom Mobile Menu Trigger Title // (options.plugins.smallscreen.title)
(function ($) {
  Drupal.behaviors.superfish = {
    attach: function (context, settings) {
      // Take a look at each list to apply Superfish to.
      $.each(settings.superfish || {}, function(index, options) {
        // Process all Superfish lists.
        $('#superfish-' + options.id, context).once('superfish', function() {
          var list = $(this);
          options.plugins.smallscreen.title = '<i class="glyphicon glyphicon-menu-hamburger "/><span>Menü</span>';
          // Check if we are to apply the Supersubs plug-in to it.
          if (options.plugins || false) {
            if (options.plugins.supersubs || false) {
              list.supersubs(options.plugins.supersubs);
            }
          }

          // Apply Superfish to the list.
          list.superfish(options.sf);

          // Check if we are to apply any other plug-in to it.
          if (options.plugins || false) {
            if (options.plugins.touchscreen || false) {
              list.sftouchscreen(options.plugins.touchscreen);
            }
            if (options.plugins.smallscreen || false) {
              list.sfsmallscreen(options.plugins.smallscreen);
            }
            if (options.plugins.automaticwidth || false) {
              list.sfautomaticwidth();
            }
            if (options.plugins.supposition || false) {
              list.supposition();
            }
            if (options.plugins.bgiframe || false) {
              list.find('ul').bgIframe({opacity:false});
            }
          }
        });
      });
    }
  };
})(jQuery);

Let Drupal Editors Pick a Color and use it in Template

I’m currently working on an image slider where each slide needs to have its own background color.

Letting editors choose a color is easy with the Color Field Module. Just install it, throw the Spectrum Color Picker into your libraries folder and add and configure a Color Field where ever it’s needed. You can then simply access the user-entered color as a hex string in your template and use it to your liking (yea, that’s one of the rare times where it’s ok to use inline style, at least in my book).

Convert Hexadecimal Color Values to RGBa

I needed my color to have alpha transparency, however, the color value is only available as a hexadecimal string. Luckily I found this handy snippet to convert hex values to RGB(a), so thanks a lot to mekshq for sharing.

Just put it into your template.php and you’re good to to to use hex2rgba() anywhere in your theme.

/* Convert hexdec color string to rgb(a) string */
function hex2rgba($color, $opacity = false) {

  $default = 'rgb(0,0,0)';

  //Return default if no color provided
  if(empty($color))
          return $default; 

  //Sanitize $color if "#" is provided 
        if ($color[0] == '#' ) {
          $color = substr( $color, 1 );
        }

        //Check if color has 6 or 3 characters and get values
        if (strlen($color) == 6) {
                $hex = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] );
        } elseif ( strlen( $color ) == 3 ) {
                $hex = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
        } else {
                return $default;
        }

        //Convert hexadec to rgb
        $rgb =  array_map('hexdec', $hex);

        //Check if opacity is set(rgba or rgb)
        if($opacity){
          if(abs($opacity) > 1)
            $opacity = 1.0;
          $output = 'rgba('.implode(",",$rgb).','.$opacity.')';
        } else {
          $output = 'rgb('.implode(",",$rgb).')';
        }

        //Return rgb(a) color string
        return $output;
}

Using Foundation’s Block Grid Mixin within the Bootstrap CSS Framework (Updated)

Here’s an adaption of Zurb Foundation’s handy Block Grid Mixin adapted to the LESS preprocessor in order to use it within Bootstrap.

Update
I’ve added a mixin that supports a shorthand syntax that enables you to simply create a block grid writing something like .make-block-grid(1,2,4,8);

// # Block Grid Mixin
//
// Technique adapted from Foundation 5 for Bootstrap 3
//
// # Example Usage
//
// To produce a grid of 2 items per row on an extra-small screen, 3 items
// on a small screen, 4 items on a medium screen and 6 items per row on large screen:
//
// ul.gallery {
//   .make-block-grid-container();
//   > li {
//     .make-xs-block-grid(2);
//     .make-sm-block-grid(3);
//     .make-md-block-grid(4);
//     .make-lg-block-grid(6);
//   }
// }

// Or, in a quicker way with the shorthand syntax:
//   ul.gallery {
//     .make-block-grid(2,3,4,6)
//   }

//Mixins for Block Grids
.make-block-grid-container (@spacing: @grid-gutter-width) {
  list-style: none;
  padding: 0;
  margin-left: (@spacing / -2);
  margin-right: (@spacing / -2);
  &:extend(.clearfix all);
  > * {
    margin-bottom: @spacing;
  }
  > li {
    &:before {
      content: none !important;
    }
  }
}
.make-xs-block-grid (@blocks; @spacing: @grid-gutter-width) {
  position: relative;
  min-height: 1px;
  padding-left: (@spacing / 2);
  padding-right: (@spacing / 2);
  float: left;
  width: percentage(1 / @blocks);
  &:nth-of-type(1n) { clear: none; }
  &:nth-of-type(@{blocks}n+1) { clear: both; }
}
.make-sm-block-grid (@blocks; @spacing: @grid-gutter-width) {
  position: relative;
  min-height: 1px;
  padding-left: (@spacing / 2);
  padding-right: (@spacing / 2);
  @media (min-width: @screen-sm-min) {
    float: left;
    width: percentage(1 / @blocks);
    &:nth-of-type(1n) { clear: none; }
    &:nth-of-type(@{blocks}n+1) { clear: both; }
  }
}
.make-md-block-grid (@blocks; @spacing: @grid-gutter-width) {
  position: relative;
  min-height: 1px;
  padding-left: (@spacing / 2);
  padding-right: (@spacing / 2);
  @media (min-width: @screen-md-min) {
    float: left;
    width: percentage(1 / @blocks);
    &:nth-of-type(1n) { clear: none; }
    &:nth-of-type(@{blocks}n+1) { clear: both; }
  }
}
.make-lg-block-grid (@blocks; @spacing: @grid-gutter-width) {
  position: relative;
  min-height: 1px;
  padding-left: (@spacing / 2);
  padding-right: (@spacing / 2);
  @media (min-width: @screen-lg-min) {
    float: left;
    width: percentage(1 / @blocks);
    &:nth-of-type(1n) { clear: none; }
    &:nth-of-type(@{blocks}n+1) { clear: both; }
  }
}

// Make one mixin for all sizes so we don't have to call 4 mixins every time we use block grids
.make-block-grid (@cols-xs, @cols-sm, @cols-md, @cols-lg) {
  .make-block-grid-container();
  >li {
    .make-xs-block-grid(@cols-xs);
    .make-sm-block-grid(@cols-sm);
    .make-md-block-grid(@cols-md);
    .make-lg-block-grid(@cols-lg);
  }
}

Deleting Drupal Fields programmatically implementing hook_update_N()

Say we’d like to get rid of a Drupal Field that has the machine name field_wein_texte and our module that’s supposed to manage this is called kx_deployment. Here’s how the kx_deployment.install needs to look like:

<?php
/**
* Implements hook_update_N().
* Managing Field Deletions programmatically
* Note: field_delete_fields() removes fields globally, to detach a field from an entity use field_delete_instance()
*/
function kx_deployment_update_7001() {
  $fields_to_delete = array(
    'field_wein_texte',
  );
  foreach ($fields_to_delete as $field_name) {
    field_delete_field($field_name);
    watchdog('kx_deployment', 'Deleted the :field_name field from all content type instances.', array(':field_name' => $field_name));
  }
}
// The fields aren't really deleted until the purge function runs, ordinarily
// during cron.  Count the number of fields we need to purge, and add five in
// case a few other miscellaneous fields are in there somehow.
if(isset($fields_to_delete)) {
  field_purge_batch(count($fields_to_delete) + 5);
}
?>

Source: http://data.agaric.com/deleting-drupal-fields-programmatically-so-change-field-type-features

Shopware 5 Theming 101

First things first:

  1. In the Theme Manager in the backend add a new theme that inherits from Responsive
  2. It will be saved to themes/Frontend/Mytheme
  3. To add your own stylesheets to your theme put a file called all.less here: themes/Frontend/Mytheme/frontend/_public/src/less/all.less. It will automatically be compiled by Shopware’s own LESS processor
  4. To add your own scripts to your theme put them in themes/Frontend/Mytheme/frontend/_public/src/js/ and them to the $javascript array in themes/Frontend/Mytheme/Theme.php (snippet below)
  5. To immediately see your custom scripts and styles disable compiler cashing and CSS and JS compression in the settings of the Theme Manager

Adding a JavaScript file to your Shopware 5 Theme:

<?php
/**
 * Javascript files which will be used in the theme
 *
 * @var array
 */
protected $javascript = array(

    // Third party plugins / libraries
    'src/js/app.js',
);

htaccess performance boost

# KILL THEM ETAGS
# http://www.askapache.com/htaccess/apache-speed-etags.html
FileETag none

# add entity tag
FileETag MTime Size

# set expires header
<FilesMatch "\.(ico|jpg|jpeg|png|gif|js|css|swf|woff|eot|svg|ttf)$">
   Header set Expires "access plus 1 year"
</FilesMatch>

<ifModule mod_headers.c> 
Header set Connection keep-alive
</ifModule>

Block Grids for Bootstrap

Thanks to ChrisTM we can have Foundation’s Block Grids in Bootstrap:

Update: For a more semantic and general approach consider using this nifty mixin to create block grids on any desired list element.

// # Block Grid
//
// Technique adapted from Foundation 5 for Bootstrap 3.0.3 to at least 3.3.1.
// https://github.com/zurb/foundation/blob/f755d8704123f86c281ede0b171881e2672f150d/scss/foundation/components/_block-grid.scss
//
// # Example Usage
//
// To produce a grid of 2 items per row on an extra-small screen, and 3 items
// per row on a small screen:
//
//     <div class="block-grid-xs-2 block-grid-sm-3">
//         <div class="block-grid-item">
//             ...
//         </div>
//     </div>

[class*="block-grid-"] {
  display: block;
  margin: -(@grid-gutter-width/2);
  padding: 0;
  .clearfix();
}

.block-grid-item {
  display: inline;
  margin: 0;
  padding: (@grid-gutter-width/2);
  height: auto;
  float: left;
  width: 100%;
  list-style: none;  // for those who like to use `li` elements as block-grid-items
}

.block-grid (@per-row) {
  & > .block-grid-item {
    width: (100%/@per-row);

    @nth-equation: ~"@{per-row}n+1";
    &:nth-of-type(n) { clear: none; }
    &:nth-of-type(@{nth-equation}) { clear: both; }
  }
}

// Recursive loop that produces rules for block grids of @per-row many items
// per row down to 1 many items per row.
.block-grids(@size, @per-row: @grid-columns) when (@per-row > 0) {
  .block-grid-@{size}-@{per-row} { .block-grid(@per-row); }
  .block-grids(@size, (@per-row - 1));
}

.block-grids(xs);
@media (min-width: @screen-sm-min) { .block-grids(sm) }
@media (min-width: @screen-md-min) { .block-grids(md) }
@media (min-width: @screen-lg-min) { .block-grids(lg) }

Source: https://gist.github.com/ChrisTM/8346916#file-block-grid-less

Run a JavaScript only on the First Page Load / only on Succeeding Page loads

On a site I’m currently building I need to do some JavaScript scrolling on every page load, except for the first on (to scroll beyond a huge image slider that I don’t want to be in the way on succeeding page loads.

Note: this example makes use of jquery.cookie Plugin by Klaus Hartl, so make sure you include it, too.

(function ($) {
  $( document ).ready(function() {
    var cookieName = 'firstPageLoad';
    var cookieValue = 1;
    // if the cookie doesn't exist we're on the first page load...
    if (!$.cookie(cookieName)) {
      // and set a cookie that is valid for the entire domain
      $.cookie(cookieName, cookieValue, { path: '/'});      
    } 
    // if the cookie does exist, its (most probably) a succeeding page load...
    else {
      // ... so we want to scroll to the navigation
      $('html, body').animate({
          scrollTop: $("#navigation").offset().top
      }, 1000);    
    }
  }); // document ready
})(jQuery);

Drupal: Insert JavaScript for Every Page except Front Page

Just a quick reminder for myself how to simply load an asset only if a certain condition is true.

In template.php we need to implement template_preprocess_page() check our condition and load our script using drupal_add_js():

<?php
function MYTHEME_preprocess_page(&$vars) {
  // if we're NOT on the front page load a script from the currently active default theme
  if (!$vars['is_front']) {
    $active_theme = drupal_get_path('theme',$GLOBALS['theme']);
    drupal_add_js($active_theme.'/js/notfront.js');
  }
}