it-swarm.com.de

Wie kann ich Änderungsfelder in einem verschachtelten Absatz "bilden", je nachdem, wo das Feld verwendet wird?

Ich habe diese Entitätstypen:

  • Ein Knotentyp: nodepage
  • Ein Absatztyp: pg_a
  • Ein Absatztyp: pg_b
  • Ein Absatztyp: pg_child

Ich habe ein Inhaltsmodell, das ist:

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

Sie können sehen, dass pg_a Und pg_b Beide ein Feld namens field_child Haben, das einen Verweis auf pg_child Ermöglicht. Dies hat eine große semantische Bedeutung für die Site-Architektur.

Jetzt möchte ich alter pg_child bilden, aber nur wenn auf pg_a Und nicht auf pg_b Verweisen wird.

In hook_field_widget_form_alter, Wo ich denke Ich sollte meine Änderungen vornehmen, kann ich Folgendes tun:

$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 = ???

Ich dachte, ich könnte weiter in die $ context-Variable schauen, aber bisher hat mich das angedeutet. Der bisher beste Kandidat ist #parents In der Form, aber wenn ich nur einen Verweis auf field_child Finde, ist dieser nicht eindeutig.

Ich vermute jetzt, dass ich irgendwo mehr $ -Kontext einfügen kann, vielleicht im übergeordneten Build.

3
simesy

In diesem Szenario wird field_caption An verschiedenen Stellen in einem cta Absatz verwendet. Das Unternehmen hat darum gebeten, field_caption Auf 25 Zeichen zu beschränken, jedoch nur, wenn es in einem Knoten in einem Entitätsreferenzfeld mit dem Namen field_foo_cta Verwendet wird.

Zuerst fügen wir dem Widget einen # process-Rückruf hinzu, basierend auf einer beliebigen Regel, indem wir hook_field_widget_form_alter Implementieren:

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'];
    }

  }
}

Dann erstellen wir eine neue Klasse im Verzeichnis src des Moduls.

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;

  }

}

Vielen Dank an @larowlan für die Hilfe.

3
simesy

Ich dachte, ich könnte weiter in die $ context-Variable schauen, aber bisher hat mich das angedeutet. Der bisher beste Kandidat ist #parents in der Form, aber wenn ich nur einen Verweis auf field_child finde, der nicht eindeutig ist.

Ist das Entitätsobjekt im Kontext $ verfügbar? Wenn nicht, kann es irgendwo in $ form_state sein.

Sobald Sie die Paragraph-Entität erhalten haben, können Sie deren übergeordnetes Element mit Paragraph::getParentEntity() und von dort aus mit dem Typ des übergeordneten Elements abrufen.

0
adrum99