Jeff Geerling's Blog: Drupal VM 6 'Rectifier' is here!

Planet Drupal - Tue, 2020/07/14 - 7:17pm
Drupal VM 6 'Rectifier' is here!

I just released Drupal VM 6.0.0 today, and it is the best version of Drupal VM yet!

The main goals for this new version are stability and compatibility.

Originally I was going to drop some features that are helpful for people running older Drupal 7 sites, but since Drupal 7's End of Life was just extended into 2022, I decided to extend the support for some features like Drush make files, as many users of Drupal VM still maintain Drupal 7 sites, or use Drupal VM to test the upgrade from Drupal 7 to Drupal 8 or 9.

The default PHP version was upgraded from PHP 7.2 to 7.4 in Drupal VM 6, and this new version should work great with almost any Drupal 7, 8, or 9 website (in fact, PHP 7.3 is Drupal 9's minimum requirement!).

Jeff Geerling July 14, 2020
Categories:

Dropsolid: Dropsolid among the first exclusive partners providing Extended Support for Drupal 7, worldwide.

Planet Drupal - Tue, 2020/07/14 - 5:04pm
14 Jul

Today, we are excited to announce that Dropsolid has joined as one of the exclusive partners that will offer Extended Support for Drupal 7 up until November 2025. This means you get at least 3 extra years of full security coverage. This Extended support program is in collaboration with the Drupal Association and Drupal Security Team, and will give you official support on your Drupal 7 site for a whole extra 3 years. This will give you all the time you need to take the right steps towards a new Digital Experience Platform on Drupal 9 and beyond.

Last year, we encouraged our clients to begin planning their migrations to Drupal 8. Not unsurprisingly, as we will need to say goodbye to our friend, Drupal 7, soon.

Drupal 7 was released on January 5, 2011. Drupal 8 was released on November 19, 2015 and the latest and shiniest release came out a couple days ago with Drupal 9 on June 3, 2020. Drupal 7 is almost 10 years old, and will be almost 12 years old when it comes time to say goodbye in November 2022.

New version or next level?

Moving from Drupal 7 to Drupal 8 or 9 could be a great opportunity to upgrade your digital platforms to the next level instead of merely to the next version. Drupal 9 is more than a CMS, it’s a DXP. Turning your website into a personalized digital experience is not something you do overnight. You need to be well prepared, start from a digital strategy with clear goals. Taking time for that preparation now, will pay off later.

Drupal Extended Support can be a solution if you need more time to finish your digital transformation strategy before upgrading.

A smooth upgrade path for every business on it’s own pace

Some businesses might have other priorities right now or might need more time to prepare the migration to Drupal 8 or 9. Businesses that are hit by COVID-19, or on the contrary, businesses that suddenly have decided to accelerate on their digital transformation and need more time to make a strategic action plan.

At Dropsolid we want to be a reliable partner for all companies using Drupal: big or small, in fast growing industries or in sectors that got hit hard by Corona. We want to provide all businesses with the best possible transition path to Drupal 9, so that business owners can focus on taking the right steps in their digital transformation whenever and however it is strategically the best time for their business.

All customers of Dropsolid using Dropsolid Experience Platform will automatically benefit from highly critical Drupal 7 updates, all other updates require signing up for our Extended Support program.

Want to move your Drupal 7 site to the Dropsolid Experience Cloud and get a bit more time to prepare your next phase?
Get in touch with us!

More information about this program of the Drupal Association can be found at https://www.drupal.org/security-team/d7es
 

Nick Veenhof
Categories:

OpenLucius: 'Simple Like Button' released as a Drupal module | Why we used a custom AJAX form -and a custom entity.

Planet Drupal - Tue, 2020/07/14 - 4:11pm

During the development of Lucius we built quite a lot of features, that are embedded in the product (an open source Drupal distribution). But we figured some of these might come in handy for other Drupal site owners, outside of the OpenLucius Drupal install profile.

So this is the first release we did: "Simple Like Button", a very simple like button Drupal module that works in two steps:

Categories:

ComputerMinds.co.uk: A recipe for editing & translating over 100 fields

Planet Drupal - Tue, 2020/07/14 - 2:23pm

I recently released a new contributed module to aid translation on Drupal 7 sites: Entity Translation: Separated Shared Elements Form (ETSSEF). Yes, it has a convoluted name! It finally resolves a suggestion from years ago in an Entity Translation project issue, to allow editing untranslatable fields separately to translatable ones. One of our clients has a multilingual product database site with a few hundred fields on their content, so anything like this that could reduce the size of their editing forms is useful. I figure the best way to demonstrate this is with a recipe that blends it together with some other super (but generally obscure) modules. I hope you can spot parts that may be helpful for your projects!

The Recipe
  Ingredients


Recipe Difficulty Rating: Intended for experienced Drupal cooks only; others may prefer to try our takeaway service.
 

Method
  1. Enable each of the modules listed above, and set the admin theme to be used.
     
  2. Configure the various Field storage modules. Try to understand what each of these is doing, and adjust appropriately for you if necessary: // Turn off storage of revision info for your content type that has many fields. $bundle = 'farmer'; variable_set('field_sql_norevisions_entities', array( 'node' => array( $bundle => 1, ), )); // Default to using Blob storage (1 table instead of 1000s). variable_set('field_storage_default', 'field_sql_blob_storage'); // Relabel the options in the UI to make the distinction clear. variable_set('field_storage_ui_relabel_options', array( 'field_sql_blob_storage' => 'Retrievable only', 'field_sql_storage' => 'Sortable & Filterable', )); // Load default-sql-storage fields in batches of 20 (instead of 1 at a time). variable_set('field_sql_storage_group_load_max_fields', 20);  
  3. Set up your content type with many many fields. Choose 'Retrievable only' for the storage type for any fields that don't really need to be used for querying against, or sorting/filtering in lists. This will improve performance, as all the field data for those is stored together in a 'blob' column in the database so can be loaded (& unserialized) in a single go, rather than requiring select queries from so many different individual database tables.
     
  4. Configure nodes of this type to use entity translation (field translation) and head to the entity translation settings at /admin/config/regional/entity-translation. Set their 'Shared elements on translation forms' setting to 'Only display on their own separate forms':

    This ensures that untranslatable fields are just edited on the initial Edit tab (in a 'Shared' secondary tab); with just translatable fields in the translation forms. When there are so many fields, it's worth slimming down forms as much as possible! This also has the advantage that untranslatable data can be edited without needing to touch any specific translation.
     
  5. Override the edit form for your node type in a custom module, to use the Field Attach Form Selective module, so that fields are only shown on the form as they are filled in. This vastly reduces the amount of stuff on the form. I've written a gist that demonstrates this, and includes wiring it up to work nicely with ETSSEF. You must copy the entire contents of node_form() from node.pages.inc in Drupal core into the farmer_node_form() function, but replace the call to field_attach_form() at the bottom, with a call to field_attach_form_selective(). Use the same arguments.
     
  6. I then added some classes and CSS to the secondary tabs on the page to show the flag icons next to each language, as well as repeating the current tab name in the page title. I then added CSS to fix the page header in place so that editors easily retain that contextual information as they scroll down the giant forms. Otherwise it's too easy for them to forget which language they are editing!

 

Season to taste

Now when you edit your content type, your forms will be much slimmer and your site will run far smoother with hundreds of fields. As with any recipe, take the bits of this that are to your taste, ignore others, or blend it into your own creations! This was only for D7, so bringing the ideas over to Drupal 8/9 in some form would be an obvious thing to do. I’d love to hear of other ingredients you use to help when editing content forms with enormous amounts of fields, translatable or not.

 

Photo by Maarten van den Heuvel on Unsplash

Categories:

Specbee: A Brief Guide on Improving the FrontEnd Performance of your Drupal 8 Website with Advanced CSS/JS Aggregation

Planet Drupal - Tue, 2020/07/14 - 10:20am
A Brief Guide on Improving the FrontEnd Performance of your Drupal 8 Website with Advanced CSS/JS Aggregation Karishma 14 Jul, 2020 Top 10 best practices for designing a perfect UX for your mobile app

A well-performing website just doesn’t cut it these days. To stand out of competition, businesses are looking for high performance websites with lightning speed load times. You could potentially lose a big chunk of customers with every additional second your website takes to load. Today let’s learn about optimizing the frontend performance of your website with the Advanced CSS/JS aggregation module for Drupal 8.

To make Drupal sites run faster, it is essential to load CSS/JS files as quickly as possible for a page. One problem with Drupal core aggregate is that it is not good at determining which resource (CSS/JS) files go together. So, when you have different pages that require different resource (CSS/JS) files, usually Drupal core does it in a way where there is lot of extra information that are unnecessary on certain pages. The Drupal AdvAgg module comes with a plethora of features to help websites render faster. And the module also supports Drupal 9!

What does the Advanced CSS/JS Aggregation module do?

The Drupal AdvAgg module does a lot of different things to help speed up delivery and loading of resource files on your website. Advanced Aggregation combines multiple CSS files and creates fewer CSS files so that sites render faster. It caches aggregated files more efficiently. It also provides more effective methods of compression. Thus helping in offering users with more engaging user experiences.

Getting started with the Advanced CSS/JS Aggregation module Installing

Installing the AdvAgg module for Drupal 8 is like installing any other contributed modules. I’m using the Composer to install since it automatically installs all of the necessary dependencies. Open the terminal, within the project enter the following command - 

$ composer require 'drupal/advagg:^4.1'

Next, enable the AdvAgg module

  Configuration tab:

This tab provides several configuration options that are discussed below.

Global Options  
  1. Enable/Disable the Advagg module temporarily by checking/unchecking the Enable advanced aggregation checkbox.
  2. Use this option if you want to allow DNS prefetching for external CSS/JS, which tries to settle domain names for links before a user clicks on them. Enabling this can have unwanted effects on site. Keep this unchecked unless needed.
  3. In the Cache settings, we have options like development, low, normal, high caching of resource (CSS/JS) files. High caching stores more data while normal stores less data compared to high. Development caching stores very less data. I'm going with normal here.
Compression options

This provides Gzip compression and Brotli compression which are the methods used for compressing CS/JS assets.

CSS Options/JS Options
  1. In order to avoid multiple CSS/JS files in one page, AdvAgg uses media queries to determine what files are needed on a page and combine them so that they load faster.
  2. Fix improperly set type – This option will fix the problem in syntax, when you are trying to reference CSS and JS files if there are any problem there
  3. If this option is checked, the external stylesheets on the same host are not converted into files.
CRON Options
  1. Here you can set the minimum amount of time between advagg_cron() runs. The default value for this is 1 day.
  2. Use this option to Delete aggregates that were modified more than the chosen time. The default value for this is 1 month.
Obscure Options

This tab does not contain any configuration options. You can flush the module cache or entire cache in the Operation tab.

Bundler Tab :

This splits your aggregated resource files into multiple bundles of small resource files. With bundler active checked, you have more bundles of small CSS files, it makes sure that it strips anything that's not being used in a given page. Even with the more http request for a resource file you can have overall boost in the performance because of fewer bytes transmission.

This tab has CSS Bundling and the Javascript Bundling with the same configuration settings.
1. Target Number of CSS/JS Bundles Per Page: Specify the number of CSS/JS Bundles to be sent per page.
2. Grouping Logic: You can select the aggregation logic should go by file count of file size.

CDN Tab:

Content distribution network (CDN), is a distributed network of proxy servers that helps immensely in boosting website performance and load time. Website content can be distributed to servers closest to the site visitor which makes response and load times even faster.

  1. CDN to use - Choose between a network of server providers Google and Microsoft. 
  2.  Checking Use Minified resources would reduce the bandwidth needed because of the smaller file sizes.
CSS Minification tab:

This allows the removal of white spaces, comments, unwanted variable names etc. You can select between the Core minifier or the YUI Compressor, where YUI is better form of compression.

External Minification tab:

External Minification is used when you are using command line compression.

JavaScript Minification tab:

For JS minification select a minifier. Selecting a faster minifier is always better.

Old IE Compatibility tab:

Prevent more than 4095 CSS selectors in the aggregated CSS file - You can modify the value to avoid getting errors from IE Version below 10, where if your CSS has more than 4095 selector IE will not render the page properly.


 

A high-performing website is a necessity in today’s world of neck and neck competition. The Advanced CSS/JS Aggregation module for Drupal 8 truly helps to improve the frontend performance of Drupal websites. This can have a huge impact on user experience and can help garner more engagement. As Drupal developers, we leverage the best of Drupal’s modules and features to ensure our clients expectations are not just met but exceeded. Contact us to know how we can help you on your next Drupal project.

Drupal Planet Drupal Drupal 8 Drupal Development Drupal Module CSS/JS Shefali ShettyApr 05, 2017 Subscribe For Our Newsletter And Stay Updated Subscribe

Leave us a Comment

  Shefali ShettyApr 05, 2017 Recent Posts Image A Brief Guide on Improving the FrontEnd Performance of your Drupal 8 Website with Advanced CSS/JS Aggregation Image Stop Spam! How to use the Captcha and ReCaptcha module in Drupal 8 Image How to manage Google Ads by integrating DFP (DoubleClick for Publishers) with your Drupal 9 website 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
Categories:

clemens-tolboom opened a pull request in SCons/scons

On github - Tue, 2020/07/14 - 9:17am
clemens-tolboom opened a pull request in SCons/scons Jul 14, 2020 Add link to documentation toolchain overview. #3744

Contributor Checklist: I have created a new test or updated the unit tests to cover the new/changed functionality. I have updated CHANGES.txt (a…

+4 -0

clemens-tolboom pushed to patch-1 in clemens-tolboom/scons

On github - Tue, 2020/07/14 - 9:16am
clemens-tolboom pushed to patch-1 in clemens-tolboom/scons Jul 14, 2020 1 commit to patch-1
  • af71b44 Add link to documentation toolchain

clemens-tolboom forked clemens-tolboom/scons from SCons/scons

On github - Tue, 2020/07/14 - 9:12am
clemens-tolboom forked clemens-tolboom/scons from SCons/scons Jul 14, 2020 SCons/scons

SCons - a software construction tool

Python 887 Updated Jul 13

ADCI Solutions: Great examples of Drupal websites for universities

Planet Drupal - Tue, 2020/07/14 - 8:29am

When users choose an educational institution, the first thing they see is a website. Today every site (no matter for which sphere) should grab the attention of the user, and the websites for educational institutions should also shout “Come to us!”. You no longer have to think about what CMS you should rely on when creating such a site!

We took care of you and picked up 9 examples of Drupal educational websites: Harvard University, Bucknell University, Brown University, Middlebury College, etc. 

Slow down and enjoy the article "Great examples of Drupal websites for universities".

 

Categories:

Matt Glaman: PHPStan Drupal and Drupal Check now on TideLift

Planet Drupal - Mon, 2020/07/13 - 9:34pm

I have officially Lifted the PHPStan Drupal extension and the Drupal Check tool on

Categories:

Promet Source: Drupal 9 Migration: Top Questions and Expert Insights

Planet Drupal - Mon, 2020/07/13 - 8:49pm
Drupal 9’s big splash in early June sparked a widespread realization that migration needed to move to front burner status in anticipation of a Nov. 2021 decommission date for Drupal 7 and 8. That sense of urgency has been temporarily tabled as the Drupal organization took the widespread uncertainty and upheaval of the global pandemic into account, and moved the end-of-life date for Drupal 7 and Drupal 8 out by one year to November 2022. So now what?
Categories:

Droptica: Paragraph View Mode – Review of a Module for Drupal

Planet Drupal - Mon, 2020/07/13 - 12:30pm

Creating components using the Paragraphs module offers incredible flexibility in building pages based on Drupal. One of the common restrictions is the issue of reusing the same paragraphs in very similar components. If the only thing that limits you is the set and layout of fields, the Paragraph View Mode module will help you.

The very first lines of the module's code were created as a dedicated module for one of the projects we implemented. I quickly noticed, however, how such a functionality could be useful in the whole Paragraphs module ecosystem. Currently, the module has a stable 1.4 version and is covered by the Security Advisory Policy.

Dates 

The first version of the module was released in July 2019. Since then, I have been actively following the list of issues, implementing patches and new functionalities. The last patches were introduced to the developer version in July 2020.

Module's popularity

According to the statistical data published on the module's page: https://www.drupal.org/project/paragraph_view_mode, it is currently used by about 450 websites, which translates into approximately 10 uses per week.

Module's creators

The first draft of the module was created in order to address the needs of a current project. After its initial release on the drupal.org website, I introduced some additional improvements and new functionalities. The community also helped, e.g. with making the module compatible with Drupal 9.
Currently, I am the only person who worked directly on the module's code. The module itself is supervised by two maintainers who respond to all issues as quickly as possible.

What is the module used for? 

Paragraph View Mode is a sub-module for the Paragraphs module. Its advantages will be appreciated by both, developers and people responsible for editing content on a website. It may be necessary when:

  • you are building a website from many components, and some of them are very similar, e.g. they use a similar set of fields;
  • you want to minimise the number of components with regards to the administration;
  • you think about streamlining the frontend part;
  • you want to ensure better organisation of templates with regards to the UI and directly within the code;
  • you want to avoid using many complex field-based modifiers, e.g. lists.

As you can see, this module can offer several useful functions, and all this goes hand in hand with the simplicity of this solution in accordance with the so-called "Drupal Way".

Unboxing

You can download the module from the https://www.drupal.org/project/paragraph_view_mode webpage or via composer:

composer require drupal/paragraph_view_mode


After the installation, go to editing the selected paragraph type, the default path is usually:
 
[your_domain]/admin/structure/paragraphs_type/[your_paragraph_bundle]
 
In the "Paragraph View Mode" drop-down section, select the option “Enable Paragraph view mode field on this paragraph type" and then save the form.

The module will automatically create a "Paragraph view mode" field with a configuration widget (available in the manage form display tab).
 
The widget's configuration consists of two fields. The first field is the selection of available display modes. The module automatically receives a list of only those that are unblocked on the current paragraph type, while you can decide which of them you want to display on the list of options in the form.

The second field is used to define the default value of the field in the absence of its value (e.g. for a newly created paragraph).

With the module configured in this way, you can dynamically switch the display modes directly in the page adding/editing form.

Plans for the future

The basic functionality of the module is already completed, and it is hard to come up with new functionalities. Recently, however, I created a new issue https://www.drupal.org/project/paragraph_view_mode/issues/3150153, in which I plan (with a little help from the community) to develop the functionality of linking the field value with the display mode of the form and its dynamic substitution. I also intend to continue supporting Drupal 9 and future versions.

Summary

The Paragraph View Mode module, despite its low complexity, offers a lot regarding the efficiency, convenience and – above all – flexibility of the editors' work. In addition, it allows the Drupal developers or the person responsible for the website to reduce the amount of work needed to organise and maintain the components on the website, thus reducing the overall cost of maintaining the website.

Categories:

Agaric Collective: Drupal migrations reference: List of configuration options for source plugins

Planet Drupal - Mon, 2020/07/13 - 8:30am

In a previous article we explained the syntax used to write Drupal migration. We also provided references of subfields and content entities' properties including those provided by the Commerce module. This time we are going to list the configuration options of many migrate source plugins. For example, when importing from a JSON file you need to specify which data fetcher and parser to use. In the case of CSV migrations, the source plugin configuration changes depending on the presence of a headers row. Finding out which options are available might require some Drupal development knowledge. To make the process easier, in today’s article we are presenting a reference of available configuration options for migrate source plugins provided by Drupal core and some contributed modules.

For each migrate source plugin we will present: the module that provides it, the class that defines it, the class that the plugin extends, and any inherited options from the class hierarchy. For each plugin configuration option we will list its name, type, a description, and a note if it is optional.

SourcePluginBase (abstract class)

Module: Migrate (Drupal Core)
Class: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Extends: Drupal\Core\Plugin\PluginBase

This abstract class is extended by most migrate source plugins. This means that the provided configuration keys apply to any source plugin extending it.

List of configuration keys:

  1. skip_count: An optional boolean value. If set, do not attempt to count the source. This includes status and import operations.
  2. cache_counts: An optional boolean value. If set, cache the source count. This saves time calculating the number of available records in the source when a count operation is requested.
  3. cache_key: An optional string value. Uniquely named cache key used for cache_counts.
  4. track_changes: An optional boolean value. If set, the Migrate API will keep a hash of the source rows to determine whether the incoming data has changed. If the hash is different the record is re-imported.
  5. high_water_property: An optional array value. If set, only content with a higher value will be imported. The value is usually a timestamp or serial ID indicating what was the last imported record. This key is configured as an associate array. The name key indicates the column in the source that will be used for the comparison. The alias key is optional and if set it serves as a table alias for the column name.
  6. source_module: An optional string value. Identifies the system providing the data the source plugin will read. If not set, the Migrate API tries to read the value from the source plugin annotation. The source plugin itself determines how the value is used. For example, Migrate Drupal's source plugins expect source_module to be the name of a module that must be installed and enabled in the source database.

The high_water_property and track_changes are mutually exclusive. They are both designed to conditionally import new or updated records from the source. Hence, only one can be configured per migration definition file.

SqlBase (abstract class)

Module: Migrate (Drupal Core)
Class: Drupal\migrate\Plugin\migrate\source\SqlBase
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This abstract class is extended by migrate source plugins whose data may be fetched via a database connection. This means that the provided configuration keys apply to any source plugin extending it.

In addition to the keys provided in the parent class chain, this abstract class provides the following configuration keys:

  1. key: An optional string value. The database key name. Defaults to 'migrate'.
  2. target: An optional string value. The database target name. Defaults to 'default'.
  3. database_state_key: An optional string value. Name of the state key which contains an array with database connection information. The Migrate API will consult the States API using the provided key. The returned value should be an associative array with at least two keys: key and target to determine which database connection to use. A third key database can also be included containing database connection information as seen in the snippet below.
  4. batch_size: An optional integer value. Number of records to fetch from the database during each batch. If omitted, all records are fetched in a single query.
  5. ignore_map: An optional boolean value. Source data is joined to the map table by default to improve performance. If set to TRUE, the map table will not be joined. Using expressions in the query may result in column aliases in the JOIN clause which would be invalid SQL. If you run into this, set ignore_map to TRUE.

To explain how these configuration keys are used, consider the following database connections:

<?php $databases['default']['default'] = [ 'database' => 'drupal-8-or-9-database-name', 'username' => 'drupal-8-or-9-database-username', 'password' => 'drupal-8-or-9-database-password', 'host' => 'drupal-8-or-9-database-server', 'port' => '3306', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', ]; $databases['migrate']['default'] = [ 'database' => 'drupal-6-or-7-database-name', 'username' => 'drupal-6-or-7-database-username', 'password' => 'drupal-6-or-7-database-password', 'host' => 'drupal-6-or-7-database-server', 'port' => '3306', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', ];

This snippet can be added to settings.php or settings.local.php. The $databases array is a nested array of at least three levels. The first level defines the database keys: default and migrate in our example. The second level defines the database targets: default in both cases. The third level is an array with connection details for each key/target combination. This documentation page contains more information about database configuration.

Based on the specified configuration values, this is how the Migrate API determines which database connection to use:

  • If the source plugin configuration contains database_state_key, its value is taken as the name of a States API key that specifies an array with the database configuration.
  • Otherwise, if the source plugin configuration contains key, the database configuration with that name is used.
  • Otherwise, load a fallback state key from the States API. The value that it tries to read is the global state key: migrate.fallback_state_key.
  • Otherwise, the database connection named migrate is used by default.
  • If all of the above steps fail, a RequirementsException is thrown.

Note that all values configuration keys are optional. If none is set, the plugin will default to use the connection specified under $databases['migrate']['default']. At least, set the key configuration even if the value is migrate. This would make it explicit which connection is being used.

DrupalSqlBase (abstract class)

Module: Migrate Drupal (Drupal Core)
Class: Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase
Extends: Drupal\migrate\Plugin\migrate\source\SqlBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, source_module, key, target, database_state_key, batch_size, and ignore_map.

This abstract class provides general purpose helper methods that are commonly needed when writing source plugins that use a Drupal database as a source. For example, check if the given module exists and read Drupal configuration variables. Check the linked class documentation for more available methods.

In addition to the keys provided in the parent class chain, this abstract class provides the following configuration key:

  1. constants: An optional array value used to add module dependencies. The value is an associative array with two possible elements. The first uses the entity_type key to add a dependency on the module that provides the specified entity type. The second uses the module key to directly add a dependency on the specified module. In both cases, the DependencyTrait is used for setting the dependencies.

Warning: A plugin extending this abstract class might want to use this configuration key in the source definition to set module dependencies. If so, the expected keys might clash with other source constants used in the process pipeline. Arrays keys in PHP are case sensitive. Using uppercase in custom source constants might avoid this clash, but it is preferred to use a different name to avoid confusion.

This abstract class is extended by dozens of core classes that provide an upgrade path from Drupal 6 and 7. It is also used by the Commerce Migrate module to read product types, product display types, and shipping flat rates from a Commerce 1 database. The same module follows a similar approach to read data from an Ubercart database. The Paragraphs module also extends it to add and implement Configurable Plugin interface so it can import field collection types and paragraphs types from Drupal 7.

Config

Module: Migrate Drupal (Drupal Core). Plugin ID: d8_config
Class: Drupal\migrate_drupal\Plugin\migrate\source\d8\Config
Extends: Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, source_module, key, target, database_state_key, batch_size, ignore_map, and constants.

This plugin allows reading configuration values from a Drupal 8 site by reading its config table.

In addition to the keys provided in the parent class chain, this plugin does not define extra configuration keys. And example configuration for this plugin would be:

source: plugin: d8_config key: migrate skip_count: true

In this case we are setting the key property from SqlBase to use the migrate default database connection. The skip_count from SourcePluginBase indicates that there is no need to count how many records exist in the source database before executing migration operations like importing them.

This plugin is presented to show that Drupal core already offers a way to migrate data from Drupal 8. Remember that there are dozens of other plugins extending DrupalSqlBase. It would be impractical to list them all here. See this API page for a list of all of them.

CSV

Module: Migrate Source CSV. Plugin ID: csv
Class: Drupal\migrate_source_csv\Plugin\migrate\source\CSV
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This plugin allows reading data from a CSV file. We used this plugin in the CSV migration example of the 31 days of migration series.

In addition to the keys provided in the parent class chain, this plugin provides the following configuration keys:

  1. path: A string value. It contains the path to the CSV file. Starting with the 8.x-3.x branch, stream wrappers are supported. The original article contains more details on specifying the location of the CSV file.
  2. ids: An array of string values. The column names listed are used to uniquely identify each record.
  3. header_offset: An optional integer value. The index of record to be used as the CSV header and the thereby each record's field name. It defaults to zero (0) because the index is zero-based. For CSV files with no header row the value should be set to null.
  4. fields: An optional associative array value. It contains a nested array of names and labels to use instead of a header row. If set, it will overwrite the column names obtained from header_offset.
  5. delimiter: An optional string value. It contains a one character column delimiter. It defaults to a comma (,). For example, if your file uses tabs as delimiter, you set this configuration to \t.
  6. enclosure: An optional string value. It contains one character used to enclose the column values. Defaults to double quotation marks (").
  7. escape: An optional string value. It contains one character used for character escaping in the column values. It defaults to a backslash (\).

Important: The configuration options changed significantly between the 8.x-3.x and 8.x-2.x branches. Refer to this change record for a reference of how to configure the plugin for the 8.x-2.x.

For reference, below is the source plugin configuration used in the CSV migration example:

source: plugin: csv path: modules/custom/ud_migrations/ud_migrations_csv_source/sources/udm_photos.csv ids: [photo_id] header_offset: null fields: - name: photo_id label: 'Photo ID' - name: photo_url label: 'Photo URL'

Spreadsheet

Module: Migrate Spreadsheet. Plugin ID: spreadsheet
Class: Drupal\migrate_spreadsheet\Plugin\migrate\source\Spreadsheet
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This plugin allows reading data from Microsoft Excel and LibreOffice Calc files. It requires the PhpOffice/PhpSpreadsheet library and many PHP extensions including ext-zip. Check this page for a full list of dependencies. We used this plugin in the spreadsheet migration examples of the 31 days of migration series.

In addition to the keys provided in the parent class chain, this plugin provides the following configuration keys:

  1. file: A string value. It stores the path to the document to process. You can use a relative path from the Drupal root, an absolute path, or stream wrappers.
  2. worksheet: A string value. It contains the name of the one worksheet to process.
  3. header_row: An optional integer value. This number indicates which row contains the headers. Contrary to CSV migrations, the row number is not zero-based. So, set this value to 1 if headers are on the first row, 2 if they are on the second, and so on.
  4. origin: An optional string value. It defaults to A2. It indicates which non-header cell contains the first value you want to import. It assumes a grid layout and you only need to indicate the position of the top-left cell value.
  5. columns: An optional array value. It is the list of columns you want to make available for the migration. In case of files with a header row, use those header values in this list. Otherwise, use the default title for columns: A, B, C, etc. If this setting is missing, the plugin will return all columns. This is not ideal, especially for very large files containing more columns than needed for the migration.
  6. row_index_column: An optional string value. This is a special column that contains the row number for each record. This can be used as a unique identifier for the records in case your dataset does not provide a suitable value. Exposing this special column in the migration is up to you. If so, you can come up with any name as long as it does not conflict with header row names set in the columns configuration. Important: this is an autogenerated column, not any of the columns that comes with your dataset.
  7. keys: An optional associative array value. If not set, it defaults to the value of row_index_column. It contains the "columns" that uniquely identify each record. The keys are column names as defined in the data_rows key. The values is an array with a single member with key 'type' and value a column type such as 'integer'. For files with a header row, you can use the values set in the columns configuration. Otherwise, use default column titles like A, B, C, etc. In both cases, you can use the row_index_column column if it was set.

Note that nowhere in the plugin configuration you specify the file type. The same setup applies for both Microsoft Excel and LibreOffice Calc files. The library will take care of detecting and validating the proper type.

For reference, below is the source plugin configuration used in the LibreOffice Calc migration example:

source: plugin: spreadsheet file: modules/custom/ud_migrations/ud_migrations_sheets_sources/sources/udm_book_paragraph.ods worksheet: 'UD Example Sheet' header_row: 1 origin: A2 columns: - book_id - book_title - 'Book author' row_index_column: 'Document Row Index' keys: book_id: type: string

SourcePluginExtension (abstract class)

Module: Migrate Plus
Class: Drupal\migrate_plus\Plugin\migrate\source\SourcePluginExtension
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This abstract class provides extra configuration keys. It is extended by the URL plugin (explained later) and by source plugins provided by other modules like Feeds Migrate.

In addition to the keys provided in the parent class chain, this abstract class provides the following configuration keys:

  1. fields: An associative array value. Each element represents a field that will be made available to the migration. The following options can be set:
  2. name: A string value. This is how the field is going to be referenced in the migration. The name itself can be arbitrary. If it contains spaces, you need to put double quotation marks (") around it when referring to it in the migration.
  3. label: An optional string value. This is a description used when presenting details about the migration. For example, in the user interface provided by the Migrate Tools module. When defined, you do not use the label to refer to the field. Keep using the name.
  4. selector: A string value. This is another XPath-like string to find the field to import. The value must be relative to the location specified by the item_selector configuration. In the example, the fields are direct children of the records to migrate. Therefore, only the property name is specified (e.g., unique_id). If you had nested objects or arrays, you would use a slash (/) character to go deeper in the hierarchy. This will be demonstrated in the image and paragraph migrations.
  5. ids: An associative array value. It contains the "columns" that uniquely identify each record. The keys are column names as defined in the data_rows key. The values is an array with a single member with key 'type' and value a column type such as 'integer'.

See the code snippet for the Url plugin in the next section for an example of how these configuration options are used.

Url (used for JSON, XML, SOAP, and Google Sheets migrations)

Module: Migrate Plus. Plugin ID: url
Class: Drupal\migrate_plus\Plugin\migrate\source\Url
Extends: Drupal\migrate_plus\Plugin\migrate\source\SourcePluginExtension
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, source_module, fields, and ids.

This plugin allows reading data from URLs. Using data parser plugins it is possible to fetch data from JSON, XML, SOAP, and Google Sheets. Note that this source plugin uses other plugins provided by Migrate Plus that might require extra configuration keys in addition to the ones explicitly defined in the plugin class. Those will also be listed.

In addition to the keys provided in the parent class chain, this plugin provides the following configuration keys:

  1. urls: An array of string values. It contains the source URLs to retrieve. If the file data fetcher plugin is used, the location can be a relative path from the Drupal root, an absolute path, a fully-qualified URL, or a stream wrapper. See this article for details on location of the JSON file. If the HTTP data fetcher plugin is used, the value can use any protocol supported by curl. See this article for more details on importing remote JSON files.
  2. data_parser_plugin: A string value. It indicates which data parser plugin to use. Possible values provided by the Migrate Plus module are json, xml, simple_xml, and soap. If the Migrate Google Sheets module is installed, it is possible to set the value to google_sheets. Review the relevant articles in the 31 days of migration series to know more about how each of them are used.

The data parser plugins provide the following configuration keys:

  1. item_selector: A string value. It indicates where in the source file lies the array of records to be migrated. Its value is an XPath-like string used to traverse the file hierarchy. Note that a slash (/) is used to separate each level in the hierarchy.
  2. data_fetcher_plugin: A string value. It indicates which data parser plugin to use. Possible values provided by the Migrate Plus module are file and http.

The HTTP data fetcher plugins provide the following configuration keys:

  1. headers: An associative array value. The key/value pairs represent HTTP headers to be sent when the request is made.
  2. authentication: An associative array value. One of the elements in the array should be the plugin key which indicates the authentication plugin to use. Possible values provided by the Migrate Plus module are basic, digest, and oauth2. Other elements in the array will depend on the selected authentication plugin.

The basic and digest authentication plugins provide the following configuration keys:

  1. username: A string value.
  2. password: A string value.

The OAuth2 authentication plugin requires the sainsburys/guzzle-oauth2-plugin composer package to work. It provides the following configuration keys:

  1. base_uri: A string value.
  2. grant_type: A string value. Possible values are authorization_code, client_credentials, urn:ietf:params:oauth:grant-type:jwt-bearer, password, and refresh_token. Each of these might require extra configuration values.

The client credentials grant type requires the following configuration keys:

  1. token_url: A string value.
  2. client_id: A string value.
  3. client_secret: A string value.

For configuration keys required by other grant types, refer to the classes that implement them. Read this article on adding HTTP request headers and authentication parameters for example configurations.

There are many combinations possible to configure this plugin. In the 31 days of migration series there are many example configurations. For reference, below is the source plugin configuration used in the local JSON node migration example:

source: plugin: url data_fetcher_plugin: file data_parser_plugin: json urls: - modules/custom/ud_migrations/ud_migrations_json_source/sources/udm_data.json item_selector: /data/udm_people fields: - name: src_unique_id label: 'Unique ID' selector: unique_id - name: src_name label: 'Name' selector: name - name: src_photo_file label: 'Photo ID' selector: photo_file - name: src_book_ref label: 'Book paragraph ID' selector: book_ref ids: src_unique_id: type: integer

EmbeddedDataSource

Module: Migrate (Drupal Core). Plugin ID: embedded_data
Class: Drupal\migrate\Plugin\migrate\source\EmbeddedDataSource
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This plugin allows the definition of data to be imported right inside the migration definition file. We used this plugin in many of the examples of the 31 days of migration series. It is also used in many core tests for the Migrate API itself.

In addition to the keys provided in the parent class chain, this abstract class provides the following configuration keys:

  1. data_rows: An array of all the records to be migrated. Each record might contain an arbitrary number of key-value pairs representing "columns" of data to be imported.
  2. ids: An associative array. It contains the "columns" that uniquely identify each record. The keys are column names as defined in the data_rows key. The values is an array with a single member with key 'type' and value a column type such as 'integer'.

Many examples of 31 days of migration series use this plugin. You can get the example modules from this repository. For reference, below is the source plugin configuration used in the first migration example:

source: plugin: embedded_data data_rows: - unique_id: 1 creative_title: 'The versatility of Drupal fields' engaging_content: 'Fields are Drupal''s atomic data storage mechanism...' - unique_id: 2 creative_title: 'What is a view in Drupal? How do they work?' engaging_content: 'In Drupal, a view is a listing of information. It can a list of nodes, users, comments, taxonomy terms, files, etc...' ids: unique_id: type: integer

This plugin can also be used to create default content when the data is known in advance. We often present Drupal site building workshops. To save time, we use this plugin to create nodes which are later used when explaining how to create Views. Check this repository for an example of this. Note that it uses a different directory structure to store the migrations as explained in this blog post.

ContentEntity

Module: Migrate Drupal (Drupal Core). Plugin ID: content_entity
Class: Drupal\migrate_drupal\Plugin\migrate\source\ContentEntity
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This plugin returns content entities from a Drupal 8 or 9 installation. It uses the Entity API to get the data to migrate. If the source entity type has custom field storage fields or computed fields, this class will need to be extended and the new class will need to load/calculate the values for those fields.

In addition to the keys provided in the parent class chain, this plugin provides the following configuration key:

  1. entity_type: A string value. The entity type ID of the entities being migrated. This is calculated dynamically by the deriver so it is only needed if the deriver is not utilized, i.e., a custom source plugin.
  2. bundle: An optionals string value. If set and the entity type is bundleable, only return entities of this bundle.
  3. include_translations: An optional boolean value. If set, entity translations are included in the returned data. It defaults to TRUE.

For reference, this is how this plugin is configured to get all nodes of type article in their default language only:

source: plugin: content_entity:node bundle: article include_translations: false

Note: this plugin was brought into core in this issue copied from the Drupal 8 migration (source) module. The latter can be used if the source database does not use the default connection.

Table

Module: Migrate Plus. Plugin ID: table
Class: Drupal\migrate_plus\Plugin\migrate\source\Table
Extends: Drupal\migrate\Plugin\migrate\source\SqlBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, source_module, key, target, database_state_key, batch_size, and ignore_map.

This plugin allows reading data from a single database table. It uses one of the database connections for the site as defined by the options. See this test for an example on how to use this plugin.

In addition to the keys provided in the parent class chain, this plugin provides the following configuration key:

  1. table_name: An string value. The table to read values from.
  2. id_fields: An associative array value. IDMap compatible array of fields that uniquely identify each record.
  3. fields: An array value. The elements are fields ("columns") present on the source table.
EmptySource (migrate module)

Module: Migrate (Drupal Core). Plugin ID: empty
Class: Drupal\migrate\Plugin\migrate\source\EmptySource
Extends: Drupal\migrate\Plugin\migrate\source\SourcePluginBase
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

This plugin returns an empty row by default. It can be used as a placeholder to defer setting the source plugin to a deriver. An example of this can be seen in the migrations for Drupal 6 and Drupal 7 entity reference translations. In both cases, the source plugin will be determined by the EntityReferenceTranslationDeriver.

In addition to the keys provided in the parent class chain, this plugin does not define extra configuration keys. If the plugin is used with source constants, a single row containing the constant values will be returned. For example:

source: plugin: empty constants: entity_type: node field_name: body

The plugin will return a single row containing 'entity_type' and 'field_name' elements, with values of 'node' and 'body', respectively. This is not very useful. For the most part, the plugin is used to defer the definition to a deriver as mentioned before.

EmptySource (migrate_drupal module)

Module: Migrate Drupal (Drupal Core). Plugin ID: md_empty
Class: Drupal\migrate_drupal\Plugin\migrate\source\EmptySource
Extends: Drupal\migrate\Plugin\migrate\source\EmptySource
Inherited configuration options: skip_count, cache_counts, cache_key, track_changes, high_water_property, and source_module.

By default, this plugin returns an empty row with Drupal specific config dependencies. If the plugin is used with source constants, a single row containing the constant values will be returned. These can be seen in the user_picture_field.yml and d6_upload_field.yml migrations.

In addition to the keys provided in the parent class chain, this abstract class provides the following configuration keys:

  1. constants: An optional array value used to add module dependencies. The value is an associative array with one possible element. An entity_type key is used to add a dependency on the module that provides the specified entity type.
Available configuration for other migrate source plugins

In Drupal core itself there are more than 100 migrate source plugins, most of which come from the Migrate Drupal module. And many more are made available by contributed modules. It would be impractical to document them all here. To get a list by yourself, load the plugin.manager.migrate.source service and call its getFieldStorageDefinitions() method. This will return all migrate source plugins provided by the modules that are currently enabled on the site. This Drush command would get the list:

# List of migrate source plugin definitions. $ drush php:eval "print_r(\Drupal::service('plugin.manager.migrate.source')->getDefinitions());" # List of migrate source plugin ids. $ drush php:eval "print_r(array_keys(\Drupal::service('plugin.manager.migrate.source')->getDefinitions()));"

To find out which configuration options are available for any source plugin consider the following:

  • Find the class that defines the plugin and find out which configuration values are read. Some plugins even include the list in the docblock of the class. Search for a pattern similar to $this->configuration['option_name'] or $configuration['option_name']. The plugins can be found in the Drupal\module_name\Plugin\migrate\source namespace. The class itself would be in a file under the /src/Plugin/migrate/source/ directory of the module.
  • Look up in the class hierarchy. The source plugin can use any configuration set directly in its definition class and any parent class. There might be multiple layers of inheritance.
  • Check if the plugin offers some extension mechanism that would allow it to use other types of plugins. For example, the data fetcher, data parses, and authentication plugins provided by Migrate Plus. The Url migrate source plugin does this.

What did you learn in today’s article? Did you know that migrate source plugins can inherit configuration keys from their class hierarchy? Were you aware that there are so many source plugins? Other than the ones listed here, which source plugins have you used? Please share your answers in the comments. Also, we would be grateful if you shared this article with your friends and colleagues.

Read more and discuss at agaric.coop.

Categories:

Nextide Blog: Innovating Healthcare with Drupal

Planet Drupal - Mon, 2020/07/13 - 12:34am

Innovation within Canadian healthcare continues to provide better care experiences for those using the system.  As the population ages and strains our facilities to care for those nearing their end-of-life, hospitals are looking at technological solutions to ease the burden on emergency rooms and give people access to accurate and timely healthcare.   Nextide partnered with uCarenet, a Toronto-based e-health company, to create an innovative health and wellness application to monitor the condition of palliative care patients for a major Canadian hospital.

 

Categories:

DrupalEasy: DrupalEasy Podcast 234 - Jess Snyder (Drupal Nonprofits), Kaleem Clarkson (Drupal Event Organizers)

Planet Drupal - Sat, 2020/07/11 - 5:02pm

Direct .mp3 file download.

Jess Snyder joins Mike Anello to talk about how Drupal and nonprofit organizations - topics include the unique needs of nonprofits, the challenges they have with Drupal 8+, and how nonprofit folks organize and support each other. Also, Kaleem Clarkson returns to the podcast to provide an update on the Drupal Event Organizers Group.

URLs mentioned DrupalEasy News Subscribe

Subscribe to our podcast on iTunes, Google Play or Miro. Listen to our podcast on Stitcher.

If you'd like to leave us a voicemail, call 321-396-2340. Please keep in mind that we might play your voicemail during one of our future podcasts. Feel free to call in with suggestions, rants, questions, or corrections. If you'd rather just send us an email, please use our contact page.

Categories:

Ben's SEO Blog: Installing Google Tag Manager, Analytics, &amp; Search Console for Drupal 9

Planet Drupal - Sat, 2020/07/11 - 12:10am

Even though installing Google Tag Manager (GTM) adds a layer of complexity, it is far more flexible (and powerful) than Google Analytics (GA) alone:

GTM can be set up to track advanced analytics, like Scroll Depth, Link Clicks, & Video Playback information. GTM makes it easy to install custom tracking, like LinkedIn Insights or Facebook Pixel, without developer help. GTM makes it easier to track transaction data, like order amount, which is essential for ROI calculations for your ad campaigns.

While not difficult, it does take a little time and effort to complete. Below are the steps Volacci goes through to do a Google Tag Manager install on all our clients’ Drupal websites. 

A NOTE OF CAUTION IF YOU ALREADY HAVE GOOGLE ANALYTICS INSTALLEDExcept in very special cases,... Read the full article: Installing Google Tag Manager, Analytics, & Search Console for Drupal 9
Categories:

Drupal blog: The first ever virtual DrupalCon

Planet Drupal - Fri, 2020/07/10 - 9:58pm

This blog has been re-posted and edited with permission from Dries Buytaert's blog.

I remember the first gathering of Drupal contributors back in 2005. At the time, there were less than 50 people in attendance. In the 15 years since that first gathering, DrupalCon has become the heartbeat of the Drupal community. With each new DrupalCon, we introduce new people to our community, demonstrate the best that Drupal has to offer, and reconnect with our Drupal family.

Next week's DrupalCon Global is going to be no different.

Because of COVID-19, it is the first DrupalCon that will be 100% virtual. But as much as we may miss seeing each other in person, the switch to virtual has opened opportunities to bring in speakers and attendees who never would have been able to attend otherwise.

There are a few moments I'm particularly excited about:

  • Mitchell Baker, CEO of the Mozilla, is joining us to talk about the future of the Open Web, and the importance of Open Source software.
  • Jacqueline Gibson, Digital Equity Advocate and Software Engineer from Microsoft, will be talking about Digital Inequity for the Black community – a topic I believe is deeply important for our community and the world.
  • Leaders of current Drupal strategic initiatives will be presenting their progress and their calls for action to keep Drupal the leading CMS on the web.
  • And of course, I'll be giving my plenary presentation to celebrate the community's accomplishment in releasing Drupal 9, and to talk about Drupal's future.

Beyond the sessions, I look forward to the human element of the conference. The side conversations and reunions with old friends make attending DrupalCon so much more powerful than simply watching the recordings after the fact. I hope to see you at DrupalCon Global next week!

Categories:

Chapter Three: Import files from Google Drive, Dropbox, OneDrive and other services into Drupal

Planet Drupal - Fri, 2020/07/10 - 9:29pm

External Media module for Drupal 8 and 9 is a successor of the File Chooser Field module that was bulit for Drupal 7. The same functionality was implemented for Wordpress too. The module provides custom form element.

The new form element would allow you to add external services such as Google Drive, Dropbox, Box, OneDrive, AWS, Unsplash, Instagram, Pixabay, Pexels and other services, in addition to regular file choose field. 

Categories:

Event Organizers: Events Organizers at DrupalCon Global

Planet Drupal - Fri, 2020/07/10 - 7:53pm

DrupalCon Global is right around the corner and as usual, the Event Organizers will be everywhere! This year we've had a booth generously sponsored by the Drupal Association, so we'll have a place right in Hopin where you can come find us, chat about events, and even win some direct consulting time to help plan your next event! Whether you’re an event organizer, interested in starting an event in your area, or just want to flag one of us down, here’s where to look.

Categories: