New fields added to the menu cannot be exported

Created on 21 June 2018, over 6 years ago
Updated 14 January 2024, 9 months ago

I added the new field to the menu using "menu_item_extras module" module.

And the extra field added cannot be exported using structure sync.

Currently it exports only below fields.
'menu_name'
'title'
'parent'
'uri'
'link_title'
'description'
'enabled'
'expanded'
'weight'
'langcode'
'uuid'
'tab_type'
'attributes'

✨ Feature request
Status

Needs review

Version

2.0

Component

Code

Created by

🇮🇳India AshithVijay

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇫🇷France tostinni

    Thanks for the patch.

    What was the idea of implementing some hooks for this instead of automatically export/import all fields ? Because this would require an extra task to create a custom module in order to fully export/import a menu with fields.

    The method suggested in structure_sync.api.php wasn't working for us, probably because we're on an old Drupal (8.9.20) as this code was returning an empty value $options = $menuLink->link->first()->options;

    So here is an implementation using the API to find the fields of the menu and export them. It will however work only for single valued fields and would need to be extended to entity reference, formatted text etc...

    /**
     * Implments hook_structure_sync_menu_link_export_alter() to deploy field_subtitle.
     */
    function souk_deploy_structure_sync_menu_link_export_alter(&$item, \Drupal\menu_link_content\Entity\MenuLinkContent $menuLink) {
      // Retrieve all extra fields from the menu link and export them
      $fields = $menuLink->getFieldDefinitions();
      foreach ($fields as $field_name => $field_definition) {
        if (!empty($field_definition->getTargetBundle())) {
          if (!$menuLink->{$field_name}->isEmpty()) {
            $item[$field_name] = $menuLink->{$field_name}->value;
          }
        }
      }
    }
    
  • 🇫🇷France tostinni

    FYI, this issue ✨ Support for translations of menu items Needs review contains code that handles extra fields besides multilingual.

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.0.7 + Environment: PHP 8.1 & MySQL 8
    last update over 1 year ago
    6 pass
  • First commit to issue fork.
  • 🇫🇷France dydave

    Hi everyone,

    Thank you very much for raising this issue and for contributing a patch, it's greatly appreciated.

    It actually helped us a lot with a very standard/simple use case:

    Exporting config added by the Menu Link Attributes → module.
    The module allows adding additional attributes to menu link items, such as 'class', 'id', 'rel', etc... and any other custom attributes, saved in the DB table 'menu_link_content_data', in the serialized field 'link__options'.

    In its current state, the Structure Sync module doesn't seem to be able to export the data contained in 'link__options', see:
    https://git.drupalcode.org/project/structure_sync/-/blob/51a15a1ba9ecaf7...
    (as explained in the issue summary)

    Thus requiring additional actions or code in a project to deploy these content changes from one environment to another (for example, manually, update hooks, etc...).

    As suggested at #10:

    What was the idea of implementing some hooks for this instead of automatically export/import all fields ? Because this would require an extra task to create a custom module in order to fully export/import a menu with fields.

    We could indeed try to think of a "one-fits-all" solution which would take into account many different cases and export automatically everything to the structure_sync.data config... But trying to cover all the possible cases and options seems like a rather big step...
    For example, if we'd wanted to only cover this particular use case, we could simply add 'link__options' to the array of elements from the link above, the same way it is currently being done in related ticket ✨ Support link options on menu item RTBC (with patch).
    However, that would only cover a single very specific use case... See for example ✨ Support Layout Builder on menu item Needs review , where other users would like to export Layout Builder configuration (key: layout_builder__layout, with the exact same changes as for the link options patch, just above.

    Therefore, I personnally think the approach suggested in this patch provides a very flexible solution and possibility to allow anyone to export/import additional data to structure_sync.data, whether from contrib, a completely custom module or set of requirements.
    Additionally, it is also inobtrusive in the fact it doesn't have any impact on module's current logic.
    Since the import/export of configuration is more of a backend/deployment operation, performance or other considerations shouldn't necessarily be high on the list of concerns, as opposed to flexibility.

    Hoping we could get more feedback and reviews, I went ahead and made a few additional "clean-up" changes and documentation improvements at #12.
    One thought though, the two import hooks could potentially be grouped together, with two operations: 'create' and 'update' (defaults to 'create'), based on the feedback and reviews received on this patch.
     

    Please find below the code we used along with this patch to support the data added by the Menu Link Attributes → module:
    Custom module file: contrib10_structure_sync.module

    <?php
    
    /**
     * @file
     * Provides 'structure_sync' hook implementations to export additional fields.
     *
     * By default, the Structure Sync module doesn't allow exporting additional
     * fields, in this particular case, for the Menu Link Attributes module, which
     * adds 'class', 'rel', 'target', etc...
     *
     * Based on the Structure Sync API added in patch from issue on Drupal.org:
     * Without the patch, none of these hooks work.
     *
     * @see: https://www.drupal.org/project/structure_sync/issues/2980893
     */
    
    use Drupal\menu_link_content\Entity\MenuLinkContent;
    
    /**
     * Implements hook_structure_sync_menu_link_export_alter().
     */
    function contrib10_structure_sync_structure_sync_menu_link_export_alter(&$item, MenuLinkContent $menu_link) {
      // Export the values of the fields added by the 'menu_link_attributes' module.
      if (!empty($menu_link->link->options['attributes'])) {
        $item['menu_link_attributes'] = $menu_link->link->options['attributes'];
      }
    }
    
    /**
     * Implements hook_structure_sync_menu_link_import_alter().
     */
    function contrib10_structure_sync_structure_sync_menu_link_import_alter(&$menu_item, $config) {
      // Import the 'menu_link_attributes' fields from configuration, if the menu
      // item does not exist: Import safe and force ((re)creates the item).
      if (!empty($config['menu_link_attributes'])) {
        $menu_item['link']['options']['attributes'] = $config['menu_link_attributes'];
      }
    }
    
    /**
     * Implements hook_structure_sync_menu_link_update_alter().
     */
    function contrib10_structure_sync_structure_sync_menu_link_update_alter(MenuLinkContent &$menu_item, $config) {
      // Import the 'menu_link_attributes' fields from configuration, if the menu
      // item already exists: Import full (with update: merge values from config).
      if (!empty($config['menu_link_attributes'])) {
        $menu_item->link->options += [
          'attributes' => $config['menu_link_attributes'],
        ];
      }
    }
    
    

     

    Although this ticket and patch only cover Menu Link content items, I certainly think it is a step in the right direction and could perhaps be further abstracted/extended to cover all objects currently supported by the module, in particular, Block Content items (see for example, #3130854: Layout Builder Blocks Export → ) and Taxonomy Terms.

    Maybe some middle ground could be found, where patches could be accepted for specific keys (for example, from Drupal Core) to be included by default in the module (such as the 'options' key from patch #3073810 ✨ Support link options on menu item RTBC ), and still have this patch/feature to allow extra/custom config to be added by contrib or custom modules.

    In any case, we would greatly appreciate if you could please try testing the patch, give us your reviews and opinions on the approach taken in this ticket.

    Feel free to let us know at any point if you have any questions or concerns on any aspects of this patch or the ticket in general, we would surely be very happy to help.
    Thanks again very much to everyone who contributed to coming up with the initial idea and code implementation.

  • 🇫🇷France dydave

    Adding another very relevant ticket ✨ Move import/export logic into plugin Active with an approach through plugins which could probably be a preferable way to go, instead of API hooks, but no implementation has been suggested yet.
    If anybody has some time, pointers, guidelines or suggestions on a possible implementation with plugins would be greatly appreciated.

    Thanks in advance!

  • 🇫🇷France louis-cuny

    This issue is about tweaking the fields to be exported/imported
    https://www.drupal.org/project/structure_sync/issues/3085904 ✨ Move import/export logic into plugin Active is about rewriting the whole module using drupal's plugin system as a base to be able to support other entity types.

    For this issue, I would agree it would be nicer to use drupal's Plugin system instead of hooks
    But the approach here feels ok with hooks at least as a first step

    From my point of view, the export/import all available fields approach would not fit this module, it should probably remain light and precise

    If others share this point of view (open for debate), I would suggest these next steps:
    - Add tests
    - Review and test manually
    - Add something about this feature in the readme.md
    - Opening other (related) issues to cover blocks and taxonomy terms
    - (optionnaly, converting the hooks to plugin managers)

Production build 0.71.5 2024