Planet Drupal

Subscribe to Planet Drupal feed
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 1 day 39 min ago

drunomics: Why we don't use GraphQL

Mon, 2024-09-16 15:38
Why we don't use GraphQL wolfgang.ziegler Mon, 09/16/2024 - 21:38 Exploring drawbacks of GraphQL in decoupled Drupal, including complexity, loose contracts, performance issues, and security concerns. RESTful alternatives are discussed. Body

At drunomics we are building decoupled Drupal sites for more than five years. During this time, GraphQL has always been a popular choice for decoupled Drupal sites among professional or enterprise projects, thanks to the well maintained GraphQL contrib module. Still, I've vetted against using GraphQL for various enterprise projects, even though sometimes it was appealing to customers. In this blog post, I'd like to summarize why we don't use GraphQL:

General complexity

GraphQL is not only a new query language to learn for both frontenders and backenders, moreover the backend has to support any kind of queries the frontenders make. On the frontend side of things, additional libraries and tooling is needed to handle the protocol.

Loose contracts

GraphQL gives a lot of power to frontend developers, but that comes with a huge price: No defined or a very loosely defined contract, i.e. the data model or more specifically the GraphQL schema layered on top. Based upon this loose contract the frontend may compose any kind of queries, which the backend has to support. What leads to the next point:

Complex queries

When the backend is exposing the Drupal data schema directly, potentiallly a lot of things become leaked unwanted and changing things might became hard, because: Who knows what data properties the frontend uses and queries for? It's quite hard to optimize for every use-case.

However, the backend may compose it's own GraphQL schema and provide exactly the data model as needed by the client, the frontend. That's indeed, a great option to have, but it requires additional work and code to translate between the schema and the real data model behind. It makes it possible to change the underlying data model and schema mapping, while staying with the same or compatible GraphQL output and schema. But is that code performing the mapping performant enough? Does it work correctly? That's quite hard to tell without knowing exactly the queries one has to optimize and test for. So things are or become complex.

Performance

First of all, GraphQL is bad for caching since it makes use of POST requests. The typical work-around is to use shortened, hashed queries and to access them via GET requests, what can help to mitigate the issue. But this comes at the cost of tying the deployed frontend and backend versions, thus increasing overall system and deployment complexity. That way, the main GraphQL advantage - flexibility at the frontend - gets lost. So not an easy or great compromise to make.

Client driven data fetching

With GraphQL, the web browser (or generally the client) sends a query to the server, specifying the exact data it needs. While this can help to reduce payload size, it puts the client in the "driving seat". That often leads to additional round trips being required: Based upon the first request, often additional data is required for rendering it. This additional data often has to be fetched in additional requests, thus requiring another or multiple round-trips to the server and thus increasing latency.

In contrast, when the server is in the "driving seat", it may efficiently do all queries and resolve additional data, and then send the resulting data over the slower network once.

Security

GraphQL queries can expose sensitive data if not properly secured. This can be mitigated by implementing proper authentication and authorization mechanisms. However, this can get very complex easily: Since the server does not know the queries needed by the client, it needs to handle every possible combination a client may request. Unfortunately, it's commonly rather easy for hackers to purposely write computationally very expensive (GraphQL) queries and to send them to the server, thus opening the door for DDOS or even DOS attacks.

Besides that, due to the complexity of the backend having to cover all possible combinations, the danger for data leaking accidentially becomes rather high.

The conclusion

GraphQL comes with a couple of issues, which are - as usual - solvable. That's a price one might want to pay in certain situations, if the benefits are worth it. Thus, is using GraphQL a good idea? As so often, it depends. But in my experience, it's more often not, than it is.

Alternatives are RESTful

The typical alternative to GraphQL is a RESTful API. As usual, with Drupal there are a couple of good options:

  • Drupal comes with the JSON-API out-of-the box, which is a great feature to have. While it's good fit in certain situations, it also faces some of the issues mentioned above, most notable "Client driven data fetching" and "Loose contracts".
  • Developers may use Drupal's API to provide custom-coded RESTful endpoints for the client. That addresses all mentioned concerns, but requires backend development time for every feature and most notable careful planing. This comes with the downside of frontend developers loosing the flexibility. (By the way, this is what GraphQL is loved for!)
  • Configurable RESTful endpoints. In order to improve the development process and gain flexibility in the frontend, we developed a solution for providing custom RESTful endpoints that are configurable via Drupal, by frontend developers. For that, we improved the Custom Elements module, which is part of Lupus Decoupled Drupal, such that it integrates with Drupal's configuration sytem and provides an UI for customizing output by entity view-mode. That way, in many situations, we can tick all the boxes, while enabling the frontend developer to work efficiently. I'll share more details about the new Custom Elements UI in a dedicated blog post later this week.
