J'ai ces types d'entités:
nodepage
pg_a
pg_b
pg_child
J'ai un modèle de contenu qui est:
nodepage
->field_a
Referenced bundles: pg_a
->field_child
Referenced bundles: pg_child
->field_b
Referenced bundles: pg_b
->field_child
Referenced bundles: pg_child
Tu peux voir ça pg_a
et pg_b
les deux ont un champ appelé field_child
qui permet une référence à pg_child
. Cela a une grande signification sémantique pour l'architecture du site.
Maintenant, quelque chose que je voudrais faire est de modifier l'algorithme pg_child, mais niquement lorsqu'il est référencé à partir de pg_a
et non de pg_b
.
Dans hook_field_widget_form_alter
, où je pense Je devrais faire mes modifications, je peux faire ce qui suit:
$field_definition = $context['items']->getFieldDefinition();
// Get the current field widget being built, eg `field_child_thing`.
$name = $field_definition->getName();
// Get the bundle, ie. `pg_child`
$targetBundle = $field_definition->getTargetBundle();
// Get the bundle that $targetBundle is attached to in this instance...
$instance = ???
Je pensais que je pouvais approfondir la variable $ context, mais jusqu'à présent, cela m'a fait allusion. Jusqu'à présent, le meilleur candidat est #parents
dans le formulaire, mais lorsque je ne trouve qu'une référence à field_child
ce qui est ambigu.
Je soupçonne maintenant que je peux injecter plus de $ context de quelque part, peut-être dans la version parent.
Dans ce scénario, nous avons field_caption
utilisé à divers endroits dans un paragraphe cta
. L'entreprise a demandé de limiter field_caption
à 25 carats, mais uniquement lorsqu'il est utilisé dans un nœud sur un champ de référence d'entité appelé field_foo_cta
.
Tout d'abord, nous ajoutons un rappel #process au widget en fonction de la règle, en implémentant hook_field_widget_form_alter
:
function mymodule_field_widget_form_alter(&$element, FormStateInterface $form_state, &$context) {
$field_definition = $context['items']->getFieldDefinition();
if ($field_definition instanceof FieldConfig) {
$config = $field_definition->id();
list ($entity_type, $bundle, $field_name) = explode('.', $config);
if ($entity_type == 'paragraph' && $field_name == 'field_caption') {
$element['#process'][] = ['\Drupal\mymodule\BusinessRules', 'alterFieldCaption'];
}
}
}
Ensuite, nous créons une nouvelle classe dans le répertoire src
du module.
namespace Drupal\mymodule;
class BusinessRules {
public static function alterFieldCaption(array &$element, FormStateInterface &$form_state, array &$complete_form) {
// Use whatever logic to target instances of `field_caption`.
if (reset($element['#parents']) == 'field_foo_cta') {
$element['value']['#maxlength'] = 25;
}
return $element;
}
}
Merci à @larowlan pour son aide.
Je pensais que je pouvais approfondir la variable $ context, mais jusqu'à présent, cela m'a fait allusion. Le meilleur candidat jusqu'à présent est #parents dans le formulaire, mais quand je ne trouve qu'une référence à field_child qui est ambiguë.
L'objet entité est-il disponible dans $ context? Sinon, il peut se trouver quelque part dans $ form_state.
Une fois que vous avez obtenu l'entité Paragraphe, vous pouvez obtenir son parent en utilisant Paragraph::getParentEntity()
et à partir de là le type du parent.