Example #1
0
/**
 * Implements hook_theme_registry_alter().
 */
function omega_theme_registry_alter(&$registry)
{
    require_once dirname(__FILE__) . '/includes/registry.inc';
    // Fix for integration with the theme developer module.
    if (module_exists('devel_themer')) {
        foreach ($registry as $hook => $data) {
            if (isset($data['original'])) {
                $registry[$hook] = $data['original'];
            }
        }
    }
    // For maintainability reasons, some of this code lives in a class.
    $handler = new OmegaThemeRegistryHandler($registry, $GLOBALS['theme']);
    // Allows themers to split preprocess / process / theme code across separate
    // files to keep the main template.php file clean. This is really fast because
    // it uses the theme registry to cache the paths to the files that it finds.
    $trail = omega_theme_trail($GLOBALS['theme']);
    foreach ($trail as $theme => $name) {
        $handler->registerHooks($theme);
        $handler->registerThemeFunctions($theme, $trail);
    }
    // Override the default 'template_process_html' hook implementation.
    $handler->overrideHook('html', 'template_process_html', 'omega_template_process_html_override');
    // We prefer the attributes array instead of the plain classes array used by
    // many core and contrib modules. In Drupal 8, we are going to convert all
    // occurrences of that into an attributes object. For now, we simply
    // synchronize our attributes array with the classes array to encourage
    // themers to use it.
    foreach ($registry as $hook => $item) {
        if (empty($item['base hook']) && empty($item['function'])) {
            if (($index = array_search('template_preprocess', $registry[$hook]['preprocess functions'], TRUE)) !== FALSE) {
                // Make sure that omega_initialize_attributes() is invoked first.
                array_unshift($registry[$hook]['process functions'], 'omega_cleanup_attributes');
                // Add omega_cleanup_attributes() right after template_preprocess().
                array_splice($registry[$hook]['preprocess functions'], $index + 1, 0, 'omega_initialize_attributes');
            }
        }
    }
    // Add a preprocessor for initializing default variables to every layout.
    foreach (array_keys(_omega_theme_layouts()) as $hook) {
        $registry[$hook]['preprocess functions'] = array_diff($registry[$hook]['preprocess functions'], array('template_preprocess'));
        array_unshift($registry[$hook]['process functions'], '_omega_preprocess_default_layout_variables');
    }
    // Allow extensions to register hooks in the theme registry.
    foreach (omega_extensions() as $extension => $info) {
        // Invoke the according hooks for every enabled extension.
        if (omega_extension_enabled($extension)) {
            // Give every enabled extension a chance to alter the theme registry.
            $hook = $info['theme'] . '_extension_' . $extension . '_theme_registry_alter';
            if (function_exists($hook)) {
                $hook($registry);
            }
        }
    }
    // Fix for integration with the theme developer module.
    if (module_exists('devel_themer') && function_exists('devel_themer_theme_registry_alter')) {
        devel_themer_theme_registry_alter($registry);
    }
}
Example #2
0
/**
 * Implements hook_form_FORM_alter().
 */
