Advertising sustains the DA. Ads are hidden for members. Join today

Extending An Already Defined Bean

Last updated on
8 December 2018

Drupal 7 will no longer be supported after January 5, 2025. Learn more and find resources for Drupal 7 sites

This page is an introduction to extending already defined beans. Creation of new beans is well-documented at Neil Hasting's blog entry on that subject.

Extending Beans

Beans provides a lot of functionality built-in by default. So much, that it is possible to use Beans without extending any of its classes. However, it's possible and probable that you will need to alter an already deployed Bean, and this alteration requires you to create a new class that extends the BeanPlugin class.

To do so, you will need to identify the particular bean that you need to extend. Go to admin/structure/block_types and click on the "manage display" button for the block type you wish to modify. The block type's ID will be in the URL with the pattern admin/structure/block-types/manage/%/display, where % is the block ID. You'll need to convert any hyphens to an underscore. This does not tell you what module created the bean, so you will need to search the code for where the block ID appears in code.

NOTE: This is assuming you're modifying a module you've written only for your website or you plan on contributing this change back to the module's authors (or are the module author).

For the purposes of this entry, the bean we are modifying is called "company_highlight" in a module called "company_content".

  1. Create a file plugins/bean/company_highlight.inc.
  2. Open the module's .info file and add the file we just created to it. The entry for the file we just created would be: files[] = plugins/bean/company_highlight.inc. This makes sure that the classes we put in the .inc file will be appropriately auto-loaded by Drupal.
  3. Now let's set up the theme stuff. If your module has already defined its own default theme functions, they will most likely be at "theme/theme.inc". If not, find out where the module is storing its theme functions and open that file. Declare your theme function in this file. In our example, the function's signature would be theme_company_content_company_highlight(&$variables). For now, let's just put some dummy HTML into the function:
    function theme_company_content_company_highlight(&$variables) {
      $html = "<div>Hello, Drupaler</div>";
    
      return $html;
    }
    

    Save the file.

  4. Open your module's .module file (in this example's case, that would be "company_content.module". Look for the function that implements hook_theme (company_content_theme). We're adding a new entry to the return value of this function like so:
    /**
     * Implements hook_theme().
     */
    function company_content_theme() {
      $items = array();
       ...
      $items['company_content_company_highlight'] = array(
        'variables' => array(
          'bean' => NULL,
          ),
          'file' => 'theme.inc',
          'path' => drupal_get_path('module', 'company_content') . '/theme',
      ); 
      return $items;
    }
    

    The 'variables' element is what gets passed to the theme_company_content_company_highlight function that we defined in theme.inc. We do need to inform Drupal of what those actual values are, that will be done a little bit later.

    Now comes the fun part, defining the Bean!

  1. First, let's double-check and make sure that the hooks hook_ctools_plugin_directory() and hook_bean_types_api_info() are defined. Look for that in the source. This should be if the module has beans.
  2. Bean types are declared in the hook_bean_types() hook. For each bean type, you declare things like the label, handlers (the class we are going to write AND its parent) and the location of the files. Here's an example:
    /**
     * Implements hook_bean_types().
     */
    function company_content_bean_types() {
      $plugins = array();
      $plugin_path = drupal_get_path('module', 'company_content') . '/plugins/bean';
      $bean_plugin_path = drupal_get_path('module', 'bean') . '/plugins';
      ...
      $plugins['company_highlight'] = array(
        'label' => t('Company Highlight'),
        'handler' => array(
          'class' => 'company_highlight_bean',
          'parent' => 'bean',
        ),
        'path' => $plugin_path,
        'file' => 'company_highlight.inc',
      );
     
      return $plugins;
    }
    

    What we have essentially done here is to tell Beans to look for a bean plugin called 'company_highlight_bean' who's parent is 'bean' in plugins/bean directory of the company_content module.
    Now, let's take a look at the company_highlight.inc file:

    class company_highlight_bean extends BeanPlugin {
      public function view($bean, $content, $view_mode = 'full', $langcode = NULL) {
        $content['#theme'] = 'company_content_company_highlight';
        $content['#bean'] = $bean;
        return $content;
      }
    }
    

    Notice that the class' name matches the name that we declared in hook_bean_types(). There are other methods available to override in this class, but in this we're only interested in overriding the view() method. This is because we want to something about how the bean generates its HTML. Remember the theme_company_content_company_highlight() function we declared in step 3? This is where we define the variables that get passed to it. The '#theme' element declares the theme function to use and subsequent "#" elements are the variables.

Clear Drupal's cache and now your bean should be working as desired!

Help improve this page

Page status: No known problems

You can: