1

here is a good one that has always stumped me.

I would love to see a solution in both D6 and D7.

I create custom modules and usually work with the menu api to create menu type -> MENU_CALLBACK.

Here is an example:

function example_menu() {
  $items['example/page1'] = array(
    'page callback'     => 'example_page1_callback',
    'access callback'   => TRUE,
    'type'              => MENU_CALLBACK,
  );
  return $items;
}

I would like to see the exact code solution to provide three different variables to be printed in a custom theme template based on the following code. To add to that challenge, I would like the code to be written in the menu callback function only. I know there are many possible ways to do it but could never figure out how to do it in a menu callback function which would be the most useful way.

//****************************************
// This code block goes in a custom module called example_menu_variables.module

// hook_menu example
function example_menu() {
  $items['example/page1'] = array(
    'page callback'     => 'example_page1_callback',
    'access callback'   => TRUE,
    'type'              => MENU_CALLBACK,
  );
  return $items;
}

// hook_meny callback function
function example_page1_callback() {
  // please provide code within this function to turn these next three
  // variables into separate output variables for the template.
  $variable_to_print1 = 'Foo';
  $variable_to_print2 = 'Bar';
  $variable_to_print3 = array('bing', 'bang', 'bong');
  return;
}
//****************************************



//****************************************
// This block of code represents the part of the custom theme template related to the menu location from the hook_menu call
// D6 template name would be page-example-page1.tpl.php
// D7 template name would be page--example--page1.tpl.php

<div><?php print  $variable_to_print1?></div>
<div><?php print  $variable_to_print2?></div>
<div><?php print  $variable_to_print3[0] . ' ' . $variable_to_print3[1] . ' ' . $variable_to_print3[2]?></div>

/*
output should look like:
Foo
Bar
bing bang bong
*/

//****************************************

Hope this is the kind of problem that someone wouldn't mind solving. Thanks for your time. :)

Ray James

  • If I understand you correctly, that is the purpose of hook_theme(). Why does the code need to be contained within the menu callback function? – Adam Balsam May 3 '13 at 17:07
  • Hi Adam and thanks for the response. I guess it would be great to see what the code would look like both ways. Using hook_theme() requires a ton of setup just to get one custom variable into the theme layer. I would like a simple solution that can be done in the same place that you would be gathering your data from the database to display as output. It would be really great to have a function that just sends that variable like this -> drupal_add_template_variable($var, $varname); or something like that. I am not sure if such a thing exists in Drupal. Thanks. – rayjamesfun May 3 '13 at 19:04
1

I got this working in Drupal 7, simply by setting the variable in the render array returned from the page callback.

In .module file

function example_page1_callback() {
$render_array['variable_to_print1'] = 'Foo';
$render_array['variable_to_print2'] = 'Bar';

// set other render array items for the page

return $render_array;
}

In page.tpl.php file

<div class="someDiv">
  1st variable = <?php print render($page['content']['system_main']['variable_to_print1']); ?><br />
  2nd variable = <?php print render($page['content']['system_main']['variable_to_print2']); ?><br />
</div>
  • My god man you did it! You figured it out! You totally rock. I have one edit though. It's system_main not system-main for Drupal 7 at least. Thank you so much. – rayjamesfun Jan 23 '14 at 20:29
6

I don't believe you can do this without using hook_theme, but this is exactly what it's for and it's quite simple. (This code is for Drupal 6.)

/**
 * Implements hook_menu().
 */
