drupal-7drupal-modulesdrupal-blocksdrupal-templates

Drupal Custom Module HTML


So I've only just begun to learn Drupal so If you believe I'm going about this the wrong way, please let me know.

I have a content type called Events. I'm basically just trying to output a snippet of the latest event on the home page. To do this, I've created a custom module following the Drupal tutorial Drupal doc's custom module tutorial

Here's my module's code

 <?php

/**
 * Implements hook_block_info().
 */
function latest_event_block_info() {
  $blocks['latest_event'] = array(
    // The name that will appear in the block list.
    'info' => t('Latest Event'),
    // Default setting.
    'cache' => DRUPAL_CACHE_PER_ROLE,
  );
  return $blocks;
}

/**
 * Custom content function. 
 * 
 * Set beginning and end dates, retrieve posts from database
 * saved in that time period.
 * 
 * @return 
 *   A result set of the targeted posts.
 */
function latest_event_contents(){
  //Get today's date.
  $today = getdate();
  //Calculate the date a week ago.
  $start_time = mktime(0, 0, 0,$today['mon'],($today['mday'] - 7), $today['year']);
  //Get all posts from one week ago to the present.
  $end_time = time();

  //Use Database API to retrieve current posts.
  $query = new EntityFieldQuery;
  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'event')
    ->propertyCondition('status', 1) // published == true
    ->propertyCondition('created', array($start_time, $end_time), 'BETWEEN')
    ->propertyOrderBy('created', 'DESC') //Most recent first.
    ->range(0, 1); //ony grab one item

    return $query->execute();
}

/**
 * Implements hook_block_view().
 * 
 * Prepares the contents of the block.
 */
function latest_event_block_view($delta = '') {
  switch ($delta) {
    case 'latest_event':
      $block['subject'] = t('Latest Event');
      if (user_access('access content')) {
        // Use our custom function to retrieve data.
        $result = latest_event_contents();

        $nodes = array();

        if (!empty($result['node'])) {
          $nodes = node_load_multiple(array_keys($result['node']));
        }

        // Iterate over the resultset and generate html.
        foreach ($nodes as $node) {
          //var_dump($node->field_date);
          $items[] = array(
            'data' => '<p>
                          <span class="text-color">Next Event</span> ' . 
                          $node->field_date['und'][0]['value'] . ' ' .
                      '</p>' .
                      '<p>' .
                          $node->title . ' ' .
                          $node->field_location['und'][0]['value'] . ' ' . 
                      '</p>'
          ); 
        }
       // No content in the last week.
        if (empty($nodes)) {
          $block['content'] = t('No events available.');  
        } 
        else {
          // Pass data through theme function.
          $block['content'] = theme('item_list', array(
            'items' => $items));
        }
      }
    return $block;
  }

}

I've added the block to a region, and it renders fine in my template page. However, the events are outputted in a list which is not what I want.

Here's how the block is being rendered in HTML

<div class="item-list">
    <ul>
        <li class="first last">
            <p>
                <span class="text-color">Next Event</span> June 23 2016 18:30 - 21:00 </p><p>Cancer Research UK Angel Building, 407 St John Street, London EC1V 4AD 
            </p>
        </li>
    </ul>
</div>

So assuming I'm going about this whole thing correctly, how can I modify this blocks html? Thanks!


Solution

  • I think first you need to understand the theme('item_list', ....). This always output a HTML list either UL or OL as given.

    If you want to show your content without the HTML list wrapper, you could try this:

    /**
     * Implements hook_block_view().
     * 
     * Prepares the contents of the block.
     */
    function latest_event_block_view($delta = '') {
      switch ($delta) {
        case 'latest_event':
          $block['subject'] = t('Latest Event');
          if (user_access('access content')) {
            // Use our custom function to retrieve data.
            $result = latest_event_contents();
    
            $nodes = array();
    
            if (!empty($result['node'])) {
              $nodes = node_load_multiple(array_keys($result['node']));
            }
    
            // Iterate over the resultset and generate html.
            $output = '';
            foreach ($nodes as $node) {
              //var_dump($node->field_date);
              $output .= '<p>
                              <span class="text-color">Next Event</span> ' . 
                              $node->field_date['und'][0]['value'] . ' ' .
                          '</p>' .
                          '<p>' .
                              $node->title . ' ' .
                              $node->field_location['und'][0]['value'] . ' ' . 
                          '</p>';
            }
           // No content in the last week.
            if (empty($output)) {
              $block['content'] = t('No events available.');  
            } 
            else {
              // Pass data through theme function.
              $block['content'] = $output;
            }
          }
        return $block;
      }
    
    }
    

    That is one way. Another way is to use your own custom them template and use the array to output through that. For eg.

    // Pass data to template through theme function.
    $block['content'] = theme('latest_event_block_template', $items);
    

    Then define a hook_theme function to get this to a template, like:

    function latest_event_theme() {
      return array(
        'latest_event_block_template' => array(
          'arguments' => array('items' => NULL),
          'template' => 'latest-event-block-template',
        ),
      );
    }
    

    Now, you should have a template at the module's root directory with the name latest-event-block-template.tpl.php. On this template you will be able to get the $items array and adjust the HTML yourself. Don't forget to clear theme registry after creating the template.

    Hope it helps!