You are here

fontawesome.module in Font Awesome Icons 7.3

Drupal integration with Font Awesome 5.

File

fontawesome.module
View source
<?php

/**
 * @file
 * Drupal integration with Font Awesome 5.
 */
define('FONTAWESOME_LIBRARY', 'fontawesome');
define('FONTAWESOME_NAME', 'Font Awesome');
define('FONTAWESOME_URL', 'https://fontawesome.com/');
define('FONTAWESOME_CDN_CSS_URL', 'https://use.fontawesome.com/releases/v5.11.2/css/all.css');
define('FONTAWESOME_CDN_SVG_URL', 'https://use.fontawesome.com/releases/v5.11.2/js/all.js');
define('FONTAWESOME_CDN_SHIM_URL', 'https://use.fontawesome.com/releases/v5.11.2/js/v4-shims.js');
define('FONTAWESOME_DOWNLOAD_URL', 'https://use.fontawesome.com/releases/v5.11.2/fontawesome-free-5.11.2-web.zip');
define('FONTAWESOME_PREFIX', 'fa');

/**
 * Implements hook_menu().
 */
function fontawesome_menu() {
  $items['admin/config/content/fontawesome'] = array(
    'title' => 'Font Awesome settings',
    'description' => 'Configure Font Awesome.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'fontawesome_admin_settings_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'fontawesome.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_help().
 */
function fontawesome_help($path, $arg) {
  switch ($path) {
    case 'admin/help#fontawesome':
      return '<p><i class="icon-flag icon-large"></i>' . t('<a href="!fontawesome_url">Font Awesome</a> is an iconic font and CSS toolkit. Font Awesome gives you scalable vector icons that can instantly be customized — size, color, drop shadow, and anything that can be done with the power of CSS. For more information on how to use Font Awesome, see the <a href="!fontawesome_examples_page">Font Awesome Examples page</a>.', array(
        '!fontawesome_url' => FONTAWESOME_URL,
        '!fontawesome_examples_page' => FONTAWESOME_URL . '/how-to-use/svg-with-js',
      )) . '</p>';
  }
}

/**
 * Implements hook_libraries_info().
 */
function fontawesome_libraries_info() {

  // @TODO: Font Awesome Pro
  // Shared core library data.
  $library_core = array(
    'name' => FONTAWESOME_NAME,
    'vendor url' => FONTAWESOME_URL,
    'download url' => FONTAWESOME_DOWNLOAD_URL,
    'cdn url' => array(
      'webfonts' => FONTAWESOME_CDN_CSS_URL,
      'svg' => FONTAWESOME_CDN_SVG_URL,
      'shim' => FONTAWESOME_CDN_SHIM_URL,
    ),
    'version callback' => '_fontawesome_version',
  );

  // SVG wtih JS library.
  $libraries[FONTAWESOME_LIBRARY . '_svg'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_svg']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_svg']['files'] = array(
    'js' => array(
      'js/all.js',
    ),
  );

  // SVG wtih JS base library.
  $libraries[FONTAWESOME_LIBRARY . '_svg_base'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_svg_base']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_svg_base']['files'] = array(
    'js' => array(
      'js/fontawesome.js',
    ),
  );

  // SVG wtih JS solid library.
  $libraries[FONTAWESOME_LIBRARY . '_svg_solid'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_svg_solid']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_svg_solid']['files'] = array(
    'js' => array(
      'js/solid.js',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_svg_solid']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_svg_base',
  );

  // SVG wtih JS regular library.
  $libraries[FONTAWESOME_LIBRARY . '_svg_regular'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_svg_regular']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_svg_regular']['files'] = array(
    'js' => array(
      'js/regular.js',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_svg_regular']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_svg_base',
  );

  // SVG wtih JS light library.
  $libraries[FONTAWESOME_LIBRARY . '_svg_light'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_svg_light']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_svg_light']['files'] = array(
    'js' => array(
      'js/light.js',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_svg_light']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_svg_base',
  );

  // SVG wtih JS brands library.
  $libraries[FONTAWESOME_LIBRARY . '_svg_brands'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_svg_brands']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_svg_brands']['files'] = array(
    'js' => array(
      'js/brands.js',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_svg_brands']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_svg_base',
  );

  // SVG wtih JS shim library.
  $libraries[FONTAWESOME_LIBRARY . '_shim'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_shim']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_shim']['files'] = array(
    'js' => array(
      'js/v4-shims.js',
    ),
  );

  // Webfonts with CSS library.
  $libraries[FONTAWESOME_LIBRARY . '_webfonts'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts']['files'] = array(
    'css' => array(
      'css/all.css',
    ),
  );

  // SVG wtih JS base library.
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_base'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_base']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_base']['files'] = array(
    'css' => array(
      'css/fontawesome.css',
    ),
  );

  // SVG wtih JS solid library.
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_solid'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_solid']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_solid']['files'] = array(
    'css' => array(
      'css/solid.css',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_solid']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_webfonts_base',
  );

  // SVG wtih JS regular library.
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_regular'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_regular']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_regular']['files'] = array(
    'css' => array(
      'css/regular.css',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_regular']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_webfonts_base',
  );

  // SVG wtih JS light library.
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_light'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_light']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_light']['files'] = array(
    'css' => array(
      'css/light.css',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_light']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_webfonts_base',
  );

  // SVG wtih JS brands library.
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_brands'] = $library_core;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_brands']['machine name'] = FONTAWESOME_LIBRARY;
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_brands']['files'] = array(
    'css' => array(
      'css/brands.css',
    ),
  );
  $libraries[FONTAWESOME_LIBRARY . '_webfonts_brands']['dependencies'] = array(
    FONTAWESOME_LIBRARY . '_webfonts_base',
  );
  return $libraries;
}

