Wrappers Delight is a development tool that eases the development of custom code for complex Drupal sites and applications. It is not a generalized tool for contrib. It's designed to help adapt those tools for use on a specific site. It will also help prevent carpal tunnel syndrome and Drupalism-induced madness.*

It consists of two parts:

  1. A set of object-oriented base classes for common entity types that provide getters and setters for entity properties. These classes are wrappers around the EntityMetadataWrapper class.
  2. A Drush command that generates wrapper classes for the specific entity bundles on your site, adding getters and setters for all fields you have configured on the bundles.

Bonus: As of 7.x-1.1, the Wrappers Delight Drush command will also generate base wrapper classes for any entities it does not know about. This means it will automatically generate base classes for your custom entities, with getters and setters for all the entity properties!

Why Use Wrappers Delight?

When you are writing a lot of custom code for a Drupal site, it's often tedious and error-prone because your IDE can't really help you. Take this example code, which might appear in a theme function:

<?php
$node_wrapper = entity_metadata_wrapper('node', $node);
$body_value = $node_wrapper->field_body->value();
$image = $node_wrapper->field_image->value();
$image_html = theme('image_style', array('path' => $image->fid, 'style_name' => 'large'));
$output = '<div class="description">' . $image_html . $body_value['safe_value'] . '</div>';
?>

With code like this, you have the following issues:

  • Your code is tightly coupled to specific field names. You must remember these, because your IDE can't autocomplete them.
  • Your code is tightly coupled to specific field data formats. ('value', 'safe_value', 'target_id', 'tid', etc.)
  • Your code tends to be verbose, with no IDE help in writing it, as the field and entity config is in the database.
  • Your code may contains errors that your IDE cannot alert you to. Simple typos can go unnoticed until runtime since the IDE has no idea how the entity object is structured.

Wrappers Delight helps with these problems by:

  • Providing a typed object class in code for accessing an entity object properties and fields. This allows for IDE autocomplete and error checking.
  • Providing a Drush command to easily generate and update bundle classes from entity and field config in the database.
  • Allowing the wrapper classes to be customized, so that you can decouple your code from the specific Drupal field implementation. You can customize your method return value formats, method signatures, add new methods, etc.

As a result, the code from above could be rewritten with Wrappers Delight like this:

<?php
$article = new ArticleNodeWrapper($node);
$output = '<div class="description">' . $article->getImageHtml('large') . $article->getBody() . '</div>';
?>

Getting Started with Wrappers Delight

To generate wrapper classes for content types on your site:

  1. Install the module on your development site.
  2. Install Drush, if you don't already have it on your development environment.
  3. At the command line, run drush wrap node.
  4. This will generate a new module called "wrappers_custom" that contains wrapper classes for all your content types.
  5. Enable this module, and you can start to write code with these wrapper classes.
  6. This process works for other entity types, as well: Users, Commerce Products, OG Memberships, Messages etc. Just follow the command pattern: drush wrap ENTITY_TYPE

Using the Wrapper Classes

The wrapper classes generated by Wrappers Delight contain getters and setters for fields defined on those entities, and they inherit getters and settings for entity base properties. To use an ArticleNodeWrapper wrapper, your code would look like this:

<?php
$article = new ArticleNodeWrapper($node);
$body_value = $article->getBody();
?>

Wrapper classes also support passing an ID instead of an entity object, so this will also work:

<?php
$article = new ArticleNodeWrapper($nid);
?>

If you want to create a new entity, wrapper classes include a static create() method, which can be used like this:

<?php
$values = array(
  'title' => 'My Article',
  'status' => 1,
  'promote' => 1,
);
$article = ArticleNodeWrapper::create($values);
$article->save();
?>

Once you generate a wrapper class for an entity bundle, you are encouraged to customize it to your specific needs. The Drush command can be run multiple times as new fields are added to entities. Customizations to the existing methods and signatures will not be overwritten by subsequent runs of the Drush command. If you want certain fields to not be exposed in the wrapper class, make their getters/setters private after you generate the class.

Drush Command Options

The Drush command supports the following options:

  • --bundles: specify the specific bundles to export
  • --module: specify the module name to create or update (will default to wrappers_custom)
  • --destination: specify the destination directory of the module (will be ignored if module with same name already exists and is enabled)
  • --skip-base-class: do not generate an entity base class for entities without an existing one. (will use WdEntityWrapper as the base class in this case)

Generating Base Classes for Custom Entities

If you have custom entities, or entities without an existing Wrappers Delight base class, the system will automatically generate a base class using the properties of the entity when you call drush wrap ENTITY_TYPE. The base class will be placed in the same location as the bundle classes, either wrappers_custom module, or the module specified by the --module option. Base classes are never updated, so if you change the entity properties, you must delete the class and re-generate it. (or just manually update it) You can freely customize a generated base class since it won't be updated automatically.

Packaging Wrapper Classes with Feature Modules or Other Bundle-Supplying Modules

You may export individual wrapper classes to existing modules by running a command like the following:

drush wrap node --bundles=blog --module=blog_feature

That will put the one single wrapper class for the blog node type in the blog_feature module, and add the files[] include lines to blog_feature.info. Wrappers Delight will be smart enough to find this class automatically on subsequent runs if you have enabled the blog_feature module. This means that once you do some individual exports, you could later run drush wrap node and existing classes would be updated. (any new classes would end up in wrappers_custom module unless --module is specified)

* This statement has not been evaluated by the FDA.

Supporting organizations: 
Developer of this module

Project information

Releases