Categories: FLOSS Project Planets

Talking Drupal: Talking Drupal #467 - Config Actions System

Mon, 2024-09-16 14:00

Today we are talking about The Config Actions System, What it does, and how it helps with Drupal Recipes with guests Alex Pott and Adam Globus-Hoenich. We’ll also cover the Events recipe as our module of the week.

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

Topics
  • Explain Config Actions
  • Is this related to the Actions UI
  • How are config actions used in Drupal
  • How will the average user interact with Config Actions
  • What does non-desctructive mean
  • Where did the Config Action system come from
  • Future of the Config Action system
  • How can people help out
  • How does the Config Action system help with Drupal CMS
Resources Guests

Alex Pott - alexpott Adam Globus-Hoenich - phenaproxima

Hosts

Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Nate Dentzau - dentzau.com nathandentzau

MOTW Correspondent

Martin Anderson-Clutz - mandclu.com mandclu

  • Brief description:
    • Have you ever wanted to set up and configure a robust events system in your Drupal website, in just a few seconds? There’s a recipe for that.
  • Module name/project name:
  • Brief history
    • How old: originally created in Mar 2013 as a distribution, but reborn as a recipe in July 2024
    • Versions available: 1.0.0-alpha3, compatible with Drupal 10.3 and 11
  • Maintainership
    • Actively maintained
    • Security coverage? - no stable release
    • Documentation in the works
    • Number of open issues: 1 open issue, which is a bug
  • Usage stats: not tracked for recipes
  • Maintainer(s): mandclu
  • Module features and usage
    • Listeners probably won’t be surprised to hear that Smart Date is at the heart of what you’ll get when you apply the Events recipe
    • You will have an Event content type, and a view to list upcoming and past events
    • The recipe will also set up add-to-calendar links on your event page, making it easy for your site visitors to be reminded of when your event will take place
    • There are companion recipes to add a calendar view, to be able to associate locations (with maps), and to add event registration
    • A modified version of the Events recipe has already been integrated into Drupal CMS, so it will be even easier to apply for a site based on that
    • Internally it makes use of the createIfNotExists and setComponents config actions, which is why I thought it would be relevant to today’s discussion
Categories: FLOSS Project Planets

mark.ie: Live Previews for LocalGov Microsites Design Changes

Mon, 2024-09-16 11:48

I had great fun today expanding what was a proof-of-concept module from last year into a very usable live preview module for LGD Microsites.

Categories: FLOSS Project Planets

ThinkDrop Consulting: Reflections on OpenDevShop and the hidden costs of open source maintainership.

Mon, 2024-09-16 09:34
Reflections on OpenDevShop and the hidden costs of open source maintainership. Jon Pugh Mon, 09/16/2024 - 09:34

#OpenDevShop failed because it tried to solve too many problems at the same time.

This directed the energy away from designing for the future. When the future arrived, it was wholly unprepared.

I saw the potential to make #Aegir an all-in-one management console for all your web tech, so I created server management things, and local CLI things, and other silly, not so useful things.

DevShop became a huge burden. Unmaintainable. Un-upgradable. Working untold unpaid hours, self-funded travel and speaking took a major toll on my life, financially and personally.

Categories: FLOSS Project Planets

The Drop Times: QED42's Journey in Shaping Digital Experiences: Insights from Piyuesh Kumar

Mon, 2024-09-16 09:10
Discover how QED42 is shaping the future of digital experiences! In this exclusive interview, Piyuesh Kumar, Director of Technology at QED42, shares insights on their journey with Drupal, their groundbreaking contributions, and the role of AI in transforming content management systems. Get a sneak peek into the upcoming advancements in Drupal and what to expect at DrupalCon Barcelona 2024. Don't miss this deep dive into QED42's vision and impact!
Categories: FLOSS Project Planets

Oliver Davies' daily list: Experimenting with the Default Content module

Sun, 2024-09-15 20:00

I recently sent a database to a client whose new Drupal website I'm building.

I'd populated it with some default users, nodes and menu links that they'd be able to review after they import the database into their hosting.

That worked well, but I've also recently been using the Default Content module which exports entities into YAML and saves them as code alongside the configuration.

Now I can install the website from scratch using the exported configuration to re-add the content types, block types, etc, and by enabling a custom module, all the default content will also be recreated.

I can tear the site down now and rebuild it as often as I like and avoid contaminating my environment with any rogue configuration or content changes.

Everything is reproducible.

I also wouldn't have needed to send the database to the client. They could have installed Drupal and followed the same steps I would do locally and got exactly the same result.

I like this approach and can see me using it more on future projects.

Categories: FLOSS Project Planets

#! code: Drupal 11: Using The Finished State In Batch Processing

Sun, 2024-09-15 14:51

This is the third article in a series of articles about the Batch API in Drupal. The Batch API is a system in Drupal that allows data to be processed in small chunks in order to prevent timeout errors or memory problems.

So far in this series we have looked at creating a batch process using a form and then creating a batch class so that batches can be run through Drush. Both of these examples used the Batch API to run a set number of items through a set number of process function callbacks. When setting up the batch run we created a list of items that we wanted to process and then split this list up into chunks, each chunk being sent to a batch process callback.

There is another way to set up the Batch API that will run the same number of operations without defining how many times we want to run them first. This is possible by using the "finished" setting in the batch context.

Let's create a batch process that we can run and control using the finished setting.

Setting Up

First we need to create a batch process that will accept the array we want to process. This is the same array as we have processed in the last two articles, but in this case we are passing the entire array to a single callback via the addOperation() method of the BatchBuilder class.

Read more

Categories: FLOSS Project Planets

CodeLift: Introduction to Diffy for Visual Regression Testing

Sun, 2024-09-15 06:00
Introduction to Diffy for Visual Regression Testing
Categories: FLOSS Project Planets

Oliver Davies' daily list: Looking for alpha testers

Sat, 2024-09-14 20:00

As someone who works on multiple Drupal applications, I know it can be tricky to keep on top of all the available updates.

So, I'm building a SaaS project to display all your available updates in one place.

If you're a freelancer or work for an agency or any team that works on multiple Drupal applications, this could be useful for you.

If this is you, I'm looking for alpha testers to help me test it.

If you're interested, reply and let me know.

Categories: FLOSS Project Planets

The Drop Times: Sustainability Takes Center Stage at DrupalCon Barcelona 2024

Fri, 2024-09-13 10:21
Discover how DrupalCon Barcelona 2024 is prioritizing sustainability with eco-friendly initiatives and practices. From reducing food waste to promoting mental well-being, attendees are encouraged to participate in creating a more environmentally conscious event. Join the movement towards a greener future at DrupalCon Barcelona.
Categories: FLOSS Project Planets

Golems GABB: Gamification on Drupal Websites

Fri, 2024-09-13 06:26
Gamification on Drupal Websites Editor Fri, 09/13/2024 - 13:26

Gamification is the integration of game elements into non-gaming environments like websites to enhance user experiences. Its purpose is to make the user's experience more fun, motivating, and rewarding. Like Grand Theft Auto: San Andreas, where players explore a big landscape full of problems and prizes, gamification adds excitement and advancement to typical digital platforms.
Drupal provides an excellent setting for incorporating gamification elements because it can adapt to changing needs. Like in the game, developers using Drupal can encourage users with rewards such as badges, points systems, and interactive tasks that create a feeling of accomplishment while also promoting involvement within the community.
This article provides a detailed look into combining gamification with Drupal's strong features. Grab a coffee, and let's begin our adventure utilizing Drupal's gamification.

Categories: FLOSS Project Planets

Wim Leers: XB week 16: better UX thanks to ghosts & Redux

Fri, 2024-09-13 06:13

A new record week: 26 MRs merged! :D Too much to cover, so going forward, I will only write about the most notable changes.

The simplified zoom interface landed thanks to Jesse “jessebaker” Baker and Gaurav “gauravvvv” — with not only better controls, but also a much smoother UX:

Smooth zoom with pinch and using the slider!
Issue #3464025, image by Jesse.

Bálint “balintbrews” Kléri, Jesse and Ben “bnjmnm” Mullins integrated the existing “undo” functionality with the component props form, resulting in the UX you’d hope:

Your browser does not support playing videos. You can download it instead.

When undoing, the component props form on the right-hand side updates and the preview updates in real-time.
Issue #3463618, video by Bálint.

Now that many fundamental pieces exist, it’s time to build upon the foundations that we have. Five weeks ago, Ben added Redux integration to the component props form, resulting in live updates. That started out with a limited set of form elements supported. Harumi “hooroomoo” Jang added support for one more this week: <select>.

SDC prop shapes using enum now work thanks to expanded Redux integration. For example, you can now change the column width.
Issue #3471083, image by Harumi.

(By the way: Bálint’s epic video showing undo/redo above? That’s also powered by the Redux integration!)

Bálint and Gaurav improved the UX by removing six lines of CSS: instead of an abstract placeholder being dragged and visualized in the currently hovered drop target, now a ghost of the component being moved is visible:

Ghost of the component at the drop target: better visualization of what is about to happen.
Issue #3469895, image by me.

Two weeks ago, we gained support for actual trees. This revealed a number of bugs in the UI that had up until that time, been ahead of the back end. Another one of those was squashed this week by Bálint, Ted and I: you can now actually drag components into empty slots :D