/**
 * Callback to determine fontawesome version number.
 */
function _fontawesome_version() {
  return '5.11.2';
}

/**
 * Implements hook_preprocess_html_tag().
 *
 * Adds pseudoelements-required data-search-pseudo-elements tag.
 */
function fontawesome_preprocess_html_tag(&$vars) {
  if ($vars['element']['#tag'] == 'script') {
    $method = variable_get('fontawesome_method', 'svg');

    // Check if this is SVG with pseudo-elements turned on.
    if ($method == 'svg' && variable_get('fontawesome_allow_pseudo_elements', FALSE)) {

      // Get settings.
      $external_settings = variable_get('fontawesome_external', array(
        'use_cdn' => TRUE,
        'external_location' => '',
      ));

      // Check if we are using the CDN.
      if ($external_settings['use_cdn']) {

        // Determine the base for the CDN.
        $path = _fontawesome_get_base_path($external_settings['external_location']);
      }
      else {
        $library = libraries_detect(FONTAWESOME_LIBRARY . '_' . $method);
        reset($library['files']['js']);
        $path = $library['library path'];
      }

      // Check if this is the javascript.
      if (isset($vars['element']['#attributes']['src']) && strpos($vars['element']['#attributes']['src'], $path) !== FALSE) {
        $vars['element']['#attributes']['data-search-pseudo-elements'] = TRUE;
      }
    }
  }
  return;
}

/**
 * Gets the base path for a CDN.
 *
 * @param string $path
 *   The path to the CDN.
 *
 * @return string
 *   The base path.
 */
function _fontawesome_get_base_path($path) {

  // Determine the base for the CDN.
  $cdn_components = parse_url($path);
  $cdn_components['path'] = explode('/', $cdn_components['path']);
  unset($cdn_components['path'][count($cdn_components['path']) - 1]);
  $cdn_components['path'] = implode('/', $cdn_components['path']) . '/';
  $cdn_components = _fontawesome_unparse_url($cdn_components);
  return $cdn_components;
}

/**
 * Unparses a CDN URL for use with individual Font Awesome file inclusions.
 *
 * @param array $parsed
 *   Array containing URL parsed data.
 *
 * @return string
 *   The unparsed URL for the CDN.
 */
function _fontawesome_unparse_url(array $parsed) {
  $get = function ($key) use ($parsed) {
    return isset($parsed[$key]) ? $parsed[$key] : NULL;
  };
  $pass = $get('pass');
  $user = $get('user');
  $userinfo = $pass !== NULL ? "{$user}:{$pass}" : $user;
  $port = $get('port');
  $scheme = $get('scheme');
  $query = $get('query');
  $fragment = $get('fragment');
  $authority = ($userinfo !== NULL ? "{$userinfo}@" : '') . $get('host') . ($port ? ":{$port}" : '');
  return (strlen($scheme) ? "{$scheme}:" : '') . (strlen($authority) ? "//{$authority}" : '') . $get('path') . (strlen($query) ? "?{$query}" : '') . (strlen($fragment) ? "#{$fragment}" : '');
}

