I have been diving into Drupal 8, it's plugin system and all the new stuff for some days now. I hope that I understood the basics and now I would like to start out with a new module.
The module should:
- Add a dropdown to the form
menu_link_edit
- do the usual save/update/delete stuff for each menu link on submission of the form, so that the selected value can be accessed from the link entity.
Following the conventions I have created that structure:
+mymodule
-mymodule.info.yml
-mymodule.services.yml
+src
-MyModuleManager.php extends DefaultPluginManager
-MyTypeInterface.php
-MyTypeBase.php implements MyTypeInterface
+Plugin
+Mytypes
-MyType1.php extends MyType
-MyType2.php extends MyType
Until here the new whole Plugin stuff is clear to me, that is why I have not posted any code so far. With the above I declare the Items that should appear in the desired dropdown
, but it does not attach the field to the form, and it does not care about the storage of the values.
I had a look at the module menu_link_attributes
and there, in menu_link_attributes.module
I found:
function menu_link_attributes_form_menu_link_content_form_alter(…){
//code
$form['actions']['submit']['#submit'][] = 'menu_link_attributes_menu_link_content_form_submit';
}
So the actual form is modified and another submit handler is added. BUT I do not get the part where the data (the values of the additional fields) is stored with the item (the menu link). HOW DOES THAT WORK?
On the other Hand, I had a look at the module link_attributes
, therein (link_attributes.module
) I found:
function link_attributes_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
if ($entity_type->id() === 'menu_link_content') {
$fields['link']->setDisplayOptions('form', [
'type' => 'link_attributes',
'weight' => -2,
]);
}
}
And if I understood everything right, this piece of code does assign a different Field Widget to the Link, so that additional fields extend the original widget.
I think I understand the process, but also here, I do not understand how the data is stored/retrieve.
Since the overall question might be unclear, I hope I can figure out my objective like that:
From my understanding I would expect to alter the entity menu_link_content
in some sort of hook_entity_alter
, or if possible in the new D8 manner. But in non of the examples I could find any approach like that, why?
So by defining a new field (which renders the dropdown) and adding that field to the definition of menu_link_content
the field should appear on the form all by itself, or do I get this totally wrong?
Thanks in advance!
UPDATE
I have implemented the following, but it does not do anything, so why is that not working?
function mymodule_entity_type_build(array &$entity_types) {
$entity_types['menu_link_content']
->setFormClass('menu_link_content_form',
'Drupal\mymodule\Form\MenuLinkContentForm');
}
I have intentionally implemented errors in 'Drupal\mymodule\Form\MenuLinkContentForm', just to check if it is used, but it isn't. So where's the catch here?
UPDATE #2
based on the accepted answer My resulting code looks like that:
//mymodule.module
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
function mymodule_entity_base_field_info(EntityTypeInterface $entityType)
{
if($entityType->id() == 'menu_link_content') {
$manager = \Drupal::service('mymodule.pluginmanager');
$labels = array_map(
function(array $definition) use ($manager)
{
$instance = $manager->createInstance($definition['id']);
return $instance->getName();
},
$manager->getDefinitions());
$field = [
'mymodulefield' => BaseFieldDefinition::create('list_string')
->setLabel(t('MYMODULE::FIELD::LABEL'))
->setSetting('allowed_values', $labels)
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true)
->setDisplayOptions('form', [
'type' => 'select',
'weight' => -10
])
];
return $field;
}
}
One thing made a lot of trouble: If during the installation of the module something went wrong, It resulted in MySql errors. Uninstalling was not possible anymore, since extra fields were attached to the entity.
menu_link_content_data
table. You can use hook_update_n to update the schema and add the missing column.