8

I don't know why, but Views doesn't add "human-readable" CSS class names (like e.g. the machine name of the view) to the blocks it creates (it only adds its classes to the generated "content" part when adding classes to the "CSS class" part in the view editor (see the screenshots below!)).
It only adds the usual block block-views, and possibly contextual-links-region CSS classes to the block(s), and generates a unique id (not class) like this: block-views-3d8f7966168beeec655c8ead69336789 (because its delta is this generated hash code).
It doesn't make sense to write CSS rules for these classes and ids (like .block-views-3d8f7966168beeec655c8ead69336789 { /* ... */ }), because these classes/ids might change when altering the Views block.

How can I add some custom CSS classes in an implementation of hook_block_view_alter(), if I cannot even identify these blocks because of their generated hash delta?


I do not want to use Block Class, because I feel it's like an overkill for just adding some classes to one or two Views-generated blocks (BTW I checked the module, and I feel SELECT css_class, module, delta FROM {block_class} query in block_class_preprocess_block() like an overkill, because it checks ALL the added classes, even if the block is hidden...).

So I would like to solve it from my own module.


EDIT

An example:

My view with the machine name and the added CSS classes: View - machine name and class

The generated block's HTML code in the inspector: View - generated block's HTML code in the inspector

5 Answers 5

7

First. You have "hash" - because you view machine name is too long.

Second - you can add your own classes to view

enter image description here

8
  • That screenshot you have regards view blocks, right?
    – cherouvim
    Oct 11, 2012 at 8:10
  • no - it is on view editing page - admin/structure/views/view/[youviewname]
    – Gaydabura
    Oct 11, 2012 at 8:11
  • 1
    "You have "hash" - because you view machine name is too long." - and why does it matter? I can add rules in CSS stylesheets to REALLY long class names too without any problems... The "CSS class" part you marked is NOT correct, because these classes are only generated into the "content" part - this is what I started my question with! So I have to add classes to the wrapper of the contents. See the screenshots I just pasted in the original question.
    – Sk8erPeter
    Oct 11, 2012 at 8:19
  • ok. in this case the simpliest way is to create custom templates for block - you want change. this link can be useful drupal.org/node/1089656 - it explains Template name suggestions
    – Gaydabura
    Oct 11, 2012 at 8:28
  • But this way I had to use a block--views--3d8f7966168beeec655c8ead69336789.tpl.php file, and in this case, I'm at the same point as if I used an if($variables['block']->delta == '3d8f7966168beeec655c8ead69336789') condition in hook_preprocess_block(). This is what I wanted to avoid, because I thought I can use a more human-readable name in my hook. For example, what if I want to move the view into another with the same parameters, I delete the previous one, but use the same machine name and CSS classes, but the generated unique hash changes? In this case, I lose my modifications.
    – Sk8erPeter
    Oct 11, 2012 at 8:38
2

That's a old question, but there is no proper answer. I came across the same problem. The solutions I could think of was CSS parent selector (which doesn't exists yet) OR some Drupal manipulation.

I added a hook_preprocess_block to add a wrapper CSS class to all view blocks that define a CSS class. That's not trivial so I will put my code here. It may not work with all view blocks, if you have an issue with this code, feel free to update it and post your own version.

Example: View with CSS class "test" will be contained in a block with the CSS class "test-wrapper".

function <MY_THEME>_preprocess_block(&$variables) {
    $default_display_id = 'default';
    // Trying to access the field:
    //     $display_id =      $variables['elements']['#views_contextual_links_info']['views_ui']['view_display_id']
    //     $default_display = $variables['elements']['#views_contextual_links_info']['views_ui']['view']->display['default']->display_options['css_class']
    //     $display =         $variables['elements']['#views_contextual_links_info']['views_ui']['view']->display[$display_id]->display_options['css_class']
    if (isset($variables['elements']['#views_contextual_links_info']['views_ui'])) {
        $view_ui = $variables['elements']['#views_contextual_links_info']['views_ui'];
        if (isset($view_ui['view_display_id'])) {
            $display_id = $view_ui['view_display_id'];
            if (isset($view_ui['view']) && property_exists($view_ui['view'], 'display') && isset($view_ui['view']->display[$display_id])) {

                $default_css_class = NULL;
                if (isset($view_ui['view']->display[$default_display_id])) {
                    $default_display = $view_ui['view']->display[$default_display_id];
                    if (property_exists($default_display, 'display_options') && isset($default_display->display_options['css_class'])) {
                        $default_css_class = $default_display->display_options['css_class'];
                    }
                }

                $view_css_class = NULL;
                $display = $view_ui['view']->display[$display_id];
                if (property_exists($display, 'display_options') && isset($display->display_options['css_class'])) {
                    $view_css_class = $display->display_options['css_class'];
                }

                $css_class = $view_css_class ? $view_css_class : $default_css_class;
                if ($css_class) {
                    $variables['classes_array'][] = "$css_class-wrapper";
                }
            }
        }
    }
}
1

There is a module for this purpose.

View block top class

Screenshot from module page

1

For me hook_preprocess_block() didn't work. (Maybe because I had to add the block directly from a template file via views_embed_view().)

However, hook_preprocess_views_view() with a simple check for $vars['view']->current_display did work:

function MYMODULE_preprocess_views_view(&$vars) {
  // 'MYBLOCK' usually comes as 'block' if this view only has one
  if ($vars['view']->name == 'MYVIEW' && $vars['view']->current_display == 'MYBLOCK') {
    // here I add a class that contains the current theme's name
    global $theme;
    $theme_name = array_pop(explode('/', (drupal_get_path('theme', $theme))));
    $vars['classes_array'][] = $theme_name.'-theme';
    // but you can simply do the following as well
    $vars['classes_array'][] = 'MYSTRING';
  }
}
0

The easiest way for me was to duplicate the file block.tpl.php, rename it to block--myregion.tpl.php and then add my classes inside it.

See: Theming blocks page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.