I create a page within my custom module with the following code:

function mymodule_menu(){
    $items['product-detail'] = array(
        'title' => t('Product detail'),
        'page callback' => '_mymodule_product_detail',
        'variables' => array('var1' => "Hello World Attempt #1"),
        'type' => MENU_CALLBACK,
        'access callback' => TRUE,

 function _mymodule_product_detail(){
      // global $var1 = "Hello Workd Attempt #3";

     return array('variables' => array("var1" => "Hello World Attempt #2") , '#markup' => '<p>This is some markup content displayed correctly in the page</p>');
 } // function

It renders the template, sets the title and display the markup (content of the page). However, I would like to fill some variables defined in the page.tpl.php and I don't know how to send these parameters, I tried with the variables key in the code but nothing is written. I want to display the message "Hello World Attempt #?" in the place in page.tpl.php where I have the code <?php if(isset($var1)) print $var1; ?>

I have been able to reach my goal with the following code, but using GLOBAL, which is not adequate:

function mymodule_preprocess_page(&$variables) {
   global $var1;
if(isset($var1) && $var1 != "") $variables["var1"] = $var1;


The global $var1 is set to $var1 = "HELLO WORLD Attempt #3" in the _mymodule_product_detail() function above (lines commented).

  • I think what you are looking for is a template, try looking that up.
    – Letharion
    Commented Oct 16, 2015 at 6:35
  • I wanted to create the page directly and pass the variables, not sure if you are indicating that it is not possible. What I usually do is: for a page displaying a listing of nodes --> I create a special content type. I create a node of that type. In template.php I detect the node->nid and make all the PHP, Drupal extraction of data (views_embed_view,etc). I fill the variables with data and send to page.tpl.php or other template. That works perfectly but another user has said to me that this is not Drupal intended behaviour, even if working with multiple domains and multiple languages perfectly
    – Cesar
    Commented Oct 16, 2015 at 7:04
  • Just to clarify further: I get a working example by adding the following code above: Update code, ´mymodule_preprocess_page´. But it uses global, I want to have the same working effect by using a return value somewhere.
    – Cesar
    Commented Oct 16, 2015 at 7:14
  • check this link drupal.stackexchange.com/questions/16384/… Commented Oct 16, 2015 at 7:37
  • While your proposal is not a variable set, which would be shared by different users ( and I need more like a global here, different for every page petition ), I think I am missing the point here. There must be some way of telling the callback function called from hook_menu that those calculated variables must be accessible to the page. It seems so a simple request, and I cannot manage to have it working. I need a return key, not a global mechanism.
    – Cesar
    Commented Oct 16, 2015 at 7:44

2 Answers 2


The link in my comment may not get you all the way there so I am adding a working example. Assuming everything else in your code is working changing this line

 return array('variables' => array("var1" => "Hello World Attempt #2") , '#markup' => '<p>This is some markup content displayed correctly in the page</p>');


$output = array("var1" => "Hello World Attempt #2" , '#markup' => '<p>This is some markup content displayed correctly in the page</p>');
return theme('page', $output);

Added the entire $output array to the hook_preprocess_page`.

NOTE: You may have to add a theme callback to your menu item. Example here.

  • Apart from the ")" after Attempt #2", which I have removed because it throws a syntax error, the code still gives a PHP error: Fatal error: Unsupported operand types in /home/public_html/includes/theme.inc on line 1091. I am using a different approach, though convoluted, works: drupal.stackexchange.com/questions/177737/…. Nobody has replied to my question, in 4 days.
    – Cesar
    Commented Oct 19, 2015 at 7:22
  • Sorry it appears I had two typos in the example. Hopefully it works now for you if you need it later. Glad to hear you found something that works for you.
    – sareed
    Commented Oct 19, 2015 at 13:22

most probably you should define your own hook_theme implementation. I will give you an example.

 * Implements hook_theme().
function mymodule_theme($existing, $type, $theme, $path) {
  return array(
    'mymodule_theme_name' => array(
      'variables' => array(),
      // Use next line only if you need template.
      // Add templates directory inside your module.
      // And add mymodule-theme-name.tpl.php file.
      'template' => 'templates/mymodule-theme-name'

 * Custom menu callback.
 * @see mymodule_menu()
function _mymodule_product_detail() {
  return theme('mymodule_theme_name', array(
      "var1" => "Hello World Attempt #2" ,
      'markup' => '<p>This is some markup content displayed correctly in the page</p>')

If you will use your own template you can access var1 as $var1 and markup as $markup.

To clean theme registry clear cache.

I hope it will help you.

  • Using your example, markup does not work, but var1 is working. However, I cannot use a template from my themes folder, because has variables called title, breadcumbs, menu, and will be giving these errors. My approach in is the only that works but still reflects a negligible understanding of Drupal... or Drupal is ill-conceived. see
    – Cesar
    Commented Oct 21, 2015 at 10:36
  • Hi, markup also should work, probably you should use render($markup) since it is html. When people don't understand something they often want to find source of knowledge lack in outside world. It is true about me too. Please don't think drupal is ill-conceived. Drupal is not perfect but it is logically structured.
    – Bogdan Tur
    Commented Oct 22, 2015 at 9:15

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