Drupal Planet

Security advisories: Drupal core - Moderately critical - Cross-site scripting - SA-CORE-2020-007

6 days 10 hours ago
Project: Drupal coreDate: 2020-September-16Security risk: Moderately critical 14∕25 AC:Basic/A:User/CI:Some/II:Some/E:Theoretical/TD:AllVulnerability: Cross-site scriptingCVE IDs: CVE-2020-13666Description: 

The Drupal AJAX API does not disable JSONP by default, which can lead to cross-site scripting.

Solution: 

Install the latest version:

Versions of Drupal 8 prior to 8.8.x are end-of-life and do not receive security coverage. Sites on 8.7.x or earlier should update to 8.8.10.

If you were previously relying on Drupal's AJAX API to perform trusted JSONP requests, you'll either need to override the AJAX options to set "jsonp: true", or you'll need to use the jQuery AJAX API directly.

If you are using jQuery's AJAX API for user-provided URLs in a contrib or custom module, you should review your code and set "jsonp: false" where this is appropriate.

Reported By: Fixed By: 

Drupal Association blog: Time to Vote!

1 week ago

Elections for the next At-Large member of the Drupal Association Board have now reached the voting phase. Voting will take place from now, 15 September, until 30 September at 10 am PDT.

Drupal Association Individual members should check their email inboxes over the next couple of days for their voting slip arriving.

In the meantime, voters should read the candidate’s info pages and watch the “Candidate Chat” videos and consider which of the candidates will help the Drupal Association most effectively fulfill its mission.

Voting

As detailed previously, we will be using Helios Voting this year and the voting process looks like this:

  1. Open the voting slip email that was sent to the primary email address defined in your drupal.org profile
    The email will arrive from [email protected] -- check your spam folder if you cannot see it, though it will take some hours to send voting slips to each of the 3200+ eligible voters!
  2. Read the instructions there to register your vote
  3. Again, you should receive an email from Helios Voting, confirming the correct registration of your vote
  4. Await the results!

We would like to thank all of our candidates this year for their participation and wish them all the very best of luck!

Have questions? Please contact me: Rachel Lawson.

Evolving Web: Drupal 8/9 Migration: Migrating Media Items and Their Relationships

1 week ago

Since Drupal 8.5, the Media module in core has been a reality and the recommended way to handle media content in Drupal.

If you're migrating from Drupal 7 to Drupal 8 or Drupal 9, this is something you need to take into consideration.

👩‍💻 Get up to speed on the latest version of Drupal! Join us on September 24 for a free webinar on Drupal 9.

In this blog post, we'll go through a migration example where you'll learn how to migrate media items and their relationships in Drupal.

The Drupal 8/9 Migration Tutorial Series

Before We Start The Problem

We have received a database dump and files backup from our imaginary client.

We need to:

  • Migrate files from articles into Drupal 8 files
  • Create media items for each migrated file
  • Migrate articles to Drupal 8 and add the related media items.
Setting up the Migration Create the migration module

We first need to create a module for our migrations. In this example, we're naming it migrate_example_media. 

We then need to add the following modules as dependencies in the module declaration:

Create a migration group

To group the migrations, we also need to create a migration group. To do so, we’ll create a fairly simple configuration file so that the group gets created when the module is installed. The file’s contents should be as follows:

id: media label: Media Group source_type: Drupal 7 shared_configuration: source: key: migrate_d7Define a new database connection

Next, you need to load the Drupal 7 database into your Drupal 8 installation. To do so, you need to define a new database connection in your settings.php file like this:

$databases['migrate_d7']['default'] = array( 'driver' => 'mysql', 'database' => 'migrate_d7', 'username' => 'user', 'password' => 'password', 'host' => 'db', 'prefix' => '', );

And then you can import the database dump into this new database connection using your preferred method.

Writing the Migrations

Next thing to do is to write the actual migrations. Per our requirements, we need to write three different migrations: one for files, one for media and one for articles.

Since Drupal 8.1.x, migrations are plugins that should be stored in a migrations folder inside any module. You can still make them configuration entities as part of the migrate_plus module, but I personally prefer to follow the core recommendation because it's easier to develop (you can make an edit and just rebuild cache to update it).

Write the file migration

The first migration to write is the file migration. To speed things up, we're placing the files backup into a migratefiles folder in sites/default/files and we'll copy the files from there to the right folder during the migration.

The source section of the migrate plugin looks like this:

source: plugin: d7_file scheme: public constants: migrate_files_path: 'sites/default/files/migratefiles'

We're setting migrate_files_path to be the base path where we put the backup files. This will be used later to copy the files to the right location.

The process section of the migrate file looks like this:

process: filename: filename replaced_filepath: - plugin: str_replace source: filepath search: "sites/default/files/" replace: "" source_full_path: - plugin: concat delimiter: / source: - constants/migrate_files_path - '@replaced_filepath' - plugin: urlencode uri: plugin: file_copy source: - '@source_full_path' - uri filemime: filemime status: status created: timestamp changed: timestamp uid: uid

First, we create a temporary replaced_filepath to remove the path prefix. Then, we'll use the concat plugin to create the source_full_path based on the migrate_files_path constant and the replaced_filepath. Then, for the uri, we use file_copy to copy from this source_full_path to the destination URI. The remaining fields are directly mapped from Drupal 7 values.

You can look at the full migration file in the code samples repo.

Write the media migration

The media migration also uses d7_file as the source. We use the skip_on_value plugin in a temporary temp1 field to skip files that are not images:

temp1: - plugin: skip_on_value method: row not_equals: true value: - image/png - image/jpg - image/jpeg source: filemime

We use migration_lookup plugin to add the actual image files like this:

field_media_image/target_id: - plugin: migration_lookup migration: file source: fid

You can look at the full migration file in the code samples repo.

Write the article migration 

The article migration is pretty similar to any other entity migrations. To set the image, we're using the sub_process and migration_lookup plugins like this:

field_image: plugin: sub_process source: field_image process: target_id: plugin: migration_lookup source: fid migration: media_image

So that it looks for the right items in the media_image migration. You can look at the full migration file in the code samples repo.

Running the Migrations

Since we have set dependencies, we can instruct Drupal to run the migration group and it will run the migrations in the right order.

To do so, execute drush mim --group=media and the output will look like this:

[notice] Processed 3 items (3 created, 0 updated, 0 failed, 0 ignored) - done with 'file' [notice] Processed 3 items (3 created, 0 updated, 0 failed, 0 ignored) - done with 'media_image' [notice] Processed 3 items (3 created, 0 updated, 0 failed, 0 ignored) - done with 'article'

You can also run drush ms to see current migration status:

--------------------- ----------------------------------- -------- ------- ---------- ------------- --------------------- Group Migration ID Status Total Imported Unprocessed Last Imported --------------------- ----------------------------------- -------- ------- ---------- ------------- --------------------- Media Group (media) file Idle 3 3 0 2020-08-24 16:06:10 Media Group (media) media_image Idle 3 3 0 2020-08-24 16:06:10 Media Group (media) article Idle 3 3 0 2020-08-24 16:06:10Next Steps + more awesome articles by Evolving Web

Manifesto: Assessing your Drupal 9 Readiness, Part II: Who is afraid of contrib modules updates?

1 week ago

In this series of blog posts, we want to help tech leads and project managers assess how ready their projects are for Drupal 9. In Part 1, we estimated the possible amount of work it takes to make  custom modules compatible with the new major release. If you’ve already done this, then congratulations! …If you. Continue reading...

The post Assessing your Drupal 9 Readiness, Part II: Who is afraid of contrib modules updates? appeared first on Manifesto.

Specbee: How to toggle between Dark and Light Mode in Drupal 8 (or 9) based on user preference

1 week ago
How to toggle between Dark and Light Mode in Drupal 8 (or 9) based on user preference Varun Rao 15 Sep, 2020 Top 10 best practices for designing a perfect UX for your mobile app

How awesome would it be to give your users the freedom to customize their interface to as per their preference? While many users prefer a light interface (light background with dark text), some users choose a dark interface (dark background with light text). Darker interfaces are perceived as cool and trendy while some also believe it reduces strain on the eyes especially for developers who spend a lot of time in front of the screen. I believe that providing an option to your users is a tremendous win in terms of accessibility and user experience. There are a couple of ways with which one can accomplish this. In this article, we will discuss on how to toggle between dark/light web design modes and implement this in Drupal 8 or Drupal 9.