Missed a prior week? See all posts tagged Experience Builder.

Goal: make it possible to follow high-level progress by reading ~5 minutes/week. I hope this empowers more people to contribute when their unique skills can best be put to use!

For more detail, join the #experience-builder Slack channel. Check out the pinned items at the top!

Empowering SDC developers

Less visible, but equally important because it boosts the productivity of the fine folks working on the Starshot Demo Design System by making XB be more explicit about what Single-Directory Components (SDCs) prop shapes it provides a complete UX for. Since last week, a sibling Component config entity is auto-generated for every SDC meeting the minimum criteria. This week, Feliksas “f.mazeikis” Mazeikis expanded the list of criteria:

  1. Since #3469461, any SDCs that we know for sure won’t work well in XB (yet!) no longer show up in the XB UI. (In more detail: when we have no way to store a particular prop shape yet: XB does not yet support type: array prop shapes yet, for example.)
  2. Since #3470424, SDCs marked as obsolete won’t get a Component config entity auto-created. But if it already exists (and hence may be in use), the config entity is not deleted, just disabled.

Evidently that could lead to surprising situations, especially while developing SDCs. So, he’ll be adding a UI that lists the reason for an SDC not being available in XB next.

In the background, back end folks empowering the front end

Ted “tedbow” Bowman helped the back end race ahead of the front end: while we don’t have designs for it yet (nor capacity to build it before DrupalCon if they would suddenly exist), there now is an HTTP API to get a list of viable candidate field properties that are able to correctly populate a particular component prop. These are what in the current XB terminology are called dynamic prop sources 1 2.

Travis “traviscarden” Carden and I made XB’s use of OpenAPI go much further than it did when it landed 3 weeks ago): rather than only validating API response bodies, it now also validates request bodies — hence catching an entire category of bugs on the client-side automatically. Clearer errors = faster iteration!

Week 16 was August 26–September 1, 2024.

  1. Dynamic Prop Sources are similar to Drupal’s tokens, but are more precise, and support more than only strings, because SDC props often require more complex shapes than just strings. ↩︎

  2. This is the shape matching from ~3 months ago made available to the client side. ↩︎

Categories: FLOSS Project Planets

Promet Source: Key Strategies for Achieving Section 508 Compliance

Fri, 2024-09-13 00:04
Note: This article has been reviewed by Level Access Senior Accessibility Consultant Mickey Williamson.   Takeaway: Streamline Section 508 compliance with proven strategies and DUSWDS, a tool designed to modernize federal websites while ensuring accessibility—saving time, reducing complexity, and meeting legal requirements efficiently. Ensuring equal access to information is not just a moral imperative—it's a legal requirement for federal agencies.
Categories: FLOSS Project Planets

CKEditor: Enhance Your Drupal Experience with the Free CKEditor 5 Plugin Pack

Thu, 2024-09-12 20:00
Enhance Drupal with the CKEditor 5 Plugin Pack: a free set of rich text editor enhancements at no cost for drupal web projects.
Categories: FLOSS Project Planets

Oliver Davies' daily list: Violinist, render arrays and feature flags

Thu, 2024-09-12 20:00

This week, I spoke with Eirik Morland again on the Beyond Blocks podcast about recent improvements to violinist.io, such as team/multi-user subscriptions.

Listen to the episode now.

I was great to speak to Eirik again and for him to be the first returning guest on the podcast.

Listen to the first episode with Eirik.

Categories: FLOSS Project Planets

Four Kitchens: Get ready for Drupal 11: An essential guide

Thu, 2024-09-12 15:19

Yuvania Castillo

Backend Engineer

A graduate of the University of Costa Rica with a passion for programming, Yuvania is driven to constantly improve, study, and learn new technologies to be better every day.

January 1, 1970

Preparing for Drupal 11 is crucial to ensure a smooth transition, and we’re here to help you make it easy and efficient. This guide offers clear steps to update your environment and modules, perform thorough tests, and use essential tools like Upgrade Status and Drupal Rector.

Don’t fall behind! Making sure your site is ready for the new features and improvements Drupal 11 brings will make the upgrade work quick and easy.

Read on to learn how to keep your site updated and future-proof.

Ensure your environment is ready
  • Upgrade to PHP 8.3: Ensure optimal performance and compatibility with Drupal 11
  • Use Drush 13: Make sure you have this version available in your development or sandbox environment
  • Database requirements: Ensure your database meets the requirements for Drupal 11:
    • MySQL 8.0
    • PostgreSQL 16
  • Web server: Drupal 11 requires Apache 2.4.7 or higher. Keep your server updated to avoid compatibility issues.

Upgrade to Drupal 10.3. Before migrating to Drupal 11, update your site to Drupal 10.3 to handle all deprecations properly. Drupal 10.3 defines all deprecated code to be removed in Drupal 11, making it easier to prepare for the next major update.

