Drupal Planet
A Drupal Couple: Running for the Drupal Association Board Again Because the Work Isn't Finished
IXP Initiative Co-Creator | Technical Account Manager | Community Contributor
I'm running for the Drupal Association Board again because the work we started isn't finished. When I first nominated myself in 2023, I talked about the need for better regional representation and sustainable talent pipelines. Today, as several major DA initiatives directly address these challenges, we need to ensure they work for everyone - from small regional agencies to large global companies, from new developers to experienced contributors. If you're a member of the Drupal community who values global inclusion and sustainable growth, I'm asking for your support in this important moment of transformation.
The Global Community VisionI have worked for years within the Drupal community in both Latin America and the United States. I helped organize DrupalCon Latin America back in 2015, and honestly, I want to bring more opportunities like that to LATAM and other regions that get overlooked.
But this isn't just about Latin America. It's about recognizing that Drupal's future depends on communities everywhere having pathways to contribute and grow.
We're in a chicken and egg situation across many areas - community growth, code contribution, sustainability, and business development. For Drupal to grow at all levels of the ecosystem pyramid, we need more popularity and adoption. But this requires support from larger agencies. At the same time, the DA needs to develop sustainable revenue beyond just big agencies and DrupalCon North America. The challenge is that we still need those larger players to help create realistic pathways for regional agencies to participate and thrive. Breaking this cycle requires action on multiple fronts at once.
The International Federation initiative offers a way to break through some of these interconnected challenges by creating structures where global communities can actually participate, potentially moving all these areas forward together.
Building Solutions, Not Just Identifying ProblemsThe thing I'm most proud of is co-creating the IXP Initiative. We saw this fundamental problem - new developers couldn't get hired without experience, but couldn't get experience without being hired. So we built something to fix it. Working with other members of the community and the Drupal Association, we turned this idea into a real program. Now we have companies actually participating, offering structured pathways for new developers, and getting 250 contribution credits for each successful engagement.
This proves we can move beyond just talking about problems to building actual solutions that strengthen the entire ecosystem.
Why Regional Perspective Matters NowMy experience working in both Colombia and the United States since moving to the US in 2007 taught me how regional economic differences create both challenges and huge opportunities for Drupal.
At a recent board meeting, I brought up how a $1,000 partnership fee that works in the US becomes impossible in countries where monthly minimum wage is $200-300. These aren't just numbers - they represent talented developers who want to contribute but need different pathways to participation.
The International Federation initiative—a concept currently being explored to potentially give regional Drupal communities more formal representation—creates exactly the framework we need to address this. This structured approach can transform regional participation by providing clear business value to local companies, creating a more accessible path to becoming Drupal Certified partners while strengthening DA revenue.
Why The Timing Is PerfectSeveral major initiatives are reshaping Drupal's global landscape:
1. Drupal CMS: Democratizing Enterprise FunctionalityDrupal CMS now delivers enterprise-grade functionality to smaller markets and diverse budget contexts. With out-of-the-box features that previously required expensive custom development and no CS degree needed, Drupal has become accessible to communities previously excluded from its benefits.
2. International Federation: Creating Global GovernanceThe International Federation initiative is creating formal structures for global governance. With the working group starting in June 2025, we need board members who understand regional economic realities and can help shape this federation to truly serve diverse communities.
3. Marketplace Initiative: Enabling New Business ModelsThe Marketplace initiative is analyzing the feasibility of creating a marketplace for templates and quick site deployment options. I believe having quick ways to spin off a site that makes it 70% ready with Drupal CMS, decent price hosting to start, and templates that bring functionality and design very quickly, opens new paths to new business models. Add IXP to that and you have the affordable workforce to work on lower budget situations.
All these initiatives are interconnected: Drupal CMS makes participation technically possible, the International Federation creates the governance structure, and the Marketplace opens business opportunities. Making them work together is how we'll create a balanced ecosystem that serves both community values and business sustainability.
Balance Between Community and BusinessI understand we need a sustainable Drupal Association that balances community needs with business realities. I recognize the importance of balancing community, open source, and businesses, but the reality is today's Drupal global activities sometimes lack on the business part.
We can do better. When I proposed bringing back DrupalCon Latin America, I suggested adapting the fair-style event model common in our region. Organizations pay for exhibition spots and actively invite end users, creating genuine business opportunities alongside community building.
Another example is how IXP-trained resources could enable agencies to open a Drupal CMS line of business for smaller budget projects. This creates opportunities to serve clients with limited resources - whether they're smaller companies, organizations in developing markets, or even departments within large enterprises looking for internal solutions. This approach simultaneously develops talent, creates business opportunities, and expands Drupal's reach.
I've been writing about ways to help make contribution more economically sustainable, including authentic community contribution approaches and ideas about how Drupal.org could better connect businesses with service providers across different economic regions.
What I'd Focus OnAs a board member, I'd focus on:
- Ensuring the International Federation serves all regions - by making regional economic realities central to governance structures
- Creating opportunities in underrepresented regions - by expanding IXP's successful model to build global talent pipelines
- Generating economic value for regional developers - by supporting DA initiatives like the Marketplace for sustainable growth
- Creating opportunities for the entire global community - by connecting diverse economic contexts to build meaningful bridges
I've spent years contributing to the Drupal community and creating programs that develop new talent. I've written extensively about community-first approaches that create sustainable business value. Now I want to bring that same focus to board-level decision making as these critical initiatives unfold.
The future of Drupal depends on communities everywhere having real pathways to contribute and grow. With the International Federation, Drupal CMS accessibility, and Marketplace opportunities all developing simultaneously, the board needs to ensure these initiatives work together to build a truly global community where everyone (regardless of region or economic context) can participate meaningfully.
If you believe in this vision for a truly global Drupal, please:
- Cast your vote during the election period (June 15-30, 2025)
- Share this nomination with your colleagues who care about global representation
- Reach out to me with questions or ideas at [email protected]
Together, we can build a Drupal ecosystem that works for everyone, everywhere.
– Carlos
Subject of IXP Graduates from Initiative to Program: Companies Can Start Using It Now! Beyond Makers and Takers: Being a Faker in Open Source About IXP Graduates from Initiative to Program: Companies Can Start Using It Now! Beyond Makers and Takers: Being a Faker in Open Source Rethinking Custom Modules: How ECA Blew My Mind Building the Bridge: How Drupal CMS and IXP Could Empower Digital Agencies Simplifying Drupal Updates: A Structured Approach to Worry-Free Maintenance Author Carlos Ospina Abstract oard nomination statement presenting Carlos Ospina's vision for global Drupal community representation, highlighting experience with International Federation development, cross-cultural business expertise, and sustainable talent pipeline creation through the IXP Initiative. Advocates for balanced community-business sustainability. Tags drupal-association-board global-representation international-federation ixp-initiative community-development drupal-leadership latin-america-drupal sustainable-growth Drupal Planet Rating Select ratingGive Running for the Drupal Association Board Again Because the Work Isn't Finished 1/5Give Running for the Drupal Association Board Again Because the Work Isn't Finished 2/5Give Running for the Drupal Association Board Again Because the Work Isn't Finished 3/5Give Running for the Drupal Association Board Again Because the Work Isn't Finished 4/5Give Running for the Drupal Association Board Again Because the Work Isn't Finished 5/5Cancel rating Average: 5 (1 vote) Leave this field blank Add new commentjofitz: Drupal AI: first steps
Artificial Intelligence has arrived in the Drupal ecosystem and it is already making huge waves. This is the first in a series of articles about my experiences as I dip a toe into these exciting waters.
The taskI was working on a large website with plenty of content dating back years, including numerous product reviews that required improved categorisation. The goal was to tag all of these review nodes with the relevant Make and Model.
The approachI chose to write a custom Drush script to loop through all of the review nodes, using Artificial Intelligence to parse the Title and Body fields and return the make and model discussed therein.
public function reviewsMakeModel(): void { $fields = ['title', 'body']; foreach ($review_nodes as $review_node) { $data = []; foreach ($fields as $field) { $data[] = $review_node->get($field)->value; } $text = implode("\n", $data); $makeAndModel = $this->getMakeAndModel($text); // More to follow... } }The providerI...
Read moreFour Kitchens: Creating depth and motion: A step-by-step guide to parallax
Frontend Engineer
Mari is a high-achieving Drupal frontend developer who has shown great proficiency in tackling complex frontend problems.
January 1, 1970
Crafting a visually engaging website isn’t just about eye-catching colors and typography — today it’s also about creating immersive experiences that captivate users as they scroll. One of the most compelling ways to achieve this is by using a parallax effect, where elements move at different speeds to create a sense of depth and motion.
With a thoughtful approach and some JavaScript, you can seamlessly add this effect to your site, enhancing storytelling and making your pages more dynamic.
This post will guide you through the process of integrating a custom parallax effect into your site. Whether building a feature-rich landing page or enhancing storytelling elements, this technique can bring your site to life. Let’s begin.
Building our componentOur example site was built in Drupal, but the overall concept would be the same in any CMS. First, we will need to build a component that has all the necessary fields that we want to display in our parallax. In this example, we will use Paragraph types and have two kinds of slides: one with an image and another without an image.
Parallax image slideThis slide will let us add an image, a title, and the caption or information we want to tell about that specific slide, the alignment of the information (left, center, or right), and an option if we want to hide the credit of the image or show it.
Parallax blank slide
This slide is similar to the previous one, but there are key differences. This one won’t include an image and anything else related to the image, and we allow a lot more text formatting on blank slides. This means that we can have the text on a blank slide take up much more of the available space without worrying about color contrast issues with advanced text formatting.
Once both paragraphs have been created, let’s create a ‘Parallax Slideshow’ paragraph that will only have a field that references the previous paragraphs created.
Connecting our component to the custom themeOnce our component is ready, the next step is to integrate it into our custom theme. In this example, we’re using Emulsify, our design system, as our custom theme, to ensure a consistent and modular approach to theming.
First, we will have our paragraph--parallax-slideshow.html.twig that will include a parallax-slideshow.twig, which has a JavaScript library called parallax-slideshow that is in charge of all logic to make our parallax effect work, and also some required styles.
{{ attach_library('your_theme/parallax-slideshow') }} {% set drupal = true %} {% include "@organisms/parallax-slideshow/parallax-slideshow.twig" with { 'slideshow_id': paragraph.id.0.value, 'slides': content.field_slide_items|render } %}Here’s what our parallax-slideshow.twig looks like. Notice the empty <div class=””parallax-slideshow__image-wrapper””></div>. This is where the slide images will be rendered and where the fade-in and fade-out effects between images will occur.
{% set classes = [ paragraph.bundle|clean_class, "parallax-slideshow", ] %} <div{{ attributes.addClass(classes) }} data-id="{{ slideshow_id }}"> <div class="parallax-slideshow__wrapper"> <div class="parallax-slideshow__image-wrapper"></div> {{ slides }} </div> </div>Then, we will have a paragraph--parallax-image-slide.html.twig and a paragraph--parallax-blank-slide.html.twig. Both files include a parallax-slide.twig, which is a molecule in the design system that organizes the content of each slide and adds all the needed styles. They are almost identical — the only difference being that the blank-slide will not pass the slide image to the parallax-slide.twig file.
{% include "@molecules/parallax-slide/parallax-slide.twig" with { 'slide_id': paragraph.id.0.value, 'slide_img': content.field_image|render, 'slide_title': paragraph.field_component_title.0.value, 'slide_caption': content.field_caption|render, 'slide_caption_alignment': paragraph.field_caption_alignment.0.value, 'slide_hide_credit': paragraph.field_hide_credit.0.value, 'slide_type': paragraph.type.0.value.target_id, } %}Here’s what our parallax-slide.twig looks like:
{% set classes = [ 'parallax-slide', slide_caption_alignment ? 'parallax-slide--caption-' ~ slide_caption_alignment|lower : '', slide_type ? 'parallax-slide--' ~ slide_type|replace({'_': '-'}) : '', ] %} <div {{ attributes.addClass(classes) }} slide-data-id="{{ slide_id }}"> <div class="parallax-slide__info-wrapper"> <div class="parallax-slide__info-inner-wrapper full-width"> {% if slide_title %} <div class="parallax-slide__title-wrapper"> <h1 class="parallax-slide__title">{{ slide_title }}</h1> </div> {% endif %} {% if slide_caption %} <div class="parallax-slide__caption">{{ slide_caption }}</div> {% endif %} </div> </div> </div> Preloading parallax slideshow dataTo prevent a visible delay between slides, the component needs to preload the first two images on page load. As the user begins scrolling, additional images are loaded dynamically in the background. This ensures a seamless transition between slides without noticeable lag and enhances the overall user experience.
We need to pass structured data from the backend to JavaScript. Below is a function that loads the data and attaches it to drupalSettings for use in a theme.
function your_theme_preprocess_paragraph_parallax_slideshow(&$variables) { $paragraph = $variables['paragraph']; $pid = $paragraph->id(); $lazy_load_data[$pid] = []; if ($paragraph->hasField('field_slide_items')) { $slide_items_ref = $paragraph->get('field_slide_items'); $slide_items = $slide_items_ref->referencedEntities(); foreach ($slide_items as $slide_id => $slide) { // Initial setup of array. $lazy_load_data[$pid][$slide_id] = [ 'id' => NULL, 'image' => NULL, ]; // ID. if ($slide->hasField('id') && !$slide->get('id')->isEmpty()) { $lazy_load_data[$pid][$slide_id]['id'] = $slide->get('id')->first()->getValue(); } // Responsive image markup. if ($slide->hasField('field_image') && !$slide->get('field_image')->isEmpty()) { $lazy_load_data[$pid][$slide_id]['image'] = _your_theme_get_rendered_slide_image($slide); } } } // Attach to JS JSON object to read in theme. $variables['#attached']['drupalSettings']['yourTheme']['parallaxSlideshowData'] = $lazy_load_data; $variables['#attached']['library'][] = 'your_theme/parallax-slideshow'; } function your_theme_get_rendered_slide_image($slide) { if ($slide->hasField('field_image') && !$slide->get('field_image')->isEmpty()) { $image_view = $slide->field_image->view('default'); $rendered_image = \Drupal::service('renderer')->render($image_view); return $rendered_image; } return NULL; }Once the data is attached to drupalSettings in our JavaScript file, we can access parallaxSlideshowData to dynamically load images and control the parallax effect.
JavaScript implementation of the parallax slideshowBelow is a breakdown of how the JavaScript file works to bring the parallax slideshow to life.
Drupal.behaviors.parallaxSlideshow = { attach: function (context) { const parallaxSlideshowData = drupalSettings.yourTheme.parallaxSlideshowData; if (!parallaxSlideshowData) return; const slideshows = once('parallax-slideshow', '.parallax-slideshow', context); slideshows.forEach((slideshow) => { const loadedSlideIds = new Set(); const loadedImages = new Set(); initializeParallaxSlideshow(slideshow, parallaxSlideshowData, loadedSlideIds, loadedImages); }); }, };Let’s start by retrieving the slideshow data from drupalSettings and ensuring the script only runs once per slideshow element. The function initializeParallaxSlideshow is responsible for setting up and managing the parallax slideshow experience by initializing each slideshow. By tracking which slides have been loaded, we prevent redundant loading:
const slideshowDataID = slideshow.getAttribute('data-id'); const slideshowData = parallaxSlideshowData[slideshowDataID]; if (!slideshowData) return;Then, it calls a preloadSlides function, which likely preloads images or other resources for the first two slides to prevent a visible delay between slides.
function preloadSlides(slideshowData, slideshow, loadedSlideIds, loadedImages){ slideshowData.slice(0, 2).forEach((slideData, index) => { // Check if the slide has already been added if (loadedSlideIds.has(slideData.id)) return; // Mark the slide as loaded loadedSlideIds.add(slideData.id); if (slideData.image !== null) { createImageDiv(slideData.id, slideData.image, slideshow, loadedImages, index === 0); } }); }Next, it calls a createImageDiv helper function that is responsible for creating and managing an image element within the parallax slideshow.
function createImageDiv(slideID, slideImage, slideshow, loadedImages, firstImage = false) { const imgDiv = document.createElement('div'); imgDiv.className = 'parallax-slideshow__image'; imgDiv.innerHTML = slideImage; if (firstImage) { const image = imgDiv.querySelector('img'); image.addEventListener('load', () => { const slideshowOverlay = slideshow.querySelector( '.parallax-slideshow__overlay', ); const slideshowWrapper = slideshow.querySelector( '.parallax-slideshow__wrapper', ); if (slideshowOverlay) { slideshowOverlay.classList.add('fade-out'); setTimeout(() => { document.body.style.overflow = ''; slideshowWrapper.removeChild(slideshowOverlay); }, 1000); } }); } // Add a custom attribute for the slide ID imgDiv.setAttribute('data-slide-image-id', slideID); loadedImages.add({ id: slideID, image: imgDiv, }); }The reason why we check if there is a firstImage is that we want the initial slide to fade in from black when it’s fully loaded. Once the image loads, it finds the overlay and the slideshow wrapper, fades out the overlay, removes the overlay, and re-enables scrolling.
Let’s go back to the initializeParallaxSlideshow. After the preloadSlides function there’s a scroll event listener for the parallax effect that listens for scroll events to update the slideshow’s image position dynamically.
The idea is to let the image wrapper take the whole height of the viewport, but since there can be components before or after the parallax slideshow, at some point it is necessary to change the position of the image wrapper, to let the user scroll and interact with other components.
window.addEventListener('scroll', () => { const windowHeight = window.innerHeight; const top = slideshow.getBoundingClientRect().top; const bottom = slideshow.getBoundingClientRect().bottom; const slideshowImageWrapper = slideshow.querySelector( '.parallax-slideshow__image-wrapper', ); if (top < 0 && bottom > windowHeight) { slideshowImageWrapper.style.position = 'fixed'; slideshowImageWrapper.style.top = 0; } else { slideshowImageWrapper.style.position = 'absolute'; if (windowHeight > bottom) { slideshowImageWrapper.style.top = 'unset'; slideshowImageWrapper.style.bottom = 0; } if (windowHeight < top) { slideshowImageWrapper.style.top = 0; slideshowImageWrapper.style.bottom = 'unset'; } } });The following logic is to set a scroll hijacking if the parallax slideshow is the first component of the page and if the first slide is an image.
// Check if slideshow is within a parent of .content-top const isContentTopParent = slideshow.closest('.content-top') !== null; // Get the first slide and check if it has the class `parallax-slide--parallax-image-slide` const firstSlide = slideshow.querySelector('.parallax-slide'); const isFirstSlideParallaxImageSlide = firstSlide && firstSlide.classList.contains('parallax-slide--parallax-image-slide'); // Lock scroll if .content-top is present and the first slide is of type image if (isContentTopParent && isFirstSlideParallaxImageSlide) { const overlay = document.createElement('div'); overlay.className = 'parallax-slideshow__overlay'; slideshow .querySelector('.parallax-slideshow__wrapper') .appendChild(overlay); document.body.style.overflow = 'hidden'; }Then, there’s a piece of code that iterates through all slides in the slideshow and calls the initializeSlideObserver() function on each slide.
const slides = slideshow.querySelectorAll('.parallax-slide'); slides.forEach((slide, index) => { const infoInnerWrapper = slide.querySelector( '.parallax-slide__info-inner-wrapper', ); initializeSlideObserver(slideshow, infoInnerWrapper, slide, slideshowData, loadedSlideIds, loadedImages); // Add classes if first image is an slide if (index === 0) { slide.classList.add('initial-slide'); if (isFirstSlideParallaxImageSlide) { slide.classList.add('initial-slide-image'); } } });Now let’s take a look at the initializeSlideObserver() function — the one that is responsible for setting up an Intersection Observer to track when a slide enters the viewport and dynamically updates the slideshow’s displayed image accordingly. It ensures that the slideshow loads the next image only when needed, preventing unnecessary rendering and improving performance.
// Initialize Intersection Observer for Slides function initializeSlideObserver(slideshow, infoInnerWrapper, slide, slideshowData, loadedSlideIds, loadedImages) { // Watches when infoInnerWrapper enters or exits the viewport, // and triggers a callback whenever visibility changes const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { const slideshowWrapper = slideshow.querySelector( '.parallax-slideshow__wrapper', ); const slideshowImageWrapper = slideshowWrapper.querySelector( '.parallax-slideshow__image-wrapper', ); const slideID = slide.getAttribute('slide-data-id'); const slideImage = Array.from(loadedImages).find( (loadedImage) => loadedImage.id === slideID, ); const { isIntersecting } = entry; // Checks if the slide currently intersects the root if (isIntersecting) { const parent = slide.parentNode; const slides = Array.from( parent.querySelectorAll('.parallax-slide'), ); const index = slides.indexOf(slide); if (index !== 0) { // If not first slide, call the function to preload the next slide in advance. loadNextSlide(slideshowData, index, loadedSlideIds, loadedImages); } // Check if there is an existing image const previousImage = slideshowImageWrapper.querySelector( '.parallax-slideshow__image', ); if (slideImage) { slideImage.image.classList.add('fade-in'); slideshowImageWrapper.appendChild(slideImage.image); // If an existing image is found, remove fade-in class and remove it after a delay if (previousImage) { const previosImageID = previousImage.getAttribute( 'data-slide-image-id', ); if (previosImageID !== slideID) { setTimeout(() => { previousImage.classList.add('fade-out'); // Add fade-out class previousImage.classList.remove('fade-in'); // Remove fade-in class previousImage.classList.remove('fade-out'); // Remove fade-out class slideshowImageWrapper.removeChild(previousImage); }, 500); } } } else { if (previousImage) { const previosImageID = previousImage.getAttribute( 'data-slide-image-id', ); if (previosImageID !== slideID) { previousImage.classList.add('fade-out'); // Add fade-out class setTimeout(() => { previousImage.classList.remove('fade-out'); slideshowImageWrapper.removeChild(previousImage); }, 500); } } } } }); }, { // The callback triggers when at least 5% of infoInnerWrapper is visible. threshold: 0.05, }, ); observer.observe(infoInnerWrapper); }Last but not least, there’s the loadNextSlide function that is responsible for preloading the next slide’s image to ensure a smooth transition when the user scrolls. This prevents unnecessary reloading of already loaded images. This function is very similar to the preloadSlides function.
function loadNextSlide(slideshowData, currentIndex, loadedSlideIds, loadedImages) { if (currentIndex + 1 < slideshowData.length) { const nextSlideData = slideshowData[currentIndex + 1]; // Check if the slide has already been added if (loadedSlideIds.has(nextSlideData.id)) return; // Mark the slide as loaded loadedSlideIds.add(nextSlideData.id); if (nextSlideData.image !== null) { createImageDiv(nextSlideData.id, nextSlideData.image, null, loadedImages); } } }With these functions in place — handling image creation, slide observation, and preloading — you now have a dynamic and efficient parallax slideshow that seamlessly transitions between images as users scroll. By leveraging the Intersection Observer API, preloading logic, and smooth fade effects, the slideshow ensures a visually engaging experience without unnecessary performance overhead.
Once you’ve added the necessary styles to control positioning, animations, and transitions, your parallax slideshow should be fully functional across your site. This approach not only enhances the storytelling aspect of your content, but also keeps interactions smooth and lightweight.
Now, all that’s left is to fine-tune the visuals to match your design, and you’re set to create an immersive scrolling experience!
The post Creating depth and motion: A step-by-step guide to parallax appeared first on Four Kitchens.
The Drop Times: From Drupal Core to Static Site Innovation: Samuel Mortenson on Tome, SFC, and Open Source Legacy
mark.ie: My LocalGov Drupal contributions for May 2025
Great month, lots done, including a new module for Drupal.org - modules_list.
DDEV Blog: Using DDEV to spin up a legacy PHP application
This guest post is by DDEV community member and TYPO3 contributor Garvin Hicking.
In my daily work, I develop TYPO3-based projects and also contribute to the TYPO3 CMS OpenSource project itself.
Usually this means working with actively supported and up-to-date PHP versions as well as database systems like MySQL/PostgreSQL/MariaDB.
Just recently I had to migrate a very outdated project: TYPO3 4.5, which utilized MySQL 5.5 and PHP 5.3. When that project was initially developed, it was done with XAMPP and later Vagrant-based VMs. This has been long superseded with using Docker and specifically DDEV for ease-of-use.
So naturally I wanted to be able to use DDEV for the legacy project to get it working just as it is running on the (outdated) hosting provider's shared web servers.
I quickly faced three major issues:
- No PHP 5.3 out-of-the-box support from DDEV; it starts with 5.6 as of the time of this writing
- No MySQL 5.5 ARM64 support either; it starts with 5.7
- Additionally, I use an Apple MacBook Pro M1 with ARM-chipset, which has no "official" MySQL 5.5 support
Thanks to the outstanding DDEV support on Discord, I was quickly able to find a way with minimal effort, just by creating very small custom, additional docker-compose YAML files.
One advantage (of many) of using DDEV instead the underlying Docker Compose is that so many things are pre-configured and "just work". So I really did not want to migrate everything to Docker Compose on my own, do my custom routing, PHP-FPM integration and whatnot.
Just being able to "bait and switch" the PHP and DB container with a different base Docker image was all that was needed for me:
Step 1: Base configI created the base ~/legacyphp/.ddev/config.yaml file manually inside my ~/legacyphp project directory, setting legacyphp as the project name.
Note that I configured PHP and MySQL versions that are supported by DDEV for this first:
name: legacyphp type: php docroot: htdocs php_version: "8.3" webserver_type: apache-fpm database: type: mysql version: "8.0" Step 2: Rewire DBNext I created the very small file ~/legacyphp/.ddev/docker-compose.db.yaml in the same directory next to config.yaml:
services: db: platform: linux/amd64 build: args: BASE_IMAGE: ddev/ddev-dbserver-mysql-5.5:v1.24.6 entrypoint: - sh - -c - | cp /docker-entrypoint.sh ~/docker-entrypoint.sh sed -i '157s|.*|if false; then|' ~/docker-entrypoint.sh sed -i '175s|.*|echo mysql_8.0 >/var/lib/mysql/db_mariadb_version.txt|' ~/docker-entrypoint.sh exec ~/docker-entrypoint.shThree things are noteworthy:
- Setting linux/amd64 as the platform will require Rosetta to be available on the macOS ARM64 platform
- The BASE_IMAGE is set to a DDEV db container of legacy Docker images that are still provided.
- Changing the entrypoint is a workaround to prevent DDEV complaining about a mismatching MySQL version after restarting the project. The small script "tricks" the DDEV inspection into believing, the version matches the one configured in .ddev/config.yaml.
Using a different PHP version is just a few lines more work, because we are not replacing the whole web container of DDEV. Instead, we add an additional PHP container which is executed from the web container via port 9000.
This is done via the file ~/legacyphp/.ddev/docker-compose.php.yaml:
services: php: container_name: ddev-${DDEV_SITENAME}-php image: devilbox/php-fpm:5.3-work restart: "no" expose: - 9000 labels: com.ddev.site-name: ${DDEV_SITENAME} com.ddev.approot: ${DDEV_APPROOT} working_dir: /var/www/html volumes: - "../:/var/www/html" - ".:/mnt/ddev_config:ro" - ddev-global-cache:/mnt/ddev-global-cache - "./php:/etc/php-custom.d" environment: - NEW_UID=${DDEV_UID} - NEW_GID=${DDEV_GID} - DDEV_PHP_VERSION - IS_DDEV_PROJECT=true web: depends_on: - phpNote here that we use devilbox/php-fpm with our needed version, and a bind-mount takes care the PHP container can access our main project root directory.
A special mount of ~/legacyphp/.ddev/php/ is included so that we can control the php.ini configuration, if needed. For example you could disable the OPCache+APC in case you're doing some legacy benchmarking that should not be falsified via caching, I created a very small file ~/legacyphp/.ddev/php/php.ini file with the contents:
# This is an example. # apc.enabled=Off # opcache.enable=Off Step 4: Utilize the PHP container with an Apache proxyTo execute PHP with our external PHP Docker image, I created the following file in ~/legacyphp/.ddev/apache/apache-site.conf:
<VirtualHost *:80> RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} =https RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last] SetEnvIf X-Forwarded-Proto "https" HTTPS=on Alias "/phpstatus" "/var/www/phpstatus.php" DocumentRoot /var/www/html/htdocs <Directory "/var/www/html/htdocs"> AllowOverride All Allow from All </Directory> CustomLog /var/log/apache2/access.log combined ProxyFCGIBackendType GENERIC ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/htdocs/$1 DirectoryIndex /index.php index.php </VirtualHost>Note that if your document root is not htdocs you would need to adapt this name to your liking (like public or wwwroot or anything) in all occurrences of this file.
Step 5: Lift-OffNow you can execute ddev start and then ddev launch to see your project up and running.
You could create a simple ~/legacyphp/htdocs/index.php file with <?php phpinfo(); ?> to verify the version.
Using ddev mysql will connect you to the MySQL 5.5 instance:
~/legacyphp> ddev mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.5.62-log MySQL Community Server (GPL) CaveatsYou can enter the PHP Docker container with a command like docker exec -it -u devilbox ddev-legacyphp-php bash if you need/want to execute PHP commands on shell-level, because the regular web container will run with the more recent PHP 8.3 version. So if you need to perform composer CLI calls, be sure to do this within the matching PHP container.
Another thing to pay attention to is that if you for example want to utilize Mailpit with TYPO3's mail configuration, you can not use localhost:1025 as an SMTP server. localhost in PHP's case will be that devilbox PHP container, and not the DDEV web container. Instead you need to setup web:1025 as the hostname.
The devilbox PHP config has pretty much all available PHP extensions set up to use, but if you need specific imagemagick or other tools, you will have to either ensure these are executed on the web container, or make them available with customization of a different base Docker container that you can build yourself.
If you want to use Xdebug with this setup, you'll need to do more internal port forwarding in the docker-compose setup, which is beyond the scope of this article.
Closing wordsHaving shown you what is possible, I hope you will never need to use it, and you will always use well-supported and current software. :-)
Thanks so much to the DDEV project for getting me across the finish line with just very little effort!
Gábor Hojtsy: I built a thing for api.drupal.org and you can too!
Did you search for Drupal API documentation in the past and ended up on outdated information on api.drupal.org? I heard this story from many people before and it also happens to AI bots. This is a problem the Drupal Association wanted to fix for a while but did not get around to it with all the priorities.
Acquia held an internal hackathon called 48Create on 15-16 May, 2025. I joined the team formed by Ben Mullins around Drupal documentation and I decided to take on this problem.
Gábor Hojtsy Thu, 05/29/2025 - 19:42The Drop Times: Dropmin: What Is It and Why Does It Exist?
Talking Drupal: TD Cafe #003 - Mike Anello & Mile Herchel
In this episode, Mike Anello and Mike Herchel dive into a casual conversation covering a wide array of topics. They start by discussing the concept of a podcast with almost no effort required and the mystery of Stephen's involvement. The conversation then quickly shifts to Florida Drupal Camp, mentioning its impressive 16 uninterrupted years, the increase in attendees, and how fun it is. They touch upon single directory components in Drupal, their importance, and intricacies like CSS styling, schemas, and Experience Builder. The discussion also includes insights into popular Drupal events like Florida Drupal Camp, Drupal Dev Days, and the upcoming DrupalCon. They infuse humor and personal anecdotes while engaging in thoughtful technical exchanges and playful banter.
For show notes visit: https://www.talkingDrupal.com/cafe003
Topics Michael AnelloMike, widely recognized by his Drupal.org username "ultimike," is a prominent figure in the Drupal community with over 15 years of experience as a developer, educator, and community leader. As the co-founder and vice president of DrupalEasy, a Florida-based training and consulting firm, he has been instrumental in shaping the careers of countless Drupal professionals through comprehensive programs like Drupal Career Online and Professional Module Development .(drupalcampnj.org, nedcamp.org) Anello's contributions extend beyond education. He has been deeply involved in the Drupal ecosystem, serving as a core contributor to the Migrate module, co-maintaining several contributed modules, and actively participating in issue queues and documentation efforts . His leadership roles include membership in the Drupal Community Working Group and the Conflict Resolution Team, as well as organizing the Florida Drupal Users' Group and Florida DrupalCamp for over a decade .(The Drop Times, nedcamp.org) As the host of the long-running DrupalEasy Podcast, Anello provides insights into Drupal development, community news, and interviews with key contributors, fostering a sense of connection and ongoing learning within the community (DrupalEasy). His dedication to mentoring and community building has made him a respected and influential voice in the Drupal world.
Mike HerchelMike is a seasoned front-end developer and a prominent contributor to the Drupal community, with over 15 years of experience in web development. He is best known as the lead developer of Olivero, Drupal's default front-end theme, which emphasizes accessibility, modern design, and user experience. (ImageX) In addition to his work on Olivero, Mike serves as a core CSS maintainer for Drupal and is the creator of the Quicklink module, which enhances site performance by preloading links in the user's viewport. He also has amazing calves. They're the size of small children. Rumor has it that his vertical jump is over 4.5 inches! He has also contributed to the introduction of Single Directory Components (SDC) into Drupal core, aiming to streamline component-based theming. (The Drop Times, herchel.com) Beyond his technical contributions, Mike is an active community leader. He has served on the Drupal Association Board of Directors and is a primary organizer of Florida DrupalCamp. (Drupal) As a speaker, he has presented at various events, including EvolveDrupal, discussing topics like the future of Drupal theming and the Starshot initiative, which seeks to make Drupal more accessible to site builders. (evolvedrupal.com) Professionally, Mike works as a Senior Front-End Developer at Agileana, where he continues to advocate for accessibility, performance, and the open web. (evolvedrupal.com) He shares his insights and experiences through his personal blog at herchel.com, contributing to the ongoing evolution of Drupal and its community.
Discussion Topics:
- The Best Podcast Idea Ever
- Florida Drupal Camp: A Legacy of Success
- Single Directory Components: Getting Started
- TD Cafe: The Podcast Name Debate
- Deep Dive into Single Directory Components
- Experience Builder and Component Integration
- Custom Themes and Single Directory Components
- Design Tool Integration
- CSS Variables and Component Architecture
- Template File vs Render Array
- CSS Preferences: Plain CSS vs Post CSS
- Top Drupal Events
- Concluding Remarks and Personal Plans
Mike Anello - DupalEasy ultimike
Mike Herchel - herchel.com mherchel
Nextide Blog: Supercharge your Jira workflows with Maestro AI
Jira is an incredibly popular project management and issue tracking tool and is very flexible and adaptable to project workflows and can be further enhanced with the extensive application ecosystem that surrounds the product. In a recent project, we used Maestro AI to supercharge a Jira workflow to offload external participant feedback loops to Maestro and let Maestro AI determine which feedback loop to use.
amazee.io: Drupaljam 2025: Big Ideas, Bold Tech, and the Power of Community
Drupal Starshot blog: Marketplace Share Out #5: Turning Insight into Structure
After weeks of listening, prompting, and pattern-spotting, we’re entering a new phase. The big questions are becoming sharper. The conversation is shifting—from what might be to what must be true.
Our early exploration surfaced a wide range of motivations, risks, and hopes for a Drupal Site Template Marketplace. The signal was clear: there’s strong belief in the potential—if we build it in a way that strengthens the ecosystem, not fragments it.
As part of this shift from the breadth of exploration and to the depth of early structure, we’re moving to a biweekly share out cadence. This Share Out #5 update highlights what’s emerging from Slack Prompts #5 and #6, insights from Survey #3 on Governance and Fairness to inform first drafts of the Lean Business Model Canvas and Governance Framework—early scaffolding for what’s to come.
From Divergence to ConvergenceIn design thinking, there’s a natural rhythm between divergence—where we explore widely—and convergence—where we begin to shape and prioritize. We’re now entering that second phase.
The goal is not to lock down answers prematurely, but to begin assembling the scaffolding that can support real-world testing, feedback, and evolution.
We’re asking:
- What makes a template worth trusting?
- What makes one worth paying for?
- What kinds of governance and community signals need to be in place from day one?
In response to Slack Prompt #5, contributors agreed that establishing baseline quality, accessibility, and transparency standards is essential.
Automation was broadly supported—but not blindly. There’s growing recognition that automated checks are necessary but not sufficient, especially for more nuanced requirements like semantic markup or keyboard navigation.
Most scanners will find 200 security bugs in Drupal and maybe 1 is real. Human review is still required.”
“Let’s at least show the automated results transparently and let buyers decide.”
Contributors are also thinking ahead about user expectations:
Paid listings should absolutely meet higher standards—users will expect it.”
These insights inform the governance framework’s approach to certifications, self-attestations, and recurring review cycles for paid listings.
What Makes a Template Worth Paying For?Slack Prompt #6 helped unpack the value exchange at the heart of the Marketplace. Why would someone purchase a GPL-licensed template?
The answer: time savings, trust in the “official” source, and ease of setup.
The confidence that comes from knowing the template came from an official, trusted source like the DA is huge."
"One-click demos for themes... that’s my #1 trust signal.”
Participants also cautioned that separating the template from hosting or support could confuse non-technical buyers, especially those coming from SaaS ecosystems.
“Too many hosting choices at signup may mirror Mastodon’s ‘pick a server’ confusion.”
This feedback is pushing us to consider default hosting pathways, bundled services, and better “first-use” experiences.
Fairness, Recognition, and GovernanceOur third community survey zeroed in on values: fairness, recognition, and trust.
Contributors emphasized the importance of clear expectations and governance guardrails—especially when money enters the picture.
“Revenue must also support the ecosystem—modules, infrastructure, DA.”
Many participants supported the idea of tiered models, where certified templates provide extra confidence:
“Even free templates should meet basic accessibility and security requirements if they’re hosted on Drupal.org.”
Recognition also matters:
“Templates should be rated based on feedback… great to know why someone considers a product to be 1 or 3 stars.”
That insight is helping shape how we design review systems that are credible, transparent, and helpful—without opening the door to spam or bias.
Early Structures Taking ShapeInformed by three surveys, one RTC session, and six slack discussions worth of community research combined with competitive research and discussions with Drupal’s intellectual property attorney, the Marketplace Working Group is now in active development on two core artifacts:
-
Lean Business Model Canvas
Mapping how the Marketplace creates, delivers, and shares value—across contributors, agencies, end users, and the Drupal Association. -
Governance Framework (Draft)
Outlining submission criteria, listing types, maintenance expectations, enforcement paths, and contributor recognition.
This scaffolding is not final—it’s a living structure meant to evolve through our continuing research, feedback and community review. Nonetheless, it does feel exciting to see it all start to take shape!
What’s Ahead-
Pilot Planning: Testing incentive and governance structures in collaboration with DCP and other agency participants in RTC #2 and beyond.
-
Governance Draft: A public request for comment (RFC) on the governance framework will launch this summer.
-
MVP Quality Standards: Defining a small, automatable set of checks for accessibility, security, and licensing for free templates.
💬 Join #drupal-cms-marketplace on Slack
Each week, there's a new prompt to explore a key question as we define this Marketplace.
🎧 Listen to Talking Drupal #504
On this week's podcast, we discussed the vision, opportunities, and challenges of creating a trusted, high-quality Drupal Site Template Marketplace that supports adoption, contributor incentives, and community values without compromising open-source principles.
Thanks to all who are continuing to shape this work with insights, critiques, and care. What we build next will depend on the strength of the scaffolding—and the people who show up to co-create it.
The Drop Times: Marcus Johansson's Return to Drupal with AI at Core
The Drop is Always Moving: UX as a first class citizen in Drupal core! Announcing new UX Manager role for Drupal core and Cristina Chumillas and Emma Horrell as first UX Managers: https://www.drupal.org/about/core/blog/ux-as-a-first-class-citizen-in…
UX as a first class citizen in Drupal core! Announcing new UX Manager role for Drupal core and Cristina Chumillas and Emma Horrell as first UX Managers: https://www.drupal.org/about/core/blog/ux-as-a-first-class-citizen-in-drupal-core
Drupal Core News: UX as a first class citizen in Drupal core
We’re excited to announce a big step forward for user experience in Drupal Core: the creation of the new UX Manager role within the core leads team. This is a foundational move toward UX-driven development, where user experience is embedded from the start, not added at the end.
Historically, UX responsibilities in Drupal Core were shared across different roles, often falling under product management. But in practice, UX input has often arrived late, focusing on small usability tweaks rather than shaping the overall experience.
By creating a dedicated UX Manager role, we’re making sure UX has a clear voice — from early feature discussions to final design decisions. This will help us build more intuitive, cohesive, and accessible experiences for everyone using Drupal. We’re also laying the groundwork for the future: supporting more UX practitioners to contribute to Drupal and from there, grow into decision-making roles, strengthening our design contributor community, establishing a stable UX testing process, and making onboarding easier for designers and researchers.
For now, this role will be co-led by Emma Horrell and myself, Cristina Chumillas.
Emma is the UX Research Lead for Drupal CMS and has shaped many aspects of the project through her work researching target audiences, testing features, and helping reduce “Drupalisms.” Her research expertise will continue to help us align Drupal with real user needs. Many thanks to the University of Edinburgh for supporting her continued contributions.
I’ve been the usability topic maintainer for years and currently serve as Product Design Lead for Drupal CMS and Drupal core Front-end Framework Manager. I’m looking forward to helping embed UX more deeply into how Drupal Core is defined, designed, and built.
This is just the beginning. If you’re interested in improving Drupal’s experience, join us in the #ux-working-group on Drupal Slack — and help us put UX at the heart of Drupal’s future.
The Drop Times: Looking Beyond the Horizon at DrupalJam 2025
DrupalEasy: Drupal Back-to-Basics - looking for a leader
In early April, 2025, I was a guest on the Talking Drupal podcast discussing Back-to-Basics, an idea I had to get more beginner-level presentations at Drupal events as a way to better support (and retain) our newer community members. As I am currently a bit overcommitted, this, regretfully, is not something that I have the bandwidth to lead.
I do feel that the idea, and getting it up and running as soon as possible, is a good one that can contribute greatly as one solution to the declining pool of Drupal developers that will sustain us into the future. So, here is my call: I am looking for someone inspired by the growing need to attract and retain Drupal newbies who is interested in taking the lead with the idea, adding their flair, and moving it forward.
As an incentive, know that I've talked with plenty of people who are willing to help, including the folks from the Drupal Open Curriculum Community Initiative. In addition, I'm more than willing to provide assistance, make introductions, and help where I am able to ensure success.
GenesisThe idea for Back-to-Basics came from one of our Drupal Career Online alum during our weekly office hours. It was shortly after Florida DrupalCamp 2025 that the alum asked me if "there were any good Views-related sessions" from the event that they could watch. The answer was "no," unfortunately, and over the next few days this bugged me more-and-more. How are we expected to grow the community with new developers and contributors if our events offer little-to-nothing for them?
GoalThe goal of Back-to-Basics is to make it easy for Drupal event organizers to include solid beginner content for their new-to-Drupal attendees. The strategy makes available 6-8 Drupal pre-prepped event presentations that can be delivered by a vetted pool of experienced Drupal presenters. The presentations will be readily available to any Drupal event organizers along with the names of willing presenters.
A sustainable solutionAs a developer of curriculum, I know how challenging and time-consuming it can be to not only develop, but also (and, perhaps, more importantly) maintain training materials. Creating, maintaining and then donating 6-8 45-minute Drupal event presentations is a big ask. However, It also occurred to me that finding 6-8 Drupal trainers and organizations who would be willing to create and/or donate and maintain a 45-minute presentation in exchange for some promotion makes a bit more sense. This was quickly validated by the first 4 trainers that I spoke with.
The final element is ensuring that the actual presentations serve to not just educate, but inspire. It is critical then, that every presentation should be delivered by the best presenters available at each event. As the old adage says, we have only one chance to make a first impression. The most experienced Drupal developers and presenters providing beginner content is the kind of impression we want to make to newer Drupalists whom we want to get excited about Drupal. It just feels right. Again, this idea was validated by every single one of the experienced presenters I approached.
ChallengesI have identified two main challenges that will need to be overcome:
- Available presentation slots at Drupal events. Not many Drupal events have the luxury of open rooms or slots in their schedule. Putting some priority on these beginner sessions would need to be part of the event planners’ insights in that it would not only be in our community's long-term interest, but contribute to growth of their event in the future, if they made room for beginner content.
- Presenter/session selection. Presenters who participate in the Back-to-Basics program (or develop their own) shouldn't be penalized for presenting beginner-level content when it comes to session selection. If the maintainer of a core subsystem wants to present beginner-level content, that shouldn't count against them if they are proposing an advanced session as well, in the normal flow of session selection for the same event.
If you are inspired, and considering making a go of leading the charge on this, I am sure you have some ideas on how to proceed. Some fuel for thought; here are the basics of what I envision you'll need to do:
- Reach out to Drupal trainers to confirm their participation. (I can help with that!)
- Determine the list of 6-8 beginner-level topics that should be covered (the Open Curriculum folks can help with this!)
- Develop guidelines for presentation slide decks, including promotion guidelines and common slides.
- Figure out where the presentations will be stored.
- Develop the list of Back-to-Basics presenters.
- Develop an informal written agreement with trainers for presentation maintenance.
- Work with the Drupal Event Organizers working group to help spread the word.
I'm sure you have more ideas to enhance the program, (like nifty t-shirts) and there will surely be some additional tasks as well, but I think this list covers the big ones.
Finally, know that I envision my role as that of a mentor for whoever decides to take this on. I'll be more than happy to provide guidance, answer questions, and make introductions.
Interested? Have questions? Connect with me (ultimike) on the Drupal Slack workspace or use our contact form.
The Drop Times: Specbee Shares How SmartLinker AI Solves A Common Drupal Challenge With Practical AI Integration
Drupal Association blog: Top Roadblocks to Migrating from Drupal 7 to modern Drupal (and How Extended Support Bridges the Gap) + A Look Ahead at Drupal AI
Still on Drupal 7? You’re not alone, but it’s time to plan ahead! Thousands of websites still run on Drupal 7. And while Dropsolid offers extended support, the reality is clear: Drupal 7 is at the end of its innovation cycle. The question is no longer if you should move, but how and when.
At Dropsolid, we guide organizations in making the best choice: whether that means extending support on Drupal 7, migrating to modern Drupal (currently Drupal 11), embracing the power of Drupal AI or a combination of this.
1. Roadblocks of Migrating to modern DrupalMigrating from Drupal 7 to a modern Drupal version is a big step, and many site owners face challenges that delay that move. These are the most common migration roadblocks:
Technical Hurdles
- Complete theme redesign
- Complex content and media structure rework and data migration
- Custom modules and thrid-party integrations often require major rewrites
Organizational Barriers
- Limited development capacity
- Budget constraints
- Competing priorities across teams
We get it. These challenges don’t make migration simple. But don’t worry, there’s a solution that can bridge the gap and give you more time to prepare: Drupal 7 Extended Support (D7ES).
2. Extend Support - The BridgeDrupal 7 Extended Support allows your team to maintain security and performance while planning a future-ready migration.
At Dropsolid, we provide Extended Support for your Drupal 7 website. Unlike many other firms, we have a large team of Drupal 7 experts on board with over 620 years of Drupal experience. And we are fully committed because we currently support a lot of Drupal 7 applications.
What we offer:
- Security patching and monitoring
- Infrastructure support and optimization
- Compatibility workarounds
- Time to prepare for a clean migration
We can offer you more time, which you can use to:
- Reassess your digital goals
- Inventory and audit your site components
- Explore D10 and Drupal AI
Note: At Dropsolid, we don’t consider Drupal 7 Extended Support as a permanent solution, but as a bridge to your next digital chapter. We can help you determine your Digital strategy and align this through our open DXP.
The Dropsolid Drupal 7 Extended Support Program is the perfect temporary solution for you. It allows you to consider your next steps and take away migration pressure.
3. From Drupal 7 to Drupal AI - The FutureAs extended support is not a long-term solution, looking into migrating to modern Drupal is essential. Dropsolid offers expert Drupal migration services to bring your website up to date with modern standards and technologies, making it faster, more secure, and more scalable. We understand that every business is unique, and we tailor our migration approach to your specific needs and challenges.
Looking beyond modern Drupal? There’s an exciting future waiting with Drupal AI! This integration and automation into your CMS unlocks a new level of efficiency, personalization, and innovation.
What can Drupal AI do?Imagine the power of AI-assisted content generation, smart tagging, and intelligent content recommendations—all within your CMS. Drupal AI has new tools to:
- Boost content velocity by generating drafts, suggestions, and ideas based on existing content and keywords.
- Improve UX by offering intelligent recommendations tailored to user behavior, interests, and needs.
- Automate routine time-intensive tasks such as tagging, categorizing, and content updates, reducing the manual effort your team needs to put in.
For example, on a Drupal e-commerce site, AI can dynamically adjust product recommendations based on user behavior, increasing conversions and personalization. Content editors could have AI-generated suggestions ready to publish based on traffic and preferences.
As your website evolves, embracing Drupal AI can be the next logical step after migrating to modern Drupal. It gives you the ability to stay ahead of trends and deliver an exceptional, personalized experience for your users.
4. Ready to Take The Next Step?Not sure which path is right? You don’t have to decide alone. Whether you need more time on Drupal 7 or are ready to innovate, we help you:
- Stay secure on Drupal 7 (for now)
- Build a migration roadmap for modern Drupal
- Discover Drupal AI's potential
We also support organizations in redefining their digital strategy—integrating a full Digital Experience Platform (DXP) and even AI . This ensures your next digital chapter isn't just an upgrade, but a transformation.
Get in touch with us and have a call with our Drupal experts. We’ll assess your current setup, explore your goals, and help you choose the smartest path forward.
Contact us → https://dropsolid.com/en/contact