function omega_form_system_theme_settings_alter(&$form, &$form_state, $form_id = NULL)
{
    // General "alters" use a form id. Settings should not be set here. The only
    // thing useful about this is if you need to alter the form for the running
    // theme and *not* the the me setting. @see http://drupal.org/node/943212
    if (isset($form_id)) {
        return;
    }
    if (variable_get('theme_' . $GLOBALS['theme_key'] . '_settings')) {
        // Alert the user that the theme settings are served from a variable.
        drupal_set_message(t('The settings for this theme are currently served from a variable. You might want to export them to your .info file.'), 'warning', FALSE);
    }
    $form['omega_enable_warning'] = array('#type' => 'checkbox', '#title' => t('Show a warning if Omega is used directly'), '#description' => t('You can disable this warning message permanently, however, please be aware that Omega is a base theme and should not be used directly. You should always create a sub-theme instead.'), '#default_value' => omega_theme_get_setting('omega_enable_warning', TRUE), '#weight' => -20, '#access' => $GLOBALS['theme_key'] === 'omega');
    // Include the template.php and theme-settings.php files for all the themes in
    // the theme trail.
    foreach (omega_theme_trail() as $theme => $name) {
        $path = drupal_get_path('theme', $theme);
        $filename = DRUPAL_ROOT . '/' . $path . '/template.php';
        if (file_exists($filename)) {
            require_once $filename;
        }
        $filename = DRUPAL_ROOT . '/' . $path . '/theme-settings.php';
        if (file_exists($filename)) {
            require_once $filename;
        }
    }
    // Get the admin theme so we can set a class for styling this form.
    $admin = drupal_html_class(variable_get('admin_theme', $GLOBALS['theme']));
    $form['#prefix'] = '<div class="admin-theme-' . $admin . '">';
    $form['#suffix'] = '</div>';
    // Add some custom styling and functionality to our theme settings form.
    $form['#attached']['css'][] = drupal_get_path('theme', 'omega') . '/css/omega.admin.css';
    $form['#attached']['js'][] = drupal_get_path('theme', 'omega') . '/js/omega.admin.min.js';
    // Collapse all the core theme settings tabs in order to have the form actions
    // visible all the time without having to scroll.
    foreach (element_children($form) as $key) {
        if ($form[$key]['#type'] == 'fieldset') {
            $form[$key]['#collapsible'] = TRUE;
            $form[$key]['#collapsed'] = TRUE;
        }
    }
    if ($extensions = omega_extensions(NULL, TRUE)) {
        $form['omega'] = array('#type' => 'vertical_tabs', '#weight' => -10);
        // Load the theme settings for all enabled extensions.
        foreach ($extensions as $extension => $info) {
            $form['omega'][$extension] = array('#type' => 'fieldset', '#title' => $info['info']['name'], '#attributes' => array('class' => array('omega-extension')));
            $errors = array();
            if (!empty($info['info']['dependencies'])) {
                foreach ($info['info']['dependencies'] as $dependency) {
                    $dependency = drupal_parse_dependency($dependency);
                    // Check if the module exists.
                    if (!($module = system_get_info('module', $dependency['name']))) {
                        $errors[] = t('This extension requires the @module module.', array('@module' => ucwords(str_replace('_', ' ', $dependency['name']))));
                    } elseif (($version = omega_check_incompatibility($dependency, $module['version'])) !== NULL) {
                        $errors[] = t('This extension requires @module @version. The currently installed version is @installed.', array('@module' => $module['name'], '@version' => $version, '@installed' => !empty($module['version']) ? $module['version'] : t('undetermined')));
                    }
                }
                if (!empty($errors)) {
                    $form['omega'][$extension]['errors'] = array('#type' => 'item', '#title' => t('Missing requirements'), '#markup' => '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>', '#weight' => -20, '#name' => 'omega-requirements');
                }
            }
            // Disable all options if there were any errors.
            $form['omega'][$extension]['#disabled'] = !empty($errors) || variable_get('omega_toggle_extension_' . $extension) !== NULL;
            $form['omega'][$extension]['omega_toggle_extension_' . $extension] = array('#type' => 'checkbox', '#title' => t('Enable @extension extension', array('@extension' => $info['info']['name'])) . (variable_get('omega_toggle_extension_' . $extension) !== NULL ? ' <span class="marker">(' . t('overridden') . ')</span>' : ''), '#description' => t('This setting can be overridden with an equally named variable (@name) so you can control it on a per-environment basis by setting it in your settings.php file.', array('@name' => 'omega_toggle_extension_' . $extension)), '#default_value' => omega_extension_enabled($extension), '#weight' => -10);
            $element = array();
            // Load the implementation for this extensions and invoke the according
            // hook.
            $file = $info['path'] . '/' . $extension . '.settings.inc';
            if (is_file($file)) {
                require_once $file;
            }
            $function = $info['theme'] . '_extension_' . $extension . '_settings_form';
            if (function_exists($function)) {
                // By default, each extension resides in a vertical tab.
                $element = $function($element, $form, $form_state) + array('#type' => 'fieldset', '#title' => t('@extension extension configuration', array('@extension' => $info['info']['name'])), '#description' => $info['info']['description'], '#attributes' => array('class' => array('omega-extension-settings')), '#states' => array('disabled' => array('input[name="omega_toggle_extension_' . $extension . '"]' => array('checked' => FALSE))));
            }
            drupal_alter('extension_' . $extension . '_settings_form', $element, $form, $form_state);
            if (element_children($element)) {
                // Append the extension form to the theme settings form if it has any
                // children.
                $form['omega'][$extension]['settings'] = $element;
            }
        }
    }
    // Custom option for toggling the main content blog on the front page.
    $form['theme_settings']['omega_toggle_front_page_content'] = array('#type' => 'checkbox', '#title' => t('Front page content'), '#description' => t('Allow the main content block to be rendered on the front page.'), '#default_value' => omega_theme_get_setting('omega_toggle_front_page_content', TRUE));
    // We need a custom form submit handler for processing some of the values.
    $form['#submit'][] = 'omega_theme_settings_form_submit';
    // Store the extensions in an array so we can loop over them in the submit
    // callback.
    $form_state['extensions'] = array_keys($extensions);
}
Example #3
0
/**
 * Implements hook_theme_registry_alter().
 */