Update contributed modules. Use Composer to update all contributed modules to versions compatible with Drupal 11. The Upgrade Status module will help identify deprecated modules and APIs. Ensure all modules are updated to avoid compatibility issues.

Fix custom code. Use Drupal Rector to identify and fix deprecations in your custom code. Drupal Rector automates much of the update process, leaving “to do” comments where manual intervention is needed. Perform a manual review of critical areas to ensure everything functions correctly.

Run tests in a safe environment. Conduct tests in a safe environment, such as a local sandbox or cloud IDE. It’s likely to fail at first, but it’s essential to run multiple tests until you achieve a successful result. Use:

  • composer update --dry-run to simulate the update without making changes
  • composer why-not drupal/core 11.0 if there are issues, identify which dependencies require an earlier version of Drupal

Compatibility tools. Install and use the Upgrade Status module to ensure your site is ready. This module provides a detailed report on your site’s compatibility with Drupal 11. Check for compatibility issues in contributed projects on Drupal.org using the Project Update Bot.

Back up everything. Before updating, ensure you have a complete backup of your code and database. This is crucial to restore your site if something goes wrong during the update.

Considerations for immediate upgrade

You may wonder if you should upgrade your site to Drupal 11 as soon as it’s available. Here are some pros and cons to consider:

  • Maybe no: Sites can wait up till when the Drupal 10 LTS (long term support) ends (mid-late 2026) and then upgrade. This allows contributed modules to be fully ready for the update.
  • Maybe yes: Upgrading early lets you take advantage of new features and improvements but may introduce new bugs. Additionally, if everyone waits to upgrade, it could delay the readiness of contributed modules for the new version.

While Drupal 10 will be supported for some time, it’s advisable to stay ahead with these updates to use the improvements they offer and ensure a smoother, optimized transition.

By following these steps and considerations, your Drupal site will be well prepared for the transition to Drupal 11, ensuring a smooth and uninterrupted experience. Get ready for the new and exciting features Drupal 11 has to offer!

References

The post Get ready for Drupal 11: An essential guide appeared first on Four Kitchens.

Categories: FLOSS Project Planets

mark.ie: My LocalGov Drupal contributions for week-ending September 13th, 2024

Thu, 2024-09-12 11:29

This week's big issue was building a prototype for "Axe Thrower" so we can "throw" multiple URLs at AXE at the same time.

Categories: FLOSS Project Planets

Mario Hernandez: Migrating your Drupal theme from Patternlab to Storybook

Thu, 2024-09-12 00:48

Building a custom Drupal theme nowadays is a more complex process than it used to be. Most themes require some kind of build tool such as Gulp, Grunt, Webpack or others to automate many of the repeatitive tasks we perform when working on the front-end. Tasks like compiling and minifying code, compressing images, linting code, and many more. As Atomic Web Design became a thing, things got more complicated because now if you are building components you need a styleguide or Design System to showcase and maintain those components. One of those design systems for me has been Patternlab. I started using Patternlab in all my Drupal projects almost ten years ago with great success. In addition, Patternlab has been the design system of choice at my place of work but one of my immediate tasks was to work on migrating to a different design system. We have a small team but were very excited about the challenge of finding and using a more modern and robust design system for our large multi-site Drupal environment.

Enter Storybook

After looking a various options for a design system, Storybook seemed to be the right choice for us for a couple of reasons: one, it has been around for about 10 years and during this time it has matured significantly, and two, it has become a very popular option in the Drupal ecosystem. In some ways, Storybook follows the same model as Drupal, it has a pretty active community and a very healthy ecosystem of plugins to extend its core functionality.

Storybook looks very promising as a design system for Drupal projects and with the recent release of Single Directory Components or SDC, and the new Storybook module, we think things can only get better for Drupal front-end development. Unfortunately for us, technical limitations in combination with our specific requirements, prevented us from using SDC or the Storybook module. Instead, we built our environment from scratch with a stand-alone integration of Storybook 8.

INFO: At the time of our implementation, TwigJS did not have the capability to resolve SDC's namespace. It appears this has been addressed and using SDC should now be possible with this custom setup. I haven't personally tried it and therefore I can't confirm. Our process and requirements

In choosing Storybook, we went through a rigorous research and testing process to ensure it will not only solve our immediate problems with our current environment, but it will be around as a long term solution. As part of this process, we also tested several available options like Emulsify and Gesso which would be great options for anyone looking for a ready-to-go system out of the box. Some of our requirements included:

1. No components refactoring

The first and non-negotiable requirement was to be able to migrate components from Patternlab to a new design system with the least amount of refactoring as possible. We have a decent amount of components which have been built within the last year and the last thing we wanted was to have to rebuild them again because we are switching design system.

2. A new Front-end build workflow

I personally have been faithful to Gulp as a front-end build tool for as long as I can remember because it did everything I needed done in a very efficient manner. The Drupal project we maintain also used Gulp, but as part of this migration, we wanted to see what other options were out there that could improve our workflow. The obvious choice seemed to be Webpack, but as we looked closer into this we learned about ViteJS, "The Next Genration Frontend Tooling". Vite delivers on its promise of being "blazing fast", and its ecosystem is great and growing, so we went with it.

3. No more Sass in favor of PostCSS

CSS has drastically improved in recent years. It is now possible with plain CSS, to do many of the things you used to be able to only do with Sass or similar CSS Preprocessor. Eliminating Sass from our workflow meant we would also be able to get rid of many other node dependencies related to Sass. The goal for this project was to use plain CSS in combination with PostCSS and one bonus of using Vite is that Vite offers PostCSS processing out of the box without additional plugins or dependencies. Ofcourse if you want to do more advance PostCSS processing you will probably need some external dependencies.

Building a new Drupal theme with Storybook

Let's go over the steps to building the base of your new Drupal theme with ViteJS and Storybook. This will be at a high-level to callout only the most important and Drupal-related parts. This process will create a brand new theme. If you already have a theme you would like to use, make the appropriate changes to the instructions.

1. Setup Storybook with ViteJS ViteJS
  • In your Drupal project, navigate to the theme's directory (i.e. /web/themes/custom/)
  • Run the following command:
npm create vite@latest storybook
  • When prompted, select the framework of your choice, for us the framework is React.
  • When prompted, select the variant for your project, for us this is JavaScript

After the setup finishes you will have a basic Vite project running.

Storybook
  • Be sure your system is running NodeJS version 18 or higher
  • Inside the newly created theme, run this command:
npx storybook@latest init --type react
  • After installation completes, you will have a new Storybook instance running
  • If Storybook didn't start on its own, start it by running:
npm run storybook TwigJS

Twig templates are server-side templates which are normally rendered with TwigPHP to HTML by Drupal, but Storybook is a JS tool. TwigJS is the JS-equivalent of TwigPHP so that Storybook understands Twig. Let's install all dependencies needed for Storybook to work with Twig.

  • If Storybook is still running, press Ctrl + C to stop it
  • Then run the following command:
npm i -D vite-plugin-twig-drupal html-react-parser twig-drupal-filters @modyfi/vite-plugin-yaml
  • vite-plugin-twig-drupal: If you are using Vite like we are, this is a Vite plugin that handles transforming twig files into a Javascript function that can be used with Storybook. This plugin includes the following:
    • Twig or TwigJS: This is the JavaScript implementation of the Twig PHP templating language. This allows Storybook to understand Twig.
      Note: TwigJS may not always be in sync with the version of Twig PHP in Drupal and you may run into issues when using certain Twig functions or filters, however, we are adding other extensions that may help with the incompatability issues.
    • drupal attribute: Adds the ability to work with Drupal attributes.
  • twig-drupal-filters: TwigJS implementation of Twig functions and filters.
  • html-react-parser: This extension is key for Storybook to parse HTML code into react elements.
  • @modifi/vite-plugin-yaml: Transforms a YAML file into a JS object. This is useful for passing the component's data to React as args.
ViteJS configuration

Update your vite.config.js so it makes use of the new extensions we just installed as well as configuring the namesapces for our components.

import { defineConfig } from "vite" import yml from '@modyfi/vite-plugin-yaml'; import twig from 'vite-plugin-twig-drupal'; import { join } from "node:path" export default defineConfig({ plugins: [ twig({ namespaces: { components: join(__dirname, "./src/components"), // Other namespaces maybe be added. }, }), // Allows Storybook to read data from YAML files. yml(), ], }) Storybook configuration

Out of the box, Storybook comes with main.js and preview.js inside the .storybook directory. These two files is where a lot of Storybook's configuration is done. We are going to define the location of our components, same location as we did in vite.config.js above (we'll create this directory shortly). We are also going to do a quick config inside preview.js for handling drupal filters.

  • Inside .storybook/main.js file, update the stories array as follows:
stories: [ "../src/components/**/*.mdx", "../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)", ],
  • Inside .storybook/preview.js, update it as follows:
/** @type { import('@storybook/react').Preview } */ import Twig from 'twig'; import drupalFilters from 'twig-drupal-filters'; function setupFilters(twig) { twig.cache(); drupalFilters(twig); return twig; } setupFilters(Twig); const preview = { parameters: { controls: { matchers: { color: /(background|color)$/i, date: /Date$/i, }, }, }, }; export default preview; Creating the components directory
  • If Storybook is still running, press Ctrl + C to stop it
  • Inside the src directory, create the components directory. Alternatively, you could rename the existing stories directory to components.
Creating your first component

With the current system in place we can start building components. We'll start with a very simple component to try things out first.

  • Inside src/components, create a new directory called title
  • Inside the title directory, create the following files: title.yml and title.twig
Writing the code
  • Inside title.yml, add the following:
--- level: 2 modifier: 'title' text: 'Welcome to your new Drupal theme with Storybook!' url: 'https://mariohernandez.io'
  • Inside title.twig, add the following:
<h{{ level|default(2) }}{% if modifier %} class="{{ modifier }}"{% endif %}> {% if url %} <a href="{{ url }}">{{ text }}</a> {% else %} <span>{{ text }}</span> {% endif %} </h{{ level|default(2) }}>

We have a simple title component that will print a title of anything you want. The level key allows us to change the heading level of the title (i.e. h1, h2, h3, etc.), and the modifier key allows us to pass a modifier class to the component, and the url will be helpful when our title needs to be a link to another page or component.

Currently the title component is not available in storybook. Storybook uses a special file to display each component as a story, the file name is component-name.stories.jsx.

  • Inside title create a file called title.stories.jsx
  • Inside the stories file, add the following:
/** * First we import the `html-react-parser` extension to be able to * parse HTML into react. */ import parse from 'html-react-parser'; /** * Next we import the component's markup and logic (twig), data schema (yml), * as well as any styles or JS the component may use. */ import title from './title.twig'; import data from './title.yml'; /** * Next we define a default configuration for the component to use. * These settings will be inherited by all stories of the component, * shall the component have multiple variations. * `component` is an arbitrary name assigned to the default configuration. * `title` determines the location and name of the story in Storybook's sidebar. * `render` uses the parser extension to render the component's html to react. * `args` uses the variables defined in title.yml as react arguments. */ const component = { title: 'Components/Title', render: (args) => parse(title(args)), args: { ...data }, }; /** * Export the Title and render it in Storybook as a Story. * The `name` key allows you to assign a name to each story of the component. * For example: `Title`, `Title dark`, `Title light`, etc. */ export const TitleElement = { name: 'Title', }; /** * Finally export the default object, `component`. Storybook/React requires this step. */ export default component;
  • If Storybook is running you should see the title story. See example below:
  • Otherwise start Storybook by running:
npm run storybook

With Storybook running, the title component should look like the image below:


The controls highlighted at the bottom of the title allow you to change the values of each of the fields for the title.

I wanted to start with the simplest of components, the title, to show how Storybook, with help from the extensions we installed, understands Twig. The good news is that the same approach we took with the title component works on even more complex components. Even the React code we wrote does not change much on large components.

In the next blog post, we will build more components that nest smaller components, and we will also add Drupal related parts and configuration to our theme so we can begin using the theme in a Drupal site. Finally, we will integrate the components we built in Storybook with Drupal so our content can be rendered using the component we're building. Stay tuned. For now, if you want to grab a copy of all the code in this post, you can do so below.

Download the code

Resources In closing

Getting to this point was a team effort and I'd like to thank Chaz Chumley, a Senior Software Engineer, who did a lot of the configuration discussed in this post. In addition, I am thankful to the Emulsify and Gesso teams for letting us pick their brains during our research. Their help was critical in this process.

I hope this was helpful and if there is anything I can help you with in your journey of a Storybook-friendly Drupal theme, feel free to reach out.

Categories: FLOSS Project Planets

Mario Hernandez: Responsive images in Drupal - a series

Thu, 2024-09-12 00:48

Images are an essential part of a website. They enhance the appeal of the site and make the user experience a more pleasant one. The challenge is finding the balance between enhancing the look of your website through the use of images and not jeopardizing performance. In this guide, we'll dig deep into how to find that balance by going over knowledge, techniques and practices that will provide you with a solid understanding of the best way to serve images to your visitors using the latest technologies and taking advantage of the advances of web browsers in recent years.

Hi, I hope you are ready to dig into responsive images. This is a seven-part guide that will cover everything you need to know about responsive images and how to manage them in a Drupal site. Although the excercises in this guide are Drupal-specific, the core principles of responsive images apply to any platform you use to build your sites.

Where do we start?

Choosing Drupal as your CMS is a great place to start. Drupal has always been ahead of the game when it comes to managing images by providing features such as image compression, image styles, responsive images styles and media library to mention a few. All these features, and more, come out of the box in Drupal. In fact, most of what we will cover in this guide will be solely out of the box Drupal features. We may touch on third party or contrib techniques or tools but only to let you know what's available not as a hard requirement for managing images in Drupal.

It is important to become well-versed with the tools available in Drupal for managing images. Only then you will be able to make the most of those tools. Don't worry though, this guide will provide you with a lot of knowledge about all the pieces that take part in building a solid system for managing and serving responsive images.

Let's start by breaking down the topics this guide will cover:

  1. What are responsive images?
  2. Art Direction using the <picture> HTML element
  3. Image resolution switching using srcset and sizes attributes
  4. Image styles and Responsive image styles in Drupal
  5. Responsive images and Media
  6. Responsive images, wrapping up
What are responsive images?

A responsive image is one whose dimensions adjust to changes in screen resolutions. The concept of responsive images is one that developers and designers have been strugling with ever since Ethan Marcotte published his famous blog post, Responsive Web Design, back in 2010 followed by his book of the same title. The concept itself is pretty straight forward, serve the right image to any device type based on various factors such as screen resolution, internet speed, device orientation, viewport size, and others. The technique for achieving this concept is not as easy. I can honestly say that over 10 years after reponsive images were introduced, we are still trying to figure out the best way to render images that are responsive. Read more about responsive images.

So if the concept of responsive images is so simple, why don't we have one standard for effectively implementing it? Well, images are complicated. They bring with them all sorts of issues that can negatively impact a website if not properly handled. Some of these issues include: Resolution, file size or weight, file type, bandwidth demands, browser support, and more.

Some of these issues have been resolved by fast internet speeds available nowadays, better browser support for file tyes such as webp, as well as excellent image compression technologies. However, there are still some issues that will probably never go away and that's what makes this topic so complicated. One issue in particular is using poorly compressed images that are extremely big in file size. Unfortunately often times this is at the hands of people who lack the knowledge of creating images that are light in weight and properly compressed. So it's up to us, developers, to anticipate the problems and proactively address them.

Ways to improve image files for your website

If you are responsible for creating or working with images in an image editor such as Photoshop, Illustrator, GIMP, and others, you have great tools at your disposal to ensure your images are optimized and sized properly. You can play around with the image quality scale as you export your images and ensure they are not bigger than they need to be. There are many other tools that can help you with compression. One little tool I've been using for years is this little app called ImageOptim, which allows you to drop in your images in it and it compresses them saving you some file size and improving compression.

Depending on your requirements and environment, you could also look at using different file types for your images. One highly recommended image type is webp. With the ability to do lossless and lossy compression, webp provides significant improvements in file sizes while still maintaining your images high quality. The browser support for webp is excellent as it is supported by all major browsers, but do some research prior to start using it as there are some hosting platforms that do not support webp.

To give you an example of how good webp is, the image in the header of this blog post was originally exported from Photoshop as a .JPG, which resulted in a 317KB file size. This is not bad at all, but then I ran the image through the ImageOptim app and the file size was reduced to 120KB. That's a 62% file size reduction. Then I exported the same image from Photoshop but this time in .webp format and the file size became 93KB. That's 71% in file size reduction compared to the original JPG version.

A must have CSS rule in your project

By now it should be clear that the goal for serving images on any website is doing it by using the responsive images approach. The way you implement responsive images on your site may vary depending on your platform, available tools, and skillset. Regardless, the following CSS rule should always be available within your project base CSS styles and should apply to all images on your site:

img { display: block; max-width: 100%; }

Easy right? That's it, we're done 😃

The CSS rule above will in fact make your images responsive (images will automatically adapt to the width of their containers/viewport). This rule should be added to your website's base styles so every image in your website becomes responsive by default. However, this should not be the extend of your responsive images solution. Although your images will be responsive with the CSS rule above, this does not address image compression nor optimization and this will result in performance issues if you are dealing with extremly large file sizes. Take a look at this example where the rule above is being used. Resize your browser to any width including super small to simulate a mobile device. Notice how the image automatically adapts to the width of the browser. Here's the problem though, the image in this example measures 5760x3840 pixels and it weights 6.7 MB. This means, even if your browser width is super narrow, and the image is resized to a very small visual size, you are still loading an image that is 6.7 MB in weight. No good 👎

In the next post of this series, we will begin the process of implementing a solution for handling responsive images the right way.

Navigate posts within this series

Categories: FLOSS Project Planets

Oliver Davies' daily list: When did you last deploy to production?

Wed, 2024-09-11 20:00

If you've experienced issues or are worried about deploying changes to production, on a Friday or another day, when did you last deploy something?

Can you make deployments smaller and more frequent?

Deploying regularly makes each deployment less risky and having a smaller changeset makes it easier to find and fix any issues that arise.

I'm much happier deploying to production if I've already done so that day, or at least that week.

Any time more than that, or if the changeset is large, the more likely there will be issues and the longer it will take to resolve them.

Categories: FLOSS Project Planets

Pages