Remove/change Omega's viewport meta tag on user-set pages

Omega sets the viewport meta tag to something like this by default when you enable (it is enabled by default) the "Allow customizing viewport meta properties on iOS and Android devices" checkbox under Appearance > Settings for your Omega sub-theme.  With this checked, Omega prints out a meta tag like this in the <head> section of the pages on your site:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />

 

Want to tweak these settings?  You can easily configure them across your theme right under that checkbox in your theme settings.

However, what if you want to configure the Viewport tag to be different for a single page, or for just a few pages on the site.  We found ourselves in this situation as we migrated a large site and some of the embedded content was not responsive-ready.  In those cases the content would be cut off, and the pre-set viewport would not allow users to interact with the content at all - uh-oh.

Fortunately, there was a pretty easy fix.

The viewport meta tag is constructed inside omega/alpha/template.php near the end of the function alpha_alpha_preprocess_html(&$vars).  There a snippet of code checks if you have the responsive part of omega enabled as well as the viewport, and if so it adds it to the $meta variable which is then loaded into the head with drupal_add_html_head().

  if($theme->settings['responsive'] && $theme->settings['viewport']['enabled']) {
    $meta = array(
      '#tag' => 'meta',
      '#attributes' => array(
        'name' => 'viewport',
        'content' => 'width=device-width, initial-scale=' . $theme->settings['viewport']['initial'] . ', maximum-scale=' . $theme->settings['viewport']['max'] . ', minimum-scale=' . $theme->settings['viewport']['min'] . ', user-scalable=' . ($theme->settings['viewport']['user'] ? 'yes' : 'no'),
      ),
    );

    drupal_add_html_head($meta, 'alpha-viewport');
  }

 

Easy enough, we can tap into hook_alpha_preprocess_html() and switch the $theme->settings['viewport']['enabled'] to disabled!  To allow users to disable this through the UI I did a quick three-step process:

  1. Created a new taxonomy called "Mobile Zoom" with two terms: "Automatic zoom" and "User manual zoom"
  2. Added this taxonomy to my desired content types and made it Required to remove the "N/A" option.
  3. Created a new context with the Context module that was triggered by the Taxonomy term "User manual zoom" and in turn did "Theme HTML" to add the class "disable-viewport" to the <body>.

Whew - all set!  Now we can pick-up that body class because it is passed inside $vars to the hook_alpha_preprocess_html() function.

This could get dropped into your theme's template.php file, but I decided to use Omega's odd, but nifty preprocess directory and created preprocess/preprocess-html.inc.  And in goes the function:

function theme_alpha_preprocess_html(&$vars) {
  $theme = alpha_get_theme();
  
  if(array_search('disable-viewport', $vars['attributes_array']['class']) !== false) {
    $theme->settings['viewport']['enabled'] = 0;
  }
  else {
    $theme->settings['viewport']['enabled'] = 1;
  }
}

 

Refresh...refresh....but it had no effect!?!  Refresh and drop dpm's and print_r's everywhere....

Turned out the hook calls alpha_alpha_preprocess_html() before our theme_alpha_preprocess_html() function.  It was too late.  What to do?

Enter hook_html_head_alter(&$head_elements) which allows us to alter (and in my case unset) the meta tags before they are rendered.

Drop this bad boy into the theme's template.php file and boom!

/**
 * Implementation of hook_html_head_alter()
 * @param type $head_elements 
 * 
 * Used in conjunction with theme_alpha_preprocess_html() (inside theme/preprocess/preprocess-html)
 * to not render the viewport tag if the <body> of this page has the 'disable-viewport' class set
 */
function mwl_theme_html_head_alter(&$head_elements) {
  $theme = alpha_get_theme();
  
  if($theme->settings['viewport']['enabled'] != 1 && isset($head_elements['alpha-viewport'])) {
    unset($head_elements['alpha-viewport']);
  }
}

 

Once I figured that out I added this comment at the start of theme_alpha_preprocess_html():

  // this function is called AFTER alpha_alpha_preprocess_html() which will have already set the meta viewport tag
  // but we go ahead and disable it anyway, and then this is picked up by mwl_theme_html_head_alter() in our template.php
  // which unsets the viewport tag if $theme->settings['viewport']['enabled'] is not true

 

If you just want to alter the viewport settings you can easily do that too - here is what lives inside of $head_elements['alpha-viewport']:

Array
(
    [#tag] => meta
    [#attributes] => Array
        (
            [name] => viewport
            [content] => width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no
        )

    [#type] => html_tag
)

 

If anyone knows a way to get at $theme->settings['viewport'] before it hits alpha_alpha_preprocess_html() I am all ears! I tried a backtrace, but nothing looked particularly promising.

About Us

Experienced Drupal Development from Des Moines, Iowa.

We do Drupal websites great and small – tailored to fit your needs. Reach out to us so we can begin. Our clients are in Des Moines, Iowa and across the world. If you have a large scale custom web project, we can be the reliable web partner to make those dreams a reality. But, if you need a simple brochure site or an e-commerce platform for your business, we can come alongside and make that happen too. 

 

covenantlogogrey.png