Categories

(83)
(69)
(8)
(34)
(74)
(149)

The use of Feature injection methods in terms of CommerceBox package

06.06.2014
Feature Injection
Author:

This information may be useful for those who are actively using the Features module, as well as for those who are just planning to work with it.

Why did our Drupal development agency comes up with the idea to use feature injection? In Drupal there is a tool for rapid site deployment which is called Apps.

Apps is a set of special applications that enable users to add new functionalities to the site quickly and easily. In other words, each such addition is a ready-to-use piece of functionality for your site. This tool makes a perfect solution for our distribution, CommerceBox based online stores. Its basic version is quite simple and is not burdened with the excessive functionality. However, we did not forget about some useful applications for users to install by their own if such need arises.

Using Apps, we have faced the fact that we need to keep specific functionality for apps using features, although the functionality may not even be switched on at the moment. So the question is whether it is possible to divide the feature in such a way so that the package contains just the feature without the very app functionality. At the same time, the rest of the feature which supplements the main one should be included into the very app (when it is enabled) and they should work as a complete unit. We have developed a technique that helps to solve such a problem and called it Feature Injection.

Probably the easiest way to explain the essence of Feature Injection is to use Views as an example. Suppose that you need to have a feature with views which displays some materials on the site. Let’s assume there are several materials of Article content type on the site, and we need to create our own views page with this content.

1. To begin with, let’s create a view which displays only one ‘title’ field of the ‘Article’ content type:

В'юшка для типу контента Article.

2. Next we should create a feature which adds this very view.

Створення фічі.

3. Extract the saved feature and enable it.

Once the feature is enabled, you can proceed directly to feature injection. Suppose that we need to add one more field to the view to be displayed, without changing the feature itself (e.g, teaser of the ‘body’ field in ‘Article’ content type), but we do not know in advance, whether it is necessary for the feature or not. We add any field into the view using code to create an illusion that the field is added by the feature itself. To do this, we should create our own module, with the help of which the necessary changes will be added to our feature when enabled. If the module is disabled, the changes will not be taken into account and our feature will be safe and sound. This makes the essence of feature injection. To continue, we need to install Diff module.

4. After enabling the Diff module we should add a field to the view which will be an additional field for our feature (that is, if the module created by us is enabled, this field will be displayed, and vice versa). Let’s take the teaser of the ‘body’ field as an example. We need to set it up and display it after the title. As a result, you will get the following output (remember to save the view when adding a new field):

В'юшка статей

5. If we take a look at our feature on admin/structure/features now, we will see it in the Override status. Clicking on this status, you will be redirected to the VIEW tab. If you enable Diff module, the tab REVIEW OVERRIDES will also appear (marked with “+”). Here you will be able to see the changes that are added to the feature.

+ /* Field: Content: Body */
+ $handler->display->display_options['fields']['body']['id'] = 'body';
+ $handler->display->display_options['fields']['body']['table'] = 'field_data_body';
+ $handler->display->display_options['fields']['body']['field'] = 'body';
+ $handler->display->display_options['fields']['body']['label'] = '';
+ $handler->display->display_options['fields']['body']['element_label_colon'] = FALSE;
+ $handler->display->display_options['fields']['body']['type'] = 'text_summary_or_trimmed';
+ $handler->display->display_options['fields']['body']['settings'] = array(
     'trim_length' => '300',
   );

 

Finally we have the code that will complement the feature (when activated) to display a field.

But where should we insert it? We should search for the hook where the resulting code from created module is to be recorded.

6. Next, we need to search in the code where the view is being added (in this case it is ‘show_articles_view.views_default.inc’ file). Thus we see that our view is created by hook_views_default_views(). Then let’s proceed to a custom module creation.

7. The module will be called ‘Feature Injection’ and two files (feature_injection.info and feature_injection.module) will be created. Here is an example of the.info file:

name = Feature injection
description = Add body field to view.
package = "Feature injection"
core = 7.x
dependencies[] = views
dependencies[] = features

 

