Drupal Custom Module HTML

717 Views Asked by At

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!

2

There are 2 best solutions below

0
Anurag On BEST ANSWER

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!

0
Tinny On

It's outputting as a list because you are passing $block['content'] the item_list theme function.

What you could do instead is create your own custom theme template using hook_theme. This will let you use custom markup in a custom template file.

After, replace this:

// Pass data through theme function.
$block['content'] = theme('item_list', array('items' => $items));

With this:

// Pass data through theme function.
$block['content'] = theme('my_custom_theme', array('items' => $items));