At Agaric, we perform a lot of Drupal upgrades. These very often involve transitioning away from older versions of PHP. Even when your hosting service provides multiple versions of PHP, you can still run into issues activating the appropriate one for each site: whether that's within the web server, at the command line, or via Drush (or other tools). In this blog post, we'll be providing remedies for all of these cases. Most content applies to any PHP application.
The National Institute for Children’s Health Quality (NICHQ) delivers a steady stream of demonstrated best practices to help children and their families thrive. Many of these findings come out of the work of NICHQ’s varied collaborative improvement initiatives, in which clinical, research, and community-based teams come together around targeted improvements (e.g., strengthening maternity care services in hospitals) or introducing broad systems-level change (e.g., coordinating early childhood systems).

We live amidst a Digital Commons - technology that is built with the principles of freedom and transparency baked into its code and design. It's maintained out in the open by the free software community. This commons is invisible to many of us, but the closer we are to the technology we use, the more that it comes into focus. At Agaric we are knee deep in this Digital Commons. Our name Agaric is a nod to the mycelial nature of the open web. We help create, maintain, and promote free and open-source software that make up this commons.
Resources can be either a file-based resource such as a PDF or a link-based resource such as a url to a website. Resources can also be categorized by resource type and can also have an associated tag. An associated image such as the cover of a PDF resource or a logo or screenshot from a website link can make the resource more visually attractive in various displays.
The resource content type lets you post a PDF (or various other text based formats) so that site visitors can easily view and download. The body field lets you provide some information about the resource to help site visitors determine the usefulness of the resource before viewing.
Helpful tips include ensuring that your PDF has a user-friendly machine name (and/or using the file description field for the title users will see) and adding a cover image for example, in the image field, to provide a visual clue to the resource.
For link-based resources, you'll need to paste in the full website URL, such as https://drutopia.org. The Link text could read "Visit the Drutopia website."
(Technically, there is one formatter each for text lists and for entity references, but all the options which In Other Words adds are the same for both.)
We can configure a separator between list items, a final join word, and whether to connect the final items with a comma (or semicolon or any other punctuation we can imagine for our list).
In all its glory in context:
E-mail us at ask@agaric.coop, call us at +1 508 283 3557, or use this form below, and one of us worker-owners at Agaric will get back to you.
City Hall in Philadelphia. Photo by Jason Murphy, licensed as Creative Commons By 2.0
Drupaldelphia is an annual camp held in Philadelphia happening this Friday May 10th for the open source content management platform, Drupal. The event attracts developers, site-builders, content administrators, designers, and anyone interested in using Drupal in their organization or upcoming project.
We're excited to have Ben present two sessions at the camp. Tickets are only $30 (if you buy today, May 7th!) and the day is packed with helpful presentations and hands-on clinics. See the full schedule.
2:15-3:45pm
Hussian Room 125
Developing a trusted, ongoing feedback loop with your users ensures that your project is effective and relevant. We call this approach Iterative UX and Ben will share how this looks in practice with the city of Cambridge. You will get a holistic, honest look at both the highlights and challenges of this type of relationship to help you apply Iterative UX in your projects.
3:45-4:55pm
Hussian Room 125
Any libre software, volunteer, or even startup project will have elements of do-ocracy (rule of those who do the work) but not all decisions should devolve to implementors. Rather, a basic principle is that decisions should be made by the people who are most affected.
What does privacy and data trust mean to you, in your daily work and life? Does it mean that your door to your house is locked or that your email is encrypted, or both? Do you use cloud services or social media for business or for personal lifestyle news and updates? No matter how you use social media and engage in a conversation, you are tracked and sorted into buckets. What does that really mean?
For more than a decade, Agaric has had a special expertise in content migrations. The first substantial treatment of Drupal content migration in a book came with Upgrading a Drupal Site from 6 to 7 by Benjamin Melançon and Stefan Freudenberg with a Data Migration overview by Mike Ryan in The Definitive Guide to Drupal 7, a 35-author tome of Drupal knowledge from experts led by Agaric co-founder Ben Melançon.
More recently, Agaric worker-owner Mauricio Dinarte wrote an epic 31 blog post tutorials about migrating into Drupal in one month and leads migration trainings at Drupal conferences (DrupalCon), camps, and online, including Drupal 8/9 content migrations and Upgrading to Drupal 8/9 using the Migrate API.
Please share where you want to go with your site and a way to contact you!
From a new Drutopia member and Agaric consulting client:
My last question of the day I think. Thanks for all your help!
I've been trying to understand the interaction between the media library and using photos within text on pages. If I upload a photo to the media library, I cannot figure out how to embed it in a text block. And vice versa, if I use the text editor to add a photo, I can get it to wrap with text but it won't show up in the media library.
It seems like the best practice is that we should try to use the media manager rather than just drop in photos using the text editor method (which doesn't seem to get the photos into the media library), but how do we get the photos in the media library to be able to wrap with text and not be visually separate content?
(The help pages I've found on this issue seem outdated, other than the useful observation "Key to this issue [of overlapping media management systems] is that Drupal ships with several features that are similar to Media. The ability to upload files and images is not replaced by Media, but rather supplemented. This means that the user is left with both options (if not more) and must somehow know which one is the built in (not to be used), and new (preferred method)." at https://www.drupal.org/docs/7/modules/media/media-2x-quick-start-guide )
We wrote back:
Hi!
You are absolutely right that "This all seems to be an overwhelmingly large number of difficult steps just to have an image browser with the editor", as a comment you might have run across put it.
But a large part of the reason why you are running into confusing instructions is that modern Drupal has it all in core and it is significantly easier! That's why there are so many old posts, including from Drupal 7 but also from modern Drupal before Media Library went into core at some point in Drupal 8, and no clear explanation of how things should be done now in Drupal 10 which now has CKEditor5 replacing CKEditor4 in core.
As long as Media and Media Library modules are installed, "all" you need to do is:
/admin/config/content/formats/manage/basic_html)/core/modules/ckeditor5/icons/medialibrary.svg) from Available buttons into the Active toolbar.And that is how you are able to insert from your media library in CKEditor5 (or add to your media library while inserting a new image with your CKEditor WYSIWYG) in Drupal 8, 9, 10, 11 and probably 12 and onward too!
We are making this the default behavior in Drutopia as we continually upgrade it with Drupal's latest features and its own unique improvements.
In the previous post, we learned how to use process plugins to transform data between source and destination. Some Drupal fields have multiple components. For example, formatted text fields store the text to display and the text format to apply. Image fields store a reference to the file, alternative, and title text, width, and height. The migrate API refers to a field’s component as a subfield. Today we will learn how to migrate into them and know which subfields are available.