function omega_theme_registry_alter(&$registry)
{
    // Fix for integration with the theme developer module.
    if (module_exists('devel_themer')) {
        foreach ($registry as $hook => $data) {
            $registry[$hook] = $data['original'];
        }
    }
    $mapping = array('preprocess' => 'preprocess functions', 'process' => 'process functions', 'theme' => 'function');
    // We prefer the attributes array instead of the plain classes array used by
    // many core and contrib modules. In Drupal 8, we are going to convert all
    // occurrences of that into an attributes object. For now, we simply
    // synchronize our attributes array with the classes array to encourage
    // themers to use it.
    foreach ($registry as $hook => $item) {
        if (empty($item['base hook']) && empty($item[$mapping['theme']])) {
            if (($index = array_search('template_preprocess', $registry[$hook][$mapping['preprocess']], TRUE)) !== FALSE) {
                // Make sure that omega_initialize_attributes() is invoked first.
                array_unshift($registry[$hook][$mapping['process']], 'omega_cleanup_attributes');
                // Add omega_cleanup_attributes() right after template_preprocess().
                array_splice($registry[$hook][$mapping['preprocess']], $index + 1, 0, 'omega_initialize_attributes');
            }
        }
    }
    // Allow themers to split preprocess / process / theme code across separate
    // files to keep the main template.php file clean. This is really fast because
    // it uses the theme registry to cache the paths to the files that it finds.
    $trail = omega_theme_trail();
    // Keep track of theme function include files that are not directly loaded
    // into the theme registry. This is the case for previously unknown theme
    // hook suggestion implementations.
    foreach ($trail as $theme => $name) {
        // Remove the current element from the trail so we only iterate over
        // higher level themes during subsequent checks.
        unset($trail[$theme]);
        foreach ($mapping as $type => $map) {
            $path = drupal_get_path('theme', $theme);
            // Only look for files that match the 'something.preprocess.inc' pattern.
            $mask = '/.' . $type . '.inc$/';
            // This is the length of the suffix (e.g. '.preprocess') of the basename
            // of a file.
            $strlen = -(strlen($type) + 1);
            // Recursively scan the folder for the current step for (pre-)process
            // files and write them to the registry.
            foreach (file_scan_directory($path . '/' . $type, $mask) as $item) {
                $hook = strtr(substr($item->name, 0, $strlen), '-', '_');
                // If there is no hook with that name, continue. This does not apply to
                // theme functions because if we want to support theme hook suggestions
                // in .theme.inc files that have not previously been declared we need to
                // run the full discovery for theme functions.
                if (!array_key_exists($hook, $registry) && ($type !== 'theme' || strpos($hook, '__') === FALSE)) {
                    continue;
                }
                // Skip theme function overrides if they are already declared 'final'.
                if ($type === 'theme' && !empty($registry[$hook]['final'])) {
                    continue;
                }
                // Name of the function (theme hook or theme function).
                $callback = $type == 'theme' ? $theme . '_' . $hook : $theme . '_' . $type . '_' . $hook;
                // Furthermore, we don't want to re-override sub-theme template file or
                // theme function overrides with theme functions from include files
                // defined in a lower-level base theme. Without this check this would
                // happen because our alter hook runs after the template file and theme
                // function discovery logic from Drupal core (theme engine).
                if ($type == 'theme' && $theme != $GLOBALS['theme'] && in_array($registry[$hook]['type'], array('base_theme_engine', 'theme_engine'))) {
                    // Now we know that there is a template file or theme function
                    // override that has been defined somewhere in the theme trail. Now
                    // we need to check if the declaration of that function or template
                    // file lives further down the theme trail than the function we are
                    // currently looking it.
                    foreach ($trail as $subkey => $subtheme) {
                        if ($registry[$hook]['theme path'] == drupal_get_path('theme', $subkey)) {
                            continue 2;
                        }
                    }
                }
                // Load the file once so we can check if the function exists.
                require_once $item->uri;
                // Proceed if the callback doesn't exist.
                if (!function_exists($callback)) {
                    continue;
                }
                // If we got this far and the following if() statement evaluates to true
                // then that means that the theme function override that is currently
                // being processed is a previously unknown theme hook suggestion.
                if ($type == 'theme' && !array_key_exists($hook, $registry) && ($separator = strpos($hook, '__'))) {
                    $suggestion = $hook;
                    $hook = substr($hook, 0, $separator);
                    if (!isset($registry[$hook])) {
                        // Bail out here if the base hook does not exist.
                        continue;
                    }
                    // Register the theme hook suggestion.
                    $arg_name = isset($registry[$hook]['variables']) ? 'variables' : 'render element';
                    $registry[$suggestion] = array($map => $callback, $arg_name => $registry[$hook][$arg_name], 'base hook' => $hook);
                } elseif ($type == 'theme') {
                    // Inject our theme function. We will leave any potential 'template'
                    // declarations in the registry as they don't hurt us anyways
                    // because drupal gives precedence to theme functions.
                    $registry[$hook][$map] = $callback;
                } else {
                    // Append the included preprocess hook to the array of functions.
                    $registry[$hook][$map][] = $callback;
                }
                // By adding this file to the 'includes' array we make sure that it is
                // available when the hook is executed.
                $registry[$hook]['includes'][] = $item->uri;
            }
        }
    }
    // Include the main extension file for every enabled extension. This is
    // required for the next step (allowing extensions to register hooks in the
    // theme registry).
    foreach (omega_extensions() as $extension => $info) {
        // Load all the implementations for this extensions and invoke the according
        // hooks.
        if (omega_extension_enabled($extension)) {
            $file = $info['path'] . '/' . $extension . '.inc';
            if (is_file($file)) {
                require_once $file;
            }
            // Give every enabled extension a chance to alter the theme registry.
            $hook = $info['theme'] . '_extension_' . $extension . '_theme_registry_alter';
            if (function_exists($hook)) {
                $hook($registry);
            }
        }
    }
    // Override pre-process and process functions for cases where we want to take
    // a completely different approach than what core does by default. In some
    // cases this is much more practical than altering or undoing things that were
    // added or changed in a previous hook.
    $overrides = array('html' => array('process' => array('template_process_html' => 'omega_template_process_html_override')));
    foreach ($overrides as $hook => $types) {
        foreach ($types as $type => $overrides) {
            foreach ($overrides as $original => $override) {
                if (($index = array_search($original, $registry[$hook][$mapping[$type]], TRUE)) !== FALSE) {
                    array_splice($registry[$hook][$mapping[$type]], $index, 1, $override);
                }
            }
        }
    }
    // Fix for integration with the theme developer module.
    if (module_exists('devel_themer')) {
        devel_themer_theme_registry_alter($registry);
    }
}