function example_menu() {
  $items['example/page1'] = array(
    'page callback'     => 'example_page1_callback',
    'access callback'   => TRUE,
    'type'              => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Page callback function
 */
function example_page1_callback() {
  $variable_to_print1 = 'Foo';
  $variable_to_print2 = 'Bar';
  return theme('example_contents', $variable_to_print1, $variable_to_print2);
}

/**
 * Implements hook_theme().
 */
function example_theme() {
  return array(
    'example_contents' => array(
      'arguments' => array('variable_to_print1' => null, 'variable_to_print2' => null),
      'template' => 'example-contents',
    ),
  );
}

$variable_to_print1 and $variable_to_print2 are now available in example-contents.tpl.php.

  • Hi Adam, thanks for the code. I put it together and ran it but got a ton of errors stating that all the other standard variables are undeclared -> Notice: Undefined variable: logo in include() (line 92 of C:\xampp\htdocs\d7themeaddvar\site\themes\bartik\templates\example-contents.tpl.php) I put the files in a git repository for easy download -> github.com/rayjames/d7themeaddvar – rayjamesfun May 3 '13 at 20:39
  • content-example.tpl.php does not replace page.tpl.php. Only the defined variables will be available in it (in this case $variable_to_print1 and $variable_to_print1). If you want to make a new variable available to page.tpl you should look into hook_preprocess(). – Adam Balsam May 3 '13 at 20:47
  • Hmm, we seem to be going in a different direction here. I'm not sure what your code does anymore. As per the initial problem, I asked for code to make variables for print in a custom template, but I guess I need to be more specific because I assumed everyone would understand that the hook_menu item would point to a "page" on the site and that there would be a custom template for said "page" that the variables would be available for. I can't figure out how to get your code to print the variables. Thanks. – rayjamesfun May 3 '13 at 21:03
  • 1
    @rayjamesfun With the best will in the world, you're heading in entirely the wrong direction at the moment. Drupal has a templating system, if you want to take advantage of that you need to follow its rules, which Adam has outlined perfectly. If you don't, then you'll need to resort to plain ol' PHP which we can't get into here; we offer Drupal solutions here, not solutions to get around Drupal :) – Clive May 3 '13 at 21:53
  • Hi Clive. I hear ya, and I totally agree. I'm in now way trying to go around Drupal, just looking for an easier solution that I already thought was there. I can't get Adam's code to work. I am no newb to Drupal. I have built some extremely complex sites but still can't seem to figure out how to wield the theme system like a ninja. Just looking for a complete example solution at this point in the way of the Drupal. Thanks. – rayjamesfun May 3 '13 at 22:02
2

The code written by Adam is correct (my +1) Your variables are available in example-contents.tpl.php file - it is a template file of your module output.

However, if you need these variables in page.tpl file, then you can just create them:

in your module file:

/**
 * Page variables
 *
 * @return
 *  custom page variables
 */ 
function custom_variables(){

  $variable_to_print1 = 'Foo';
  $variable_to_print2 = 'Bar';
  $variable_to_print3 = array('bing', 'bang', 'bong');

  return array( 'variable_to_print1'    => $variable_to_print1,
                'variable_to_print2'    => $variable_to_print2,
                'variable_to_print3'    => $variable_to_print3
  );
}

in your template.php file:

/**
 * Override or insert variables into the page templates.
 *
 * @param $variables
 *   An array of variables to pass to the theme template.
 * @param $hook
 *   The name of the template being rendered ("page" in this case.)
 */
function YOURTHEME_preprocess_page(&$variables, $hook) {

  // pass your module variables to page--example1.tpl.php file
  if (in_array('page__example1', $variables['theme_hook_suggestions'])){
    if (module_exists('your_module')){
        $your_module_variables = custom_variables();
        $variables['variable_to_print1'] = $your_module_variables['variable_to_print1'];
        $variables['variable_to_print2'] = $your_module_variables['variable_to_print2'];
        $variables['variable_to_print3'] = $your_module_variables['variable_to_print3'];
    }
  }
}
  • Hi Jack, is this a D6 or D7 solution? I was wondering if you could link to the tutorial or Drupal page that might explain what is going on in your code better too. I am assuming that you do not know of a solution that can be implemented within the menu callback, correct? I am also assuming that you would/could write a different function for each "page" so as to keep the variables organized. This doesn't look like it would work with a page that has dynamic page arguments either. Thanks. – rayjamesfun May 4 '13 at 2:08
  • 1
    All above mentioned examples works perfect. My answer concerning a D7 solution. It doesn't matter if your page has dynamic arguments or not. Your variables will be available on every "example1" page ("example1" it's a content type) If you need them on every content type page, then just remove the first IF statement in preprocess_page from my example. You can create your variables anywhere (in your module for example) but then, they have to pass through YOURTHEME_preprocess_page function, because it's the place where your variables are defined as a page variables. – Jack-PL May 4 '13 at 12:59
1

Had same problem, this is what worked for me on Drupal 7.x

function example_menu() {
  $items['example/page1'] = array(
  'page callback'     => 'example_page1_callback',
  'access callback'   => TRUE,
  'type'              => MENU_CALLBACK,
  );
return $items;
}


function example_page1_callback() {
  $variable_to_print1 = 'Foo';
  $variable_to_print2 = 'Bar';
  $variable_to_print3 = array('bing', 'bang', 'bong');

  //use below given statement when you only want to pass one variable
  // to your template
  //return theme('example',array('output'=>$variable_to_print1));

  //use this statement when you want to pass array
  return theme('example',array('output' => $variable_to_print3)); 
}

In addition to all this you need a example_theme() hook

function example_theme(){
    //lets say your template file is called example.tpl.php and it resides
    //within your module directory.
    $custom_example_template = array();

    $custom_example_template['example'] = array(
        'template' => 'example',
        'variables' => array('output' => NULL)
    );
}

Now what about your example.tpl.php

<div id='someotherid'>
    <?php
             //use this code when you have passed only one variable
             print $variables['output'];
    ?>
</div>

You can name your variables whatever you want, you don't need to stick with 'output' as I did. For some reason you can't see my foreach loop to loop through the array we have passed.

  • I don't believe this will pass the variables to page.tpl.php, i.e. header, footer; only to the content. – timofey.com Mar 10 '15 at 21:41
0

I got Jack's method to work, although I must say the render_array idea is simpler. Here's what worked for me:

In Module:

//page callback to create the page and include some CSS & Javascript
function my_callback() {
   drupal_add_css(...); 
   drupal_add_js(...); 
   return '';   
}

function _my_module_vars(){
   $var1 = 'foo'
   $var2 = 'bar'
}

In theme's Template.php

function MYTHEME_preprocess_page(&$vars) {
   //add some custom variables to the module page
    if(in_array('page__my_content_type', $vars['theme_hook_suggestions'])) { 
       if(module_exists('my_module')) { 
          $my_vars = _my_module_vars();  
          $vars['var1'] = $my_vars['var1'];
          $vars['var2'] = $my_vars['var2'];
    }
  }
}

In page.tpl.php (or you could use page--my_content_type.tpl.php):

print $var1; 
print $var2; 
  • Just to clarify, the reason I also wanted to do this way (as opposed to hook_theme in the module method) is that here, the variables are available in the page.tpl.php file. In the hook_theme way, the module template file is rendered into the page's content variable (if I remember correct), which makes it tough to do much with it. – wheelercreek Nov 14 '13 at 17:43

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.