We will be focusing on two methods to implement this -
1.    Using only CSS.
2.    Implementing the CSS & JS toggle switch

Using only CSS

To achieve Dark mode on any website with only CSS, one must keep in mind some of the system requirements.

One such important requirement is the system-wide dark mode. If a user prefers to use dark mode on his PC, then the user is served with a website which shows a dark-colored background with light text on it.

The prefers-color-scheme (media query) is used to identify if the user has requested the system to use a light or dark color theme.

Implementation:

1.    Declare the CSS variables.
2.    Use the variables wherever it is necessary.

The result:
See the Pen Prefers-color-scheme (Auto dark/light mode) by Varun Rao (@varoonrao) on CodePen.

Note: To emulate the result on some unsupported devices, just enter DevTool by pressing F12. Next, press CTRL+SHIFT+P, then search for prefers-color-scheme: dark and press enter.  

Implementing the CSS and JS toggle switch

If we are going with this approach, then we don’t need to bother about the system requirements. Just write couple of lines of CSS and JS and you should be ready.

Once we have initialized the variables, we can reference these variables in our stylesheets.

This will be the HTML structure to toggle between dark and light mode.

                                                       HTML Structure


And some lines of CSS should result in this switch.

The Switch

The final part is to add a bit of JavaScript to tie it all together.
●    Store the user preference for future visits
●    Check for saved user preference, if any, on load of the website

That's it! Check out the full demo below.


See the Pen DARK/LIGHT with js toggle switch by Varun Rao (@varoonrao) on CodePen.

Or click here to view the demo.

Implementing the Dark / Light Toggle in Drupal 8 (or Drupal 9)

To start with creating a custom Drupal 8 theme, please refer the awesome article here. Let us now start creating a theme to show how to use dark theme/ light theme in Drupal 8 or Drupal 9.
 
The file structure will look like this: 

 

Now, update the header section inside the page.html.twig with the following code.
page.html.twig

   
     
        {{ page.branding }}
        {{ page.navigation }}
       
         
           
           
         
       
     
   
 
The rest of the HTML structure will be dependent on your design or requirements.
Once you are done with the HTML structure, it is time to make them look nice by styling the elements in CSS.
First, you have to create all the default variables which will be responsible for the colors on Light/ Dark mode.

style.css

:root {
  --color-background: #f0f0f0;
  --color-header: rgb(14, 33, 141);
  --color-header-text: #aecafa;
  --color-text: #2c0000;
  --color-card-bg: #fff;
  --color-link: rgb(255, 0, 0);
}
/* Variable decleration for dark mode */
[data-theme="dark"] {
  --color-background: #1a1a1a;
  --color-header: #aecafa;
  --color-header-text: 0e218d;
  --color-text: #d3d3d3;
  --color-card-bg: #435561;
  --color-link: #24ce24;
}

Now that you are done defining the variables, it is time to add style to the Header section to get the required result.
style.css
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom-right-radius: 10px;
  border-bottom-left-radius: 10px;
  background-color: var(--color-header);
}

.header a {
  color: var(--color-header-text);
  text-decoration: none;
  font-weight: bold;
}

.region-navigation {
  display: flex;
  justify-content: center;
}

ul.menu {
  display: flex;
  justify-content: center;
}

ul.menu li {
  margin-right: 30px;
}

.switch-wrapper {
  display: flex;
  align-items: center;
}

.switch {
  display: inline-block;
  height: 34px;
  position: relative;
  width: 60px;
}

.switch input {
  display: none;
}

.slider {
  background-color: white;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  transition: 0.4s;
}

.slider:before {
  background-color: rgb(255, 196, 0);
  bottom: 4px;
  content: url("../assets/sunny-day.svg");
  height: 26px;
  left: 4px;
  position: absolute;
  transition: 0.4s;
  width: 26px;
}

input:checked + .slider {
  background-color: rgb(36, 36, 36);
}

input:checked + .slider:before {
  transform: translateX(26px);
  content: url("../assets/night.svg");
  background-color: rgb(59, 116, 223);
}

.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}
Please note that the styling may vary according to your requirements.
After all the styling, it is now time to write some functionality in Jquery code.
The Jquery code will look something like this (script.js in our case)

script.js

(($, Drupal) => {
  Drupal.behaviors.mainMenu = {
    attach(context) {
      const toggleSwitch = document.querySelector(
        '.switch input[type="checkbox"]'
      );
      const currentTheme = localStorage.getItem("theme");

      if (currentTheme) {
        document.documentElement.setAttribute("data-theme", currentTheme);

        if (currentTheme === "dark") {
          toggleSwitch.checked = true;
        }
      }

      function switchTheme(e) {
        if (e.target.checked) {
          document.documentElement.setAttribute("data-theme", "dark");
          localStorage.setItem("theme", "dark");
        } else {
          document.documentElement.setAttribute("data-theme", "light");
          localStorage.setItem("theme", "light");
        }
      }

      toggleSwitch.addEventListener("change", switchTheme, false);
    },
  };
})(jQuery, Drupal);

And don’t forget to include your JS and CSS files inside your theme_name.libraries.yml file.

global-styling:
  version: 1.x
  css:
    theme:
      css/style.css: {}
  js:
    js/script.js: {}
  dependencies:
    - core/jquery
- core/drupal
Now clear the site cache to see the result. Your end result should look like this :

 

 

UI/UX developers sometimes prefer creating two separate themes for light and dark themes. However, an easier and more time-saving option would be to design the theme in a way where the user can toggle between light and dark modes easily. I hope you have found this article on implementing the toggle in Drupal 8 (or 9) helpful. Contact us to know more about our Drupal development services and how we can help you.

Drupal Planet Drupal Development Drupal Drupal 9 Shefali ShettyApr 05, 2017 Subscribe For Our Newsletter And Stay Updated Subscribe

Leave us a Comment

  Shefali ShettyApr 05, 2017 Recent Posts Image How to toggle between Dark and Light Mode in Drupal 8 (or 9) based on user preference Image Testing Your Drupal Website just got easier with Behat (A comprehensive tutorial) Image Design VS Code – Why should they go hand-in-hand? Want to extract the maximum out of Drupal? TALK TO US Featured Success Stories

Know more about our technology driven approach to recreate the content management workflow for [24]7.ai

link

Find out how we transformed the digital image of world’s largest healthcare provider, an attribute that defined their global presence in the medical world.

link

Discover how a Drupal powered internal portal encouraged the sellers at Flipkart to obtain the latest insights with respect to a particular domain.

link

Debug Academy: Why you should focus on learning HTML and CSS

1 week 1 day ago
Why you should focus on learning HTML and CSS

You’ve probably noticed we have a course called “HTML/CSS Ramp-Up” and are wondering if this is the right place for you to start on your journey to learning how to build websites. You could be looking to do front-end development, you could be looking to do site-building in Drupal or Acquia’s Site Factory, or you could still be wayfinding and trying to figure out if front-end or back-end is the right path for you. No matter the case, the HTML/CSS ramp-up course Debug Academy has put together will give you an introduction to the essential components of every website.

lindsey.gemmil… Mon, 09/14/2020

Tag1 Consulting: Simplifying your workflow: Getting started with DDEV

1 week 1 day ago

In his Drupal 4 Gov webinar Using tools and Git workflow best practices to simplify your local development, Tag1 Senior Infrastructure Engineer Greg Lund-Chaix talks about some of the ways that teams struggle when they become successful and need to learn to scale. One of his primary focuses for teams is helping them learn how to improve their development workflow.

Read more [email protected]… Mon, 09/14/2020 - 08:46

Angie "webchick" Byron: Running both Drush 8 (for Drupal 7) and Drush 10 (for Drupal 9) at the same time

1 week 1 day ago
Background

These days, my life is all migrations, all the time, which means I often need to run Drupal 7 and Drupal 9 sites side-by-side simultaneously to compare the results.

The problem?

The latest version of Drush, Drush 10, only works on Drupal versions 8.4+. To use Drush on Drupal 7 sites, you need an older version, Drush 8. And both of them use the command drush. Tricksy...

There are various Drupal-knowledgeable local development environments, such as Acquia Dev Desktop, Lando, DDEV, and Drupal VM that handle this complexity for you, which is super handy. However, the rest of my team uses a "from scratch" local development environment on Mac OS X, so I needed to figure out how to do this by hand.