This is a sample of a completed ‘.module’ file.

<?php

/**
* @file
* Extends drupal functionality.
*/

/**
* Implements hook_views_default_views_alter().
*
* @ingroup features_injection
*/
function feature_injection_views_default_views_alter(&$data) {
  if (isset($data['show_articles_view'])) {
    $display = &$data['show_articles_view']->display['default'];

    /* Field: Content: Body */
    $display->display_options['fields']['body']['id'] = 'body';
    $display->display_options['fields']['body']['table'] = 'field_data_body';
    $display->display_options['fields']['body']['field'] = 'body';
    $display->display_options['fields']['body']['label'] = '';
    $display->display_options['fields']['body']['element_label_colon'] = FALSE;
    $display->display_options['fields']['body']['type'] = 'text_summary_or_trimmed';
    $display->display_options['fields']['body']['settings'] = array(
      'trim_length' => '300',
    );
  }
}

 

Let’s comment each step. To begin with, we should use the alter for hook, with the help of which our view is created. That is, if the hook was called hook_views_default_views(), it will be called hook_views_default_views_alter() then. The $data variable where our feature is recorded will be transferred to this hook. This variable contains (in our case) all the views, which are added using the feature. We can insert the changes into $data and make an illusion that these adjustments are added by the feature itself. Next, we need to check whether our view exists: if (isset ($ data ['show_all_articles'])) (where show_all_articles is a machine name of the view).

After that, the ‘display’ value from the $data variable should be set to the $display variable. Is such a way, we insert here the required code and substitute $handler->display with $display variable.

That's it, now you can either delete ‘body’ field from the view or to revert the elements in the feature (i.e. return all the changes to their initial state using the feature). You also need to check whether your Feature Injection module is working. So currently we should have the feature which creates the view without ‘body’ field. If you enable the module, the ‘body’ field will be added to the view. When the module is disabled, it should disappear.

If everything is up and running - congratulations! The feature injection is completed! But if something goes wrong - try to flush the cache. You can do it on admin/config/development/performance.

If there are some problems with recording into $data variable, try to look it through using a debug() function to see where the changes should be recorded. If you have Devel module installed, you can use dmp() function instead of debug() one.

Where can this be used? Suppose that you are ecommerce development on Drupal 7 and you do not know in advance if you need to add some fields: comments, links, images, etc. In this case, you can use the Feature injection for everyone to decide themselves whether to add these fields or not. Fields will be added by enabling a particular module, and this will create an illusion that the field is set by the feature itself. That is, if you enable one module the link in views will appear, if you enable another one, the image will be displayed, and so on.

Now in CommerceBox package Feature injection is used during apps development. For example, if you enable the app product status you will be able to tag items with ‘New’ status without editing views and this field can be easily removed from views. Accordingly, when the app is disabled, this functionality disappears.

What can cause some troubles? Probably, the hardest thing is to find a hook in the feature that generates the required data. Then this hook should be complemented by the code using alters. The code can be found with the help of Diff module. So you do not need to know, how the field is created using the code; you need just copy and use its required part instead.

This method is demonstrated on a simple example for easier understanding. However, Feature Injection can be used not only for views, but also for any functionality that you add to your feature.

6 votes, Rating: 5

Read also

1

Being a member of Drupal Community is very responsible. That is why internetDevels company organized regular 3-months contribution code sprint. The results are promising.

2

Based on our experience we know that sometimes website owners face different problems connected with their Drupal projects. To handle such situations we have launched a new service offering a...

3

Nowadays services which provide out-of-box html-themes gain popularity. The question is whether it is that easy to use them as a basis for...

4

Often one can see such charges against Drupal: “It is impossible to build a high-load website using this framework”. We will refute this myth on...

5

One of the main issues after making decision to launch a website is development platform - CMS or custom coding? Let's elucidate Drupal framework advantages.

Subscribe to our blog updates