2

I have a Drupal module where I want to separate the html from the logic by placing it in a template file. You'd think this would be easy but I can't figure out how it's supposed to work within Drupal. When I google it I come upon massive guides on making Drupal themes or articles on focusing on a single aspect of the templating process. I downloaded and installed the Examples for Developers module which has a section for templating, but even that does not do exactly what I want and breaks as soon as I make any significant change.

I made a simple module called blob to try to get this to work. I have the following template file called blob-stuff.tpl.php:

<div class="container-inline">
    Hi <?php  print $myname; ?>
</div>

In blob.module I have

function blob_menu() {
  $items['blob1'] = array(
    'title' => 'Blob1',
    'page callback'    => 'blob_stuff',
    'access arguments' => array('access content'),
  );
  return $items;
}

function blob_theme() {
  return array(    
    'blob_stuff'  => array(
      'template' => 'blob-stuff',
    ),
  );
}

function template_preprocess_blob_stuff(&$variables) {
  $variables['myname']='Bob';
}

function blob_stuff(){
  return 'Bob';
}

Which of course doesn't work, because at this point I'm just guessing.

Can anyone give me a simple, working example of this, following Drupal best practices?

2
  • 1
    What are you trying to do exactly? Reading between the lines I think you want to call a theme function from a page callback, but I can't work out what you're trying to do with the variable. Do you want to pass the variable into the theme function from the page callback? That's pretty standard fare, but it can also make sense to return a string from a page callback or inject a static/dynamic var into a template via a preprocess hook, so it's difficult to give you an accurate answer
    – Clive
    Commented Oct 3, 2016 at 22:43
  • It seems by the time I checked back there was already a full answer that did what I wanted, but thanks for your interest. Specifically the value of my variable originates in blob_stuff() since it gets it from the database. I just wanted that to end up in the template and display the result. Commented Oct 4, 2016 at 0:13

1 Answer 1

8

You're on the right track, the only thing you need to do is call your theme function in your page callback, blob_stuff(). There are two ways to do this, the preferable way is using a render array:

function blob_stuff(){
  $page = array
  (
    '#theme' => 'blob_stuff',
  );

  return $page;
}

You could also directly call your theme function, but this is not the preferable way to do it:

function blob_stuff(){
  return theme('blob_stuff');
}

But to go further with this, you've hard-coded the name Bob into your code. Usually you'll want something dynamic, pulled from the path in the URL. You can define a dynamic path with a wildcard in hook_menu()

function blob_menu() {
  $items['blob1/%'] = array(
    'title' => 'Blob1',
    'page callback' => 'blob_stuff',
    // Pass the 1st index of the path (the wildcard) to your page callback
    'page arguments' => array(1),
    'access arguments' => array('access content'),
  );
  return $items;
}

In hook_theme(), you'll add a variable:

function blob_theme() {
  return array(    
    'blob_stuff'  => array(
       'variables' => array(
         'name' => FALSE,
       ),
       'template' => 'blob-stuff',
     ),
  );
}

Now in your page callback, you can pass the wild card to your theme function, which will output it in your template:

// $name comes from the wildcard in the URL
function blob_stuff($name){
  $page = array
  (
    '#theme' => 'blob_stuff',
    '#name' => $name,
  );
  return $page;
}

Your template will now look like this:

<div class="container-inline">
  Hi <?php  print $name; ?>
</div>
2
  • 4
    Really good answer, covers everytyhing
    – Clive
    Commented Oct 3, 2016 at 22:48
  • Someone needs to put this in a tutorial somewhere, it would have saved me a lot of time and frustration. Commented Oct 4, 2016 at 0:14

Your Answer

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

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