Use this page to edit the block styles.
When you edit the css for a style definition and save this form, all blocks with that style will receive the new css. When editing Style definitions you may change the style name OR the css for the style, per form submission. To change both css and style name of a single Style definition, you need to do the css first, save the form, then do the style name and save the form.
Each style generates a theme hook suggestion, so you can override block.tpl.php
for each style with the appropriate tpl file. See Template suggestions list for the template filenames that correspond to each style. This list will only appear after you have created one or more styles and saved this form.
Other things to note:
- The list of style definitions is defined by all the block classes/styles that have been previously assigned to blocks as well as any definitions made here that have not yet been assigned.
- The only way to make all Style definitions disappear (from the box below) is to remove all classes/styles from each and every block.
- However, you may hide a style from appearing in the styles list on block edit forms by unchecking it from the select list options below.
- Unchecking a style from the select list options does not affect a block with that style assigned to it. To affect the block you need to edit the block itself and unassign the style.
- An unchecked style will still appear on a block's edit form if it has been selected for that block. The style name will be appended with "***" to designate it's been hidden.
EOD;
}
return $output;
}
/**
* Implements hook_permission().
*/
function block_class_styles_permission() {
return array(
'administer block_class_styles' => array(
'title' => t('Administer Block Styles'),
'description' => t('Define styles and other settings for the module.'),
'restrict access' => TRUE,
),
'block_class_styles:use' => array(
'title' => t('Use Block Styles'),
'description' => t("See/change a given block's style when editing it."),
),
);
}
/**
* Implements hook_menu().
*/
function block_class_styles_menu() {
$items = array();
$items[BLOCK_CLASS_STYLES_PATH_SETTINGS] = array(
'title' => 'Block styles',
'description' => 'Define preset classes and styles.',
'page callback' => 'drupal_get_form',
'page arguments' => array('block_class_styles_admin_settings'),
'file' => 'block_class_styles.admin.inc',
'access arguments' => array('administer block_class_styles'),
'type' => MENU_LOCAL_TASK,
'weight' => 50,
);
return $items;
}
/**
* Returns an array of css classes for a given style name.
*
* @param $style The human readable declaration of a style.
*
* @return null|array
*/
function block_class_styles_get_css_by_style($style) {
$info = block_class_styles_info();
$classes = array_search($style, $info);
return empty($classes) ? NULL : explode(' ', $classes);
}
/**
* Return an array of style presets
*
* @param boolean $include_hidden Include hiden styles
*
* @return array Keys are classes, values are styles
*/
function block_class_styles_info($include_hidden = FALSE) {
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['presets'] = &drupal_static(__FUNCTION__, NULL);
}
$presets = &$drupal_static_fast['presets'];
if (!isset($presets)) {
$presets = array();
// Load distinct classes and groupings of classes from blocks table; this
// makes sure that we have a style for every class or class group that is
// currently assigned to a block.
$classes = db_select(_block_class_tablename(), 'b')
->fields('b', array('css_class'))
->condition('css_class', '', '!=')
->distinct()
->execute()->fetchCol();
foreach ($classes as $class) {
$presets[$class] = ucwords(preg_replace('/[_-]/', ' ', $class));
}
// Now match to our presets if possible; this will overwrite the automatic
// naming convention from above and add any styles that have been defined
// but not yet assigned.
$presets = variable_get('block_class_styles_presets', array()) + $presets;
// Remove any hidden styles if asked.
$hidden = variable_get('block_class_styles_hidden', array());
if (!$include_hidden) {
$presets = array_diff_key($presets, $hidden);
}
// Let other modules alter this list
drupal_alter('block_class_styles_info', $presets);
$presets = (array)$presets;
}
return $presets;
}
/**
* Implements hook_flush_caches().
*
* Scans theme info files for presets and modifies our variable
*/
function block_class_styles_flush_caches() {
$presets = variable_get('block_class_styles_presets', array());
// Scan the theme info files
$include_from_themes = array();
$info = array();
foreach (list_themes() as $name => $data) {
// Check for the parent themes because we'll need to include that info
if ($data->status && isset($data->base_themes)) {
$include_from_themes += $data->base_themes;
}
if (isset($data->info['block_class_styles'])) {
$include_from_themes[$name] = $data->info['name'];
$info[$name] = $data->info['block_class_styles'];
}
}
$info = array_intersect_key($info, $include_from_themes);
foreach ($info as $array) {
$presets = array_merge($presets, $array);
}
variable_set('block_class_styles_presets', $presets);
}
/**
* Return a style by it's css
*
* @param string $css
*
* @return string or FALSE
*/
function block_class_styles_get_style($css) {
$presets = block_class_styles_info();
return $css && array_key_exists($css, $presets) ? $presets[$css] : FALSE;
}
/**
* Return the name of the table to use based on module version
*
* @return string The name of the table.
*/
function _block_class_tablename() {
return db_field_exists('block', 'css_class') ? 'block' : 'block_class';
}
/**
* Implements hook_form_alter().
*/
function block_class_styles_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'block_admin_configure' || $form_id == 'block_add_block_form') {
$form['block_class']['#access'] = user_access('block_class_styles:use');
$form['block_class']['#title'] = variable_get('block_class_styles_fs_title', BLOCK_CLASS_STYLES_FS_TITLE);
$form['block_class']['#description'] = variable_get('block_class_styles_fs_description', BLOCK_CLASS_STYLES_FS_DESCRIPTION);
$block = new stdClass;
$block->module = $form['module']['#value'];
$block->delta = $form['delta']['#value'];
$css_class = '';
if (!empty($form['settings']['css_class']['#default_value'])) {
$css_class = $form['settings']['css_class']['#default_value'];
}
$multiple = FALSE;
//@todo See admin.inc for explanation
//$multiple = current(variable_get('block_class_styles_allow_multiple', BLOCK_CLASS_STYLES_ALLOW_MULTIPLE));
$options = block_class_styles_info();
$default = array($css_class);
// If the default is hidden we need to grab it
if ($css_class && !array_key_exists($css_class, $options)) {
$default_is_hidden = TRUE;
$hidden = block_class_styles_info(TRUE);
$options += array_intersect_key($hidden, array_flip($default));
$options[$css_class] .= ' ***';
}
if (!$multiple) {
$options = array(NULL => t('-None-')) + $options;
$default = $css_class;
}
$form['block_class_styles'] = array(
'#access' => $form['block_class']['#access'],
'#type' => 'fieldset',
'#title' => variable_get('block_class_styles_fs_title', BLOCK_CLASS_STYLES_FS_TITLE),
'#description' => variable_get('block_class_styles_fs_description', BLOCK_CLASS_STYLES_FS_DESCRIPTION),
'#collapsible' => TRUE,
'#collapsed' => !variable_get('block_class_styles_form_collapsed', FALSE),
'#weight' => variable_get('block_class_styles_form_weight', 0),
);
$form['block_class_styles']['css_class'] = array(
'#type' => $multiple ? 'checkboxes' : 'select',
'#title' => variable_get('block_class_styles_title', BLOCK_CLASS_STYLES_TITLE),
'#options' => $options,
'#default_value' => $default,
'#description' => variable_get('block_class_styles_description', BLOCK_CLASS_STYLES_DESCRIPTION),
'#maxlength' => 255,
);
$form['block_class_styles']['admin'] = array(
'#markup' => t('To edit styles click here.', array('!url' => url(BLOCK_CLASS_STYLES_PATH_SETTINGS, array('query' => drupal_get_destination())))),
'#access' => user_access('administer block_class_styles'),
);
// This field needs to be hidden because we show it in our own way in our
// fieldset, and... we can't set #access to FALSE because our variable name
// is the same, so we have turn it into a non-displaying type = 'value'
$form['settings']['css_class']['#type'] = 'value';
}
}
/**
* Implements hook_block_view().
*/
function block_class_styles_block_view_alter(&$data, $block) {
if (empty($block->css_class)) {
return;
}
$name = preg_replace('/[ -]/', '_', strtolower($block->css_class));
$name = preg_replace('/[^a-z0-1_]/', '', $name);
$data['block_class_styles'] = (object)array(
'name' => $name,
'css' => drupal_html_class($name),
'title' => block_class_styles_get_style($block->css_class),
'classes_array' => array(explode(' ', $block->css_class)),
);
}
/**
* Implements hook_preprocess_block().
*
* @param &$vars
*
* @return NULL
*/
function block_class_styles_preprocess_block(&$vars) {
if (isset($vars['block']->css_class)
&& ($css = $vars['block']->css_class)
&& ($style = block_class_styles_get_style($css))
&& ($suggestions = _block_class_styles_theme_hook_suggestion($style))
) {
if ($insert_after = array_search('block__block', $vars['theme_hook_suggestions'])) {
array_splice($vars['theme_hook_suggestions'], $insert_after + 1, 0, $suggestions);
}
else {
$vars['theme_hook_suggestions'] = array_merge($vars['theme_hook_suggestions'], $suggestions);
}
}
if ($vars['block']->title &&
$vars['block']->title != '' &&
($format = variable_get('block_class_styles_title_format', BLOCK_CLASS_STYLES_TITLE_FORMAT))
) {
$vars['block']->subject = check_markup($vars['block']->title, $format);
// Now strip the outermost which could show up from check_markup
preg_match('/^\s*
(.*)<\/p>\s*$/is', $vars['block']->subject, $found);
$vars['block']->subject = isset($found[1]) ? $found[1] : $vars['block']->subject;
}
}
/**
* Return the theme_hook_suggestion for a style
*
* @param string $style
*
* @return string
*/
function _block_class_styles_theme_hook_suggestion($style) {
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['hooks'] = &drupal_static(__FUNCTION__, NULL);
}
$hooks = &$drupal_static_fast['hooks'];
if (!isset($hooks[$style])) {
$suggestions = array();
$suggestions[] = 'block__' . strtolower(str_replace('-', '_', drupal_clean_css_identifier($style)));
if (($classes = block_class_styles_get_css_by_style($style))) {
do {
$hook = implode('__', $classes);
$suggestions[] = 'block__' . strtolower(str_replace('-', '_', drupal_html_class($hook)));
} while (array_pop($classes) && $classes);
}
$hooks[$style] = array_unique($suggestions);
}
return $hooks[$style];
}
//function block_class_menu_contextual_links_alter(&$links, $router_item, $root_path) {
// if ($root_path === 'admin/structure/block/manage/%/%') {
// $presets = block_class_styles_info();
// foreach ($presets as $key => $preset) {
// $links[] = array(
// 'title' => check_plain($preset),
// 'href' => "block_class_styles/$key",
// 'localized_options' => array(
// 'query' => drupal_get_destination() + array(
// 'token' => drupal_get_token('block_class'),
// ),
// ),
// );
// }
// }
//
// $links = $links;
//}