Specbee: DESIGNING RESPONSIVELY: A DEEP DIVE INTO CSS CONTAINER QUERIES

In the world of web development, responsive design has become a cornerstone of creating user-friendly and visually appealing websites. CSS media queries have long been the go-to solution for adapting layouts to various screen sizes. However, as web design and user expectations have evolved, the limitations of traditional media queries have become apparent. This is where CSS container queries come to the rescue. In this article, we'll explore CSS container queries, how to use them, and the limitations of traditional approaches.  What are CSS Container Queries CSS Container queries is a component-driven styling approach where the styling of the component is based on the container in which the component is present. Instead of relying solely on the viewport dimensions, container queries enable CSS rules to adapt dynamically to changes in the container they are applied to. This lets the components modify their appearance to fit the context in which they’re put. This is not always related to the viewport’s size but sometimes also where the component is placed in the layout. Not just the positioning of inner elements, but even their styling can change with these queries. This helps in component reusability without code duplication. The first implementations of this spec came in 2021 and have become relatively stable in major browsers. Currently, they are supported in recent versions of Chrome, Firefox, Safari, Edge, etc. Beyond Media queries CSS media queries are incredibly powerful and have allowed developers to create flexible and adaptive layouts. They enable us to apply different styles based on the device's screen width, height, or aspect ratio. While this approach works well for simple cases, it falls short when dealing with component-based designs. The problem arises when a container (such as a `div`, `section`, or `article`) changes its size dynamically due to its content or the overall layout adjustments. Traditional media queries depend on the viewport size and not on the size of individual containers. As a result, developers have had to resort to JavaScript workarounds or rely on complex CSS rules to achieve desired results. Exploring Flex and Grid Developers still use certain CSS grids and flex behaviors to approximate container responsiveness. Some of the properties that can be useful for responsiveness are: “flex-wrap” can be used to move items to the next line in case we don’t have enough space without writing a media query.  “flex-grow” and “flex-shrink” allow the element to grow or shrink proportionally without explicitly mentioning the width of each element. Similarly grid allows us to use “fr” units and “minmax” functions to adaptively size the contents inside the grid structure. The following is the behavior of flex-wrap when there is a change in the size of the parent container. Limitations of Flex and Grid Flex and Grid are restricted to defining layout adjustments from horizontal to vertical arrangements, and don’t address the need to modify other properties. A lot of times they depend on the viewport media queries for responsiveness which basically helps with components that are full-width. For example, we can give a property like a flex-wrap for the children to move to the next line in case the flex box cannot accommodate all the children. But we cannot change any other property like font-size or number of elements per row when the wrapping occurs. Component behavior with Container Queries Container queries help in styling the same component for various component sizes. As we can see below the smaller version of the component automatically adjusts the elements and their spacings based on the container size in the same viewport. CSS Rules for Container Queries The proposed CSS `@container` rule is the foundation of container queries. It allows developers to create context-specific rules that apply to the targeted container. The syntax is somewhat similar to media queries, with a slight difference in how the container's dimensions are referenced. container-name:  A custom name that can be given to the container. .wrapper { container-name: my-wrapper; }container-type: This defines the type of containment used in a container query which currently is supported by 3 values. .wrapper { container-type: inline-size; } container: Shorthand way of combining rules for container-name and container-type. .wrapper { container: my-wrapper / inline-size; }@container: The query inside which the element styling changes as per the parent container properties. .wrapper { container: my-wrapper / inline-size; } @container my-wrapper (min-width: 700px) { h2 { font-size: 52px; } } Working with Container Queries In the following demo, we see there is a simple card with an image, some text and a couple of buttons which are arranged in a certain way for the given resolution. index.html Image removed.

Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam luctus lacinia augue, ut pulvinar massa rhoncus id. Sed semper mauris id aliquam porttitor. Mauris scelerisque egestas sagittis. Nullam velit odio, iaculis nec tempus sed, ultrices sit amet purus. Nullam a augue urna. Quisque rutrum tristique porta. Nullam sem turpis, laoreet non erat sed, tempor tristique mi. In sed pretium metus.

Details Contact me style.scss .card { display: flex; flex-direction: row; gap: 1rem; border: 1px solid #ccc; padding: 1rem; &__media { flex-shrink: 0; } } On addition of another component on the left, we expect the card to stack into a better view, but without any modifications, it will look something like this: The card looks a little weird without stacking. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc condimentum dolor vel elementum dignissim. Morbi ex justo, consectetur sollicitudin nunc ornare, condimentum hendrerit diam. Nam eu lectus magna. Praesent pellentesque nibh felis, nec porttitor dui pharetra fringilla. Donec sit amet purus dui. Duis est nulla, posuere nec velit et, suscipit sollicitudin justo. Sed finibus diam ut augue dapibus auctor. Morbi pellentesque finibus mauris ac consectetur. Morbi et sagittis odio, eget pulvinar nisi. Pellentesque eu viverra velit. Donec nec ornare leo. Ut ornare quis leo a fringilla. Vivamus faucibus, justo eget lobortis rutrum, elit tellus venenatis neque, id convallis tellus tellus in neque. Etiam libero risus, blandit vitae elementum a, ultrices eu diam. Donec tempor eget tellus eget iaculis. Curabitur consequat blandit sapien, eget ornare diam. Cras vel imperdiet purus. Ut aliquet magna quis porttitor finibus. Vivamus eu leo odio. Suspendisse nec auctor felis. Donec mollis orci ut justo porttitor tempor. Vivamus faucibus ac lacus in fringilla. Pellentesque laoreet, risus sed mollis laoreet, erat augue vehicula nulla, non fermentum risus metus ullamcorper risus. Quisque fringilla eros id nisl accumsan fermentum. Ut elit sapien, placerat et semper in, mollis at arcu. Aenean rhoncus odio nulla, non convallis purus tristique in. Nulla auctor hendrerit egestas. Quisque finibus lacus ut lectus porta venenatis. Ut pellentesque nec lacus quis vehicula. Quisque vel laoreet arcu, ac tincidunt nulla. Nulla sit amet vestibulum lectus. Maecenas lectus ante, auctor et turpis in, egestas lacinia ipsum. Praesent magna lectus, facilisis nec diam vitae, tristique dictum velit. Vestibulum semper, orci consequat bibendum ultrices, turpis mauris ornare nulla, et efficitur ante lectus sit amet orci. In eget turpis sit amet justo interdum viverra vel vitae mi. Integer interdum lobortis sem, quis commodo nulla aliquet in. Nunc aliquam convallis semper. Aliquam tempus tellus eu rutrum pulvinar. Praesent malesuada mi in mollis imperdiet. Quisque aliquet nisi vitae quam consequat egestas. In lacus dolor, rhoncus ac augue in, ultricies facilisis felis. Praesent quis est et est feugiat sollicitudin sed sed justo. Vestibulum eu nisi et felis tincidunt posuere. Maecenas facilisis felis aliquam mi posuere, eget congue tortor placerat. Curabitur a dapibus eros, eget tempus sem. Mauris vel erat auctor, euismod nunc ac, pretium quam. Morbi iaculis, odio a facilisis convallis, mi purus venenatis justo, sit amet cursus velit risus vitae nisl. Praesent vitae faucibus mi, eu consectetur quam. Donec eu lacus hendrerit, auctor arcu maximus, laoreet libero. Ut imperdiet facilisis nunc. Mauris tincidunt consequat metus, a mattis tellus semper ut. Fusce vitae elit eu velit interdum molestie ac non nisi. Integer id eros non quam pellentesque hendrerit. Etiam non arcu commodo, iaculis purus sit amet, viverra tortor. Aliquam ac auctor nibh, ut efficitur leo. Fusce ut semper elit. Image removed.

Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam luctus lacinia augue, ut pulvinar massa rhoncus id. Sed semper mauris id aliquam porttitor. Mauris scelerisque egestas sagittis. Nullam velit odio, iaculis nec tempus sed, ultrices sit amet purus. Nullam a augue urna. Quisque rutrum tristique porta. Nullam sem turpis, laoreet non erat sed, tempor tristique mi. In sed pretium metus.

Details Contact me style.scss .card { display: flex; flex-direction: row; gap: 1rem; border: 1px solid #ccc; padding: 1rem; &__media { flex-shrink: 0; } } // Adding CSS for newly added .card-container { flex-basis: 50%; } .big-wrapper { display: flex; } .article { padding-inline-end: 20px; flex-basis: 50%; }To fix this we can add flex-wrap property to the card which will help in stacking the elements inside the card.  .card { display: flex; flex-direction: row; gap: 1rem; border: 1px solid #ccc; padding: 1rem; // Adding flex-wrap flex-wrap: wrap; &__media { flex-shrink: 0; } } But this changes the default card behavior even if it is placed alone. There comes unwanted stacking even when the card has full width to occupy.  To fix this problem, we remove the flex-wrap property and introduce the container query based on the container size. This way the component behaves in a convenient manner if placed alone or in a smaller space. style.scss .card { display: flex; flex-direction: row; gap: 1rem; border: 1px solid #ccc; padding: 1rem; &__media { flex-shrink: 0; } } .big-wrapper { display: flex; } .article { padding-inline-end: 20px; flex-basis: 50%; } // Adding container-type .card-container { flex-basis: 50%; container-type: inline-size; } // Adding container query here @container (max-width: 750px) { .card { flex-direction: column; } }Card with Article:  Card without Article  Thus, the behavior is much better without changing the actual style of the card.  Container Units With the advent of container queries, it was obvious that there would be some CSS units to take care of the sizes relative to the container size. The following CSS units have been brought:   Browser support Source: MDN Fallback As the older browsers do not support container queries, it is recommended to use one of the following fallback options: Use @supports to check the availability of feature and add relevant CSS fallback eg. media queries, flex, and grid options. Using container-query-polyfill for using container queries as it is. Final Thoughts In wrapping up, it's clear that CSS container queries are more than just a solution to today's design challenges – they are a glimpse into the exciting future of web development. As technology and user expectations continue to evolve, container queries are poised to play a pivotal role in creating adaptive, user-centric websites. Embrace this innovation and stay ahead in the ever-evolving world of web design! Looking for a Drupal agency to bring your web projects to life? With a proven track record in delivering top-notch Drupal solutions, we understand the importance of responsive design and keeping up with the latest web development trends. Talk to us today! 

Talking Drupal: Talking Drupal #414 - Future of Web Content

Today we are talking about The Future of Content Management, What we see for Drupal in the future, and How AI might factor in with guest John Doyle. We’ll also cover Access Policy as our module of the week.

For show notes visit: www.talkingDrupal.com/414

Topics
  • Digital Polygon
  • Content Management can mean many things, what is our definition
  • What factors contribute to the changes moving to a more centralized model
  • How do organizations manage content for different channels
  • Where do design systems collide with content management
  • Why is Drupal a good fit
  • How does headless fit in
  • Maintaining content architecture long term
  • Drupal adaptations over the next 5 years
Resources
  • Talking Drupal #409 - Data Lakes
  • Hey everyone! Our friends at the Linux Foundation are offering Talking Drupal Listeners 25% off on any e-learning course, certification exam or bundle. Good from August 22-Sept 30, 2023. With discount code LFDrupal25 Please note Bootcamps, ILTs and FinOps courses are excluded… Again that code is LFDrupal25 and you can use that at https://training.linuxfoundation.org/ Thank you to the linux foundation!
  • Flexible Permissions
Guests

John Doyle - digitalpolygon.com _doyle_

Hosts

Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Andy Blum - andy-blum.com - andy_blum

MOTW Correspondent

Martin Anderson-Clutz - @mandclu Access Policy

  • Brief description:
    • Does your Drupal site need a flexible way to manage access to content? There’s a module for that!
  • Brief history
    • How old: created in Nov 2022
    • Versions available: 1.0.0-beta1, works with D9 and 10
  • Maintainership
    • Actively maintained, most recent release was in the past week
  • Number of open issues:
    • 4, none of which are bugs
  • Test coverage
  • Usage stats:
    • 12 sites
  • Maintainer(s):
    • partdigital
  • Module features and usage
    • Allows a site builder to define different policies that can be used to manage content access or editing capabilities based on various factors, all within the Drupal UI
    • Criteria can include field values of the content, field values on the current user’s profile, the time of day, and more
    • The policy can restrict access, for example view acces to only selected people or people with a certain role or field value on their profile. I
    • Once defined, policies can be assigned manually, or automatically applied based on configurable selection criteria
    • The project page describes this as an Attribute Based Access Control (ABAC) architecture, which complements Drupal core’s Role Based Access Control that our listeners are probably familiar with
    • I used it for the first recently, and found that given the power and flexibility the module provides, it’s great that it has in-depth documentation
    • I filed a couple of issues (technically half of the open issues) and partdigital was very responsive
    • The module does also provide an API for defining your own policy type, access rules, rule widgets, and more. So if you need a setup even more custom that what Access Policy can provide out of the box, it’s likely you can extend it to meet your individual use case

The Drop Times: Embracing Continuous Learning

I believe that every day has a valuable lesson to offer. Whether it was a chance encounter with a stranger on my daily commute or a setback at work, I approached each day with curiosity and an open heart. I feel that life's most valuable lessons often emerge from the most unexpected places, and the willingness to learn from every experience has turned my everyday life into a continuous journey of growth and self-discovery.

Just like my everyday experiences contribute to my personal development, the Drupal community's shared insights and experiences shape the community's ongoing success, embodying the spirit of continuous learning and progress.

Let us look into last week's stories by The Drop Times.

Last week, we published an interview with Sibu Stephen, a User Interface Consultant at Digital Polygon. He talks about his connection with Drupal and various other aspects. Read the interview here. The clock is ticking as DrupalCon Lille approaches. Regular registration ends on September 11th, so don't miss out on the chance to register and experience all the benefits of DrupalCon.

Furthermore, the 2023 Drupal Business Survey remains open for anonymous participation until today, September 4th, 2023, offering a unique opportunity to contribute to the community's growth. DrupalCamp Sevilla 2023 is also on the horizon, scheduled for this month from September 21 to 23. Looking ahead, DrupalCon Portland 2024 Volunteer Applications Now Open and DrupalSouth Sydney 2024 are all set to host their conference from March 20 to 22, 2024.

Luca Lusso brought out a book that delves deep into Drupal theme creation. VDMi's blog delves into Drupal's prowess in managing multilingual web platforms, harnessing its robust multilingual capabilities to cater to diverse linguistic preferences. A detailed walkthrough of the seamless integration of Drupal 9-compatible modules into Drupal 10 projects is provided in Specbee’s blog post. A blog post by KishaWeb decodes the Drupal Website Development Costs. Also, an article by Tactis highlights the important insights from this year's Customer Contact Week (CCW) conference in Las Vegas. A guide by Spark Fabrik lists 11 advantages of Drupal that can benefit businesses.

Acquia offers insights into conditionally increasing PHP memory limits to optimise performance without resorting to complex code changes. A tutorial by DrupalEasy gives an in-depth analysis guiding Drupal developers in transitioning from Drupal 9 to Drupal 10. Lastly, I interacted with Stefanie Bilen, The Director of Marketing and Communication at FFW, drafted her insights and learned more about The Women in Drupal Award. I'd want to remind everybody who is interested that the application deadline is tomorrow.

Sincerely,

Elma John
Sub-Editor, TheDropTimes

#! code: Drupal 10: Adding Third Party Settings To Drupal Configuration Entities

Drupal's modular system allows for all kinds of additions to be added to your site through plugins, entities and configuration.

Thanks to Drupal's modular configuration system you can also inject custom configuration into existing configuration entities. This allows you to extend the functionality of an existing entity and ensure that any customisation are saved in the system configuration. Any configuration entity can be augmented without changing the existing configuration schema of the entity, which might cause knock on effects to other modules.

If you have spent time with Drupal configuration then you might have seen the addition of a third_party_settings block to your configuration. A good example of this is with the core Shortcut module and the third party settings it adds to the installed themes when the site is installed using the standard install profile. The Claro theme, for example, will have the following configuration out of the box.

third_party_settings: shortcut: module_link: true

This allows the Shortcut module to detect if it should show a link on the page when this theme is present on the page. The configuration for this setting then doesn't have to live in a separate configuration entity (which would be exported into a separate file); it can just live with the configuration for the theme and be loaded as part of the theme configuration.

In this article I will look at how to use additional settings to add custom configuration items to an existing configuration entity. I'll also cover a couple of use cases for this technique.

Read more

LN Webworks: Drupal: The Cutting-Edge CMS Now an Incredible Base for Ecommerce Websites

Image removed.

Research suggests that there are currently more than 26 million ecommerce websites available for consumers to explore and more are being created every day. An effective way for e-commerce companies to outperform such fierce competition is to choose a cutting-edge and robust e-commerce platform. As more and more entrepreneurs have this realization, there is an increasing shift toward Drupal commerce. The following reasons paint a clear picture and perfectly elucidate why more and more e-commerce companies are availing of Drupal development services

Droptica: Save Time Building Complex Drupal Websites with Code Generation and No Code Tools

Image removed.

The long time to build a system is often pointed out as a drawback of using Drupal in web development. However, creating complex websites using this technology doesn’t have to be time-consuming at all. In this blog post, I’ll present you with a list of modules and tools that clearly reduce the time to build systems on Drupal. 

General information about Drupal

Drupal is a system written in PHP and built from modules. There are dozens of them in Drupal's core, and several thousand are available for free download from the Drupal.org website.

A PHP developer can also create a custom module for Drupal and add any functionality. Developers often take this route. It’s apparently easier (though not faster) to write the required functionality than to familiarize yourself with existing modules to build it. 

The key to reaping the benefits of choosing Drupal as a technology is to treat it and its modules like LEGO blocks from which you build a system. 

Considering Drupal as a base and adding all the needed functionality in the custom code is a path to increase project costs. Ultimately, in the long run, it also translates into abandoning Drupal as a base solution for building systems. This is because no one likes to pay more than for alternative options available on the market, and nowadays, there is a lot to choose from in the web development world. 

When looking at other technologies, it’s worth paying attention to how many different technologies you need to use to achieve what Drupal offers. Very often, you need to use many frameworks, libraries, or systems and combine them all. With these connections, problems and errors often arise (e.g., website A didn't correctly send data to website B's API, etc.), which take time to debug and fix. 

Systems on Drupal are most often built as a single application with a single codebase (headless Drupal will also appear later in the text), and this simplifies application maintenance, development, and the new version implementation quite a bit. This is a significant advantage for applications with regular deployments (e.g., once a week), which reduces their time, eliminates potential problems, and facilitates application maintenance costs. 

Code generation and no code tools to speed up work in Drupal

I’ve divided the tools that will help you speed up the time of creating complex web pages on Drupal into several groups. You’ll find here descriptions, screenshots, and short videos. Based on these examples, you’ll see how quickly you can build websites in Drupal. 

Code and data generators

Code and database generators can significantly reduce the programmer’s work time. Every web developer working with Drupal should become familiar with these tools. 

Module Builder

Module Builder is a module for Drupal that generates the files needed to make a module. Some elements are repetitive, and constantly writing them from scratch unnecessarily takes precious minutes. With the help of Module Builder, you’ll reduce the time of creating custom modules. 

Drush Generate

Drush is a tool for managing Drupal from the command line. One of the handy commands available in Drush is “generate.” Like Module Builder, this command helps you create the code needed when building modules and saves you time. 

Devel Generate

Devel Generate is part of the Devel module. This tool can generate test data. This is very useful when testing how the system behaves or looks when a large amount of data comes in. By reaching for this module, you save time creating test content and can focus on testing the application. I especially recommend this solution to testers working with Drupal.

No code tools and modules 

There are certain modules in Drupal, so you don't have to write your own custom ones. You can generate data structures and application logic without writing a single line of code. Some of these modules are already in Drupal core. Combining these tools with code generators (not everything can be achieved by clicking, and sometimes you need to write code) gives you a considerable advantage when implementing applications and websites on Drupal over other solutions. 

Fields module

Fields is a module that is part of Drupal core. It allows you to extend entities with additional attributes - for example, you can add a “Phone” field to a user profile to store phone number information, or you can add a “File upload” field to the “Page” content type to enable you to insert downloadable PDF files.

Views module 

The Views module is also part of Drupal core. It allows you to take data from a database and display it in a formatted way. You can extend its capabilities using many additional modules, such as exporting data to CSV format. 

Entity Construction Kit (ECK)

Drupal core has several entity types, including Node, User, and Taxonomy. Sometimes, you need to build your own entity instead of using, for example, a new content type. You can do it by creating a new custom module (for example, using the Module Builder module mentioned above) or you can use the Entity Construction Kit (ECK) module. With its help, without writing code, you can create a new data structure in the database and use it with, e.g., Fields and Views modules. In this case, you can also perfectly see another advantage of Drupal - modules work together rather than being separate elements. 

Event - Condition - Action (ECA)

The ECA module allows you to create actions on various events, such as “send an email if someone adds a comment.” The module's capabilities are vast, and if an option is missing, it can be expanded with additional actions or conditions. 

Webform 

A form on a web page and in an application is a common form of interaction with users. It’s often essential for website administrators to be able to easily create new forms without waiting for a development team. Marketing departments need to add them to landing pages for campaigns, and HR departments need them to collect data from employees in various types of surveys. The examples are many. The Webform module perfectly solves the necessity to build contact forms easily. 

Feeds module 

The Feeds module retrieves data from external sources and saves it to a database in Drupal. The simplest use of the module is to retrieve data from RSS, but you can also configure it for other sources, such as XML files. All data import configuration is done by clicking around the administration interface. So, there is no need to involve a programmer in this. An example of using this module could be, for example, importing job postings to a company website from an external management system or importing recent blog posts to a corporate intranet system (built on Drupal).

Content building tools

Nowadays, building new subpages on a website involves not only adding text but also inserting many components that will make a web page attractive and convenient to use for the visitor. An editor needs tools to build complex sites and a system that doesn’t limit them in creating content. 

There are several such solutions in Drupal. Depending on the needs of content managers, you can choose from the many options available. Here are some examples. 

Layout Builder 

The Layout Builder module is found in Drupal core. It allows you to manage the layout of elements for a content type (e.g., all articles) or specific content. The module is regularly developed, and its capabilities can be extended with additional modules. 

Paragraphs module

Paragraphs is an additional module that extends the possibilities of building a data structure with the Fields module. It’s the basis of the Droopler system - a tool for quickly building company and corporate websites. We have built over a dozen ready-made components that editors can use when creating content there. 

Other tools for content

In addition to the solutions above, other content-building tools are:

Integrations with external applications

Today, the number of applications that companies and organizations use is growing. Drupal fits perfectly into such an environment because it can easily integrate with external systems.  

Drupal can pass stored data to other systems or accept data from applications. It has a RESTful Web Services module that allows simple and complex configurations.

These integration options open up the possibility of using Drupal as a headless CMS. One example can be found in our case study of a project for PZPN, documenting the creation of a system where the frontend is separated from the backend.   

No code and code generation tools - summary 

The examples described above are only a tiny part of the capabilities of Drupal modules. There are many more, and all these tools make Drupal possible to reduce the time needed to build websites or web applications. 

If you plan to create a complex website, Drupal is worth considering. Is this technology suitable for your project? Take advantage of a free consultation at our Drupal agency, during which we will help analyze your case. 

ImageX: Content Editing on a Drupal Website in 2023: What's New and Hot

The practices of publishing, editing, and deleting content are essential for keeping your website fresh and engaging. Drupal always offers new ways to improve editorial efficiency. So if you are involved with content editing or interested in boosting workflows for your team, we now invite you to take a front-row seat. We’ve handpicked some great articles about the tools and practices that you might want to add to your content editing arsenal in 2023. 

Promet Source: More to Love: Big Site Builder Benefits in Drupal 10.1

One of the best enhancements in Drupal over the years has to be incremental improvements.  This means that with every minor release, we can expect changes and enhancements to our Drupal experience. Drupal 10.1 certainly lives up to this idea! Promet Source has introduced thousands of people to Drupal through training. I’ve been teaching Drupal site builders and developers since 2011 and I’ve never been more excited about the direction of our favorite open source project! Here’s the truth about Drupal 10: It’s awesome. 

Matt Glaman: PhpStorm live templates to automate the boring things

I finally took a look at writing a custom live template with PhpStorm. I've used them several times to automate scaffolding a foreach statement or other random suggestions that a Tab keypress leads to automated scaffolded code. But I never really dove in to see how they work or could be customized. Then, I had to fix some of my code to comply with Drupal's coding standards.

Drupal requires document comments for all methods, including a short comment. 

Specbee: How to incorporate Drupal 9-compatible modules into your Drupal 10 project

With every major release, Drupal aims to introduce new features, improvements, and architectural changes. Drupal 10, the latest major upgrade, was out in December 2022 and came with many remarkable updates in features and dependencies. Every Drupal application is heavily dependent on its diverse array of contributed modules. These modules extend Drupal's core functionality, allowing developers to customize and tailor Drupal websites according to specific needs. It's important to note that while some contributed modules will seamlessly align with Drupal 10 through compatible releases, others might necessitate additional attention and adaptation. In this article, we’ll discuss how you can utilize Drupal 9 modules in your Drupal 10 project and meet the standards and expectations set by it. Moving the modules to Drupal 10 What's our strategy for transitioning to Drupal 10 while incorporating these modules? Utilizing the available patches is an option, but its feasibility depends on our project's version control workflow and the hosting platform in play. If our remote repository includes all repositories such as modules/contrib/* and themes/contrib/*, and the hosting platform doesn't ignore these, patches can be applied directly. However, if these repositories are ignored, and given that Drupal projects now adhere to a composer-based structure, we might need to incorporate the patches within the composer.json file itself. If the module does not have any dependency library or module, we add it by simply ignoring the core_version_requirement key with drupal/lenient. But if the module has a dependency module and is not D10-compatible, you will need to implement the following steps as described below.  Utilizing incompatible Drupal 9 modules with Drupal 10     Incorporating incompatible Drupal 9 modules into a Drupal 10 setup necessitates several key steps within the composer.json configuration: Inclusion of Module Repository: Begin by adding the module’s repository to the composer.json file Module Key Update: Update the module’s key as required to ensure proper integration Patch Integration: Add the relevant patch under patches to address compatibility issues effectively Root Composer Dependency: Add the module’s dependency within the root composer.json  Note: Kindly note that for the sake of this article, we will consistently reference the module "drupal/header_and_footer_scripts" as an illustrative example. As of the article’s creation, this module lacks a Drupal 10 release. Inclusion of Module Repository in composer.json As the composer is a dependency manager, it will check for compatibility with other modules’ composer.json file, Drupal version, PHP version, etc. So, you will need to instruct the composer not to check the dependency and directly clone the directory from repositories. In the root composer.json file, add the module’s repositories as follows: "repositories": [  "header_and_footer_scripts": {  "type": "package",  "package": {  "name": "drupal-gitlab/header_and_footer_scripts",  "type": "drupal-module",  "version": "dev-3.0.x@dev",  "source": {  "type": "git",  "url": "https://git.drupalcode.org/project/header_and_footer_scripts.git",  "reference": "3.0.x"  }  }  }  ]  You can take the repository details from the project overview page here. Copy the URL.    Here, I have used drupal-gitlab/module-name as the package name and the reference should be the existing version of the module from which the patch was created. Module Key Update Now, since we have used drupal-gitlab/header_and_footer_scripts as the package name (as mentioned above), let’s replace/add the same under the required key of composer.json so that composer takes it as a dependency and try to download the repositories into our codebase. "require": {      “drupal-gitlab/header_and_footer_scripts: “dev-3.0.x@dev”  }Here, you should refer to the version mentioned as the package version in the repository. Patch Integration To use the patches you will require the “cweagans/composer-patches” so that you can apply the patch. "extra": {  "patches": {  "drupal-gitlab/header_and_footer_scripts": {  "Drupal 10 compatibility": "patches/header_and_footer_scripts_d10.patch"  }  },You can apply the patch in two ways: From a patch file:  a. Download the patch file and place it in your project repository.b. Refer to the file as mentioned in the above code.  From a URL: a. Get the patch URL from the drupal.org issues page.b. Replace the file path with the URL.  If a patch is not available, you can create one by verifying the deprecated methods and other problems using the “Upgrade Status” or “Rector” module.  Root Composer Dependency  Certain modules may include a composer.json file within their repository. It is imperative to verify and, when necessary, incorporate these dependencies into our root composer.json. This precaution is essential, particularly since we have specified that dependency checks should be bypassed as part of our instructions.  Referring to the composer.json file of "header_and_footer_scripts" available here, it's important to note the following guidelines:  If the composer.json of a module lists dependencies under the require key, these should be added to the root composer.json of our project. In cases where the listed items pertain to verification, such as PHP and Drupal version requirements, it is acceptable to disregard these during the process.  It is extremely important to note that the absence of the required dependencies could potentially lead to a complete site breakdown.  Putting it to the test In a vanilla Drupal 10 instance, let’s implement the Drupal 10 upgrade for the same module in both ways: the traditional way and the way we displayed above, and see what happens! Following the traditional approach: { "name": "drupal/drupal", "description": "Drupal is an open source content management platform powering millions of websites and applications.", "type": "project", "license": "GPL-2.0-or-later", "homepage": "https://www.drupal.org/project/drupal", "support": { "docs": "https://www.drupal.org/docs/user_guide/en/index.html", "chat": "https://www.drupal.org/node/314178" }, "require": { "composer/installers": "^2.0", "drupal/core": "self.version", "drupal/core-project-message": "self.version", "drupal/core-vendor-hardening": "self.version", "drupal/header_and_footer_scripts": "^3.0" }, "require-dev": { "behat/mink": "^1.10", "behat/mink-browserkit-driver": "^2.1", "behat/mink-selenium2-driver": "^1.4", "colinodell/psr-testlogger": "^1.2", "composer/composer": "^2.4", "drupal/coder": "^8.3.10", "instaclick/php-webdriver": "^1.4.1", "justinrainbow/json-schema": "^5.2", "mglaman/phpstan-drupal": "^1.1.34", "mikey179/vfsstream": "^1.6.11", "phpspec/prophecy-phpunit": "^2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10.1", "phpstan/phpstan-phpunit": "^1.3.11", "phpunit/phpunit": "^9.5", "symfony/browser-kit": "^6.3", "symfony/css-selector": "^6.3", "symfony/dom-crawler": "^6.3", "symfony/error-handler": "^6.3", "symfony/filesystem": "^6.3", "symfony/finder": "^6.3", "symfony/lock": "^6.3", "symfony/phpunit-bridge": "^6.3", "symfony/var-dumper": "^6.3" }, "replace": { "symfony/polyfill-php72": "*", "symfony/polyfill-php73": "*", "symfony/polyfill-php74": "*", "symfony/polyfill-php80": "*", "symfony/polyfill-php81": "*" }, "minimum-stability": "dev", "prefer-stable": true, "config": { "preferred-install": "dist", "sort-packages": true, "platform": { "php": "8.1.0" }, "allow-plugins": { "composer/installers": true, "drupal/core-project-message": true, "drupal/core-vendor-hardening": true, "phpstan/extension-installer": true, "dealerdirect/phpcodesniffer-composer-installer": true } }, "extra": { "_readme": [ "By default Drupal loads the autoloader from ./vendor/autoload.php.", "To change the autoloader you can edit ./autoload.php.", "This file specifies the packages.drupal.org repository.", "You can read more about this composer repository at:", "https://www.drupal.org/node/2718229" ], "installer-paths": { "core": ["type:drupal-core"], "libraries/{$name}": ["type:drupal-library"], "modules/contrib/{$name}": ["type:drupal-module"], "profiles/contrib/{$name}": ["type:drupal-profile"], "themes/contrib/{$name}": ["type:drupal-theme"], "drush/Commands/contrib/{$name}": ["type:drupal-drush"], "modules/custom/{$name}": ["type:drupal-custom-module"], "themes/custom/{$name}": ["type:drupal-custom-theme"] }, "drupal-core-project-message": { "post-install-cmd-message": [ "drupal/drupal: This package is meant for core development,", " and not intended to be used for production sites.", " See: https://www.drupal.org/node/3082474" ], "post-create-project-cmd-message": [ "drupal/drupal: This package is meant for core development,", " and not intended to be used for production sites.", " See: https://www.drupal.org/node/3082474" ] } }, "autoload": { "psr-4": { "Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer", "Drupal\\Composer\\": "composer" } }, "scripts": { "pre-install-cmd": "Drupal\\Composer\\Composer::ensureComposerVersion", "pre-update-cmd": "Drupal\\Composer\\Composer::ensureComposerVersion", "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump", "drupal-phpunit-upgrade-check": "Drupal\\Core\\Composer\\Composer::upgradePHPUnit", "drupal-phpunit-upgrade": [ "@composer update phpunit/phpunit --with-dependencies --no-progress" ], "post-update-cmd": [ "Drupal\\Composer\\Composer::generateMetapackages", "Drupal\\Composer\\Composer::generateComponentPackages" ], "phpcs": "phpcs --standard=core/phpcs.xml.dist --parallel=$(nproc) --", "phpcbf": "phpcbf --standard=core/phpcs.xml.dist --parallel=$(nproc) --" }, "repositories": [ { "type": "path", "url": "core" }, { "type": "path", "url": "composer/Plugin/ProjectMessage" }, { "type": "path", "url": "composer/Plugin/VendorHardening" }, { "type": "composer", "url": "https://packages.drupal.org/8" } ] }You will notice an error while updating the dependencies “Your requirements could not be resolved to an installable set of packages.” Following the previously discussed approach: { "name": "drupal/drupal", "description": "Drupal is an open source content management platform powering millions of websites and applications.", "type": "project", "license": "GPL-2.0-or-later", "homepage": "https://www.drupal.org/project/drupal", "support": { "docs": "https://www.drupal.org/docs/user_guide/en/index.html", "chat": "https://www.drupal.org/node/314178" }, "require": { "composer/installers": "^2.0", "cweagans/composer-patches": "^1.7", "drupal/core": "self.version", "drupal/core-project-message": "self.version", "drupal/core-vendor-hardening": "self.version", "drupal-gitlab/header_and_footer_scripts": "dev-3.0.x@dev" }, "require-dev": { "behat/mink": "^1.10", "behat/mink-browserkit-driver": "^2.1", "behat/mink-selenium2-driver": "^1.4", "colinodell/psr-testlogger": "^1.2", "composer/composer": "^2.4", "drupal/coder": "^8.3.10", "instaclick/php-webdriver": "^1.4.1", "justinrainbow/json-schema": "^5.2", "mglaman/phpstan-drupal": "^1.1.34", "mikey179/vfsstream": "^1.6.11", "phpspec/prophecy-phpunit": "^2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10.1", "phpstan/phpstan-phpunit": "^1.3.11", "phpunit/phpunit": "^9.5", "symfony/browser-kit": "^6.3", "symfony/css-selector": "^6.3", "symfony/dom-crawler": "^6.3", "symfony/error-handler": "^6.3", "symfony/filesystem": "^6.3", "symfony/finder": "^6.3", "symfony/lock": "^6.3", "symfony/phpunit-bridge": "^6.3", "symfony/var-dumper": "^6.3" }, "replace": { "symfony/polyfill-php72": "*", "symfony/polyfill-php73": "*", "symfony/polyfill-php74": "*", "symfony/polyfill-php80": "*", "symfony/polyfill-php81": "*" }, "minimum-stability": "dev", "prefer-stable": true, "config": { "preferred-install": "dist", "sort-packages": true, "platform": { "php": "8.1.0" }, "allow-plugins": { "composer/installers": true, "drupal/core-project-message": true, "drupal/core-vendor-hardening": true, "phpstan/extension-installer": true, "dealerdirect/phpcodesniffer-composer-installer": true, "cweagans/composer-patches": true } }, "extra": { "patches": { "drupal-gitlab/header_and_footer_scripts": { "Drupal 10 compatibility": "patches/header_and_footer_scripts_d10.patch" } }, "_readme": [ "By default Drupal loads the autoloader from ./vendor/autoload.php.", "To change the autoloader you can edit ./autoload.php.", "This file specifies the packages.drupal.org repository.", "You can read more about this composer repository at:", "https://www.drupal.org/node/2718229" ], "installer-paths": { "core": ["type:drupal-core"], "libraries/{$name}": ["type:drupal-library"], "modules/contrib/{$name}": ["type:drupal-module"], "profiles/contrib/{$name}": ["type:drupal-profile"], "themes/contrib/{$name}": ["type:drupal-theme"], "drush/Commands/contrib/{$name}": ["type:drupal-drush"], "modules/custom/{$name}": ["type:drupal-custom-module"], "themes/custom/{$name}": ["type:drupal-custom-theme"] }, "drupal-core-project-message": { "post-install-cmd-message": [ "drupal/drupal: This package is meant for core development,", " and not intended to be used for production sites.", " See: https://www.drupal.org/node/3082474" ], "post-create-project-cmd-message": [ "drupal/drupal: This package is meant for core development,", " and not intended to be used for production sites.", " See: https://www.drupal.org/node/3082474" ] } }, "autoload": { "psr-4": { "Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer", "Drupal\\Composer\\": "composer" } }, "scripts": { "pre-install-cmd": "Drupal\\Composer\\Composer::ensureComposerVersion", "pre-update-cmd": "Drupal\\Composer\\Composer::ensureComposerVersion", "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump", "drupal-phpunit-upgrade-check": "Drupal\\Core\\Composer\\Composer::upgradePHPUnit", "drupal-phpunit-upgrade": [ "@composer update phpunit/phpunit --with-dependencies --no-progress" ], "post-update-cmd": [ "Drupal\\Composer\\Composer::generateMetapackages", "Drupal\\Composer\\Composer::generateComponentPackages" ], "phpcs": "phpcs --standard=core/phpcs.xml.dist --parallel=$(nproc) --", "phpcbf": "phpcbf --standard=core/phpcs.xml.dist --parallel=$(nproc) --" }, "repositories": [ { "type": "path", "url": "core" }, { "type": "path", "url": "composer/Plugin/ProjectMessage" }, { "type": "path", "url": "composer/Plugin/VendorHardening" }, { "type": "composer", "url": "https://packages.drupal.org/8" }, { "type": "package", "package": { "name": "drupal-gitlab/header_and_footer_scripts", "type": "drupal-module", "version": "dev-3.0.x@dev", "source": { "type": "git", "url": "https://git.drupalcode.org/project/header_and_footer_scripts.git", "reference": "3.0.x" } } } ] } Once there is a Drupal 10 release of the module, remove the above code and add it as usual - “drupal/module-name”: “version”.   Final Thoughts Looking ahead, Drupal 10’s adoption of modern technologies and adherence to industry standards positions it to lead the charge in delivering cutting-edge digital experiences. Incorporating Drupal 9-compatible modules into your Drupal 10 project isn't just about code integration—it's about enabling your site to thrive in the dynamic digital ecosystem of tomorrow. At Specbee, we're dedicated to realizing the full potential of Drupal for your digital projects. Our seasoned experts are well-versed in Drupal 10's advancements and possess the skills needed to seamlessly integrate modules, ensuring your website remains at the forefront of technology. Partner with us to drive your Drupal 10 project forward with confidence and innovation.