Introduction:

Iam currently working on a complex integration of entity, commerce and display suite. The workflow I am targeting is as follows:

- Base products are defined in commerce (product entity)
- Attribute sets like gender, shoe size and clothing size are defined on line items (different entity)
- Specific branded products refer a product entity, add a specific image and in the display mode select the preferred attribute set by setting a line item.

So lets say I have the following product type entities with matching line items types:
- shoes
- t-shirts

With display suite I also add the corresponding view modes each selecting the correct line item type.

The idea:

Since drupal 7.17 support was added for changing the view mode of an entity before it is being rendered by use of hook_entity_view_mode_alter. This is currently only implemented by the node module, but in theory could be implemented by all entity providers.

I wrote a simple module that adds the following:
- An "When selecting the entity view mode" event that triggers by use of the hook_entity_view_mode_alter hook. Passing the node as a wrapped entity tot the rules api.
- An "Alter view mode" action that selects a view mode compatible with the specific entity_type.

The module attached does work in my case. But I would think it is far from optimal, and it would be a powerful feature for website builders without programming knowledge.

Is this a feature that could be added to Rules core, or is it best used as a contributed module?

Module code:


function rules_view_mode_rules_event_info() {
  $defaults = array(
    'group' => t('Entities'),
    'module' => 'entity',
  );
  return array(
    'entity_view_mode' => $defaults + array(
      'label' => t('When selecting the entity view mode'),
      'variables' => array(
        'entity' => array('type' => 'entity', 'label' => t('The target entity')),
      ),
    ),
  );
}

function rules_view_mode_rules_action_info() {
  $defaults = array(
    'parameter' => array(
      'entity' => array(
        'type' => 'entity',
        'label' => t('The target entity'),
        //'save' => TRUE,
      ),
      'view_mode' => array(
        'type' => 'list<text>',
        'label' => t('View modes'),
        'options list' => 'rules_view_mode_view_modes',
      ),
    ),
    'group' => t('Entities'),
  );
  $actions['entity_view_mode_action'] = $defaults + array(
    'label' => t('Alter view mode'),
    'base' => 'rules_view_mode_alter_view_mode_action',
  );
  return $actions;
}

function rules_view_mode_view_modes($input){
  $variables = $input->availableVariables();
  $info = entity_get_info($variables['entity']['type']);

  $array = array();

  foreach ( $info['view modes'] as $key => $detail ){
    $array[$key] = t($detail['label']);
  }

  return $array;
}

function rules_view_mode_alter_view_mode_action($entity,$view_mode){
  $store = &drupal_static('view_mode_store');
  // More hacks, don't know how to create a single value select field. Only use the first value.
  $store = array_shift($view_mode);
  return;
}

function rules_view_mode_entity_view_mode_alter(&$view_mode, $context){
  // Since we cant return values from rules, use a static intermediary.<<< hacks
  $altered = &drupal_static('view_mode_store',false);

  // Rules expect a metadata wrapped entity;
  $entity = entity_metadata_wrapper($context['entity_type'], $context['entity'], array('bundle'=>$context['entity']->type));

  $info = entity_get_info($context['entity_type']);
  // Put rules to work
  rules_invoke_event('entity_view_mode', $entity);

  if ( $altered ){
    $view_mode = $altered;
  }

  // Reset static store
  drupal_static_reset('view_mode_store');
}

Comments

vadym.kononenko’s picture

Nice feature. :)

More flexible alternative to:
drupal.org/project/context_entity_field‎ +
drupal.org/project/contextual_view_modes‎ +
drupal.org/project/context_rules‎

Thank you for sharing.

vadym.kononenko’s picture

Issue summary: View changes

Fix in module code

soulston’s picture

Hi,

Did this ever make it in to Rules or contrib somewhere?

Looking at using this on a project

tr’s picture

Version: 7.x-2.3 » 7.x-2.x-dev
Status: Active » Needs work

Needs a patch and tests.