Drupal In a Box - Creating really custom functionality within Drupal 7

drupal in a box

Drupal In a Box - Creating really custom functionality within Drupal 7

I often get tasks on Drupal client sites for completely custom functionality. Those are the most fun tasks for me. I have the amount of freedom and creativity to build up the required functionality and at the same time I can utilize Drupal's framework and infrastructure to keep things modular and reusable.

Some developers are great with HTML/CSS and Javascript yet they struggle with getting their functionality done on Drupal given that it has a bit complex architecture. This blog post might be very helpful for the beginner and intermediate Drupal Developers and Site Builders.

In this post, I'm going to walk you through the steps of building custom work on Drupal, and I'm going to provide you with a module skeleton for reference.

First of all, let me show you some examples of very custom components that I had to rebuild on Drupal:

As you can see, these are very customized components (Javascript mainly) that have not so much to do with Drupal itself. However, they can be wrapped nicely within Drupal's framework and module system. Of course, I'm not going to discuss the micro technicalities, but rather I want to show you how such component can be plugged into Drupal, and I'll leave the rest to your imagination. Think of your component as a canvas and Drupal is the frame of it.

I'm going to start a new Custom.module and walk through the major helpful hooks. I'm going to display the component within Drupal either as a standalone page or as a block that can be placed where ever.

Component function

/**
 * The main function where the component is being generated
 */

function custom_component() {

  // Simple arguments
  $arguments = array('argument1' => 'Hello', 'argument2' => 'World!');

  // Adding required CSS styling and Javascript functionality
  drupal_add_css(drupal_get_path('module', 'custom') . '/custom.css');
  drupal_add_js(drupal_get_path('module', 'custom') . '/custom.js');

  // Passing arguments to a theme function
  $output = theme('custom_component', array('arguments' => $arguments));

  // Return clean HTML output
  return $output;
}

 

Theme Function

/**
 * Implements hook_theme().
 */
function custom_theme($existing, $type, $theme, $path) {

  // Simple theme definition that points to the file
  // custom-component.tpl.php where you can place your HTML

  return array(
    'custom_component' =>  array(
      'path' => drupal_get_path('module', 'custom') . '/templates',
      'template' => 'custom-component',
      'variables' => array('argument1' => '', 'argument2' => ''),
    ),
  );
}

 

Template File

<?php

/***
 * This is a template file
 * This is where most of your creative custom work goes
 * You can write HTML code as well as Javascript / CSS and PHP, obviously!
 * For simplicity I'm just receiving arguments and printing them here.
 * But this can be the HTML of any sophisticated component. 
 */

?>
<div class="custom-component">
  <p>I'm just going to display the arguments passed to form a Hello World! sentence.</p>

  <h1><?php print $argument1 ?></h1>
  <h2><?php print $argument2 ?></h2>
</div>

 

Define A Drupal Page (Path)

/**
 * Implementation of hook_menu()
 */

function custom_menu() {
  $items = array();

  // This item will point to the path /custom_component
  // and is going to use custom_component_page function as a callback

  $items['custom_component'] = array(
    'title' => t('Custom Component'),
    'page callback' => 'custom_component_page',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK
  );

  return $items;
}

 

Define the PAGE Callback

/**
 * Custom Component Page Callback, returns the output of 
 * the custom_component function within an extra HTML wrapper  
 */

function custom_component_page() {
  
  $output = "<div class=\"component-page-wrapper\">";

  $output .= custom_component();

  $output .= "</div> <!-- // end of page wrapper -->";
  
  return $output;
}

 

So far this is a fully functional module. Once enabled, users can visit the /custom_component page and be able to view its content. And since we have the component built why not add another Block display that would be more portable.

 

Add a block Display

/**
 * Implements hook_block_info().
 */

function custom_block_info() {
  $blocks['custom_component'] = array(
    'info' => t('Custom Component'),
    'cache' => DRUPAL_CACHE_PER_PAGE,
  );
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function custom_block_view($delta = '') {
  switch ($delta) {
    case 'custom_component':
      $block['subject'] = t('Custom Component');
      $block['content'] = custom_component();
      break;
  }
  return $block;
}

 

Dealing With Settings and Configs

For real life components when things get a bit more complex,  it's essential to deal with dynamic arguments, parameters, and configurations. Let's say you want to pass dynamic arguments to theme files, or pass settings to Javascript Drupal Behaviors. You can easily accomplish this using Drupal helper functions. Below is an example for that

/**
 * Implements hook_init().
 */

function custom_init() {
  
  // Save variables in Drupal
  variable_set('config_name' , 'config_value');
  
  // Get variables from Drupal
  $config = variable_get('config_name', 'default value');
  
  // Make settings visible to Javascript Drupal Behaviors
  // Used within Drupal Behaviors like this:
  // Drupal.settings.customComponent.myJsConfig
  
  drupal_add_js(
    array(
      'customComponent' => array(
        'myJsConfig' => $config,
      )
    ), 'setting');
}

 

Javascript Behavior (CUSTOM.JS)

(function($) {

    /**
     * Drupal Behaviors.
     */

    Drupal.behaviors.customComponent = {
        attach: function (context, settings) {
            var config = Drupal.settings.customComponent.myJsConfig;

            // Do whatever with the config/param/setting value
            console.log('Drupal custom module config value: ' + config);
        }
    };

})(jQuery);


Have any questions on any of this? Write them in the comments section below and we'll answer them as soon as possible.

Related Posts

Creating Custom Fields In Drupal Using Display Suite

Kyle Taylor
Read more

Creating Custom Google Analytics Events In Drupal

Tom McCracken
Read more

OE Pro: Creating Custom Content Layouts With Drupal 7

Brent Bice
Read more

Creating content types in Drupal 7

Tom McCracken
Read more

Creating Dynamic Custom Pages with Views, Panels & Arguments

Chris Sloan
Read more

Link Taxonomy Terms to Custom Views in Drupal

Dustin Currie
Read more