I made a Twitter inquiry if there was an existing tutorial on how to do this, and since I couldn't find one, here it is. :) Hopefully this helps others, as well! (Thanks to those who responded, pointing me in the right direction!)

1. Installing Drush 8 for your Drupal 7 sites

https://docs.drush.org/en/8.x/install/ are the installation docs for Drush 8. While the recommended way to install all versions of Drush is to pull it in as a local Composer dependency (we'll go through that route in a sec), almost 0% of Drupal 7 sites are installed with Composer (and mine certainly weren't :P), since Composer was not even a "thing" back then. This means you typically need to install it instead globally, so it's available to all D7 sites on your computer.

To do this:

1. Go to https://github.com/drush-ops/drush/releases and download the latest Drush 8 release's "drush.phar" file (as of this writing, 8.4.1).

2. Test that it's working by attempting to run it with PHP:


$ php PATH_TO_DRUSH/drush.phar --version
Drush Version : 8.4.1

3. Since it's super annoying to type php PATH_TO_DRUSH/drush.phar all the time, make it executable and move it somewhere in your $PATH.


cd PATH_TO_DRUSH
chmod +x drush.phar
sudo mv drush.phar /usr/local/bin/drush

Now you can execute with just drush [whatever] from within a given Drupal 7 site's docroot. Perfect!

2. Installing Drush 10 for your Drupal 8/9 sites

Well. Perfect except for the not-so-minor detail that despite Drush 8 working surprisingly well for not being supported in Drupal 8.4+, it is nevertheless not supported in Drupal 8.4+. Also, there are newer, useful commands in Drush 10 that are not available in Drush 8, such as drush config:satus.

So! Let's fix this by adding Drush 10 to our Drupal 9 site. https://www.drush.org/install/ has the installation instructions.

The "best practice" way to do this is in Drupal 9, since the code base has already been "Composer-fied" out of the box (thanks, Composer initiative!) is to add Drush in as a dependency:


cd PATH_TO/drupal9
composer require drush/drush

Check to make sure it's working:


drush --version
Drush Commandline Tool 10.3.4

Move back to your Drupal 7 directory and you should see:


drush --version
Drush Version : 8.4.1

Wicked!

3. That's it. Don't do anything else. ;)

I figured I would need Drush Launcher to finish things off, but it appears that Drush 8 has some basic launch-like capabilities in it, because it automatically switches from one to the other seamlessly. Nifty!

And in fact, if you do install Drush launcher, Drush 8 won't work anymore. (Womp, womp.) Which brings us to...

Troubleshooting
It says "command not found" when I type "drush"
That probably means that the place you moved Drush 8 to is not in your $PATH. Try echo $PATH and move it to somewhere in that list, or add your desired location to $PATH in ~/.bash_profile
It says "mv: rename drush.phar to /usr/local/bin/drush: No such file or directory," but /usr/local/bin exists!
Don't forget to chmod it first.
When I run "drush" from within Drupal 7, it says "The Drush launcher could not find a Drupal site to operate on."
Ah, you skipped the tutorial and installed Drush Launcher. ;) Following those steps will blow away your Drush 8 installation, which also lives at /usr/local/bin/drush. You can either re-do the steps above to use Drush 8, and thus kill your Drush Launcher (Drush 8 seems to have basic Drush Launcher capabilities, which is nice), or you can Composer-ize your Drupal 7 code base and then add Drush 8 as a dependency, just as you did with Drush 10, with:

composer require drush/drush:~8

Tags: drupaldrushdrupal 7drupal 9migratelocalhost

Ryan Szrama: Reflecting on the changes to Drupal Association election voter eligibility

1 week 2 days ago

The Drupal Association (D.A.) Board decided in May to update the eligibility criteria for voting in the election of At-Large Directors of the D.A. These are the members of the Board whose purpose is to “reflect and represent the Drupal community at large,” and their election is to be “by the community” and dependent on “[ratification] by the rest of the Board.” We changed the voter eligibility criteria for these elections from requiring community members to have logged in to drupal.org in the year prior to nominations opening to requiring them to have an active D.A. Membership prior to the start of voting.

As we wrote in our statement about this resolution, we believe we failed as a Board to consider how to engage the community and communicate the change proactively. I personally endeavored to answer as many questions as I could in various threads on Twitter, but Twitter is a poor place for long answers, nuance, or organized communication. As such, I solicited specific questions I could answer in this post as a member of the Board who approved the resolution.

A word before I dive in: this post contains my personal recollections of fact and statements of opinion, and I’m not speaking herein on behalf of the full Board. We’re fifteen different individuals with unique perspectives on this discussion and virtually every topic we approach. In places where I’m answering questions of fact, I ask the reader to be gracious - just because I’m stating how something occurred (e.g. “neither the discussion nor the final resolution were controversial to the Board”) doesn’t mean I or the Board don’t understand competing opinions or wouldn’t accept other points of view as legitimate alternatives.

I also wish I could have prepared this post faster, but finding a solid 8 hours to give to the task has proven difficult. My family was gracious to give me most of this Saturday for it, and while I'm sure I won't satisfy every critic, I hope the post is received as my honest attempt to plainly, directly answer your questions.

Ok, diving in!

I’m going to follow Sally Young’s list of questions as a general outline and try to address as many questions or concerns as I can that were raised in the various Twitter threads by other community members.

1. What was the impetus for the change being tabled?

I didn’t write the initial proposal and can’t recall which specific conversation would have birthed it. However, I believe the resolution was generally a byproduct of recurring conversations at Board meetings about continuing to evolve the D.A. and its Board in pursuit of its mission. These conversations include comparative analysis, advice and counsel from outside experts, and books and reference material designed to help organizations like ours mature.

You can see the results of these conversations in who we hire to be Executive Director, who we recruit to serve on the Board, how we work to diversify our staff, programs, and revenue, and how we clarify who our stakeholders are and how we serve them. These conversations have included questions about the meaning and purpose of both individual and organizational supporters of the D.A., and as far as I can recall, our discussions on the topic of the resolution were primarily a matter of alignment - that people who desire a say in who should lead the organization, or who desire to serve as its leaders, ought to be individually committed to the organization through a D.A. Membership.

I understand there are people who conscientiously object to D.A. Membership for a variety of reasons, including its structure, its prior decisions or actions, its current programs, or a sense that contribution “ought to be enough.” While I wish they were able to find common cause and become advocates for the D.A. as the primary organization responsible for the Drupal community’s infrastructure, I don’t begrudge them their abstention. I would likely even agree with them on various critiques of the D.A. - nobody believes it's perfect! I just don’t believe people who intentionally refuse D.A. Membership or who believe the D.A. as it is shouldn’t even exist must be given a say in who leads it.

(Note: lest I be accused of saying such people don’t matter, please understand that I am talking about the leadership specifically of the D.A., which is distinct from but exists to serve the Drupal community at large. You can be a contributor to the project and a leader in the community without believing in or respecting the D.A. While I might disagree with your position, it wouldn’t make me respect you or value your contributions any less, nor would I expect the D.A. not to work hard to serve you. By nature it serves the whole community, and in many areas it solicits guidance and feedback from a wide variety of individuals, working groups, committees, etc. to attempt to do so even better.)

To Sally’s follow-up questions on this point regarding specific expectations for engagement or data-driven analysis, all I can say, even if it’s unsatisfying, is this wasn’t a data-driven decision. We saw it as correcting a misalignment and trust the staff of the D.A. to find new ways to activate and empower individuals who maintain a D.A. Membership, including those who perhaps through this very discussion engage the D.A. for the first time.

2. What was the process of this being proposed?

The resolution was presented to the Board for discussion at our meeting in May. From my memory, we had previously discussed this topic at an earlier strategy meeting, so I don’t believe it was a surprise to anyone or that anyone expressed concerns with respect to the text of the resolution itself. We approved it by the unanimous consent of all those present, including myself (who previously served as an At-Large Director) and our two currently serving At-Large Directors.

3. What percentage of people who voted in the previous election were D.A. members?