/**
 * Implements hook_preprocess_html().
 *
 * Purposefully only load on page requests and not hook_init(). This is
 * required so it does not increase the bootstrap time of Drupal when it isn't
 * necessary.
 */
function fontawesome_preprocess_html() {

  // Get module settings.
  $method = variable_get('fontawesome_method', 'svg');
  $external_settings = variable_get('fontawesome_external', array(
    'use_cdn' => TRUE,
    'external_location' => '',
  ));
  $shim_settings = variable_get('fontawesome_shim', array(
    'use_shim' => FALSE,
    'external_location' => '',
  ));
  $partial_files_settings = variable_get('fontawesome_partial', array(
    'use_solid_file' => TRUE,
    'use_regular_file' => TRUE,
    'use_light_file' => TRUE,
    'use_brands_file' => TRUE,
  ));

  // Check if we are using the CDN.
  if ($external_settings['use_cdn']) {

    // First check if we're using everything.
    if ($partial_files_settings['use_solid_file'] && $partial_files_settings['use_regular_file'] && $partial_files_settings['use_light_file'] && $partial_files_settings['use_brands_file']) {

      // Webfonts.
      if ($method == 'webfonts') {

        // Load the file.
        drupal_add_css($external_settings['external_location'], array(
          'type' => 'external',
          'group' => CSS_THEME,
          'every_page' => TRUE,
        ));
      }
      elseif ($method == 'svg') {

        // Load the file.
        drupal_add_js($external_settings['external_location'], array(
          'type' => 'external',
          'scope' => 'footer',
          'group' => JS_THEME,
          'every_page' => TRUE,
          'weight' => 10,
        ));
      }
    }
    else {

      // Determine the base for the CDN.
      $cdn_components = _fontawesome_get_base_path($external_settings['external_location']);

      // Webfonts.
      if ($method == 'webfonts') {

        // Load the base file.
        drupal_add_css($cdn_components . 'fontawesome.css', array(
          'type' => 'external',
          'group' => CSS_THEME,
          'every_page' => TRUE,
        ));
        if ($partial_files_settings['use_solid_file']) {

          // Load the solid file.
          drupal_add_css($cdn_components . 'solid.css', array(
            'type' => 'external',
            'group' => CSS_THEME,
            'every_page' => TRUE,
          ));
        }
        if ($partial_files_settings['use_regular_file']) {

          // Load the regular file.
          drupal_add_css($cdn_components . 'regular.css', array(
            'type' => 'external',
            'group' => CSS_THEME,
            'every_page' => TRUE,
          ));
        }
        if ($partial_files_settings['use_light_file']) {

          // Load the light file.
          drupal_add_css($cdn_components . 'light.css', array(
            'type' => 'external',
            'group' => CSS_THEME,
            'every_page' => TRUE,
          ));
        }
        if ($partial_files_settings['use_brands_file']) {

          // Load the brands file.
          drupal_add_css($cdn_components . 'brands.css', array(
            'type' => 'external',
            'group' => CSS_THEME,
            'every_page' => TRUE,
          ));
        }
      }
      elseif ($method == 'svg') {

        // Load the base file.
        drupal_add_js($cdn_components . 'fontawesome.js', array(
          'type' => 'external',
          'scope' => 'footer',
          'group' => JS_THEME,
          'every_page' => TRUE,
          'weight' => 10,
        ));
        if ($partial_files_settings['use_solid_file']) {

          // Load the solid file.
          drupal_add_js($cdn_components . 'solid.js', array(
            'type' => 'external',
            'scope' => 'footer',
            'group' => JS_THEME,
            'every_page' => TRUE,
            'weight' => 10,
          ));
        }
        if ($partial_files_settings['use_regular_file']) {

          // Load the regular file.
          drupal_add_js($cdn_components . 'regular.js', array(
            'type' => 'external',
            'scope' => 'footer',
            'group' => JS_THEME,
            'every_page' => TRUE,
            'weight' => 10,
          ));
        }
        if ($partial_files_settings['use_light_file']) {

          // Load the light file.
          drupal_add_js($cdn_components . 'light.js', array(
            'type' => 'external',
            'scope' => 'footer',
            'group' => JS_THEME,
            'every_page' => TRUE,
            'weight' => 10,
          ));
        }
        if ($partial_files_settings['use_brands_file']) {

          // Load the brands file.
          drupal_add_js($cdn_components . 'brands.js', array(
            'type' => 'external',
            'scope' => 'footer',
            'group' => JS_THEME,
            'every_page' => TRUE,
            'weight' => 10,
          ));
        }
      }
    }

    // Handle backwards compatibility shim file.
    if ($method == 'svg' && $shim_settings['use_shim']) {
      drupal_add_js($shim_settings['external_location'], array(
        'type' => 'external',
        'scope' => 'footer',
        'group' => JS_THEME,
        'every_page' => TRUE,
        'weight' => 11,
      ));
    }
  }
  else {

    // First check if we're using everything.
    if ($partial_files_settings['use_solid_file'] && $partial_files_settings['use_regular_file'] && $partial_files_settings['use_light_file'] && $partial_files_settings['use_brands_file']) {

      // Load the main library.
      $library = libraries_load(FONTAWESOME_LIBRARY . '_' . $method);
      if (!$library['loaded']) {
        drupal_set_message($library['error message'] . ' ' . t('Please make sure that Font Awesome was downloaded and extracted in the sites/all/libraries/fontawesome directory. Please check README.txt for more details.'), 'warning');
      }
    }
    else {
      if ($partial_files_settings['use_solid_file']) {
        $library = libraries_load(FONTAWESOME_LIBRARY . '_' . $method . '_solid');
        if (!$library['loaded']) {
          drupal_set_message($library['error message'] . ' ' . t('Please make sure that Font Awesome was downloaded and extracted in the sites/all/libraries/fontawesome directory. Please check README.txt for more details.'), 'warning');
        }
      }
      if ($partial_files_settings['use_regular_file']) {
        $library = libraries_load(FONTAWESOME_LIBRARY . '_' . $method . '_regular');
        if (!$library['loaded']) {
          drupal_set_message($library['error message'] . ' ' . t('Please make sure that Font Awesome was downloaded and extracted in the sites/all/libraries/fontawesome directory. Please check README.txt for more details.'), 'warning');
        }
      }
      if ($partial_files_settings['use_light_file']) {
        $library = libraries_load(FONTAWESOME_LIBRARY . '_' . $method . '_light');
        if (!$library['loaded']) {
          drupal_set_message($library['error message'] . ' ' . t('Please make sure that Font Awesome was downloaded and extracted in the sites/all/libraries/fontawesome directory. Please check README.txt for more details.'), 'warning');
        }
      }
      if ($partial_files_settings['use_brands_file']) {
        $library = libraries_load(FONTAWESOME_LIBRARY . '_' . $method . '_brands');
        if (!$library['loaded']) {
          drupal_set_message($library['error message'] . ' ' . t('Please make sure that Font Awesome was downloaded and extracted in the sites/all/libraries/fontawesome directory. Please check README.txt for more details.'), 'warning');
        }
      }
    }

    // Handle backwards compatibility shim file.
    if ($method == 'svg' && $shim_settings['use_shim']) {
      $library = libraries_load(FONTAWESOME_LIBRARY . '_shim');
      if (!$library['loaded']) {
        drupal_set_message($library['error message'] . ' ' . t('Please make sure that Font Awesome was downloaded and extracted in the sites/all/libraries/fontawesome directory. Please check README.txt for more details.'), 'warning');
      }
    }
  }
}

