Pass a variable from a node to a block module that uses a custom template I have a custom module "jsblock." When the page renders, the module should get the title of the page, pass it to drupal_add_js() and ultimately render an output in a block.

I tested the module with the template name suggested by the system. The output rendered in the block as expected. Now, I'm trying to add a custom template to the module but the variable appears to no longer be passed to the block.

Directory structure



I have been playing around with hook_block_view() and a helper function to handle the drupal_add_js() function, but I think I am not attaching it to the block correctly.

jsblock.module file

// Helper

function get_the_page_title() {
  if ($node = menu_get_object('node')) {
    $title = drupal_get_title();
    drupal_add_js(array('jsblock' =&gt; array('test' =&gt; $title)), 'setting');
  }
}

// Theme
function jsblock_theme($existing, $type, $theme, $path){
  return array(
      'jsblock_custom_theme' =&gt; array(
          'variables' =&gt; array('content' =&gt; NULL),
          'template' =&gt; 'jsblock_custom_theme',
          'path' =&gt; drupal_get_path('module', 'jsblock') .'/theme/',
      )
  );
}

// Print
function jsblock_block_view($delta = 'jsblock') {
  if($delta == 'jsblock')
    {
      $block = array();
      $block['content'] = get_the_page_title();
      $block['content']['#attached']['css'][] = drupal_get_path("module", "jsblock")."/css/styles.css";
      $block['content'] = theme('jsblock_custom_theme');
      return $block;
  }
}


I checked the console for Drupal.settings.jsblock.test and it is returning the expected value. I can see the block is printing based on an expected outline, but the data is not rendered.

How can I pass the JS variable from the page to the block that uses a custom template?
When using a custom theme wrapper for your block output, you actually theme the content parts, before the block will be rendered using the actual block theme wrappers.

If you like to pass in variables to your custom template, you need to provide them via the second parameter of the theme() function:

/**
 * Implements hook_theme().
 */
function jsblock_theme($existing, $type, $theme, $path){
  return array(
    'jsblock_custom_theme' =&gt; array(
      'variables' =&gt; array('my_title' =&gt; NULL),
      'template' =&gt; 'jsblock_custom_theme',
      'path' =&gt; drupal_get_path('module', 'jsblock') .'/theme/',
    )
  );
}

/**
 * Implements hook_block_view().
 */
function jsblock_block_view($delta) {
  $block = array();

  if($delta == 'jsblock') {
    $variables = array();
    $variables['my_title'] = get_the_page_title();
    $block['content']['#markup'] = theme('jsblock_custom_theme', $variables);
    $block['content']['#attached']['css'][] = drupal_get_path('module', 'jsblock') . '/css/styles.css';
  }

  return $block;
}


Note the difference between the $variables and the $block array.

To also cover your second question (which surely should go into a separate question on Drupal Answers):

Keep in mind, that blocks are cached by default for performance reasons, until you clear the caches. So with your current implementation the block view will be generated only once and hence the JavaScript only attached to the first page you render after a cache clear.

Therefore you should attach your JS to the block output as you did with your CSS (attach it to the content part of the block output) and make sure to have a distinct cached version of the block for every page by using appropriate cache tags in your hook_block_info():

/**
 * Implements hook_block_info().
 */
function jsblock_block_info() {
  $blocks = array();

  $blocks['jsblock'] = array(
    'info' =&gt; t('My JS block'),
    // Use DRUPAL_NO_CACHE for no caching, or
    // DRUPAL_CACHE_PER_PAGE if you are fine with
    // cached versions per page.
    'cache' =&gt; DRUPAL_NO_CACHE,
  );

  return $blocks;
}