1

We had a outside company help us with our Drupal version of our site. They created the code below.

Since then we have hired another company that seems to be more professional about there code and standards.

The code below is the entire code of the module. The new company suggested that we "Implement hook_theme and create a template for alerts, move markup from hook_preprocess_page to the template."

I understand a bit about Drupal modules, but I'm unsure how to accomplish what they are suggesting.

Can someone help me in this regard?

<?php

function foo_alerts_preprocess_page(&$vars) {
  $vars['alerts'] = '';

  if ($nid = foo_alerts_check_alerts()) {
    $node = node_load($nid);

    if (isset($_COOKIE['alert'.$node->nid]) && $_COOKIE['alert'.$node->nid] == 'closed') {
      return;
    }

    $html = '<div id="alert-bar" rel="'.$node->nid.'"><div class="inner">';
    $html .= '<h2>News Alerts:</h2>';
    if (isset($node->field_link['und'][0]['url'])) {
      $html .= l($node->title, $node->field_link['und'][0]['url'], array('attributes' => array('title' => $node->field_link['und'][0]['title'], 'class' => array('alert-link'))));
    } else {
      $html .= '<span class="alert-link">' . $node->title . '</span>';
    }
    $html .= '<a href="#" id="close-alert-bar"></a>';

    $html .= '</div></div>';
    $vars['alerts'] = $html;
  }
}

function foo_alerts_check_alerts() {
  return db_query("SELECT nid FROM {node} 
    LEFT JOIN {field_data_field_dates} ON entity_id=nid
    WHERE type='alert' AND field_dates_value < NOW()
    AND field_dates_value2 > NOW() AND status = 1 LIMIT 1")->fetchField();
}
2
  • What's exactly the problem you are trying to solve? If it is just a refactor to improve code maintainability and best practices, you could start by checking the documentation on the theme function or generally on some theming concepts.
    – marcoscano
    Oct 28 '15 at 14:21
  • I’m curious if the preprocess is even needed, or can the call to foo_alerts_check_alerts() be written into the hook_theme() to determine whether it returns the template or not. Every example I see of hook_theme() does not include any conditionals within. If that is the case, then how do I access the data from foo_alerts_check_alerts() and place them into an array that hook_theme can use with a template?
    – Cy Jobes
    Oct 28 '15 at 14:26
0

So, hook_theme is where you define your theme implementations and templates to use for them. In your case, that would look something like:

foo_alerts_theme() {
  $module_path = drupal_get_path('module', 'foo_alerts');
  return array(
    'alerts_theme_name' => array(
      'path' => $module_path . '/templates',
      'template' => 'alerts-theme-template-name',
      'variables' => array(
        'node' => NULL,
      );
    ),
  );
}

Your template file, named alerts-theme-template-name.tpl.php goes in the templates folder in your foo_alerts module folder. In your page preprocess you're going to pass in the node loaded from the alerts function to the theme function, so that would look like this:

function foo_alerts_preprocess_page(&$vars) {
  $vars['alerts'] = '';

  if ($nid = foo_alerts_check_alerts()) {
    $node = node_load($nid);

    if (isset($_COOKIE['alert'.$node->nid]) && $_COOKIE['alert'.$node->nid] == 'closed') {
      return;
    }

    $vars['alerts'] = theme('alerts_theme_name', array('node' => $node));
  }
}

That leaves all of the non-template logic still in the preprocess function, and returns the output of theme(), which will be the html from your template. Your template would then be something like this:

<div id="alert-bar" rel="<?php print $node->nid; ?>">
  <div class="inner">
    <h2>News Alerts:</h2>
    <?php if (isset($node->field_link['und'][0]['url'])) : ?>
      <?php print l($node->title, $node->field_link['und'][0]['url'], array(
        'attributes' => array(
          'title' -> $node->field_link['und'][0]['title'],
          'class' => array('alert-link'),
        ),
      )); ?>
    <?php else : ?>
      <span class="alert-link"><?php print $node->title; ?></span>
    <?php endif; ?>
    <a href="#" id="close-alert-bar"></a>
  </div>
</div>

Does that all make sense? Do you see how the code the old dev team left you with got turned into this? If you have any questions, let me know and I'll try to explain better what I did.

3
  • Is hook_theme() being called before the preprocess?
    – Cy Jobes
    Oct 28 '15 at 15:35
  • Yup! All the preprocess functions get called in _theme_process_registry, from what I can tell, which gets called after the hook invocation in _theme_build_registry when the theme is initialized. Oct 28 '15 at 15:41
  • Thanks so much for this. I see it and understand it. Now I just gotta remember it. Will need to study more to get it to sink in, but it is very helpful, and I appreciate your tutelage and work into it.
    – Cy Jobes
    Oct 28 '15 at 18:02

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.