Today’s example will consist of migrating data into the Body and Image fields of the Article content type that are available out of the box. This assumes that Drupal was installed using the Standard installation profile. As in previous examples, we will create a new module and write a migration definition file to perform the migration. The code snippets will be compact to focus on particular elements of the migration. The full code snippet is available at https://github.com/dinarcon/ud_migrations The module name is UD Migration Subfields and its machine name is ud_migrations_subfields. The `id` of the example migration is `udm_subfields`. Refer to this article for instructions on how to enable the module and run the migration.
source:
plugin: embedded_data
data_rows:
-
unique_id: 1
name: 'Michele Metts'
profile: 'freescholar on Drupal.org'
photo_url: 'https://agaric.coop/sites/default/files/2018-12/micky-cropped.jpg'
photo_description: 'Photo of Michele Metts'
photo_width: '587'
photo_height: '657'Only one record is presented to keep snippet short, but more exist. In addition to having a unique identifier, each record includes a name, a short profile, and details about the image.
The Body field is of type Text (formatted, long, with summary). This type of field has three components: the full text (value) to present, a summary text, and a text format. The Migrate API allows you to write to each component separately defining subfields targets. The next code snippets shows how to do it:
process:
field_text_with_summary/value: source_value
field_text_with_summary/summary: source_summary
field_text_with_summary/format: source_formatThe syntax to migrate into subfields is the machine name of the field and the subfield name separated by a slash (/). Then, a colon (:), a space, and the value. You can set the value to a source column name for a verbatim copy or use any combination of process plugins. It is not required to migrate into all subfields. Each field determines what components are required, so it is possible that not all subfields are set. In this example, only the value and text format will be set.
process:
body/value: profile
body/format:
plugin: default_value
default_value: restricted_htmlThe `value` subfield is set to the `profile` source column. As you can see in the first snippet, it contains HTML markup. An `a` tag to be precise. Because we want the tag to be rendered as a link, a text format that allows such tag needs to be specified. There is no information about text formats in the source, but Drupal comes with a couple we can choose from. In this case, we use the `Restricted HTML` text format. Note that the `default_value` plugin is used and set to `restricted_html`. When setting text formats, it is necessary to use its machine name. You can find them in the configuration page for each text format. For `Restricted HTML` that is /admin/config/content/formats/manage/restricted_html.
Note: Text formats are a whole different subject that even has security implications. To keep the discussion on topic, we will only give some recommendations. When you need to migrate HTML markup, you need to know which tags appear in your source, which ones you want to allow in Drupal, and select a text format that accepts what you have whitelisted and filter out any dangerous tags like `script`. As a general rule, you should avoid setting the `format` subfield to use the Full HTML text format.
There are different approaches to migrating images. Today, we are going to use the Migrate Files module. It is important to note that Drupal treats images as files with extra properties and behavior. Any approach used to migrate files can be adapted to migrate images.
process:
field_image/target_id:
plugin: file_import
source: photo_url
reuse: TRUE
id_only: TRUE
field_image/alt: photo_description
field_image/title: photo_description
field_image/width: photo_width
field_image/height: photo_heightWhen migrating any field, you have to use their machine in the mapping section. For the `Image` field, the machine name is `field_image`. Knowing that, you set each of its subfields:
For the `target_id`, the plugin `file_import` is used. This plugin requires a `source` configuration value with a URL to the file. In this case, the `photo_url` column from the source section is used. The `reuse` flag indicates that if a file with the same location and name exists, it should be used instead of downloading a new copy. When working on migrations, it is common to run them over and over until you get the expected results. Using the `reuse` flag will avoid creating multiple references or copies of the image file, depending on the plugin configuration. The `id_only` flag is set so that the plugin only returns that file identifier used by Drupal instead of an entity reference array. This is done because each subfield is being set manually. For the rest of the subfields (`alt`, `title`, `width`, and `height`) the value is a verbatim copy from the source.
Note: The Migrate Files module offers another plugin named `image_import`. That one allows you to set all the subfields as part of the plugin configuration. An example of its use will be shown in the next article. This example uses the `file_import` plugin to emphasize the configuration of the image subfields.
Some fields have many subfields. Address fields, for example, have 13 subfields. How can you know which ones are available? The answer is found in the class that provides the field type. Once you find the class, look for the `schema` method. The subfields are contained in the `columns` array of the value returned by the `schema` method. Let’s see some examples:
The `schema` method defines the database columns used by the field to store its data. When migrating into subfields, you are actually migrating into those particular database columns. Any restriction set by the database schema needs to be respected. That is why you do not use units when migrating width and height for images. The database only expects an integer number representing the corresponding values in pixels. Because of object-oriented practices, sometimes you need to look at the parent class to know all the subfields that are available.
Another option is to connect to the database and check the table structures. For example, the `Image` field stores its data in the `node__field_image` table. Among others, this table has five columns named after the field’s machine name and the subfield:
Looking at the source code or the database schema is arguably not straightforward. This information is included for reference to those who want to explore the Migrate API in more detail. You can look for migrations examples to see what subfields are available. I might even provide a list in a future blog post. ;-)
Tip: You can use Drupal Console for code introspection and analysis of database table structure. Also, many plugins are defined by classes that end with the string `Item`. You can use your IDEs search feature to find the class using the name of the field as hint.
Every Drupal field has at least one subfield. For example, `Text (plain)` and `Number (integer)` defines only the `value` subfield. The following code snippets are equivalent:
process:
field_string/value: source_value_string
field_integer/value: source_value_integer
process:
field_string: source_value_string
field_integer: source_value_integerIn examples from previous days, no subfield has been manually set, but Drupal knows what to do. As we have mentioned, the Migrate API offers syntactic sugar to write shorter migration definition files. This is another example. You can safely skip the default subfield and manually set the others as needed. For `File` and `Image` fields, the default subfield is `target_id`. How does the Migrate API know what subfield is the default? You need to check the code again.
The default subfield is determined by the return value of `mainPropertyName` method of the class providing the field type. Again, object oriented practices might require looking at the parent classes to find this method. In the case of the `Image` field, it is provided by ImageItem which extends FileItem which extends EntityReferenceItem. It is the latter that contains the `mainPropertyName` returning the string `target_id`.
What did you learn in today’s blog post? Were you aware of the concept of subfields? Did you ever wonder what are the possible destination targets (subfields) for each field type? Did you know that the Migrate API finds the default subfield for you? Please share your answers in the comments. Also, I would be grateful if you shared this blog post with your colleagues.
Next: Using constants and pseudofields as data placeholders in the Drupal migration process pipeline
This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether it is the migration series or other topics.
Find It makes it easier for government and non-profit organizations to reach the people they work to serve.
We help organizations meet their goals by providing consulting in online technology strategy, by building and customizing high quality software, and by educating people.

We build with proven software that gives you power and control over your website and online presence.
We use and contribute to libre software whenever possible, creative commons license our documentation, and work under an open organization model.

We use design justice principles to help your online presence meet your goals and make real world impact.

We are experts in Drupal migrations. (We can train you to do migrations too.) We can move content from your old site—whether it is Drupal or not—to a new Drupal 9, 10, or 11 site so that you can keep working with all of your old content, all while gaining access to the flexibility and functionality of modern Drupal.

We mentor and teach, building on your existing expertise.
Learn more about opportunities to receive training from Agaric.

We believe in the movement to protect the privacy of everyone using electronic devices. Every student should have the right to privacy when learning online. That is why we offer schools a suite of Libre Software learning management tools that will assist teachers in getting their students to take initiative and to engage fully in the learning experience.
Talk to us about your online learning needs.

We share our knowledge and promote free software by speaking at events.
Topics include:
Book us for an upcoming event.