Theming Drupal’s Print Module Icons

By Josh Walker,
Print module icons

Drupal’s Print module has some pretty dated-looking icons that come bundled with it. However, support for Windows 3.1 ended 14 years ago and so did the need for tiny little pixelated icons. Being the fashion-forward web developers we are at Kalamuna, we’d like you show you how to imbue your Print module links with a modern aesthetic that will look great at any size and on any screen using FontAwesome icons.

print, share, pdf icons before-and-after

Before we go any further, make sure you have the FontAwesome CSS available to you via the FontAwesome module (by non-other than Kalamuna’s own Rob Loach) or some other method—depending on your front-end setup.

Wherefore Art Thou Render Arrays?

One of the main issues preventing this from being easier is the fact that the Print module doesn’t utilize Drupal’s theme system effectively. If render arrays were used to output the print, email and PDF links it would be far easier for us to swap out the icons in a preprocess function. But, this isn’t the case. Instead, we are going to have to override the theme_print_ui_format_link() function.

Before we do that, though, we need to implement a custom theme function to output some FontAwesome awesomeness. Add the following two functions to the template.php in your theme, making sure you change all instances of ‘yourthemename’ to the actual name of your theme:

/**
 * Implements hook_theme.
 */
function yourthemename_theme() {
  return array(
    'fa_icon' => array(
      'variables' => array(
        'icon' => NULL,
        'attributes' => array(
          'class' => array('fa'),
        ),
      ),
    ),
  );
}
/**
 * Return markup for a fontawesome icon.
 */
function yourthemename_fa_icon($vars){
  // Add the icon name.
  $vars['attributes']['class'][] = 'fa-' . $vars['icon'];
  
  // Return an i tag just like FontAwesome likes.
  return '<i ' . drupal_attributes($vars['attributes']) . '></i>';
}

Once you’ve saved template.php, clear the cache. You should now have a theme function that will return the markup for a FontAwesome icon.

Theme Function Override

Now it’s time to override the Print module’s theme_print_ui_format_link() function. Copy the following code into your theme’s template.php, again making sure you change all instances of ‘yourthemename’ to the actual name of your theme.

/**
 * Format the Printer-friendly link
 *
 * @return array
 *   An associative array containing:
 *   - text: The content of the link
 *   - html: TRUE if the text contains HTML tags, FALSE if it's plain text
 *   - attributes: several attributes of the link tag (title, class, target,
 *     onclick, rel)
 *
 * @see _print_ui_fill_attributes()
 * @ingroup themeable
 * @ingroup print_themeable
 */
function yourthemename_print_ui_format_link($vars) {
  $format = $vars['format'];

  foreach (module_implements('print_link') as $module) {
    $function = $module . '_print_link';
    if (function_exists($function)) {
      $link = call_user_func_array($function, array());

      if ($link['format'] == $format) {
        $link_class = variable_get('print_' . $link['format'] . '_link_class', $link['class']);

        $new_window = FALSE;
        $func = $module . '_print_new_window_alter';
        if (function_exists($func)) {
          $func($new_window, $link['format']);
        }

        $show_link = variable_get('print_' . $link['format'] . '_show_link', PRINT_UI_SHOW_LINK_DEFAULT);
        $link_text = filter_xss(variable_get('print_' . $link['format'] . '_link_text', $link['text']));

        if ($show_link >= 2) {
          // Work out which icon we want to show based on the link's format.
          switch ($link['format']){
            case 'html':
              $icon_name = 'print';
              break;  
            
            case 'mail':
              $icon_name = 'envelope-o';
              break;

            case 'pdf':
              $icon_name = 'file-pdf-o';
              break;
          }

          // Build the icon.
          $icon = theme('fa_icon', array('icon' => $icon_name));

          // Show the icon with or without text, depending on config settings.
          switch ($show_link) {
            case 2:
              $text = $icon;
              break;
            case 3:
              $text = $icon . ' ' . $link_text;
              break;
          }
          $html = TRUE;
        }
        else {
          $text = $link_text;
          $html = FALSE;
        }

        return array(
          'text' => $text,
          'html' => $html,
          'attributes' => _print_ui_fill_attributes($link['description'], strip_tags($link_class), $new_window),
        );
      }
    }
  }
}

Two main things are happening here that differ from the original function:

  1. Work out what the icons name should be based on the type of link we are printing.
  2. Swap the image theme call and use our custom fa_icon theme call instead.

Make sure to clear the cache again. That should be all you need to see shiny new FontAwesome icons on your Print module links. Also, you can now style your icons—color, size, position—all with CSS!

Joshua Walker

Developer

In an e-land of hackery and villany, Kalamuna developer Josh Walker is humanity’s one true hope. When Josh steps onto the scene, the Drupal bandits run and cower in fear. After inceptioning the code to believe what he and he alone wants, Josh celebrates by crafting up a delicious beer. In addition to being rockstar programmer, he’s also a rockstar dad of two boys.