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
Comment #1
vadym.kononenko commentedNice 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.
Comment #1.0
vadym.kononenko commentedFix in module code
Comment #2
soulston commentedHi,
Did this ever make it in to Rules or contrib somewhere?
Looking at using this on a project
Comment #3
tr commentedNeeds a patch and tests.