/**
 * Implements hook_icon_providers().
 */
function fontawesome_icon_providers() {
  $providers[FONTAWESOME_LIBRARY] = array(
    'title' => FONTAWESOME_NAME,
    'url' => FONTAWESOME_URL,
  );
  return $providers;
}

/**
 * Implements hook_icon_bundle_configure().
 */
function fontawesome_icon_bundle_configure(&$settings, &$form_state, &$complete_form) {
  $bundle = $form_state['bundle'];
  if ($bundle['provider'] === FONTAWESOME_LIBRARY) {
    $settings['tag'] = array(
      '#type' => 'select',
      '#title' => t('HTML Markup'),
      '#description' => t('Choose the HTML markup tag that @fontawesome icons should be created with. Typically, this is a %tag tag, however it can be changed to suite the theme requirements.', array(
        '@fontawesome' => FONTAWESOME_NAME,
        '%tag' => '<' . $bundle['settings']['tag'] . '>',
      )),
      '#options' => drupal_map_assoc(array(
        'i',
        'span',
        'div',
      )),
      '#default_value' => $bundle['settings']['tag'],
    );
  }
}

/**
 * Implements hook_preprocess_icon_RENDER_HOOK().
 */
function fontawesome_preprocess_icon_sprite(&$variables) {
  $bundle =& $variables['bundle'];
  if ($bundle['provider'] === FONTAWESOME_LIBRARY) {

    // Remove the default "icon" class.
    $key = array_search('icon', $variables['attributes']['class']);
    if ($key !== FALSE) {
      unset($variables['attributes']['class'][$key]);
    }

    // Add the necessary FA identifier class.
    $variables['attributes']['class'][] = FONTAWESOME_PREFIX;

    // Prepend the icon with the FA prefix (which will be used as the class).
    $variables['icon'] = FONTAWESOME_PREFIX . '-' . $variables['icon'];
  }
}

