If I load my page where my block is displayed as user 2 (any user besides user 1) my block displays correctly. If I reload the page my block doesn't display correctly and my js and css that was added via template_preprocess() doesn't show up.

I verified that if I turn off Block caching the problem goes away so it tells me that I shouldn't be adding js and css in the template_preprocess functions and add it via '#attach' but I have a function (video_widget_add_js) that I am adding javascript because I am adding it in multiple places and want to reuse the code. Anyone have a good suggestion on this?


   * Implements hook_block_view().
  function leadership_block_view($delta = '') {
    $block = array();

    switch($delta) {
      case 'leadership_all_companies':
        $node = menu_get_object();

        $data_card_content = leadership_get_data_card_content($node);

        if (!$data_card_content) {
          $block = array(
            'subject' => '<img class="ld-block-logo" src="' . variable_get('leadership_block_logo') . '" alt="Leadership Logo" />',
            'content' => theme('leadership_allcompanies', array(
                'taxonomies' => leadership_get_taxonomies(FALSE),
                'delta' => $delta,



   * Implements hook_theme().
  function leadership_theme() {
    return array(
      'leadership_allcompanies' =>  array(
        'variables' => array('taxonomies' => NULL, 'delta' => NULL, 'has_data_card' => NULL),
        'template' => 'leadership-allcompanies',

   * Preprocess for the all companies block.
   * @param array $vars
   *   An associative array containing:
   *   - taxonomies array
   *     An array that contains taxonomy objects @see taxonomy_get_tree().
   *   - delta string
   *     The block string key.
   *   - has_data_card
   *     This will only be used in the all_companies_and_data_card block. If set
   *     to FALSE then only all data that would appear in the all companies block
   *     will appear. If set to TRUE both will appear.
  function template_preprocess_leadership_allcompanies(&$vars) {
    // Add js and css files.

    $js_extension = (variable_get('smg_global_is_production', false)) ? '.min.js' : '.js';

    $path = drupal_get_path('module', 'leadership');
    $video_widget_path = drupal_get_path('module', 'video_widget');
    drupal_add_css($path . '/css/all_companies_block.css');
    drupal_add_css($path . '/css/datacard.css');
    drupal_add_css($path . '/css/datacard_' . variable_get('smg_global_site') . '.css');
    drupal_add_css($video_widget_path . '/video_widget_includes/css/video_widget.css');
    drupal_add_js($video_widget_path . "/video_widget_includes/angular/app{$js_extension}");
    drupal_add_js($path . "/angular/js/all_companies_block{$js_extension}", array('every_page' => TRUE, 'preprocess' => TRUE));
    drupal_add_js($path . "/angular/js/datacard{$js_extension}");

    $vars['site_id'] = variable_get('smg_global_site');

    $taxonomies = $vars['taxonomies'];
    if ($taxonomies) {
      if (variable_get('smg_global_site') == 'pw') {
        // Add the parent tids,titles (Ex: Machinery, Materials, Service)
        foreach ($taxonomies as $taxonomy) {
          $categories[$taxonomy->parents[0]]['tids'][] = $taxonomy;
        foreach ($categories as $tid => $category) {
          $categories[$tid]['tid'] = $tid;
          $categories[$tid]['title'] = taxonomy_term_load($tid)->name;
        $vars['taxonomies'] = $categories;

      // Add taxonomy list to Drupal object to be used by Angular.
      drupal_add_js(array('leadership_all_companies_block' => $taxonomies), 'setting');

      // Call the video widget registering function

Generally, yes, you should use ['#attached'] in renderable arrays to add assets in a cache-compatible way. $block['content'] can be a renderable array if you make it an array instead of a string, so you're not too far off here. I'm not sure exactly what you're doing inside video_widget_add_js(), but if it's just adding a bunch of assets, then consider implementing hook_library() instead. Library implementations are attachable in ['#attached'].

In your case, however, the attached assets aren't your only problem. With block caching enabled, a cache hit bypasses hook_block_view() completely, instead retrieving the previously compiled $block array from cache. Since you use $node = menu_get_object() in hook_block_view(), you probably need the block to vary by page. However, the default block cache setting is DRUPAL_CACHE_PER_ROLE, which only varies by a user's role combinations.

You could set your block to cache with DRUPAL_CACHE_PER_PAGE instead, but the easiest thing to do without refactoring a bunch of your code is to set your block to DRUPAL_NO_CACHE. DRUPAL_CACHE_PER_PAGE isn't hugely efficient anyway unless you have a lot of authenticated user traffic.

To set a particular cache setting on a block, edit the hook_block_info() implementation:

/** * Implements hook_block_info(). */ function leadership_block_info() { return array( 'leadership_all_companies' => array( 'info' => t('Leadership block'), 'cache' => DRUPAL_NO_CACHE, ); ); }

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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