Een hart voor de Drupal Community

Bij make it fly geloven we sterk in Drupal en Open Source software in het algemeen. We maken dagelijks gebruik van vele open source componenten en de vele Drupal modules die beschikbaar zijn. We dragen actief ons steentje bij aan de community door zelf patches, modules en documentatie te voorzien, daarnaast zijn enkele teamleden ook actief in de Drupal User Group vzw.

Een overzicht van onze bijdragen aan de Drupal community vind je terug op onze Drupal.org pagina. Naast het actief meerwerken aan de Drupal community, zetten we ook andere ontwikkelaars op weg door vragen te beantwoorden op Drupal Answers.

  1. Time-out in ContextUploader

    Brecht Ceyssens

    @loparev,

    We still run into these issues today. Correct responses are received, with content like this:

        [processUid] => 3107a0c4-954d-4db5-ac48-ae07f0e8f598
        [processState] => IN_PROGRESS
        [processType] => MATCH_CONTEXT
        [createdDate] => 2025-09-10T14:10:46Z
        [modifiedDate] => 2025-09-10T14:10:46Z
        [result] => Array ...
    

    Until it switches to state COMPLETED, so the functionality works as designed but it sometimes just takes to long. We tried increasing the time-out to 30 seconds, but it still happens to often. I'll try to capture some of the problematic process ID if you can use those the check logs or something?

    Is it really necessary to wait for the matching to complete processing? Edit: If I read the code correctly the response is only used to log a message? I assume it's enough to wait for the upload to complete and continue on Drupal's side?

    From time to time queue items are building up rapidly because a lot of translations are being requested (campaign season for our client). We already disabled cron processing to not disturb other processes. See https://www.drupal.org/project/tmgmt_smartling/issues/3545995

  2. Optional use of Drupal cron

    Brecht Ceyssens

    In our case we disabled cron processing due to large amount of translation requests building up queue items and holding back other cron processing tasks (more info here https://www.drupal.org/project/tmgmt_smartling/issues/3454628).

    For now we do it this way and run the queue worker via Drush in an infinite running script:

    function hook_queue_info_alter(&$queues) {
      $queues['tmgmt_extension_suit_download']['cron'] = NULL;
      $queues['smartling_context_upload']['cron'] = NULL;
    }
    

    Would it possible to incorporate that into a Smartling module feature instead?

  3. Dalton

    Fons

    Drupal integration for Dalton.

    Dalton makes your website self-enhancing.

    Visit Dalton for more information.

    This module is still under development.

  4. Offering to co-maintain webform_composite

    Sven Decabooter

    Problem/Motivation

    I would like to become a co-maintainer of this module to merge the Drupal 11 compatibility patch along with any appropriate RTBC issues and create a D11-compatible release.

    You can view my profile to see my large history of work.

    Proposed resolution

    Review my profile and, if approved, add me as co-maintainer with appropriate permissions to merge code, manage issues, and create releases.

    Remaining tasks

    Add me as co-maintainer for this module.

  5. Offering to co-maintain ymd_date

    Sven Decabooter

    Problem/Motivation

    I would like to become a co-maintainer of this module to merge the Drupal 11 compatibility patch along with any appropriate RTBC issues and create a D11-compatible release.

    You can view my profile to see my large history of work.

    Proposed resolution

    Review my profile and, if approved, add me as co-maintainer with appropriate permissions to merge code, manage issues, and create releases.

    Remaining tasks

    Add me as co-maintainer for this module.

  6. Add ai_usage_limits to project page

    Sven Decabooter

    Problem/Motivation

    The project page for the AI module has a section "Other modules/recipes that work with the AI module". Can the https://www.drupal.org/project/ai_usage_limits module be added to that?

    There is now a first alpha release available. It requires at least a version of AI module higher than 1.2.0-alpha2 (or 1.2.x-dev). So maybe the module should only be added to that list, once such a release is available.

    Thanks for your consideration.

  7. Add support for Key module

    Sven Decabooter

    Problem/Motivation

    It would be good to have the option to manage the client ID / client secret via the Key module, instead of storing it in config. This would increase security.

  8. User context switching not working

    Brecht Ceyssens

    @loparev I'm not sure if we really need to switch user like the masquerade module does? The tmgmt module added an access bypass feature around the same time context user switching has been added in this project.

    anonymous_access is enabled by default, that's probably why it works in most cases? If it is disabled or the key query param is stripped before it reaches the webserver, you'll run into the tmgmt_smartling authentication issue.

    • https://git.drupalcode.org/project/tmgmt/-/commit/b28aeb95e70a17fff72df7...
    • https://git.drupalcode.org/project/tmgmt_smartling/-/commit/d65e50a8d910...
  9. AI Translate settings are not sufficient

    Sven Decabooter

    Those seem like some valid points and good improvements to the AI translation system to me. To implement some of those, some major refactoring might be needed to the AI Translate system, so not sure if they would all be easily doable.

    Currently the field data gets extracted from the entity, based on the field type of each field. The 3rd party settings available on a field could be leveraged to configure this some more. E.g. the ReferenceFieldExtractor plugin already does this, to decide whether to translate a certain entity_reference field or not. Extending this with the option to "optionally disable translation per field" seems fairly doable.

    An optional prompt per field is something that would need to be passed along in the metadata of the extracted field values, towards the TextTranslator service. This should also be possible, but would complicate the already somewhat complex array structure of this even more.

    Switching providers per field would work in the same way. Actually the \Drupal\ai_translate\TextTranslator::translateContent() method already has a context array parameter implying in the documentation that should be possible, but the implementation code doesn't do anything with it.

    We should probably provide a decent framework where configurable context can get passed along during the translation pipeline (text extraction, AI service calling, translation saving), and more events get triggered, so other contrib modules could plugin into that and provide extra tools - if not provided with the ai_translate module itself.

    I think this request should probably need some more analysis, and be split out into separate subtasks.

  10. User context switching not working

    Brecht Ceyssens

    Hi @loparev, we're running into the same issue.

    We've setup a new Drupal environment to isolate the issue: Drupal: 11.2.2 Tmgmt: 8.x-1.17 Tmgmt Smartling: 8.x-9.17

    We've used the context debug submodule which works as advertised. The issue however only occurs when trying to upload unpublished pages, in combination with the queue worker running from command line.

    It looks like the code, copied from masquerade, on its own (handled with curl afterwards) doesn't handle sessions completely. Masquerade does a redirect on which the Symfony frameworks handles the session correctly and sets the cookie in a response listener.

    To dive deeper into the issue, dumping the cookies from modules/contrib/tmgmt_smartling/src/Context/ContextUserAuth.php's getCookies() looks like SSESSc2b280e207aa821b24606f896b740d6d=. As you can see it lacks the session_id value.

    It's probably because the queue is handled via command line (cron)? Let me know if you need more information to reproduce on your end.

  11. Error when trying to create an ECA model via AI

    Sven Decabooter

    Problem/Motivation

    I tried clicking the "Ask AI" button, to have it generate an ECA model for me. I didn't save the exact prompt beforehand unfortunately, so I don't have that to reproduce.

    The general purpose was like this:

    Upon saving a node, create an SEO-friendly summary of the full node display, and fill it in in a designated field. The full node display context was provided via the [node:render:full] token (drupal/token_entity_render module).

    After this request, the batch process started, but crashed with the following error:

  12. Error when trying to trigger AI Automator

    Sven Decabooter

    Problem/Motivation

    I tried creating an ECA model that automatically fills in a textarea field on a page node (field_seo_description). It is supposed to take the whole node contents (full view mode), and use AI to create a summary out of that, and fill it in the aforementioned field.

    However, when trying to use the "AI automator" action trigger, I'm getting the following error: action "AI Automator Trigger" (eca_ai_automator_1fcddok): The submitted value in the Automator element is not allowed.

    Steps to reproduce

    Used module versions:

    • "drupal/ai": 1.2.0-alpha2
    • "drupal/ai_integration_eca": 1.0.0-rc2
    • "drupal/bpmn_io": 3.0.0
    • "drupal/eca": 3.0.2
    • "drupal/modeler_api": 1.0.x-dev
    • "drupal/token_entity_render": 2.0.0
    • "drupal/schemata": 1.0.0

    Configuration for my field_seo_description field:

    • “Enable AI Automator”: checked
    • Automator type: LLM Text
    • Input mode: Advanced
    • Prompt:
      Create an SEO-friendly summary of the page content, as provided within the context below.
      The description should be in the same language as the provided body text.
      If the context is not sufficient or empty, please just return an empty string.
      
      Context:
      Title: [node:title]
      Body: [node:render:full]
      

      Body token is provided by the token_entity_render module. It provides HTML output of the whole page. Not sure if this is the best approach, since I'd want only the text, not the HTML, but it's a start...

    • "Edit when changed": checked
    • “Automator worker”: ECA
    • "AI Provider": LLM Proxy (using lite_llm)
    • “Joiner”: Space

    I created an ECA model, and dragged a start event on it - selecting "Update content entity" (bundle: node page) The action is of type "AI Automator Trigger".

    Screenshot:

  13. Move TextExtractor service to AI core

    Sven Decabooter

    So for example:

    \Drupal\ai\AiFieldTextExtractor\TextFieldExtractor:

    #[AiFieldTextExtractor(
      id: "text",
      label: new TranslatableMarkup('Text'),
      field_types: [
        'title',
        'text',
        'text_long',
        'string',
        'string_long',
      ],
    )]
    class TextFieldExtractor {
    
      /**
       * {@inheritdoc}
       */
      public function getColumns(): array {
        return ['value'];
      }
    
      /**
       * {@inheritdoc}
       */
      public function extract(ContentEntityInterface $entity, string $fieldName): array {
        // IMPLEMENTATION.
      }
    
      /**
       * {@inheritdoc}
       */
      public function shouldExtract(ContentEntityInterface $entity, FieldConfigInterface $fieldDefinition): bool {
        return TRUE;
      }
    
    }
    

    (some of these methods would be in a base class obviously, but for illustration purposes I added them here)

    and

    \Drupal\ai_translate\FieldTextExtractor\TextFieldExtractor:

    #[FieldTextExtractor(
      id: "text",
      label: new TranslatableMarkup('Text'),
      field_types: [
        'title',
        'text',
        'text_long',
        'string',
        'string_long',
      ],
    )]
    class TextFieldExtractor extends \Drupal\ai\AiFieldTextExtractor\TextFieldExtractor: {
    
      /**
       * {@inheritdoc}
       */
      public function setValue(ContentEntityInterface $entity, string $fieldName, array $textMeta) : void {
        // IMPLEMENTATION.
      }
    
      /**
       * {@inheritdoc}
       */
      public function shouldExtract(ContentEntityInterface $entity, FieldConfigInterface $fieldDefinition): bool {
        return $fieldDefinition->isTranslatable();
      }
    
    }
    
  14. Move TextExtractor service to AI core

    Sven Decabooter

    I probably was a bit too enthusiastic with my MR.

    I identified multiple problems with just moving the FieldTextExtractor plugins from ai_translate to ai core:

    1. The logic in shouldExtract() for each plugin is tightly coupled to translation logic. In it's easiest form, it checks if a field is translatable. In more complex cases, e.g. for Entity References, it checks configuration settings to determine whether to extract a given entity reference.
    2. The logic in setValue() is also tightly coupled to translation logic. It assumes the plugin that extracted the field value, will store it again on the exact field same location (but on the translated version of an entity)

    The scenario's where text extraction could be useful outside of translation logic, seem to be:

    • For ai_content_suggestion: this just needs the extraction part, not the logic for setting the value again on the same field!
    • For ai_automators: might be useful to provide the extracted values as tokens to automators? There is already something in place like that, but using the extractor plugins might extend that logic? Haven't looked to deeply into this. But this would also only need the extraction logic I assume?
    • ... other places?

    Refactoring the FieldTextExtractor plugins to be more generic, while keeping backwards compatibility, seems rather challenging. I was thinking we could set it up as follows:

    New plugin type: AiFieldTextExtractor
    • Resides in the Drupal\ai namespace
    • Provides implementations for various field types, same as current ai_translate FieldTextExtractor plugins
    • Only implements the methods: extract(), shouldExtract() & getColumns() no value setting logic
    • Does it need to be limited to extracting text? If not, name it AiFieldExtractor? Haven't thought this through yet :)
    Existing plugin type: FieldTextExtractor
    • Resides in the Drupal\ai_translate namespace
    • Already has implementations for various field types: they will be refactored to extend their AiFieldTextExtractor equivalent
    • Only provides the setValue() method.
    • extract() and shouldExtract() could be overridden to provide translation-specific logic that is not in the parent AiFieldTextExtractor plugin counterpart
    • Could potentially be deprecated in 2.0.0 in favor of a better named AiTranslateFieldTextExtractor plugin / namespace, but that might be nitpicking on my part...

    ai_translate and contrib modules extending this module would keep on using the FieldTextExtractor plugins. Other AI modules could use just the extract logic from the AiFieldTextExtractor plugins, and run with it.

    Does that make sense, or is it overly complex and unnecessary? Thanks for giving it some thought.

  15. Move TextExtractor service to AI core

    Sven Decabooter

    TODO:

    - \Drupal\ai\TextExtractor::shouldExtract() still contains translation-specific logic. This should be moved to the module making use of the Text Extractor service, in this case ai_translate. Not sure how this should be set up.

  16. Move TextExtractor service to AI core

    Sven Decabooter

    Added a MR to refactor this. Marked the existing ai_translate classes / services deprecated, so contrib modules extending them, have time to update their dependencies.

  17. PageSpeed Insights - Accessibility (ARIA)

    Fons

    Problem/Motivation

    Hello, I'm using the FAQ field module on my websites and it's really nice.

    I render them with the JQuery accordion formatter.

    I've noticed that PageSpeed Insights has accessibility warnings based on the standard implementation.

    Steps to reproduce

    Setup a FAQ field with formatter JQuery accordion.

    Run the PageSpeed Insights tool (https://pagespeed.web.dev/).

    You'll see you get a 95 score (if your websites complies on all other points and a notice):

    "Elements with an ARIA [role] that require children to contain a specific [role] are missing some or all of those required children."

    I've already changed the h3 to a button to see if that helps and some other stuff but I keep getting the warning.

    Anyone else has any ideas? Would love to get this fixed.

  18. Translation batch process does not handle translation errors

    Sven Decabooter

    Setting back to 1.2.x as the correct branch to target.

    I tried reproducing this, as I had earlier experienced weird behavior when I had connection problems to my AI API endpoint. However, in my testing, I get into \Drupal\ai_translate\Plugin\AiProvider\ChatTranslationProvider::translateText(), and into the GuzzleException catching. This then logs the error, but proceeds to return an empty translated text output.

    This finally results into database errors trying to save the translation, and the display of the message "There was some issue with content translation.".

    So the scenario above might be a separate use case that could be taken into account for improving the error message output. The error message should be more clear, and a translation should not be attempted to be created I guess?

Sven Decabooter - Drupal Developer

"Onze teamleden bouwen zelf ook mee aan ons geliefde Drupal, en daar zijn we trots op"

Sven Decabooter
Drupal developer

Betrouwbare technologie, naadloze prestaties. Dat zijn onze Drupal-oplossingen.