Unfortunately, I don’t know the answer to this, and I can’t say off the top of my head what it would take to find out (i.e. do we have the data in the right shape and places to run such a query?). I’m sure a significant percentage of voters were not D.A. members, because only a small fraction of all eligible voters under the prior criteria were D.A. Members. (I do expect D.A. Members were overrepresented in the vote; I'd love to see the actual statistics on this, too.)

That said, I do know that we have significantly more Individual Members of the D.A. than we have had participants in any recent election. I gathered the statistics from the last 4 elections from the D.A. blog, and the numbers aren’t particularly encouraging. (I’ll save my reflections on the trend for another post; trying to stay focused here...) We have over 2,900 Individual Members in our directory, but we have averaged only 1,345 voters over the last four elections with an average turnout of only 1.59% of eligible voters.

I’m very curious to see the numbers from the upcoming election.

4. [With respect to the text of the by-laws stating the corporation has no members,] when an individual signs up for a membership, what status are they within the organization?

(Let me state the obvious here: I am not a lawyer or an expert in nonprofit law. While I consulted a lawyer to understand the meaning of our by-laws on these points, the following still just reflects my personal understanding … i.e. I could be stating something incorrectly, apologies in advance.)

The D.A. is a board driven organization with a self-perpetuating board as opposed to a member driven organization where members directly elect the organization’s leaders. As stated in our by-laws, the Board of Directors “exercise or direct the exercise of all corporate powers,” and with respect to our community elections, the Board must ratify the winners before they become part of the Board.

I wasn’t party to the creation of the D.A. to speak to why this specific structure was chosen, but I’ve read various articles on the advantages and disadvantages of each. I believe our structure gives us room to think more strategically / long term, as our nominations process allows us to ensure continuity of purpose year over year, but it also centralizes decision making in a way that may make some stakeholders unhappy. (This particular debate is a case in point.)

The D.A. doesn’t have members who vote for directors; we have a membership of people from all over the world who have an interest in the success of the Association’s mission, somewhat similar to other nonprofits like NPR. (As one example, you can refer to the membership page of the nonprofit supporting public radio in South Carolina.) I personally think we’ll need to rename the “Drupal Association Membership” to clarify this distinction, finding a term that is not semantically overloaded, in much the same way that we have to be careful about words like “Partner” or “Affiliate”.

In short, a person’s “status in the organization” is unchanged when they sign up for a D.A. Membership, but they do receive a variety of benefits for joining.

5. [With respect to the text of the by-laws describing the nature of At-Large Directors and their election process,] will this be changed?

I’m not sure if Sally means the name, “At-Large Directors”, or the text related to the election process. I’ll answer each one in turn just in case, as other folks have echoed these questions in various Twitter threads.

First, will we rename At-Large Directors?

The answer to that is no, they have and will continue to “reflect and represent the Drupal community at large,” and as such will still be referred to as “At-Large Directors.” Speaking from personal experience, when I served as an At-Large Director, my input was regularly, directly solicited on a variety of community impacting topics. I expect this to continue to be the case.

I see two basic objections to this position:

On the one hand, some people believe every member of the Drupal Association Board ought to be directly elected by members of the nonprofit, and as such “At-Large Director” was a misnomer even before we made this change. I understand this critique, but I personally consider our structure to be a foregone conclusion and theorizing about “how it could have been” to be interesting but impractical. (Speaking of “how it could have been,” imagine if the suggestion to use Certified to Rock for qualification had gained traction…)

On the other hand, some people believe that restricting eligible voters in these elections to people who maintain D.A. Memberships means the Directors cannot be described as representatives of “the Drupal community at large.” I think there’s merit to this point but that there’s room for disagreement, especially in light of historical precedent.

Our by-laws are ambiguous about what constitutes the “community” with respect to elections, and even our earliest discussions about elections demonstrate the debate was about what the criteria ought to be beyond simple self-identification as a member of the Drupal community. Notes from that era specifically ask the question, “Who is the Drupal community we're trying to capture in our voting eligibility criteria?”

In other words, from the very beginning, our debate hasn’t been about how to maximally define “community” but about how to define “community” in a way that is clear, concrete, and ensures that everyone who does vote is inarguably part of the community. After those initial discussions, D.A. Memberships and drupal.org user accounts were the two final criteria being considered for the election, and both were described as “not remotely represent[ing] the ENTIRE community.” No one objected then that that meant the directors could not be called “At-Large Directors” as a result. That same post also reflected an understanding “that this definition could shift over time,” including in a hypothetical future where we provided a “sliding scale cost for membership, or free memberships to certain subsets of the community.”

I revisit this history for a couple reasons. It demonstrates that the decision of the Board in May was very much in line with the earliest thinking of the Drupal community on this topic, and it comes at a point after we’ve long provided a sliding scale for the Individual Membership price and in conjunction with a policy that allows anyone to request a free Membership.

Even more poignant, from a process standpoint, it’s clear that from the very beginning the D.A. Board was leading the process. The election committee tasked with defining election policies was constituted by the Board, populated by the Board, reported to the Board, and produced recommendations that required Board approval prior to the first election. If Board leadership wasn’t illegitimate then, it isn’t today. That said, even if our decision was both within our realm of responsibility and in keeping with the spirit and positions of previous discussions, I still very much agree with the Board statement that we should have discussed and defined a communications strategy at the time we made it.

Going back to the second part of question 5, will we revise the by-laws with respect to the election process?

On this point, my current answer is I’m not sure but probably. I don’t believe the changed criteria conflicts with the by-laws any more than the prior criteria did - in either case, we’re restricting who, among all the people in the world who might consider themselves part of the Drupal community, is actually eligible to vote.

I do think we should consider amending the by-laws to point to a definitive policy document that addresses both how we determine voter eligibility and what it means for the Board to ratify an elected candidate.

6. Do the [new rules] create a different kind of barrier and why?

Yes, the new rules create a different kind of barrier, no bones about it. I know others disagree, but I don’t personally find the new criteria particularly more onerous than the old criteria.

Additionally, the new criteria create more room for people to participate under certain conditions, because eligibility is no longer determined based on when you last logged in to drupal.org. I know that’s a “simple” requirement, but it’s also fairly arbitrary. Even if you’d participated in Drupal events or worked at a Drupal agency, if you hadn’t created an account until after nominations opened or logged in to an existing account in the year prior to that date, you were ineligible to vote and without recourse to become eligible. Under the new criteria, you simply must log in or create an account and then become a D.A. Member at any point before the election in order to participate. These may be freely acquired by those who cannot afford the variable price fee or whose organizations do not already provide them an Individual Membership.

That answers the “what has changed” and as to the “why”, as I stated above, I believe the new criteria better align voter eligibility with the purpose of the vote. You are electing a Director of the D.A., which is a distinct entity within the Drupal community, and as such it’s more relevant whether or not you have a D.A. Membership than whether or not you have logged in to drupal.org in the year prior to nominations opening for a new election.

7. What effect will this [barrier] have on under represented groups?

I think its impact will be negligible but likely impossible to quantify. As I pointed out above, even in 2012, election discussions foresaw a shift in eligibility criteria, especially after the means of acquiring a D.A. Membership expanded and / or became more accessible. I understand some consider having to ask for a free Membership to be an impediment unto itself, but I’m not convinced this will be a practical barrier in the context of our community, which includes many such scholarships, grants, sponsorships, etc. and a no-questions, no-shame based approach to the awarding of these.

Furthermore, what Pedro Cambra writes in his self-nomination is not entirely correct, that “You can still vote even if you’re not a member of the Drupal Association.” I understand the intent of this heading, but the D.A. is literally activating a D.A. Membership upon request, with all the benefits that come with it, not just doling out voting rights. It is not a lesser Membership; there is no asterisk beside the badge on grantees’ user profiles. They are members, and upon becoming members, they are eligible to vote.

(Yes, as Sally points out, one person was directed to the normal registration form after requesting a D.A. Membership; this was an unfortunate mistake that was rectified the next day. I asked about it as soon as it was brought to my attention - a supporting staff member had not immediately understood the nature of the request. It was corrected, the process was amended to prevent further mistakes, and ultimately no one who has requested a membership has been denied one.)

I remain confident that anyone who wants to participate in this election will be able to do so, and I appreciate the efforts of the D.A. staff to communicate the changes in a variety of channels and generally improve the process for helping the community get to know their nominees. Might someone still be surprised come election day? There’s always a chance, but I don’t consider it any greater a chance with the new criteria than with the old.

8. Did the Association consider adding a free option to its regular membership sign up form?

I do not know the answer to this question or the follow-ups. I can only say I wasn’t party to any such conversation, nor have I heard of any taking place.

Personally speaking, I would expect such decisions to be left to the Executive Director and the D.A. staff. The Board passes resolutions and works with the Executive Director at a higher level to prepare budgets, organize priorities, plan the organization’s strategy, etc. but leaves the implementation details up to her and the staff. This goes for any number of areas of the Association's operations, not just the specifics of managing these elections, and the staff are always careful, competent, and eager to do right by the community in their work.

In closing...

I've been a part of the community since 2006 and a part of the D.A. Board since 2017. I first met other members of the Drupal community in person at DrupalCon Barcelona 2007, and I met my partners and many of my team members at Commerce Guys and Centarro through subsequent DrupalCons. I grew my career through contributions on drupal.org. The Drupal Association undergirds these things today, and as such, I strongly believe in the D.A. and its mission, want it to succeed, and want as many people as possible to join me in supporting it.

We do have a strong roster of candidates in the current election, and voting for the next At-Large Director begins on Tuesday, September 15th. I encourage you to learn more about the candidates and secure your D.A. Membership by September 14th in order to join me in this upcoming election.

The Russian Lullaby: Books/ Drupal 9 Module Development

1 week 4 days ago

For a long time I was thinking about write or not a review of the Drupal 8 Module Development (the former edition of the current). For me there were two very important keys: on the one hand, it was a very ambitious book in terms of scope and content (so it was an important challenge to make a synthesis on its simple review). On the other hand, Drupal 9 was already on its way and it was possible that it would be deprecated quickly. Luckily, Drupal 9 has already arrived and the transition from 8 to 9 has not only not been at all traumatic (there are still many people trapped in the crack between …

MidCamp - Midwest Drupal Camp: Join us to help plan MidCamp 2021

1 week 4 days ago
Join us to help plan MidCamp 2021

Please join us for our first MidCamp 2021 planning meeting!

Why come?

Because we value giving back to the Drupal community and this is one way you can do that.

What should I expect?

That's mostly up to you -- there are a lot of roles and skillsets needed to put on a conference like MidCamp. Regardless of what you do day-to-day, you can find a fit.

What if I don't live in Chicago?

That's OK! The planning of things is done remotely. A good portion of the planning team doesn't live in or near Chicago. People join because they care about Drupal and want to help make MidCamp happen.

How to join?

We'll be using a Waiting Room for the Zoom, so please RSVP if you plan on joining so we're able to let you in.

Evolving Web: Drupal 8/9 Migration: Migrating Hierarchical Taxonomy Terms

1 week 5 days ago

When you migrate relations between two different entities, you usually migrate the target entities first and then the source entities.

But what if the target and source are of the same entity and bundle type? How do you ensure that the target entity gets migrated before the source entity?

Have you run into a chicken-versus-egg problem?

In this article, we'll look at how to migrate hierarchical taxonomy terms to Drupal 8 or Drupal 9 by following along with an example migration. We’ll address the above questions to give you a good understanding of how to implement similar migrations in your projects.

The Drupal 8/9 Migration Tutorial Series

Before We Start

👩‍💻 Get up to speed on the latest version of Drupal! Join us on September 24 for a free webinar on Drupal 9.

The Problem

We have received these CSV files from our imaginary client:

We need to:

  • Migrate categories including their relationships (parent categories) from categories.csv
  • Migrate articles from articles.csv

Let’s get started.

Setting up the Migrations Create the migration module

We need to create a module for our migrations. In this example, we're naming it migrate_example_hierarchical_terms.

We then need to add the following modules as dependencies in the module declaration:

Create a migration group

To group the migrations, we also need to create a migration group. To do so, we’ll create a fairly simple configuration file so that the group gets created when the module is installed.

The file’s contents should be as follows:

id: hierarchical_terms label: Hierarchical Terms Group source_type: CSVWriting the Migrations

Next thing to do is to write the actual migrations. For our requirements, we need to write two different migrations: one for categories and one for articles. The hierarchy stuff will be handled as part of the categories migration.

Since Drupal 8.1.x, migrations are plugins that should be stored in a migrations folder inside any module. You can still make them configuration entities as part of the migrate_plus module but I personally prefer to follow the core recommendation because it's easier to develop (you can make an edit and just rebuild cache to update it).

Write the category migration

For the categories migration, we're creating a categories.yml file inside the migrations folder. This migration uses CSV as source, so we need to declare it like this:

source: plugin: 'csv' path: 'modules/custom/migrate_example_hierarchical_terms/data/categories.csv' delimiter: ',' enclosure: '"' header_offset: 0 ids: - name fields: 0: name: name label: 'Name' ...

The destination part of the migration is pretty standard so we'll skip it, but you can still look at it in the code.

For the process, the important part is the parent field:

parent: - plugin: migration_lookup migration: categories source: parent - plugin: default_value default_value: 0

We're using the migration_lookup plugin and the current migration (categories) to look for the parent entities. We're allowing stubs to be created (by not setting no_stub: true) so that if a child term is migrated before its parent term, the parent will be created as a stub and it will be completed later with the real data.

We're also defaulting to 0 as parent if no parent is set in the source data. This way, the hierarchy will be preserved when running the migration.

Write the article migration

To migrate the articles, we've created the articles.yml migration file. If you have previous experience with migrations in Drupal 8, it's pretty straightforward. It's also using CSV as a source, so its source section is pretty similar to the one in the categories migration. The destination is set to be the article bundle of the node entity type.

The process section looks like this:

process: title: title body/value: content field_category: - plugin: migration_lookup migration: categories source: category

Title from the CSV file is mapped directly to title in the node. The content column in the CSV file is mapped to the value sub-field of the body field. For field_category, we're also using the migration_lookup plugin to get the categories that we've previously migrated.

We're also setting a dependency to the categories migration to ensure that categories run before articles:

migration_dependencies: required: - categories

Now, everything is in place and we're ready to run the migrations.

Running the Migrations

Given that we have set dependencies, we can instruct Drupal to run the migration group and it will run the migrations in the right order.

To do so, execute drush mim --group=hierarchical_terms. The output will look like this:

[notice] Processed 11 items (7 created, 4 updated, 0 failed, 0 ignored) - done with 'categories' [notice] Processed 10 items (10 created, 0 updated, 0 failed, 0 ignored) - done with 'articles'

Note that the counts for categories are not what you'd expect looking at the data. This is because of the stub creation that happened during the migration. However, if you run drush ms, the output will be as expected:

----------------------------------------------- -------------- -------- ------- ---------- ------------- --------------------- Group Migration ID Status Total Imported Unprocessed Last Imported ----------------------------------------------- -------------- -------- ------- ---------- ------------- --------------------- Hierarchical Terms Group (hierarchical_terms) categories Idle 9 9 0 2020-08-21 19:18:46 Hierarchical Terms Group (hierarchical_terms) articles Idle 10 10 0 2020-08-21 19:18:46 ----------------------------------------------- -------------- -------- ------- ---------- ------------- ---------------------Next Steps + more awesome articles by Evolving Web

Evolving Web: Drupal 8 Migration: Migrating Hierarchical Taxonomy Terms

1 week 5 days ago

When you migrate relations between two different entities, you usually migrate the target entities first and then the source entities.

But what if the target and source are of the same entity and bundle type? How do you ensure that the target entity gets migrated before the source entity?

Have you run into a chicken-versus-egg problem?

In this article, we'll look at how to migrate hierarchical taxonomy terms to Drupal 8 or Drupal 9 by following along with an example migration. We’ll address the above questions to give you a good understanding of how to implement similar migrations in your projects.

The Drupal 8 Migration Tutorial Series

Before We Start

👩‍💻 Get up to speed on the latest version of Drupal! Join us on September 24 for a free webinar on Drupal 9.

The Problem

We have received these CSV files from our imaginary client:

We need to:

  • Migrate categories including their relationships (parent categories) from categories.csv
  • Migrate articles from articles.csv

Let’s get started.

Setting up the Migrations Create the migration module

We need to create a module for our migrations. In this example, we're naming it migrate_example_hierarchical_terms.

We then need to add the following modules as dependencies in the module declaration:

Create a migration group

To group the migrations, we also need to create a migration group. To do so, we’ll create a fairly simple configuration file so that the group gets created when the module is installed.

The file’s contents should be as follows:

id: hierarchical_terms label: Hierarchical Terms Group source_type: CSVWriting the Migrations

Next thing to do is to write the actual migrations. For our requirements, we need to write two different migrations: one for categories and one for articles. The hierarchy stuff will be handled as part of the categories migration.

Since Drupal 8.1.x, migrations are plugins that should be stored in a migrations folder inside any module. You can still make them configuration entities as part of the migrate_plus module but I personally prefer to follow the core recommendation because it's easier to develop (you can make an edit and just rebuild cache to update it).

Write the category migration

For the categories migration, we're creating a categories.yml file inside the migrations folder. This migration uses CSV as source, so we need to declare it like this:

source: plugin: 'csv' path: 'modules/custom/migrate_example_hierarchical_terms/data/categories.csv' delimiter: ',' enclosure: '"' header_offset: 0 ids: - name fields: 0: name: name label: 'Name' ...

The destination part of the migration is pretty standard so we'll skip it, but you can still look at it in the code.

For the process, the important part is the parent field:

parent: - plugin: migration_lookup migration: categories source: parent - plugin: default_value default_value: 0

We're using the migration_lookup plugin and the current migration (categories) to look for the parent entities. We're allowing stubs to be created (by not setting no_stub: true) so that if a child term is migrated before its parent term, the parent will be created as a stub and it will be completed later with the real data.

We're also defaulting to 0 as parent if no parent is set in the source data. This way, the hierarchy will be preserved when running the migration.

Write the article migration

To migrate the articles, we've created the articles.yml migration file. If you have previous experience with migrations in Drupal 8, it's pretty straightforward. It's also using CSV as a source, so its source section is pretty similar to the one in the categories migration. The destination is set to be the article bundle of the node entity type.

The process section looks like this:

process: title: title body/value: content field_category: - plugin: migration_lookup migration: categories source: category

Title from the CSV file is mapped directly to title in the node. The content column in the CSV file is mapped to the value sub-field of the body field. For field_category, we're also using the migration_lookup plugin to get the categories that we've previously migrated.

We're also setting a dependency to the categories migration to ensure that categories run before articles:

migration_dependencies: required: - categories

Now, everything is in place and we're ready to run the migrations.

Running the Migrations

Given that we have set dependencies, we can instruct Drupal to run the migration group and it will run the migrations in the right order.

To do so, execute drush mim --group=hierarchical_terms. The output will look like this:

[notice] Processed 11 items (7 created, 4 updated, 0 failed, 0 ignored) - done with 'categories' [notice] Processed 10 items (10 created, 0 updated, 0 failed, 0 ignored) - done with 'articles'

Note that the counts for categories are not what you'd expect looking at the data. This is because of the stub creation that happened during the migration. However, if you run drush ms, the output will be as expected:

----------------------------------------------- -------------- -------- ------- ---------- ------------- --------------------- Group Migration ID Status Total Imported Unprocessed Last Imported ----------------------------------------------- -------------- -------- ------- ---------- ------------- --------------------- Hierarchical Terms Group (hierarchical_terms) categories Idle 9 9 0 2020-08-21 19:18:46 Hierarchical Terms Group (hierarchical_terms) articles Idle 10 10 0 2020-08-21 19:18:46 ----------------------------------------------- -------------- -------- ------- ---------- ------------- ---------------------Next Steps + more awesome articles by Evolving Web

drunomics: Custom Elements: A solution for soft-decoupled Drupal!

1 week 5 days ago
Let's decouple Drupal - Well, what exactly?

When it comes to decoupling, it turns out there are many options on how to decouple. Not only are there many technology choices in choosing the right frontend framework and APIs involved, the questions become also more foundational: Which system should be in charge of handling different aspects of the application, e.g. routing, placing blocks or authentication?

So before moving on, we need to clarify what exactly we want to achieve:

Clarifying goals: Why to decouple?

For us, the main reasons are:

Independent frontend development

By separating the frontend from the backend, frontend development can happen completely independent of the backend. So frontend developers do not have to know Drupal development, but can focus solely or their part: the frontend. That way, it's much easier to find and onboard frontend developers.

Easier performance optimization

While efficiently lazy-loading CSS or JS assets of a page is quite hard to do with Drupal, modern frontend technologies handle this with breeze and simply lazy-load pre-built asset chunks as needed. Furthermore, the frontend can better optimize the page loading experience (and the assets needed per-page) since the frontend has the knowledge of what exactly is needed by which frontend component.

Re-usable frontend components

Re-usable frontend components - including asset dependency management - are a solved problem in the Javascript world and all the various Javascript frontend frameworks provide that. Additionally, tools like Storybook make it really easy to build up your own component library.

Modern frontend and UX

By building upon modern frontend tooling we can provide a more app-like UX to our users, handle client-side route changes and only reload and repaint what's needed when navigating pages. The web page can become and feel more app-like, or even be turned into a Progressive Web App that does more than providing an offline copy of the site!

Challenges faced

This sounds all good - but there are lots of challenges that must be well-considered:

Re-inventing the wheel

By throwing away Drupal's frontend, you also throw away all the existing integration Drupal provides with its own frontend. Besides the more obvious, like handling forms and logins, features like contextual edit links, previews or the layout builder just do not work out of the box anymore. So one has to develop alternative solutions for all those features - if needed. Depending on the solutions choosen, this can be a lot of work.

Server-Side-Rendering and Hosting

For delivering a decent user experience and being friendly to robots (Google) some sort of pre-rendering is needed on the server. So this needs extra thought and comes with new infrastructure requirements (Node.js) that, come at a cost, and must be considered when choosing where to host.

Cold cache performance

When the Drupal backend is connected via JSON API or GraphQL a first, uncached page load typically needs various kind of data, quickly ending up in multiple API requests to the backend. Since all of those need to be resolved on a cold-cache page hit requests possibly end up really slow and lead to slow first page loads.

Coupling of the frontend to the backend

When the frontend talks to Drupal via its default JSON or GraphQL APIs, the frontend needs to know about Drupal's data structure. Field names, their types and entity relationships are no Drupal interna anymore, but become part of the contract between the backend and the frontend, limiting the possibilities to develop them separately. One could implement custom JSON endpoints or GraphQL Schema to mitigate and fine-tune that.

Our solution: Rendering into Custom Elements markup

We figured that in order to reach the mentioned goals, we can use a soft approach to decoupled Drupal in order to keep more of Drupal's features available. The basic idea is that Drupal keeps rendering pages by providing the main page content as custom elements (markup). Then, this simplified markup can be picked up by client-side frameworks like Vue.js to handle rendering the elements client-side.

An example of custom element would be the following markup for a Twitter paragraph:

<pg-twitter src="https://twitter.com/bmann/status/1283090375742091264"> <h3 slot="title">#Driesnote suggesting to ship an official component for React and Vue for managing menus</h3> </pg-twitter>

Note that we use pg as abbreviation for paragraph here. Or a quote paragraph:

<pg-quote> <h1 slot="title">a quote from twitter...</h1> <p>#Driesnote suggesting to ship an official component for React and Vue for managing menus<br>Ship it in NPM as those devs expect.</p> <span slot="author">Boris Mann</span> </pg-quote>

Generating this markup, is exactly what the Custom Elements module does. The module renders the data of all visible fields either as attribute to the custom element tag, or as nested tag with a slot attribute.

As custom elements are part of Web components specification, web components provide a good fit for rendering the content client-side, but other client-side frameworks like Vue.js or React.js can pick up the data and render it as well - so there is plenty of choice for the best-suiting client-side solution.

So what about the page template?

Since the header and footer area is pretty static for most of the time on most of our sites, we figured they are best implemented by mostly static components in the frontend. Any dynamic parts, like meta tags or navigation elements can be complemented with data provided by (long-cached) API calls or even computed client-side (for example, the active menu item). If necessary, it's easy to re-render parts of it and client-side frameworks like Vue.js and React can handle updating only the necessary bits when navigating pages.
While the dynamic per-page content is provided by the backend in a single API response per page, the header and footer can be controlled by the frontend. The frontend application takes the custom element content and renders it, next to taking care of updating essential page metadata like meta tags.

 

Thus, for rendering individual pages, the frontend needs to fetch the main content - rendered as Custom Elements - as well as any page metadata that it needs for rendering the page from the backend. For that, we've implemented the Lupus Custom Elements Renderer module which turns Drupal into an API backend providing exactly that.

Summing up

By rendering the page shell and custom element content in a frontend framework of our choice, we achieve all of our goals stated. Moreover, the custom elements "format" provides a good way of decoupling the frontend of the backend, since any Drupalisms or backend complexities in the data model can easily by translated into a meaningful collection of custom elements. Those elements comprise a well-defined structure representing your site's content elements and transferring the necessary data to the frontend. In the frontend, the custom elements map nicely to Vue/React/Web/... components.

By keeping Drupal's page routing mechanism, we can keep using Drupal's path handling, including useful features like editor controlled path aliases or redirects. Since page responses are handled as whole by Drupal, we optimize and cache full-page responses and leverage Drupal's existing cache infrastructure and optimized cache tags for caching individual parts of the page.

Finally, the approach taken allows us to keep using some of Drupal's existing solutions like, cookie-based authentication for user-specific page responses, the layout builder or even form processing.

Following up

Since there is so many details more to talk about, I'll be following up with further blog posts in the coming weeks, covering the following topics:

  • Selecting a frontend framework. Server-Side-Rendering and hosting options
  • Architecture variants, Authentication, Custom Elements markup & json formats
  • A developer introduction: Creating components, adding Custom Element processors, the relationship to Drupal's render API, Custom routes and optimizing cache metadata.
  • Handling blocks & layout builder, content previews, forms, caching & performance optimizations.

Finally, I'm going to talk more about this stack at the Drupalcon Europe 2020 in my session "Custom Elements: An alternate Render API for decoupled Drupal" - so mark your calendars!

OpenSense Labs: First key Drupal modules to install right away

1 week 5 days ago
First key Drupal modules to install right away Shalini Rawat Thu, 09/10/2020 - 18:15

“Since getting started with Drupal can be a bit intimidating for newbies, this blog is literally a great investment to take a look at”.

Apparently, Drupal offers a wide range of modules, nearly thousands of modules that are available to download anytime and anywhere. Modules play a pivotal role in the overall Drupal experience. The reason being, a module is a compact set of PHP, JavaScript and/or CSS files that provide a framework to strengthen the functionality of the website.

When you are starting a new Drupal project, there are certain modules that you need to consider installing right away irrespective of what sort of industry type that is for or what will be the key functions of that website.

Therefore, in this blog, we have rounded up some of the most common Drupal modules that are really helpful and can be used in almost all cases. So, without any further ado, let’s get right into the article. 

Modules for site-building Admin Toolbar

The Drupal Admin Toolbar is a very light module and allows faster and easier functioning to all administration pages. The module is highly capable to improve the default Toolbar (the administration menu at the top of your site) by transforming it into a drop-down menu. You can also create simple icons using Admin Toolbar which offers quick shortcut links to make for a more mobile-friendly and receptive experience.

PathAuto

The PathAuto module is a must-have module in every Drupal project. It is one of those tools that has got your back when you experience some not-so-fun work. Not only this, but the module also does it quickly and effectively. The Drupal PathAuto module helps in generating SEO friendly and well-structured URLs. Site admins can also change the pattern system by changing the tokens it uses. Read the ultimate Drupal SEO guide for 2020 to know more about Drupal’s SEO features.

Token

A Token is a fundamental element in any Drupal website. This Drupal module provides additional tokens (which are not supported by core), as well as a UI for browsing tokens. In addition to this, the Token module auto generates metadata about a website that further helps in search engine optimization (SEO). 

Inline Entity Form

Originally created for Drupal 7, the Inline Entity Form is a popular Drupal module that provides a widget for inline management (creation, modification, removal) of referenced entities. The module allows you to create multiple types of content (or other related entities) from a single form and is primarily used to let you manage order items from the order add / edit form.  

Paragraphs

The Drupal 8 Paragraphs module is an author-friendly extension that allows content authors and editors to create flexible and structured content at ease. Using drag and drop functionalities, Paragraphs makes it possible to combine several different fields into a custom reusable element. Moreover, you can add various paragraphs field types such as images, text blocks, quotes, slideshows, videos and so much more.

Advanced Aggregation

The Advanced CSS/JS Aggregation module allows you to enhance the frontend performance of your site by minimizing the CSS and Javascript. The module has the capability to reduce the delivery of the number of files as well as their size. This in turn augments the download and display speed of the entire content of a web page. Not to mention, Advanced CSS/JS Aggregation collects and stores each resource category, thereby consuming less amount of data to download the page. Read Drupal’s effect on high-performance websites to understand more about Drupal’s performance optimization capabilities.

Metatag

The Metatag module plays a significant role as it allows you to automatically provide structured metadata aka "meta tags", about a website. If used in the right manner, Metatags can help you reach your audience in the most natural manner. In addition to this, the module provides support for meta tags (Open Graph Protocol from Facebook, Twitter Cards from Twitter) that have the power to control how content will appear when shared on social networks.

Redirect

The most important part to build a site right is to involve the Redirect Drupal module. The module allows the creation and management of redirects using a simpler user interface. In order to sustain in the long-term, the website must have the ability to create and maintain redirects. Well, this function can be handled perfectly by the Redirect module which creates manual redirects and maintains a canonical URL for all content, redirecting all other requests to that path.

Coffee

Inspired by Mac apps Alfred and Spotlight, the Coffee module allows you to navigate the admin area using your keyboard which is always much faster than a mouse. Just type (alt + D) or (alt + shift + D) using a simple keyboard shortcut, depending on your internet browser, and you are all set to search for the page you are looking to visit, and it will source it in the fewest characters possible.

Entity Reference Revision 

The core Entity Reference module forms the basis of the Entity Reference Revision module that allows you to reference a specific revision of an entity. This Drupal module is presented form the team that brought the Paragraphs model in existence. Besides this, it adds an Entity Reference field type that has revision support and can work in favor of modules like Paragraphs and Inline Entity Form.

Webform

Webform Drupal module is one of the most powerful modules responsible for making forms and surveys available for your users to submit. Once a customizable email is sent to administrators and/or submitters, results can be immediately taken out into Excel or other spreadsheet applications. Moreover, Webform also provides some basic statistical reviews and has an extensive API in-store to further expand its features.

Simple XML sitemap

Search Engine Optimization (SEO) has always been the topmost priority for the Drupal community and therefore tons of modules are created to improve the SEO ranking. Specifically made for Drupal 8, the Simple XML Sitemap module adheres to google’s latest standard and supports multilingual content which makes it even more futuristic and flexible. It also provides an API that allows you to customize links and configurations.

Field group

Field group as the name suggests group fields together which cleans up content types and reduces the burden which falls directly in the lap of content editors. All fieldable entities have the possibility to add groups to wrap their fields together. The main intent of this particular Drupal module is to allow grouping similar fields into tabs, thereby making it easier for people to visualize and deal with the content on the page. 

Fast 404

Drupal suffers from expensive 404 errors which consume more memory of the server to load a page than it should take. This is where the Fast 404 module comes into the picture. Fast 404 Drupal module reduces expensive page rendering without the urge for an additional module. By enabling this module, you can decrease waste bandwidth and server load on-site. In other words, you can deliver 404 errors using less than 1MB of memory on your server. 

403 to 404

403 to 404 refers to a simple Drupal module that emits a 404 error when a user tries to access a page that they don't have access to view.

Modules for development Devel

Being a web developer who is looking for some tools for debugging, the Devel module can be really powerful that any developer would love to improve efficiency. This module is like a compendium of tools with functions that are handy. For example- the ability to create dummy users, nodes, and taxonomy terms as well as easily view information about APIs, cache effectiveness, Views, database queries, and more.

Devel PHP

The Devel module is used to remove the execute feature from the Drupal module. The Devel PHP module allows you to re-use this feature provided by the Admin toolbar by re-adding the executive tool as an external feature. 

Backup and Migrate

Creating a regular backup is an important step to ensure that you don’t lose your data. Drupal is no different and understands this concern. You will be glad to know that Drupal has a dedicated module to look after backup issues that software might face. This module is popularly called the Backup and Migrate module which allows backing up databases, files, codes, etc. This Drupal module is easy and is highly recommended for beginners. Go through the ultimate guide on Drupal 9 to plan a better migration path.

Twig Tweak

Twig Tweak Drupal module is a small module that is accountable to provide a Twig extension with some useful functions. Along with it, the module allows filters that hold the potential to improve the development experience.

Ctools

Ctools is an important module in the Drupal framework which basically is a suite of APIs and tools that can make code readily available with a view to improving the developer experience. This suite comprises a module called the Page Manager who is responsible for managing pages. The usage of Ctools varies from people to people and is highly dependent on the person using it. 

Modules included in core and disabled by default Media 

The Media module is held responsible for the management of creation, editing, deletion, settings, and display of the media entities. The media items generally include images, documents, slideshows, YouTube videos, tweets, Instagram photos, etc.

Media Library

Have you ever wondered if a tool can help you manage media at ease? No? Well for your notice, Media Library is a media management tool that can help you find already existing on your site. Not to mention, the tool can help you make additions of new media items to an entity reference field, or embed media into your content via a text editor. This Drupal module is used in sites which is rich in content, where the media assets can be reused.

Layout Builder

Drupal Layout Builder is a unique module that allows content editors and site builders to create a powerful visual design for displaying content, that too with ease. Using this module, developers can easily and conveniently build page layouts using a UI and allows embedding and linking any elements in layouts (fields, views, menus, and forms). Layout Builder in Drupal 8 gives you access to add/remove sections to display the content using different layouts, and customizing your pages based on the requirements. 

JSON: API

JSON: API is intended to minimize the number of requests and the amount of data transferred between clients and servers efficiently. This Drupal module is of pre-determined nature where everything is pre-fixed. In other words, the possibility of making amends in this module is zero. Be it about the location where the resources will reside, or what methods are immediately available on them. Not to mention, JSON: API provides access control to Drupal Core's permissions system. 

GraphQL 

The GraphQL is a perfect fit for anyone who wishes to raise a query or update/delete any content or configuration. This can be done with the help of the official GraphQL query language.  The GraphQL module is considered as one of the finest as well as a mightier tool of Drupal which can be used as a foundation for building your own schema through custom code or you can use and extend the generated schema using the plugin architecture and the provided plugin implementations form the sub-module.

RESTful Web Services

Inspired by Drupal 7, the RESTful web services module relies on the Serialization module in Drupal 8 core to allow a customizable and extensible RESTful API of data that is managed by Drupal. Surprisingly, this Drupal module provides you to create an interaction with any content entity (nodes, users, comments) as well as closely monitor the database log entries.

Core Multilingual modules

A multilingual site allows developers to access Drupal in a language that they prefer. For this obvious reason, the multilingual component feature of Drupal has become an ideal choice for both businesses and developers. Presently, Drupal offers 4 different modules for language and content translation which can be enabled as per the need of the website.  

Language Module:

This is the base module that is required for any non-English or multi-lingual site. It provides users access to arrange languages and apply languages to content.

Locale (Interface Translation) module:

This particular Drupal module is responsible for translating the built-in user interface, your added modules, and themes.

Content Translation module:

This module provides the translation of content entities. Further, it lets you translate your site content, including pages, taxonomy terms, blocks, etc., into different languages.

Configuration Translation:

It is responsible to allow translation of the text that is part of the configuration, such as field labels, the text used in views, etc.

Migrate

The Migrate module is used to provide a flexible framework for migrating content into Drupal from other sources. For example- converting a site from another CMS to Drupal. Besides this, this module can be easily extended for migrating other kinds of content too.  

Migrate UI

Drupal Migrate UI is responsible to provide the browser user interface (UI) for Migrate Drupal. This Drupal module provides a user interface for editing and configuring migrations to Drupal 8.

Conclusion 

And now that you have reached the end of the blog, we expect you to have some really solid suggestions on your radar. Most importantly, make sure that whatever you figure out should be the best fit for your website and your workflow. 

Think you are ready to take a plunge into Drupal? Contact us at [email protected] and our experts will help you plan and launch your site with ease.

blog banner blog image Drupal Drupal module Blog Type Articles Is it a good read ? On

Wim Leers: The sunset of the API-first initiative

1 week 5 days ago

Mateu, Gabe and I agreed to sunset the API-first initiative, about which I’ve written a lot in 2016–2019.

We’ve all spent countless hours on it — Gabe and I were able to work on it mostly full time, Mateu contributed an incredible amount of his free time to get the API-first initiative and the JSON:API module ecosystem in particular to where it is today.

I learned a lot from these two lovely people, and we also had lots of laughs!

API-first Drupal with multiple consumers @DrupalConNA :D pic.twitter.com/GhgY8O5SSa

— Gábor Hojtsy (@gaborhojtsy) April 11, 2018

Mateu wrote a great retrospective, which is a superb way to end this project. Quoted here in full:

TL;DR: we are putting an official end to the API-first initiative although we don’t consider our work done. The initiative leads have struggled to find availability or energy to keep moving it forward. The upcoming JS components initiative will likely light this flame back up, and we’ll be there to assist and guide in their API endeavors. This patch removes the initiative from the MAINTAINERS.txt.

Connection: close

We mark the API-first initiative done. :wave:.

However, we are not done. There are so many things we would like to improve in Drupal core. Those include hypermedia support, Open API and schema reliability, non-entity JSON:API resources, OAuth2, etc. Nonetheless, we believe that this is a good stopping point for the initiative. We achieved so much, there are so many unforgettable moments. This initiative has played a huge role into transitioning Drupal to the next 10 years of success! We are so proud of what we have accomplished that it has not been easy to wrap it up.

Let’s have HTTP guide us through this decision.

207 (Multi-status)

There is no single definitive reason, but the sum of several reasons have lead us to the unanimous decision to call this initiative done.

202 (Accepted)

JSON:API was the major goal and crowning achievement of the initiative. It was hard to imagine how much work, stress, and personal time that would take from us. As of Drupal 8.7 we can use JSON:API as part of Drupal core. This was the first time we were tempted to call it done.

426 (Upgrade required)

The API-first initiative started with Wim working hard to make REST in core more reliable. In parallel Mateu was writing a myriad of contrib modules bring decoupled Drupal more usable to deliver the expected experiences for customers. In the midst of this Gabe joined the team to help us guide the project to the finish line with the contribution of many volunteers—to whom we are supremely grateful. Thank you! :pray:

It seems this was such a long time ago. Nowadays none of us has the time or the energy to keep tugging this ship. It’s time for a different team to take the lead.

429 (Too many requests)

We recognize that Drupal has a very long road to truly become API-first. On top of that we still have to finish and polish so many key contributed modules. At different points we entertained the idea of adding to core:

  • Consumers.
  • Simple OAuth.
  • JSON:API Hypermedia.
  • Open API.
  • JSON:API Resources.
  • Decoupled Router.
  • Consumer Image Styles.

We probably don’t want them all, but we talked about how very useful they are to the decoupled Drupal endeavour. It is also worth mentioning that there are many other modules that are not very good candidates to Drupal core because they are not broadly applicable enough, while they remain tremendously important to the API-first ecosystem. One obvious example: JSON:API Explorer.

303 (See other)

Dries proposed a new JS components initiative that will likely begin by “solving” decoupled navigation. We vehemently agree that is a great place to start. It is a thorny problem that is not very well solved right now from the API perspective and requires API-first users to reinvent their own solutions over-and-over.

We expect that the JS components initiative team will have to work on the API side in order to complete their goals. We will be there for them, and we will help with code. We hope to be involved as much as we are able to.

Cookie: Contributors=new;

This post was about marking the initiative as done. As such we have talked about the decisions, and the mindset of the initiative coordinators. However, it would be terribly unfair to add this bow on top of the initiative without mentioning the contributors. Everyone that contributed with code, documentation, ideas, designs, support, etc. THANK YOU.

OSTraining: How to Use the Drupal Book Module

1 week 5 days ago

With the Drupal Book module, it is possible to create collections of related pieces of documents presented in a hierarchy. This format is suitable for handbooks and tutorials, for example.

Notice: This module is not for creating ebooks.

The Book module comes by default (disabled) with Drupal core modules, so there is no need to download or install anything additional on your system.

Keep reading to learn how to use this module!

Checked
1 hour 59 minutes ago
Drupal.org - aggregated feeds in category Planet Drupal
Subscribe to Drupal Planet feed