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. Add token usage to streamed chat

    Sven Decabooter

    I have created a MR to start implementing this functionality.

    MR currently contains logic for the first action point:

    Add so that you can collect tokens in the StreamedChatMessage, but do not add it to the interface (no breaking changes).

    This allows this to be used in the ai_provider_openai module for example:

    class OpenAiChatMessageIterator extends StreamedChatMessageIterator {
    
      /**
       * {@inheritdoc}
       */
      public function getIterator(): \Generator {
        foreach ($this->iterator->getIterator() as $data) {
          $metadata = $data->usage ? $data->usage->toArray() : [];
          $streamedChatMessage = new StreamedChatMessage(
            $data->choices[0]->delta->role ?? '',
            $data->choices[0]->delta->content ?? '',
            $metadata
          );
          if (!empty($metadata)) {
            $streamedChatMessage->setInputTokenUsage($metadata['prompt_tokens']);
            $streamedChatMessage->setOutputTokenUsage($metadata['completion_tokens']);
            $streamedChatMessage->setTotalTokenUsage($metadata['total_tokens']);
            $streamedChatMessage->setCachedTokenUsage($metadata['prompt_tokens_details']['cached_tokens']);
            $streamedChatMessage->setReasoningTokenUsage($metadata['completion_tokens_details']['reasoning_tokens']);
          }
          yield $streamedChatMessage;
        }
      }
    
    }
    

    I am a bit stuck on the second and third action point:

    Add so we can collect it in the PostStreamingResponseEvent

    Add so we inject it into the PostStreamingResponseEvent

    I've been looking through the code in the AI module, but can't find where the PostStreamingResponseEvent gets triggered. Well, it gets triggered in \Drupal\ai\OperationType\Chat\StreamedChatMessageIterator::triggerEvent(), but I cannot find where that method is called. Is that supposed to be called by the OpenAI provider for example (because it doesn't currently)? I'm a bit confused as to what the exact code flow should look like...

  2. Only works for nodes, other entity types aren't supported.

    Randal

    I had to open a new branch because the existing one (1.x) created issues for me locally, due to it having the same name as the main module's git branch.

    This attempts to make the functionality as 'global' as possible, by retrieving most stuff dynamically. Please take a look and feel free to test it.

    There is an edge case where this could "not work", which is when the route parameter in `entity.[entity_type].canonical` is not the same as the entity type machine name... But I can't think of a single instance where that would be the case.

  3. Only works for nodes, other entity types aren't supported.

    Randal

    I think this issue is definitely an important one, but the scope still seems too small. I wonder why it should be limited to nodes and taxonomy terms at all, all content entities should be valid here.

    I'll see if I can cough up a solution for that.

  4. [5.0.0-alpha3] Menu items do not get is-active class

    Sven Decabooter

    Problem/Motivation

    The main menu gets rendered as a "ui_suite_daisyui:menu" component, through menu--main.html.twig. However, do to the logic in there, the menu item <a> elements do not automatically get the "is-active" class assigned to them, which does happen in Drupal core themes (probably through the "drupal.active-link" library).

    It would make sense to have the active menu item be visually styled the same as when a menu item is hovered...

    Steps to reproduce

    - Add main menu block to a DaisyUI-powered theme - Navigate to a page within the main menu - Inspect the active menu item - it has no specific class to indicate it is the active item, nor any different visual style applied to it.

    Proposed resolution

    - Make sure the Drupal core "is-active" class gets correctly added to the active menu item - Preferably, apply a different visual style to menu link items that have class "is-active".

  5. [5.0.0-alpha3] Add documentation on how to add new theme/skins to the starterkit

    Sven Decabooter

    It does seem to work if I add it like this in `mytheme/css/themes/fancy.pcss.css`:

    :root:has(input.theme-controller[value=fancy]:checked),[data-theme="fancy"] {
      color-scheme: "light";
      --color-base-100: #FAF7F2;
      ...
    

    As per documentation at https://daisyui.com/docs/themes/#how-to-add-a-new-custom-theme, under "If you're using CDN and you want to use a custom theme, use it like this".

    I would create a MR to add this to the documentation, but I'm not sure if this is the correct way to implement a custom theme...

  6. [5.0.0-alpha3] Add documentation on how to add new theme/skins to the starterkit

    Sven Decabooter

    I was trying to add my own custom theme, and followed the following process:

    - Create a new theme based on the starterkit - as per `starterkits/ui_suite_daisyui_starterkit/README.md` - Run the `npm install` and `npm run build` commands - Add new theme file in `mytheme/css/themes/fancy.pcss.css` with contents like this:

    @plugin "daisyui/theme" {
      name: "fancy";
      default: true;
      prefersdark: false;
      color-scheme: "light";
      --color-base-100: #FAF7F2;
      ...
    }
    

    - Add file `mytheme/mytheme.ui_skins.themes.yml` with contents like this:

    # No value because same as plugin ID.
    fancy:
      label: "Fancy"
      label_context: "color"
      key: "data-theme"
      target: html
    

    - Run the `npm install` and `npm run build` commands again - Go to `/admin/appearance/settings/mytheme` and select the "Fancy" theme from the "Theme" dropdown

    The CSS file for fancy theme is included in the HTML output, and my tag contains `data-theme="fancy". I can't see any of the colors though...

    Is this because I use hex color codes, instead of oklch()? Or anything else in the process I missed?

  7. Conflict with core system/base hidden.module.css

    Sven Decabooter

    Problem/Motivation

    I have an element that needs to be hidden on smaller screens, and shown on larger ones. So I have set it up with the following classes: <div class="hidden lg:block">Show this only on large screens.</div>

    The file `css/components/hidden.module.css` in Drupal core's system/base library also contains a definition for .hidden classes, and seems to take precedence over the DaisyUI / Tailwind logic.

    The result is: my block is not shown on larger screens, even though that is desired.

    Proposed resolution

    Override the hidden.module.css logic, to avoid this behaviour for .hidden classes. Other functionalities provided by this CSS file should remain intact.

  8. Variation cache error when enabling the "domain"-module.

    Randal

    Problem/Motivation

    When enabling the core "Navigation" module and contributed "Domain" module, I seem to run into this error:

    The complete set of cache contexts for a variation cache item must contain all of the initial cache contexts, missing: user.site
    

    I saw in the cache contexts that the exact ones listed in the default value of the container parameter `render.config:required_cache_contexts` were used, but when looking at the NavigationRenderer, they're hardcoded into it. If I replace the hardcoded contexts list on line 133 in the NavigationRenderer:

    $build[$delta]['#cache']['contexts'] = ['user.permissions', 'theme', 'languages:language_interface'];
    

    With this code:

    $renderer_config = \Drupal::getContainer()->getParameter('renderer.config');
    $build[$delta]['#cache']['contexts'] = $renderer_config['required_cache_contexts']
      ?? ['user.permissions', 'theme', 'languages:language_interface'];
    

    Then it seems to work (since I've added `user.list` as a required context in my services file).

    Steps to reproduce

    - Start on an empty Drupal 11 website - Enable the Navigation and Domain modules

    Proposed resolution

    I think, using the container parameter renderer.config:required_cache_contexts instead of the hardcoded list: - user.permissions - theme - languages:language_interface

    Should be fine? Unless I completely misunderstand this functionality.

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.