touch_icons.module in Touch Icons 6
Same filename and directory in other branches
Adds a fieldset to theme settings form which allows site administrators to specify Apple Touch icons for Drupal websites. The Touch icon settings behave in a similar manner to the Site Logo and Favicon settings provided by Drupal core.
Also provides a simple means for theme developers to provide default Touch icons with their theme.
@todo implement hook_help()
@todo refactor fieldsets? do I want two top-level fieldsets? or one top-level/two-children? should children be collapsible? children not collapsible inside VTabs?
File
touch_icons.moduleView source
<?php
/**
* @file
*
* Adds a fieldset to theme settings form which allows site administrators to
* specify Apple Touch icons for Drupal websites. The Touch icon settings behave
* in a similar manner to the Site Logo and Favicon settings provided by Drupal
* core.
*
* Also provides a simple means for theme developers to provide default Touch
* icons with their theme.
*
* @todo implement hook_help()
* @todo refactor fieldsets?
* do I want two top-level fieldsets? or one top-level/two-children?
* should children be collapsible?
* children not collapsible inside VTabs?
*/
/**
* helper function to get theme key for theme settings page.
*
* if we don't receive $key parameter like system_theme_settings()
* we can get it from path, i.e. 'admin/build/themes/settings/THEMENAME'
*
* NOTE: this is NOT the active theme being used to display the page; it is the
* theme currently being configured on the theme settings form.
*/
function _touch_icons_get_theme_settings_key() {
$key = arg(4);
if ($key == "global") {
// undesirable side-effect of admin_menu.module
$key = '';
}
return $key;
}
/**
* Implementation of hook_form_FORM_ID_alter().
* Implementation of hook_form_system_theme_settings_alter().
*
* Add Apple Touch icon customization settings to the theme settings form.
*
* @see system_theme_settings()
*/
function touch_icons_form_system_theme_settings_alter(&$form, $form_state) {
// default values for touch_icons theme_settings
$defaults = array(
'toggle_touch_icon_plain' => 1,
'default_touch_icon_plain' => 1,
'toggle_touch_icon_precomp' => 1,
'default_touch_icon_precomp' => 1,
);
// we don't receive $key parameter like system_theme_settings()
$key = _touch_icons_get_theme_settings_key();
// get theme_settings, using defaults if no touch_icons settings exist
$settings = array_merge($defaults, theme_get_settings($key));
// touch icons fieldset
$form['touch_icons'] = array(
'#type' => 'fieldset',
'#title' => t('iOS touch icon settings'),
'#description' => t('Touch icons are shown as bookmarks on the home-screen of an iOS device.'),
);
// plain touch icon fieldset
$form['touch_icons']['plain'] = array(
'#type' => 'fieldset',
'#title' => t('iOS touch icon'),
'#description' => t('Most iOS devices can display this kind of icon. Rounded corners and a glass-effect overlay are applied by the iOS device.'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
// precomposed touch icon fieldset
$form['touch_icons']['precomp'] = array(
'#type' => 'fieldset',
'#title' => t('iOS touch icon (precomposed)'),
'#description' => t('Using a 'precomposed' touch icon allows more control over the icon's appearance. iOS devices do not apply any special effects to these icons. It is <em>highly recommended</em> that you also enable a plain version, as early iOS versions do not support precomposed icons.'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
// touch icon display settings
if (!module_exists('themesettings_ui_extras')) {
// core-style checkboxes
_touch_icons_themesettings_checkbox($form, $form_state, $settings);
}
else {
// integrate with themesettings_ui_extras.module
_touch_icons_themesettings_radio($form, $form_state, $settings);
}
// custom plain touch icon settings
$form['touch_icons']['plain']['touch_icon_plain_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to custom icon'),
'#default_value' => $settings['touch_icon_plain_path'],
'#description' => t('The path to the file you would like to use as your touch icon instead of the default touch icon.'),
);
$form['touch_icons']['plain']['touch_icon_plain_upload'] = array(
'#type' => 'file',
'#title' => t('Upload icon'),
'#description' => t("If you don't have direct file access to the server, use this field to upload your touch icon."),
'#element_validate' => array(
'_touch_icons_plain_upload_validate',
),
);
// custom precomposed touch icon settings
$form['touch_icons']['precomp']['touch_icon_precomp_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to custom precomposed icon'),
'#default_value' => $settings['touch_icon_precomp_path'],
'#description' => t('The path to the file you would like to use as your precomposed touch icon instead of the default precomposed touch icon.'),
);
$form['touch_icons']['precomp']['touch_icon_precomp_upload'] = array(
'#type' => 'file',
'#title' => t('Upload precomposed icon'),
'#description' => t("If you don't have direct file access to the server, use this field to upload your precomposed touch icon."),
'#element_validate' => array(
'_touch_icons_precomp_upload_validate',
),
);
// adjust form element weights, keep things pretty
// @todo review weights - do any other contrib modules alter this form?
// YES, designkit adds fieldsets too.
if ($form['engine_specific']) {
$form['engine_specific']['#weight'] = 8;
}
if ($form['theme_specific']) {
$form['theme_specific']['#weight'] = 9;
}
$form['buttons']['#weight'] = 10;
// same weight as designkit uses
}
/**
* Helper function for touch icons theme settings form elements.
*
* Provides core-style checkboxes for touch icon theme settings.
*
* @see touch_icons_form_alter()
*/
function _touch_icons_themesettings_checkbox(&$form, &$form_state, &$settings) {
// toggle-display checkboxes
$form['theme_settings']['toggle_touch_icon_plain'] = array(
'#type' => 'checkbox',
'#title' => t('iOS touch icon'),
'#default_value' => $settings['toggle_touch_icon_plain'],
);
$form['theme_settings']['toggle_touch_icon_precomp'] = array(
'#type' => 'checkbox',
'#title' => t('iOS touch icon (precomposed)'),
'#default_value' => $settings['toggle_touch_icon_precomp'],
);
// use default icon checkboxes
$form['touch_icons']['plain']['default_touch_icon_plain'] = array(
'#type' => 'checkbox',
'#title' => t('Use the default iOS touch icon.'),
'#default_value' => $settings['default_touch_icon_plain'],
'#tree' => FALSE,
'#description' => t('Check here if you want the theme to use the touch icon supplied with it.'),
);
$form['touch_icons']['precomp']['default_touch_icon_precomp'] = array(
'#type' => 'checkbox',
'#title' => t('Use the default precomposed iOS touch icon.'),
'#default_value' => $settings['default_touch_icon_precomp'],
'#tree' => FALSE,
'#description' => t('Check here if you want the theme to use the precomposed touch icon supplied with it.'),
);
// integrate with themsettings_verticaltabs.module
if (module_exists('themesettings_verticaltabs')) {
$form['touch_icons']['#attached'] = array(
'js' => array(
'vertical-tabs' => drupal_get_path('module', 'touch_icons') . '/touch_icons_verticaltabs.js',
),
);
}
}
/**
* Helper function for touch icons theme settings form elements.
*
* Integration with themesettings_ui_extras.module
* Provides radio buttons for touch icon theme settings.
*
* @see touch_icons_form_alter()
* @see themesettings_ui_extras_form_alter()
*/
function _touch_icons_themesettings_radio(&$form, &$form_state, &$settings) {
// javascript behaviour to show/hide custom path and file upload elements
drupal_add_js(drupal_get_path('module', 'touch_icons') . '/touch_icons_themesettings_ui_extras.js');
// deduce which plain touch icon radio-button to pre-select
if ($settings['toggle_touch_icon_plain'] == '0') {
$touch_icon_plain_display_value = 'none';
}
elseif ($settings['toggle_touch_icon_plain'] == 1 && $settings['default_touch_icon_plain'] == 1) {
$touch_icon_plain_display_value = 'default';
}
elseif ($settings['toggle_touch_icon_plain'] == 1 && $settings['default_touch_icon_plain'] == 0) {
$touch_icon_plain_display_value = 'custom';
}
// plain touch icon radio-buttons
$form['touch_icons']['plain']['touch_icon_plain_display'] = array(
'#type' => 'radios',
'#title' => t('Display touch icon'),
'#description' => t('Whether a touch icon should be displayed.'),
'#options' => array(
'none' => 'No touch icon',
'default' => 'Default touch icon',
'custom' => 'Custom touch icon',
),
'#default_value' => $touch_icon_plain_display_value,
'#element_validate' => array(
'_touch_icons_plain_radio_validate',
),
);
// deduce which precomposed touch icon radio-button to pre-select
if ($settings['toggle_touch_icon_precomp'] == '0') {
$touch_icon_precomp_display_value = 'none';
}
elseif ($settings['toggle_touch_icon_precomp'] == 1 && $settings['default_touch_icon_precomp'] == 1) {
$touch_icon_precomp_display_value = 'default';
}
elseif ($settings['toggle_touch_icon_precomp'] == 1 && $settings['default_touch_icon_precomp'] == 0) {
$touch_icon_precomp_display_value = 'custom';
}
// precomposed touch icon radio-buttons
$form['touch_icons']['precomp']['touch_icon_precomp_display'] = array(
'#type' => 'radios',
'#title' => t('Display precomposed touch icon'),
'#description' => t('Whether a precomposed touch icon should be displayed.'),
'#options' => array(
'none' => 'No precomposed touch icon',
'default' => 'Default precomposed touch icon',
'custom' => 'Custom precomposed touch icon',
),
'#default_value' => $touch_icon_precomp_display_value,
'#element_validate' => array(
'_touch_icons_precomp_radio_validate',
),
);
// integrate with themsettings_verticaltabs.module
if (module_exists('themesettings_verticaltabs')) {
$form['touch_icons']['#attached'] = array(
'js' => array(
'vertical-tabs' => drupal_get_path('module', 'touch_icons') . '/touch_icons_verticaltabs_radios.js',
),
);
}
}
/**
* Validate plain touch icon display setting.
*
* Helper for integration with themesettings_ui_extras.module
*
* Ensures that theme settings variables are stored in a core-compatible format,
* in case themesettings_ui_extras.module is disabled later.
*/
function _touch_icons_plain_radio_validate($element, &$form_state) {
switch ($form_state['values']['touch_icon_plain_display']) {
case 'none':
$form_state['values']['toggle_touch_icon_plain'] = 0;
// best to set a default value, in case module disabled later...
$form_state['values']['default_touch_icon_plain'] = 1;
break;
case 'default':
$form_state['values']['toggle_touch_icon_plain'] = 1;
$form_state['values']['default_touch_icon_plain'] = 1;
break;
case 'custom':
$form_state['values']['toggle_touch_icon_plain'] = 1;
$form_state['values']['default_touch_icon_plain'] = 0;
break;
}
// no need to store this
unset($form_state['values']['touch_icon_plain_display']);
}
/**
* Validate precomp touch icon display setting.
*
* Helper for integration with themesettings_ui_extras.module
*
* Ensures that theme settings variables are stored in a core-compatible format,
* in case themesettings_ui_extras.module is disabled later.
*/
function _touch_icons_precomp_radio_validate($element, &$form_state) {
switch ($form_state['values']['touch_icon_precomp_display']) {
case 'none':
$form_state['values']['toggle_touch_icon_precomp'] = 0;
// best to set a default value, in case module disabled later...
$form_state['values']['default_touch_icon_precomp'] = 1;
break;
case 'default':
$form_state['values']['toggle_touch_icon_precomp'] = 1;
$form_state['values']['default_touch_icon_precomp'] = 1;
break;
case 'custom':
$form_state['values']['toggle_touch_icon_precomp'] = 1;
$form_state['values']['default_touch_icon_precomp'] = 0;
break;
}
// no need to store this
unset($form_state['values']['touch_icon_precomp_display']);
}
/**
* Validate custom plain touch icon upload.
*
* Saves the uploaded file and prepares file path variable.
*/
function _touch_icons_plain_upload_validate($element, &$form_state) {
// need theme key for saving theme-specific icons
// e.g. garland_apple-touch-icon.png
$key = _touch_icons_get_theme_settings_key();
// ensure there is a directory to save touch icons
$directory_path = file_directory_path() . '/touch_icons';
file_check_directory($directory_path, FILE_CREATE_DIRECTORY);
// Handle plain touch icon upload
if ($file = file_save_upload('touch_icon_plain_upload', array(
'file_validate_is_image' => array(),
))) {
$parts = pathinfo($file->filename);
$filename = $key ? 'touch_icons/' . str_replace('/', '_', $key) . '_apple-touch-icon.' . $parts['extension'] : 'touch_icons/' . 'apple-touch-icon.' . $parts['extension'];
if (file_copy($file, $filename, FILE_EXISTS_REPLACE)) {
drupal_set_message(t('The new touch icon was saved.'));
$form_state['values']['touch_icon_plain_path'] = $file->filepath;
// prepare theme settings variables for storage
// keep consistent with core logo/favicon behaviour
$form_state['values']['default_touch_icon_plain'] = 0;
$form_state['values']['toggle_touch_icon_plain'] = 1;
}
}
}
/**
* Validate custom precomposed touch icon upload.
*
* Saves the uploaded file and prepares file path variable.
*/
function _touch_icons_precomp_upload_validate($element, &$form_state) {
// need theme key for saving theme-specific icons
// e.g. garland_apple-touch-icon.png
$key = _touch_icons_get_theme_settings_key();
// ensure there is a directory to save touch icons
$directory_path = file_directory_path() . '/touch_icons';
file_check_directory($directory_path, FILE_CREATE_DIRECTORY);
// Handle precomposed touch icon upload
if ($file = file_save_upload('touch_icon_precomp_upload', array(
'file_validate_is_image' => array(),
))) {
$parts = pathinfo($file->filename);
$filename = $key ? 'touch_icons/' . str_replace('/', '_', $key) . '_apple-touch-icon-precomposed.' . $parts['extension'] : 'touch_icons/' . 'apple-touch-icon-precomposed.' . $parts['extension'];
if (file_copy($file, $filename, FILE_EXISTS_REPLACE)) {
drupal_set_message(t('The new precomposed touch icon was saved.'));
$form_state['values']['touch_icon_precomp_path'] = $file->filepath;
// prepare theme settings variables for storage
// keep consistent with core logo/favicon behaviour
$form_state['values']['default_touch_icon_precomp'] = 0;
$form_state['values']['toggle_touch_icon_precomp'] = 1;
}
}
}
/**
* Implementation of hook_preprocess_page().
*
* Output <link> elements for the touch icons.
*/
function touch_icons_preprocess_page(&$variables) {
global $theme_key;
$touch_icons_links = '';
// output link for plain touch icon
$url_plain = _touch_icons_create_touch_icon_url($theme_key);
if (check_url($url_plain)) {
$touch_icons_links .= '<link href="' . $url_plain . '" type="' . file_get_mimetype($url_plain) . '" rel="apple-touch-icon" />' . "\n";
}
// output link for precomposed touch icon
$url_precomp = _touch_icons_create_touch_icon_url($theme_key, TRUE);
if (check_url($url_precomp)) {
$touch_icons_links .= '<link href="' . $url_precomp . '" type="' . file_get_mimetype($url_precomp) . '" rel="apple-touch-icon-precomposed" />' . "\n";
}
drupal_set_html_head($touch_icons_links);
$variables['head'] = drupal_get_html_head();
}
/**
* Returns a URL for a touch icon image file, for any theme.
*
* @param $key
* The theme which we need the touch icon URL for.
* @param $precomp
* Specify TRUE if the precomposed touch icon variant is required.
* Default value is FALSE, i.e. the plain touch icon variant.
*
* @return
* A URL for the touch icon.
*/
function _touch_icons_create_touch_icon_url($key, $precomp = FALSE) {
$themes = list_themes();
$theme_object = $themes[$key];
$settings = theme_get_settings($key);
$icon_type = $precomp ? 'precomp' : 'plain';
$default_filename = 'apple-touch-icon' . ($precomp ? '-precomposed' : '') . '.png';
// build apple-touch-icon URL
$url = '';
if (!empty($settings['toggle_touch_icon_' . $icon_type])) {
if (!empty($settings['default_touch_icon_' . $icon_type])) {
if (file_exists($touch_icon = dirname($theme_object->filename) . '/' . $default_filename)) {
$url = base_path() . $touch_icon;
}
else {
$url = base_path() . drupal_get_path('module', 'touch_icons') . '/' . $default_filename;
}
}
elseif ($settings['touch_icon_' . $icon_type . '_path']) {
$url = base_path() . $settings['touch_icon_' . $icon_type . '_path'];
}
}
return $url;
}
Functions
Name![]() |
Description |
---|---|
touch_icons_form_system_theme_settings_alter | Implementation of hook_form_FORM_ID_alter(). Implementation of hook_form_system_theme_settings_alter(). |
touch_icons_preprocess_page | Implementation of hook_preprocess_page(). |
_touch_icons_create_touch_icon_url | Returns a URL for a touch icon image file, for any theme. |
_touch_icons_get_theme_settings_key | helper function to get theme key for theme settings page. |
_touch_icons_plain_radio_validate | Validate plain touch icon display setting. |
_touch_icons_plain_upload_validate | Validate custom plain touch icon upload. |
_touch_icons_precomp_radio_validate | Validate precomp touch icon display setting. |
_touch_icons_precomp_upload_validate | Validate custom precomposed touch icon upload. |
_touch_icons_themesettings_checkbox | Helper function for touch icons theme settings form elements. |
_touch_icons_themesettings_radio | Helper function for touch icons theme settings form elements. |