6

So I reviewed the code in the core book, menu_ui, and path modules, and they all seem to handle adding a settings widget in a vertical tab differently.

The book module uses a method called addFormElement(), which is called within a hook_form_BASE_FORM_ID_alter() hook.

The menu_ui module is similar, but uses hook_form_BASE_FORM_ID_alter() directly.

Path seems to use a method called formElement(), and I'm not even sure where/how this method is used at the moment.

The real question I have is, how does one actually process the form setting and save it to the database? I have tried to find an example, but I'm at a loss.

Is there a help page with examples like the ones I found for adding an admin settings page?

If not, is there a recommended approach to displaying/saving a value in a vertical tab on a node add/edit form?

2

I'm going to take a stab and show how I solved it, but I'm still curious to know if there's a better way.

In a nutshell, I used hook_form_BASE_FORM_ID_alter(), hook_node_submit(), and hook_ENTITY_TYPE_insert() or hook_ENTITY_TYPE_update() in the .module file.

Then I have a class called HierarchyManager that does all the heavy lifting that the D7 .module and .inc files used to do. It's listed as a service named "nodehierarchy.manager".

Lastly, I have a class called HierarchyOutlineStorage that handles the database inserts and updates. Quite a bit of that code was copied directly from D7.

In my .module file:

/**
 * Implements hook_form_BASE_FORM_ID_alter() for node_form().
 *
 * Adds the hierarchy form element to the node form.
 */
function nodehierarchy_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Load the node object associated with this form
  $node = $form_state->getFormObject()->getEntity();
  $account = \Drupal::currentUser();

  // Optional but keeps the .module code cleaner IMO      
  $hierarchy_manager = \Drupal::service('nodehierarchy.manager');

  // Do your permission checks here
  $has_permission = ...;
  if($has_permission) {
    $form = $hierarchy_manager->addHierarchyFormElement($form, $form_state, $node, $account, $collapsed);
  } 
}

/**
 * Implements hook_node_submit().
 */
function nodehierarchy_node_submit(NodeInterface $node, $form, FormStateInterface $form_state) {
  // Here the node object gets updated with the form value to be used later
  // If you aren't sure about the $form_state, download/enable devel and add
  // dsm($form_state->getValues()) to show all available values
  if (!$form_state->isValueEmpty('nodehierarchy_parents')) {
    $node->nodehierarchy_parents = $form_state->getValue('nodehierarchy_parents');
  }
}

/**
 * Implements hook_ENTITY_TYPE_insert() for node entities.
 *
 * Save the form settings
 */
function nodehierarchy_node_insert(NodeInterface $node) {
  $hierarchy_manager = \Drupal::service('nodehierarchy.manager');
  $has_permission = ...
  if ($has_permisson) {
    $hierarchy_manager->hierarchySaveNode($node);
  }
}

/**
 * Implements hook_ENTITY_TYPE_update().
 */
function nodehierarchy_node_update(EntityInterface $node) {
  $hierarchy_manager = \Drupal::service('nodehierarchy.manager');
  $hierarchy_manager->hierarchySaveNode($node);
}

In the HierarchyManager.php file:

public function addHierarchyFormElement(array $form, FormStateInterface $form_state, NodeInterface $node, AccountInterface $account, $collapsed = TRUE) {
  // Insert $form array here
  $form['hierarchy'] = array(...);
}

public function hierarchySaveNode(&$node) {
  // Do all your processing here, then insert or update dB record
  $isNew = ...
  if ($isNew) {
    return $this->hierarchyOutlineStorage->insert($item);  
  }
  else {
    return $this->hierarchyOutlineStorage->update($item->hid, $item);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.