/**
 * Implements hook_icon_bundles().
 */
function fontawesome_icon_bundles() {
  $bundles[FONTAWESOME_LIBRARY] = array(
    'title' => FONTAWESOME_NAME,
    'provider' => FONTAWESOME_LIBRARY,
    'render' => 'sprite',
    'settings' => array(
      'tag' => 'i',
    ),
    'icons' => fontawesome_extract_icons(),
  );
  return $bundles;
}

/**
 * Loads the Font Awesome metadata file.
 *
 * @return string
 *   The filepath of the metadata file.
 */
function fontawesome_get_metadata_filepath() {

  // Load the library so we can get the path.
  $library = libraries_load(FONTAWESOME_LIBRARY . '_svg');

  // Attempt to load the icons from the local library's metadata if possible.
  $metadataFile = drupal_realpath($library['library path'] . '/metadata/icons.json');

  // If we can't load the local file, use the included module icons file.
  if (!file_exists($metadataFile)) {
    $metadataFile = drupal_get_path('module', 'fontawesome') . '/metadata/icons.json';
  }
  return $metadataFile;
}

/**
 * Provides a list of all available Font Awesome icons from metadata.
 *
 * @return array
 *   Array containing icons.
 */
function fontawesome_extract_icons() {
  $icons = array();

  // Get the contents of the YAML file.
  $content = file_get_contents(fontawesome_get_metadata_filepath());

  // Parse the icons metadata.
  foreach (json_decode($content) as $name => $icon) {

    // Determine the icon type - brands behave differently.
    $type = 'solid';
    foreach ($icon->styles as $style) {
      if ($style == 'brands') {
        $type = 'brands';
        break;
      }
    }
    $icons[$name] = array(
      'name' => $name,
      'type' => $type,
      'label' => $icon->label,
      'styles' => $icon->styles,
    );
  }
  return $icons;
}

Functions

Namesort descending Description
fontawesome_extract_icons Provides a list of all available Font Awesome icons from metadata.
fontawesome_get_metadata_filepath Loads the Font Awesome metadata file.
fontawesome_help Implements hook_help().
fontawesome_icon_bundles Implements hook_icon_bundles().
fontawesome_icon_bundle_configure Implements hook_icon_bundle_configure().
fontawesome_icon_providers Implements hook_icon_providers().
fontawesome_libraries_info Implements hook_libraries_info().
fontawesome_menu Implements hook_menu().
fontawesome_preprocess_html Implements hook_preprocess_html().
fontawesome_preprocess_html_tag Implements hook_preprocess_html_tag().
fontawesome_preprocess_icon_sprite Implements hook_preprocess_icon_RENDER_HOOK().
_fontawesome_get_base_path Gets the base path for a CDN.
_fontawesome_unparse_url Unparses a CDN URL for use with individual Font Awesome file inclusions.
_fontawesome_version Callback to determine fontawesome version number.

Constants