Development News

Annertech: Annertechies at DrupalCon Global 2020

Main Drupal Feed - Fri, 07/10/2020 - 11:04

Annnertech are once again excited to be presenting at DrupalCon but this year it's DrupalCon with a difference!

WPTavern: Open Source Initiative to Host Virtual State of the Source Summit, September 9-10

Wordpress Planet - Thu, 07/09/2020 - 22:07

OSI (Open Source Initiative) is hosting a new 24-hour, virtual conference called State of the Source Summit, September 9-10. The non-profit organization plays an important role in the open source ecosystem as stewards of the Open Source Definition (OSD). OSI is responsible for reviewing and approving licenses as OSD-conformant, which indirectly helps mediate community conflicts.

As part of the organization’s overall mission to educate the public on the economic and strategic advantages of open source technologies and licenses, OSI is hosting a global summit to facilitate conversations on the current state of open source software.

“We are so very excited to host our first-ever conference, with a global approach,” OSI Board President Josh Simmons said. “State of the Source provides an opportunity for both the open source software community and the OSI—all those who have contributed so much—to reflect on how we got here, why we have succeeded, and what needs to happen now.”

The conference will run four tracks with sessions that fall under these general groupings:

OSI has identified several example topics for each track, to guide potential presenters in writing a proposal. The first track encompasses more OSI-specific topics, such as license proliferation and license enforcement.

Projects & People includes topics that apply more broadly to communities and organizations – open source business models, sustainability, patents, and trademarks. The Principles, Policy, and Practices track is geared towards application and example topics include things like explaining a license to your peers, learning how to select a license for your project, and compliance, compatibility, and re-licensing.

As more conferences are forced to move to a virtual format, the wider open source community has the opportunity to be more engaged in an event like State of the Source. It’s a good venue for addressing non-technical issues related to the challenges facing open source maintainers and the community. The call for proposals ends July 16, and speakers will be announced August 25.

WPTavern: Gutenberg 8.5 Adds Single Gallery Image Editing, Allows Image Uploads From External Sources, and Improves Drag and Drop

Wordpress Planet - Thu, 07/09/2020 - 21:00

On Wednesday, the Gutenberg team released version 8.5 of its plugin to the public. This will be the final major plugin release to make its way into the upcoming WordPress 5.5, which has a target release date of August 11. This update does not include any groundbreaking features, but it does offer several enhancements and polishes the product.

Gutenberg 8.5 introduces the ability to upload images from third-party sites instead of simply hotlinking them. It also improves the drag-and-drop experience with blocks, adds an edit button for images in galleries, and moves reusable blocks to their own tab in the inserter.

Users can also now add an HTML anchor/ID to all static blocks. This was a relatively minor change but provides tremendous value. No longer will users need to switch to code editing mode and risk validation issues to add a basic HTML ID.

Upload External Images New upload external image button.

The largest enhancement in Gutenberg 8.5 is an improvement to inserting an image from an external URL. This update allows users to upload the image to their media library.

In past versions, users could insert an image from any URL. However, the image would remain hosted on that external site. The problem was that the end-user had no control over what happened to that image in the future. The third-party site could disappear. The site owner could remove or replace the image. The image shown on users’ sites may not have been what they intended.

The upload process is manual rather than automatic. After inserting an image via a URL, the editor toolbar will have a new upload icon with an arrow that points up. Users must click it to add the image to their media library.

The additional benefit of self-hosting the image is that the editor’s other image tools become available. Users can resize, rotate, or crop the image, options which were added to Gutenberg 8.4.

Improved Drag and Drop Dragging multiple blocks in the editor.

I had forgotten there was even a drag-and-drop feature for the block editor. Since it was introduced, I have never used it outside of testing. It is also not available when using Top Toolbar mode, which is my go-to choice.

The editor now allows dragging and dropping multi-block selections. The dragging-and-scrolling behavior is much approved. Instead of scrolling when reaching the edge of the viewport, the window scrolls almost immediately as you drag.

Despite the improvement, I do not find the drag-and-drop feature efficient in comparison to using the up/down arrows to move a block. However, I have never been much of a fan of dragging and dropping elements. Discoverability suffers because the hand icon that appears when hovering the toolbar is not a great indicator that I can drag the block, especially given its similarity to the normal hand cursor when moving my mouse. Some sort of directional arrow icon would make more sense and distinguish it.

Edit Single Gallery Images Editing an individual gallery image.

Gutenberg 8.5 features a new edit button on the individual images within a gallery block. This allows end-users to replace the image on the spot.

This is one of my favorite features to make it in before the upcoming WordPress 5.5 deadline. It has been one of those minor nit-picks for the past couple of years that I have wanted to see addressed. Overall, the team has done a solid job of making it work.

However, it is not quite perfect yet. The biggest issue comes after clicking the edit button. Suddenly, there is no good way to cancel the edit if I change my mind. I got around this limitation by choosing to add an image from the media library, which automatically had the previous image selected. My first thought was to click the x icon. However, that removes the image from the gallery. A trashcan icon makes more sense for removing the image while the x icon makes more sense for canceling an action.

Reusable Blocks Tab New reusable blocks tab in the inserter.

Reusable blocks are no longer tucked away at the bottom of the normal blocks list in the inserter. The team has moved them to their own tab. The inserter is now separated into Blocks, Patterns, and Reusable tabs. This will be an entirely new experience for users when WordPress 5.5 drops because the patterns feature and its corresponding tab are also new.

Moving the reusable blocks to a separate tab better exposes the feature. The previous location in which they were situated at the bottom of the blocks list hid them from anyone who did not scroll to the end. For far too long, this powerful feature was not getting the exposure that it deserved. Perhaps this new location will correct that.

The next step would be to finally add a reusable blocks menu item that is accessible from anywhere in the WordPress admin. We will likely have to wait for the WordPress admin block directory for that to happen.

WPTavern: WordPress University Was Always Online

Wordpress Planet - Thu, 07/09/2020 - 14:36

Did anybody listen to Peter Thiel? In 2011, the billionaire co-founder of PayPal, dubbed “contrarian investor” by the New York Times, created the Thiel Fellowship. A collection of 24 youngsters under the age of 20 were awarded $100,000 in exchange for dropping out of college to start tech companies.

Thiel said:

I believe you have a bubble whenever you have something that’s overvalued and intensely believed. In education, you have this clear price escalation without incredible improvement in the product. At the same time you have this incredible intensity of belief that this is what people have to do…It seems very similar in some ways to the housing bubble and the tech bubble.

Thiel had struck a raw cultural nerve. For years, as the world reeled and slowly recovered from a financial crisis, the quality of higher education was rapidly degrading while tuition costs were steadily increasing.

As more colleges make the switch to online only in the response to the pandemic, and the “college experience” becomes a relic of a bygone era, one wonders what the future of the university might look like.

Peter Thiel and Elon Musk, founders of PayPal. Typical underachievers.

Does a college education still improve economic outcomes in any significant way?

For people interested in tech careers, the answer is probably no. A college education produces minimal, if any, value. In effect, the university model, with American student loan debt amounting to $1.6 trillion, seems to do more harm than good.

COVID-19 has taught the world many harsh lessons and forced us all to reckon with difficult conclusions. But it has also shown us the promise and potential we might have otherwise passed without comment.

According to the U.S. Bureau of Labor Statistics, the 2019 median salary for a web developer comes to $73,760 per year, or $35.46 per hour, with no former work experience in related occupations required. The bureau lists an associate’s degree as the typical entry-level education, which, at most colleges, amounts to 5-6 semesters—considerably smaller investment than a four year degree.

But with readily available—and free—online courses in WordPress, HTML, CSS, PHP, and JavaScript, and the ubiquity of certification programs and “boot camps,” even an associate’s degree seems like overkill. When anyone, from any background, can launch a $70,000 per year career with no more experience than a few free courses available through any public library, we have either entered an era of unparalleled prosperity—or The Twilight Zone.

Should any web developer decide to pick up full stack development skills, or expand into general software engineering, the median salary jumps up to six figures. And this is before we get to the new frontiers of big data and “the cloud.”

Instead of thinking in monotone sentiments like “learn to code,” let’s imagine a generation raised under the banner of learn how to learn.

“The computer was a tool,” says John Dorner, IT coordinator for a USDA grant program, and WordPress developer. Starting his career as a 4-H program leader and agricultural extension agent for the University of Georgia in the 1980s, Dorner discovered computing as a shortcut to efficiency.

It wasn’t so easy to learn computers in those days. Tasks any high-schooler would consider common today required deep knowledge of how hardware and software worked together. There were no hard drives. Dorner had to employ two floppy disks, one with the operating system and application and one with his data, in order to create a spreadsheet.

“Writing code without the Internet was…interesting,” Dorner recalls. Learning PHP and MySQL from a recliner, balancing a laptop on his lap, and a book on the arm of the chair, Dorner demonstrates that the will to learn can exist outside of the classroom.

During our conversation over Google Meet, we talked about the alternatives available to people young and old, and from virtually any socio-economic background, who are interested in pursuing careers in IT or development.

Before opting for an associate’s degree, there are shorter duration programs available. Boot camps and certification programs provide rigorous course work and leave their students with some experience and a portfolio—and no student debt.

Dorner says:

Most web agencies would hire people if [they’ve] got a certificate, a portfolio, or some way to prove [they] have the skills…That’s more important than a full degree. Now, if you want to work at IBM, they might require a Bachelor’s or Master’s Degree. And there is a lot you can learn in those [full degree] programs. But somebody coming out of [community college or a boot camp] can get a good job and something starting.

In addition to free courses online, Dorner suggests that WordPress can be a powerful accelerant to tackling bigger concepts in web development. The WordPress path to web mastery works in “layers.”

“WordPress is a good starting point,” Dorner says. “[You] can do a lot in WordPress without knowing any code.” Once one has achieved a level of comfort with the WordPress interface, he can start adding custom CSS rules. From there, he can try his hand at child themes. And before long, full themes and plugins.

“The more you hack, the more you learn.”

In addition to learning the WordPress interface, the learner is being exposed to deeper concepts like web servers, open source philosophy, and version control.

What is left for the universities to cover?

Everybody needs to have some general education, Dorner replies. Basic math, science, and some of the humanities help to round out a liberal education. Beyond the general education, there are life skills and experience that must happen oustide of the classroom.

Dorner not only works in IT, but creates jobs as well. During the hiring process, I asked, what’s the most important criteria an applicant must meet?

It’s very important to be a self-directed, lifelong learner. I hired someone [recently]…[She] had the minimum requirements, but she had the initiative to learn something new. She was self-taught, went out and learned the stuff, and was able to solve the problem. That was more important to me than [the credentials].

The pathways into the tech field are now baked into society itself. Every kid who learns how to Google for information is building a working knowledge of SEO. Every kid who touches an iPhone learns the fundamentals of UX. And so forth.

The question for the coming years is whether or not the university model will meet these kids on the journey to careers in tech with something unique to offer them, or if the kids can get there well enough on their own.

WordPress university was always online.

Drupal In the News: Drupal Association Launches Drupal Steward Program To Increase Protection For Site Owners

Main Drupal Feed - Thu, 07/09/2020 - 11:20

The Drupal Steward Program enhances the security of Drupal Sites by protecting sites from exploits even before they are able to patch, and supports the sustainability of the Drupal Security Team and Drupal Association.

PORTLAND, Ore. July 7, 2020—The Drupal Association is announcing the launch of the Drupal Steward security program, together with founding partners Acquia and Pantheon, two of the largest hosting platforms for Drupal, and major contributors to the project. This is a paid service offered to further enhance the sites built on Drupal. A portion of the proceeds from both the founding partners and the community tier are used to support the Drupal Security Team and Drupal Association.

The Drupal Steward program answers the most pressing concern that keeps CIOs/CTOs up at night - "How do I protect my sites from the next unknown vulnerability?" In today's world, a Public Service Announcement of a critical vulnerability means disruption to existing engineering roadmaps, overtime hours, and all-hands on deck waiting for a patch release so that it can be deployed before bad actors reverse engineer the vulnerability.

Drupal Steward addresses this issue by putting in place a network-level mitigation strategy that prevents many of these kinds of highly critical vulnerabilities from being exploited, even before the patch has been applied. While there may be some rare vulnerabilities that cannot be mitigated with this technique - most of the highly critical vulnerabilities in Drupal's past would have been mitigated with this method.

"I am proud that we can advance Drupal's commitment to enterprise-grade security," said Heather Rocker, Executive Director of the Drupal Association. "The Drupal Steward program and its security protections should give the world the confidence to build the next generation of digital experiences on open source technology."

Drupal sites hosted with the Drupal Steward Founding Partners Acquia and Pantheon will be directly protected by those partners. For sites not hosted by the Drupal Steward founding partners, Drupal site owners will be able to subscribe to the Community tier of the Drupal Steward program directly through the Drupal Association at an affordable cost, with discounts provided to clients of Drupal Association supporting partners with a record of contribution to the project in the form of time, talent, or treasure.

Learn more about Drupal Steward

For complete details about the Drupal Steward program, including how to sign up - please visit https://www.drupal.org/security-team/steward

Powered by a global community

Drupal is a true open source project, leveraging the expertise of tens of thousands of developers around the world. Drupal has a proven track record for strong security practices, with a strong belief that the transparency of open source leads to more secure software.

About Drupal and the Drupal Association

Drupal is the open source content management software used by millions of people and organizations around the world, made possible by a community of 100,000-plus contributors and enabling more than 1.3 million users on Drupal.org. The Drupal Association is the non-profit organization dedicated to accelerating the Drupal software project, fostering the community, and supporting its growth.

###

For more information contact secwg-partnerships@association.drupal.org 

Amazee Labs: Join us at DrupalCon Global

Main Drupal Feed - Thu, 07/09/2020 - 10:29
<img src="https://www.amazeelabs.com/sites/default/files/styles/leading_image/public/images/current-affairs/AL-Going-to-DrupalCon-Global-Blogs.jpg?h=994a2424&amp;itok=j5e9gWaA" width="1120" height="630" alt="Join us at DrupalCon Global " title="Join us at DrupalCon Global " class="image-style-leading-image" /> DrupalCon Global 2020 is just a few days away, and we’re excitedly prepping up for what’s sure to be a virtual event like nothing the community has seen before. To say the least, it’s been a strange few months for everyone on the planet, but we at Amazee Labs think nothing exemplifies the resilient and persistent spirit of the open-source community like the innovative skills and organizational determination it took to bring DrupalCon Global 2020 and all its global attendees together.

Agaric Collective: Drupal migrations reference: List of properties per content entity

Main Drupal Feed - Thu, 07/09/2020 - 04:30

In a previous article we explained the syntax used to write Drupal migrations. When migrating into content entities, these define several properties that can be included in the process section to populate their values. For example, when importing nodes you can specify the title, publication status, creation date, etc. In the case of users, you can set the username, password, timezone, etc. Finding out which properties are available for an entity might require some Drupal development knowledge. To make the process easier, in today’s article we are presenting a reference of properties available in content entities provided by Drupal core and some contributed modules.

For each entity we will present: the module that provides it, the class that defines it, and the available properties. For each property we will list its name, field type, a description, and a note if the field allows unlimited values (i.e. it has an unlimited cardinality). The list of properties available for a content entity depend on many factors. For example, if the entity is revisionable (e.g. revision_default), translatable (e.g. langcode), or both (e.g. revision_translation_affected). The modules that are enabled on the site can also affect the available properties. For instance, if the “Workspaces” module is installed, it will add a workspace property to many content entities. This reference assumes that Drupal was installed using the standard installation profile and all modules that provide content entities are enabled.

It is worth noting that entity properties are divided in two categories: base field definitions and field storage configurations. Base field configurations will always be available for the entity. On the other hand, the presence of field storage configurations will depend on various factors. For one, they can only be added to fieldable entities. Attaching the fields to the entity can be done manually by the user, by a module, or by an installation profile. Again, this reference assumes that Drupal was installed using the standard installation profile. Among other things, it adds a user_picture image field to the user entity and body, comment, field_image, and field_tags fields to the node entity. For entities that can have multiple bundles, not all properties provided by the field storage configurations will be available in all bundles. For example, with the standard installation profile all content types will have a body field associated with it, but only the article content type has the field_image, and field_tags fields. If subfields are available for the field type, you can migrate into them.

Content (Node) entity

Module: Node (Drupal Core)
Class: Drupal\node\Entity\Node
Related article: Writing your first Drupal migration

List of base field definitions:

  1. nid: (integer) The node ID.
  2. uuid: (uuid) The node UUID.
  3. vid: (integer) Revision ID.
  4. langcode: (language) Language code (e.g. en).
  5. type: (entity_reference to node_type) Content type machine name.
  6. revision_timestamp: (created) The time that the current revision was created.
  7. revision_uid: (entity_reference to user) The user ID of the author of the current revision.
  8. revision_log: (string_long) Briefly describe the changes you have made.
  9. status: (boolean) Node published when set to TRUE.
  10. uid: (entity_reference to user) The user ID of the content author.
  11. title: (string) Title.
  12. created: (created) The time that the node was created.
  13. changed: (changed) The time that the node was last edited.
  14. promote: (boolean) Node promoted to front page when set to TRUE.
  15. sticky: (boolean) Node sticky at top of lists when set to TRUE.
  16. default_langcode: (boolean) A flag indicating whether this is the default translation.
  17. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  18. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  19. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.

List of field storage configurations:

  1. body: text_with_summary field.
  2. comment: comment field.
  3. field_image: image field.
  4. field_tags: entity_reference field.
User entity

Module: User (Drupal Core)
Class: Drupal\user\Entity\User
Related articles: Migrating users into Drupal - Part 1 and Migrating users into Drupal - Part 2

List of base field definitions:

  1. uid: (integer) The user ID.
  2. uuid: (uuid) The user UUID.
  3. langcode: (language) The user language code.
  4. preferred_langcode: (language) The user's preferred language code for receiving emails and viewing the site.
  5. preferred_admin_langcode: (language) The user's preferred language code for viewing administration pages.
  6. name: (string) The name of this user.
  7. pass: (password) The password of this user (hashed).
  8. mail: (email) The email of this user.
  9. timezone: (string) The timezone of this user.
  10. status: (boolean) Whether the user is active or blocked.
  11. created: (created) The time that the user was created.
  12. changed: (changed) The time that the user was last edited.
  13. access: (timestamp) The time that the user last accessed the site.
  14. login: (timestamp) The time that the user last logged in.
  15. init: (email) The email address used for initial account creation.
  16. roles: (entity_reference to user_role) The roles the user has. Allows unlimited values.
  17. default_langcode: (boolean) A flag indicating whether this is the default translation.

List of field storage configurations:

  1. user_picture: image field.
Taxonomy term entity

Module: Taxonomy (Drupal Core)
Class: Drupal\taxonomy\Entity\Term
Related article: Migrating taxonomy terms and multivalue fields into Drupal

List of base field definitions:

  1. tid: (integer) The term ID.
  2. uuid: (uuid) The term UUID.
  3. revision_id: (integer) Revision ID.
  4. langcode: (language) The term language code.
  5. vid: (entity_reference to taxonomy_vocabulary) The vocabulary to which the term is assigned.
  6. revision_created: (created) The time that the current revision was created.
  7. revision_user: (entity_reference to user) The user ID of the author of the current revision.
  8. revision_log_message: (string_long) Briefly describe the changes you have made.
  9. status: (boolean) Published.
  10. name: (string) Name.
  11. description: (text_long) Description.
  12. weight: (integer) The weight of this term in relation to other terms.
  13. parent: (entity_reference to taxonomy_term) The parents of this term. Allows unlimited values.
  14. changed: (changed) The time that the term was last edited.
  15. default_langcode: (boolean) A flag indicating whether this is the default translation.
  16. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  17. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  18. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.
File entity

Module: File (Drupal Core)
Class: Drupal\file\Entity\File
Related articles: Migrating files and images into Drupal, Migrating images using the image_import plugin, and Migrating images using the image_import plugin

List of base field definitions:

  1. fid: (integer) The file ID.
  2. uuid: (uuid) The file UUID.
  3. langcode: (language) The file language code.
  4. uid: (entity_reference to user) The user ID of the file.
  5. filename: (string) Name of the file with no path components.
  6. uri: (file_uri) The URI to access the file (either local or remote).
  7. filemime: (string) The file's MIME type.
  8. filesize: (integer) The size of the file in bytes.
  9. status: (boolean) The status of the file, temporary (FALSE) and permanent (TRUE).
  10. created: (created) The timestamp that the file was created.
  11. changed: (changed) The timestamp that the file was last changed.
Media entity

Module: Media (Drupal Core)
Class: Drupal\media\Entity\Media

List of base field definitions:

  1. mid: (integer) The media ID.
  2. uuid: (uuid) The media UUID.
  3. vid: (integer) Revision ID.
  4. langcode: (language) Language code (e.g. en).
  5. bundle: (entity_reference to media_type) Media type.
  6. revision_created: (created) The time that the current revision was created.
  7. revision_user: (entity_reference to user) The user ID of the author of the current revision.
  8. revision_log_message: (string_long) Briefly describe the changes you have made.
  9. status: (boolean) Published.
  10. uid: (entity_reference to user) The user ID of the author.
  11. name: (string) Name.
  12. thumbnail: (image) The thumbnail of the media item.
  13. created: (created) The time the media item was created.
  14. changed: (changed) The time the media item was last edited.
  15. default_langcode: (boolean) A flag indicating whether this is the default translation.
  16. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  17. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  18. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.

List of field storage configurations:

  1. field_media_audio_file: file field.
  2. field_media_document: file field.
  3. field_media_image: image field.
  4. field_media_oembed_video: string field.
  5. field_media_video_file: file field.
Comment entity

Module: Comment (Drupal Core)
Class: Drupal\comment\Entity\Comment

List of base field definitions:

  1. cid: (integer) The comment ID.
  2. uuid: (uuid) The comment UUID.
  3. langcode: (language) The comment language code.
  4. comment_type: (entity_reference to comment_type) The comment type.
  5. status: (boolean) Published.
  6. uid: (entity_reference to user) The user ID of the comment author.
  7. pid: (entity_reference to comment) The parent comment ID if this is a reply to a comment.
  8. entity_id: (entity_reference to node) The ID of the entity of which this comment is a reply.
  9. subject: (string) Subject.
  10. name: (string) The comment author's name.
  11. mail: (email) The comment author's email address.
  12. homepage: (uri) The comment author's home page address.
  13. hostname: (string) The comment author's hostname.
  14. created: (created) The time that the comment was created.
  15. changed: (changed) The time that the comment was last edited.
  16. thread: (string) The alphadecimal representation of the comment's place in a thread, consisting of a base 36 string prefixed by an integer indicating its length.
  17. entity_type: (string) The entity type to which this comment is attached.
  18. field_name: (string) The field name through which this comment was added.
  19. default_langcode: (boolean) A flag indicating whether this is the default translation.

List of field storage configurations:

  1. comment_body: text_long field.
Aggregator feed entity

Module: Aggregator (Drupal Core)
Class: Drupal\aggregator\Entity\Feed

List of base field definitions:

  1. fid: (integer) The ID of the aggregator feed.
  2. uuid: (uuid) The aggregator feed UUID.
  3. langcode: (language) The feed language code.
  4. title: (string) The name of the feed (or the name of the website providing the feed).
  5. url: (uri) The fully-qualified URL of the feed.
  6. refresh: (list_integer) The length of time between feed updates. Requires a correctly configured cron maintenance task.
  7. checked: (timestamp) Last time feed was checked for new items, as Unix timestamp.
  8. queued: (timestamp) Time when this feed was queued for refresh, 0 if not queued.
  9. link: (uri) The link of the feed.
  10. description: (string_long) The parent website's description that comes from the element in the feed.
  11. image: (uri) An image representing the feed.
  12. hash: (string) Calculated hash of the feed data, used for validating cache.
  13. etag: (string) Entity tag HTTP response header, used for validating cache.
  14. modified: (timestamp) When the feed was last modified, as a Unix timestamp.
Aggregator feed item entity

Module: Aggregator (Drupal Core)
Class: Drupal\aggregator\Entity\Item

List of base field definitions:

  1. iid: (integer) The ID of the feed item.
  2. langcode: (language) The feed item language code.
  3. fid: (entity_reference to aggregator_feed) The aggregator feed entity associated with this item.
  4. title: (string) The title of the feed item.
  5. link: (uri) The link of the feed item.
  6. author: (string) The author of the feed item.
  7. description: (string_long) The body of the feed item.
  8. timestamp: (created) Posted date of the feed item, as a Unix timestamp.
  9. guid: (string_long) Unique identifier for the feed item.
Custom block entity

Module: Custom Block (Drupal Core)
Class: Drupal\block_content\Entity\BlockContent

List of base field definitions:

  1. id: (integer) The custom block ID.
  2. uuid: (uuid) The custom block UUID.
  3. revision_id: (integer) The revision ID.
  4. langcode: (language) The custom block language code.
  5. type: (entity_reference to block_content_type) The block type.
  6. revision_created: (created) The time that the current revision was created.
  7. revision_user: (entity_reference to user) The user ID of the author of the current revision.
  8. revision_log: (string_long) The log entry explaining the changes in this revision.
  9. status: (boolean) Published.
  10. info: (string) A brief description of your block.
  11. changed: (changed) The time that the custom block was last edited.
  12. reusable: (boolean) A boolean indicating whether this block is reusable.
  13. default_langcode: (boolean) A flag indicating whether this is the default translation.
  14. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  15. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  16. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.

List of field storage configurations:

  1. body: text_with_summary field.
Contact message entity

Module: Contact (Drupal Core)
Class: Drupal\contact\Entity\Message

List of base field definitions:

  1. uuid: (uuid) The message UUID.
  2. langcode: (language) The message language code.
  3. contact_form: (entity_reference to contact_form) The ID of the associated form.
  4. name: (string) The name of the person that is sending the contact message.
  5. mail: (email) The email of the person that is sending the contact message.
  6. subject: (string) Subject.
  7. message: (string_long) Message.
  8. copy: (boolean) Whether to send a copy of the message to the sender.
  9. recipient: (entity_reference to user) The ID of the recipient user for personal contact messages.
Content moderation state entity

Module: Content Moderation (Drupal Core)
Class: Drupal\content_moderation\Entity\ContentModerationState

List of base field definitions:

  1. id: (integer) ID.
  2. uuid: (uuid) UUID.
  3. revision_id: (integer) Revision ID.
  4. langcode: (language) Language.
  5. uid: (entity_reference to user) The username of the entity creator.
  6. workflow: (entity_reference to workflow) The workflow the moderation state is in.
  7. moderation_state: (string) The moderation state of the referenced content.
  8. content_entity_type_id: (string) The ID of the content entity type this moderation state is for.
  9. content_entity_id: (integer) The ID of the content entity this moderation state is for.
  10. content_entity_revision_id: (integer) The revision ID of the content entity this moderation state is for.
  11. default_langcode: (boolean) A flag indicating whether this is the default translation.
  12. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  13. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
URL alias entity

Module: Path alias (Drupal Core)
Class: Drupal\path_alias\Entity\PathAlias

List of base field definitions:

  1. id: (integer) ID.
  2. uuid: (uuid) UUID.
  3. revision_id: (integer) Revision ID.
  4. langcode: (language) Language.
  5. path: (string) The path that this alias belongs to.
  6. alias: (string) An alias used with this path.
  7. status: (boolean) Published.
  8. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  9. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.
Shortcut link entity

Module: Shortcut (Drupal Core)
Class: Drupal\shortcut\Entity\Shortcut

List of base field definitions:

  1. id: (integer) The ID of the shortcut.
  2. uuid: (uuid) The UUID of the shortcut.
  3. langcode: (language) The language code of the shortcut.
  4. shortcut_set: (entity_reference to shortcut_set) The bundle of the shortcut.
  5. title: (string) The name of the shortcut.
  6. weight: (integer) Weight among shortcuts in the same shortcut set.
  7. link: (link) The location this shortcut points to.
  8. default_langcode: (boolean) A flag indicating whether this is the default translation.
Workspace entity

Module: Workspaces (Drupal Core)
Class: Drupal\workspaces\Entity\Workspace

List of base field definitions:

  1. id: (string) The workspace ID.
  2. uuid: (uuid) UUID.
  3. revision_id: (integer) Revision ID.
  4. uid: (entity_reference to user) The workspace owner.
  5. label: (string) The workspace name.
  6. parent: (entity_reference to workspace) The parent workspace.
  7. changed: (changed) The time that the workspace was last edited.
  8. created: (created) The time that the workspace was created.
  9. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
Custom menu link entity

Module: Custom Menu Links (Drupal Core)
Class: Drupal\menu_link_content\Entity\MenuLinkContent

List of base field definitions:

  1. id: (integer) The entity ID for this menu link content entity.
  2. uuid: (uuid) The content menu link UUID.
  3. revision_id: (integer) Revision ID.
  4. langcode: (language) The menu link language code.
  5. bundle: (string) The content menu link bundle.
  6. revision_created: (created) The time that the current revision was created.
  7. revision_user: (entity_reference to user) The user ID of the author of the current revision.
  8. revision_log_message: (string_long) Briefly describe the changes you have made.
  9. enabled: (boolean) A flag for whether the link should be enabled in menus or hidden.
  10. title: (string) The text to be used for this link in the menu.
  11. description: (string) Shown when hovering over the menu link.
  12. menu_name: (string) The menu name. All links with the same menu name (such as "tools") are part of the same menu.
  13. link: (link) The location this menu link points to.
  14. external: (boolean) A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).
  15. rediscover: (boolean) Indicates whether the menu link should be rediscovered.
  16. weight: (integer) Link weight among links in the same menu at the same depth. In the menu, the links with high weight will sink and links with a low weight will be positioned nearer the top.
  17. expanded: (boolean) If selected and this menu link has children, the menu will always appear expanded. This option may be overridden for the entire menu tree when placing a menu block.
  18. parent: (string) The ID of the parent menu link plugin, or empty string when at the top level of the hierarchy.
  19. changed: (changed) The time that the menu link was last edited.
  20. default_langcode: (boolean) A flag indicating whether this is the default translation.
  21. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  22. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  23. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.
Paragraph entity

Module: Paragraphs module
Class: Drupal\paragraphs\Entity\Paragraph
Related article: Introduction to paragraphs migrations in Drupal

List of base field definitions:

  1. id: (integer) ID.
  2. uuid: (uuid) UUID.
  3. revision_id: (integer) Revision ID.
  4. langcode: (language) The paragraphs entity language code.
  5. type: (entity_reference to paragraphs_type) Paragraph type.
  6. status: (boolean) Published.
  7. created: (created) The time that the Paragraph was created.
  8. parent_id: (string) The ID of the parent entity of which this entity is referenced.
  9. parent_type: (string) The entity parent type to which this entity is referenced.
  10. parent_field_name: (string) The entity parent field name to which this entity is referenced.
  11. behavior_settings: (string_long) The behavior plugin settings
  12. default_langcode: (boolean) A flag indicating whether this is the default translation.
  13. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  14. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  15. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.

List of field storage configurations:

  1. field_reusable_paragraph: entity_reference field.
Paragraphs library item entity

Module: Paragraphs Library (part of paragraphs module)
Class: Drupal\paragraphs_library\Entity\LibraryItem

List of base field definitions:

  1. id: (integer) ID.
  2. uuid: (uuid) UUID.
  3. revision_id: (integer) Revision ID.
  4. langcode: (language) Language.
  5. revision_created: (created) The time that the current revision was created.
  6. revision_uid: (entity_reference to user) The user ID of the author of the current revision.
  7. revision_log: (string_long) Briefly describe the changes you have made.
  8. status: (boolean) Published.
  9. label: (string) Label.
  10. paragraphs: (entity_reference_revisions) Paragraphs.
  11. created: (created) The time that the library item was created.
  12. changed: (changed) The time that the library item was last edited.
  13. uid: (entity_reference to user) The user ID of the library item author.
  14. default_langcode: (boolean) A flag indicating whether this is the default translation.
  15. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  16. revision_translation_affected: (boolean) Indicates if the last edit of a translation belongs to current revision.
  17. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.
Profile entity

Module: Profile module
Class: Drupal\profile\Entity\Profile

List of base field definitions:

  1. profile_id: (integer) ID.
  2. uuid: (uuid) UUID.
  3. revision_id: (integer) Revision ID.
  4. type: (entity_reference to profile_type) Profile type.
  5. revision_created: (created) The time that the current revision was created.
  6. revision_user: (entity_reference to user) The user ID of the author of the current revision.
  7. revision_log_message: (string_long) Briefly describe the changes you have made.
  8. status: (boolean) Whether the profile is active.
  9. uid: (entity_reference to user) The user that owns this profile.
  10. is_default: (boolean) Whether this is the default profile.
  11. data: (map) A serialized array of additional data.
  12. created: (created) The time when the profile was created.
  13. changed: (changed) The time when the profile was last edited.
  14. revision_default: (boolean) A flag indicating whether this was a default revision when it was saved.
  15. workspace: (entity_reference to workspace) Indicates the workspace that this revision belongs to.
Available properties for other content entities

This reference includes all core content entities and some provided by contributed modules. The next article will include a reference for Drupal Commerce content entities. That being said, it would be impractical to cover all contributed modules. To get a list of yourself for other content entities, load the entity_type.manager service and call its getFieldStorageDefinitions() method passing the machine name of the entity as a parameter. Although this reference only covers content entities, the same process can be used for configuration entities.

What did you learn in today’s article? Did you know that there were so many entity properties in Drupal core? Were you aware that the list of available properties depend on factors like if the entity is fieldable, translatable, and revisionable? Did you know how to find properties for content entities from contributed modules? 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.

OSTraining: How to Use the Recaptcha Module in Drupal 8

Main Drupal Feed - Thu, 07/09/2020 - 04:00

The reCAPTCHA module for Drupal 8 integrates the reCAPTCHA service provided by Google with your Drupal site. This service provides additional protection by detecting if the user accessing your site is a real person or a robot. 

Keep reading to learn how to use this module!

PreviousNext: Testing Twig templates and custom JavaScript with Jest

Main Drupal Feed - Wed, 07/08/2020 - 23:11

Jest is the defacto standard for testing in modern JavaScript but we've traditionally not been able to leverage it for testing in Drupal.

But with twig-testing-library, we can now test our twig templates and any dynamic behaviours added by Javascript using Jest.

In this article we will go through the process of adding Jest based testing to an existing accordion component.

by lee.rowlands / 9 July 2020 Installation

Firstly we need to install twig-testing-library and jest

npm i --save-dev twig-testing-library jest

And we're also going to add additional dom-based Jest asserts using jest-dom

npm i --save-dev @testing-library/jest-dom

Now we need to configure Jest by telling it how to find our tests as well as configuring transpiling.

In this project, we've got all of our components in folders in a /packages sub directory.

So we create a jest.config.js file in the root with the following contents:

// For a detailed explanation regarding each configuration property, visit: // https://jestjs.io/docs/en/configuration.html module.exports = { clearMocks: true, // Clear mocks on each test. testMatch: ['/packages/**/src/__tests__/**.test.js'], // How to find our tests. transform: { '^.+\\.js?$': `/jest-preprocess.js`, // Babel transforms. }, setupFilesAfterEnv: [`/setup-test-env.js`], // Additional setup. };

For transpiling we're just using babel-jest and then chaining with our projects presets. The contents of jest-preprocess.js is as follows:

const babelOptions = { presets: ['@babel/preset-env'], }; module.exports = require('babel-jest').createTransformer(babelOptions);

As we're going to also use the Jest dom extension for additional Dom based assertions, our setup-test-environment takes care of that as well as some globals that Drupal JS expects to exist. The contents of our setup-test-env.js file is as follows:

import '@testing-library/jest-dom/extend-expect'; global.Drupal = { behaviors: {}, }; Writing our first test

Now we have the plumbing done, let's create our first test

As per the pattern above, these need to live in a __tests__ folder inside the src folder of our components

So let's create a test for the accordion component, by creating packages/accordion/src/__tests__/accordion.test.js

Let's start with a basic test that the accordion should render and match a snapshot. This will pickup when there are changes in the markup and also verify that the template is valid.

Here's the markup in the twig template

<div class="accordion js-accordion"> {% block button %} <button class="button button--primary accordion__toggle">{{ title | default('Open Me') }}button> {% endblock %} <div class="accordion__content"> {% block content %} <h1>Accordion Contenth1> <p>This content is hidden inside the accordion body until it is disclosed by clicking the accordion toggle.p> {% endblock %} div> div>

So let's render that with twig-testing-library and assert some things in packages/accordion/src/__tests__/accordion.test.js

import { render } from 'twig-testing-library'; describe('Accordion functionality', () => { it('Should render', async () => { expect.assertions(2); const { container } = await render( './packages/accordion/src/accordion.twig', { title: 'Accordion', open: false, }, ); expect(container).toMatchSnapshot(); expect(container.querySelectorAll('.accordion__toggle')).toHaveLength(1); }); }); Running the tests

So let's run our first test by adding a jest command to our package.json under "scripts"

"jest": "jest --runInBand"

Now we run with

npm run jest > jest --runInBand PASS packages/accordion/src/__tests__/accordion.test.js Accordion functionality ✓ Should render (43 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 1 passed, 1 total Time: 4.62 s, estimated 6 s Ran all test suites. Testing dynamic behaviour

Now we know our template renders, and we're seeing some expected output, let's test that we can expand and collapse our accordion.

Our accordion JS does the following:

  • On click of the accordion title, expands the element by adding accordion--open class and sets the aria-expanded attribute
  • On click again, closes the accordion by removing the class and attribute

So let's write a test for that - by adding this to our existing test:

it('Should expand and collapse', async () => { expect.assertions(4); const { container, getByText } = await render( './packages/accordion/src/accordion.twig', { title: 'Open accordion', }, ); const accordionElement = container.querySelector( '.accordion:not(.processed)', ); const accordion = new Accordion(accordionElement); accordion.init(); const accordionToggle = getByText('Open accordion'); fireEvent.click(accordionToggle); expect(accordionElement).toHaveClass('accordion--open'); expect(accordionToggle).toHaveAttribute('aria-expanded', 'true'); fireEvent.click(accordionToggle); expect(accordionElement).not.toHaveClass('accordion--open'); expect(accordionToggle).toHaveAttribute('aria-expanded', 'false'); });

Now let's run that

npm run jest packages/accordion/src/__tests__/accordion.test.es6.js Accordion functionality ✓ Should render (29 ms) ✓ Should expand and collapse (20 ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 1 passed, 1 total Time: 5.031 s, estimated 6 s Ran all test suites.

Neat! We now have some test coverage for our accordion component

Next steps

So the neat thing about Jest is, it can collect code-coverage, let's run that

npm run jest -- --coverage packages/accordion/src/__tests__/accordion.test.es6.js Accordion functionality ✓ Should render (28 ms) ✓ Should expand and collapse (13 ms) -------------------|---------|----------|---------|---------|-------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -------------------|---------|----------|---------|---------|-------------------- All files | 29.55 | 11.27 | 24.14 | 30 | accordion/src | 100 | 85.71 | 100 | 100 | accordion.es6.js | 100 | 85.71 | 100 | 100 | 53 base/src | 11.43 | 3.13 | 4.35 | 11.65 | utils.es6.js | 11.43 | 3.13 | 4.35 | 11.65 | 14,28,41-48,58-357 -------------------|---------|----------|---------|---------|-------------------- Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 1 passed, 1 total Time: 2.813 s, estimated 5 s Ran all test suites.

Pretty nice hey?

What's happening behind the scenes

If you've worked on a React project before, you've probably encountered Dom testing library and React testing library. Twig testing library aims to provide the same developer ergonomics as both of these libraries. If you've familiar with either of those, you should find Twig testing library's API's comparable.

Under the hood it's using Twig.js for Twig based rendering in JavaScript and Jest uses jsdom for browser JavaScript APIs.

A longer introduction

I did a session on using this for a Drupal South virtual meetup, here's the recording of it.

Get involved

If you'd like to get involved, come say hi on github.

Tagged Front End Development, Testing, Jest, JavaScript

WPTavern: Jetpack 8.7 Adds New Tweetstorm Unroll Feature, Improves Search Customization

Wordpress Planet - Wed, 07/08/2020 - 20:48

Jetpack 8.7 was released this week with an exciting new feature that allows users to “unroll” a tweetstorm and publish it in a post. The feature works inside the Tweet block. After a user embeds a tweet, it will automatically detect a tweetstorm and display a prompt to fetch the rest of the tweets. It functions in a similar way to the Thread Reader app, except the unrolled thread is hosted on your WordPress post.

Tweetstorms remain a controversial way to get a lengthy point across. Twitter users with large followings will often get wider exposure and more traction and interaction on their ideas when they share them in a series of bite-size tweets. Although tweetstorms might be better as a blog, especially for those who are consuming and sharing them, a link to a blog post doesn’t carry the same weight as tweets for capturing Twitter users’ immediate attention.

If your thread is more than 3 tweets it does not belong on Twitter. Don't @ me. #longlivetheblog

— Jon Desrosiers (@desrosj) March 24, 2020

You may not be able to convince people to stop posting tweetstorms, but with Jetpack 8.7 you can make sure that these tweets are available inside a blog post.

Gary Pendergast, who has been working on the unroll feature for several months, tweeted a demo video of how it works.

Not particularly controversial opinion: most tweetstorms should be blog posts.

Putting my money where my mouth is: pic.twitter.com/HFBbmQtwql

— Gary (@GaryPendergast) May 29, 2020

If you’re looking to compose and publish tweetstorms from a blog post, with your post as the point of origin, John James Jacoby’s Publishiza plugin performs the opposite function of Jetpack’s new unroll feature. Pendergast said he is also investigating how to add the ability to publish a tweetstorm using the block editor, which seems like an ideal use case for writing content in blocks.

Jetpack 8.7 also brings updates to the recently revamped Search feature, adding more customization options for the search overlay:

  • Choose between minimal and expanded results
  • Change the default sorting to options — like chronological
  • Hide the sort option to reduce the size of the interface

This release also gives users easier access to their Google Photos and the free Pexels library. Access to these services was previously integrated with media library but is now also accessible via the block editor.

Version 8.7 introduces a WhatsApp Button block to allow visitors and customers to get in touch easily. The Jetpack team has also added more customization options to the Calendly, Mailchimp, Eventbrite, and Payment blocks. Check out the release post for a full list of improvements in this update.

WPTavern: After 11 Years, Users Will Be Able to Update Themes and Plugins via a ZIP File

Wordpress Planet - Wed, 07/08/2020 - 20:09

It has been a long road. Eleven long years. WordPress will finally allow end-users to update an installed plugin or theme by uploading a ZIP file. After over a decade, most people who had hoped to see this day have likely moved on. However, for those of us still waiting for this long sought after feature, it will land in WordPress 5.5.

A little patience never hurt anyone. Over the years, we have seen plugins crop up to handle this missing feature. There has been a clear and present need for it. Easy Theme and Plugin Upgrades by Chris Jean has over 200,000 active installs. Update Theme and Plugins from Zip File by Jeff Sherk has another 20,000. The community owes the developers of these plugins at least a small bit of thanks for taking on a job that should have long ago been a part of the core experience.

There was a time when this feature would have been one of the most important tools to land in WordPress. This was a time when one-click updates were not a thing. This was long before the idea of automatic theme and plugin updates, a feature that is also coming in WordPress 5.5, was conceived. While it is still exciting to finally get a feature that has long been on the waiting list, it is far less useful than it once was.

This missing feature has also likely at least partially spurred commercial theme and plugin shops to come up with custom solutions. This represents arguably one of the largest segments of users that still need the feature, at least for those using products from shops that do not provide one-click or automatic updates.

Updating themes via a ZIP file is a bit old-school, but there are scenarios where that is the better or preferred option for some users.

I routinely use a third-party plugin to handle this for various sites I am involved with where I might maintain a custom theme. This is particularly true if I don’t have FTP or other access to the server. It is simple to upload a ZIP file in those cases.

Despite less of a need for this feature in 2020 than in 2009, I can still use it. Judging by the download numbers of existing plugins, a couple hundred thousand others can too.

How Updating via ZIP Works

The new feature is not immediately apparent. However, it is more of a power-user feature that users will need to know about before attempting to use.

Updating a theme or plugin works in the same fashion as uploading a new one. By visiting the Add New plugin or theme screen in the WordPress admin and clicking the upload button, users can drop the ZIP file from their computer. After clicking the Install Now button, WordPress will direct users to a new screen that compares the currently-installed extension with the uploaded versions. Users can then choose between continuing with the installation or canceling.

Steps to updating an existing plugin.

After clicking the “Upload Plugin” button via the new plugin screen, the uploader currently reads, “If you have a plugin in a .zip format, you may install it by uploading it here.” There is no mention that users may upload a plugin that is already installed. A tweak to the language could help make it clear.

The comparison feature is a welcome addition, which should curb users accidentally uploading something they already have installed or rolling back when they already have a newer version active on the site. Some of the existing solutions from third-party plugins do not handle this feature, so this should make for a good upgrade.

Lullabot: Alternatives to Upgrading from Drupal 7 to Drupal 9

Main Drupal Feed - Wed, 07/08/2020 - 18:07

Drupal 9 was recently released, Drupal 8 will reach end-of-life November 2021, and Drupal 7’s life will expire in November 2022 (the date was extended due to COVID-19). With a window of a little under a year and a half to upgrade from 7 to 9, it's time to make a plan, or pursue other options if that timeline isn't viable. But what other options are there?

Mobomo: How Drupal manages Accessibility

Main Drupal Feed - Wed, 07/08/2020 - 16:33

Businesses and governments build websites for one reason: to provide value to their users. But what if your website was incapable of reaching millions of your users? 25% of Americans live with disabilities. For some of them, the simple act of navigating websites, digesting information, and understanding your content is difficult. Yet, despite brands increasing spending on web design and digital marketing, less than 10% of websites actually follow accessibility standards. Businesses are spending significant money to capture an audience, yet they’re not ensuring that their audience can engage with their website.

It’s a problem—a big one.

You don’t want to exclude customers. It’s bad for business, and it’s bad for your brand. Better yet, accessibility features help improve your SEO, reduce your website complexity, and increase your ability to connect with your loyal audience. But accessibility standards aren’t always baked into the architecture of websites.

Luckily, there are some content management systems (CMS) that let you create hyper-accessible websites without even trying. Drupal comes equipped with a variety of accessibility features — each of which helps make your website more accessible for your customers.

Understanding the Importance of Website Accessibility

Creating an accessible website may sound vague, but there’s already a worldwide standard you can follow. The Web Content Accessibility Guidelines (WCAG) — which is maintained by The World Wide Web Consortium — is the global standard for web accessibility used by companies, governments, and merchants across the world.

Sure! Following the WCAG standard helps you reach a wider audience. But it also keeps you out of legal hot water. Not only has the ADA made it abundantly clear that compliance requires website accessibility. A United States District Court in Florida ruled that WCAG standards are the de facto standards of web accessibility. And there are already cases of businesses getting sued for failing to adhere to them.

  • The DOJ sues H&R Block over its website’s accessibility.
  • WinnDixie.com was sued for accessibility, and the judge required them to update their website.
  • The National Museum of Crime and Punishment was required to update its website accessibility.

The list goes on. Adhering to WCAG web accessibility standards helps protect your brand against litigation. But, more importantly, it opens doors to millions of customers who need accessibility to navigate and engage with your amazing content.

One-third of individuals over the age of 65 have hearing loss. Around 15% of Americans struggle with vision loss. And millions have issues with mobility. The CDC lists six forms of disability:

  • Mobility (difficulty walking or climbing)
  • Cognition (difficult remembering, making decisions, or concentrating)
  • Hearing (difficulty hearing)
  • Vision (difficulty seeing)
  • Independent living (difficulty doing basic errands)
  • Self-care (difficulty bathing, dressing, or taking care of yourself)

Web accessibility touches all of those types of disabilities. For those with trouble seeing, screen readers help them comprehend websites. But, screen readers strip away the CSS layer. Your core content has to be accessible for them to be able to comprehend it. Those with mobility issues may need to use keyboard shortcuts to help them navigate your website. Hearing-impaired individuals may require subtitles and captions. Those with cognitive issues may need your website to be built with focusable elements and good contrasting.

There are many disabilities. WCAG creates a unified guideline that helps government entities and businesses build websites that are hyper-accessible to people with a wide range of these disabilities.

Drupal is WCAG-compliant

WCAG is vast. A great starting point is the Accessibility Principles document. But, creating an accessible website doesn’t have to be a time-consuming and expensive process. Drupal has an entire team dedicated to ensuring that their platform is WCAG compliant. In fact, Drupal is both WCAG 2.0 compliant and Authoring Tool Accessibility Guidelines (ATAG 2.0) compliant. The latter deals with the tools developers use to build websites. So, Drupal has accessibility compliance on both ends.

What Accessibility Features Does Drupal Have?

Drupal’s accessibility compliance comes in two forms:

  1. Drupal has built-in compliance features that are native to every install (7+).
  2. Drupal supports and enables the community to develop accessibility modules.
Drupal’s Built-in Compliance Features

Drupal 7+ comes native with semantic markup. To keep things simple, semantic markup helps clarify the context of content. At Mobomo, we employ some of the best designers and website developers on the planet. So, we could make bad HTML markup nearly invisible to the average user with rich CSS and superb visuals. But when people use screen readers or other assistive technology, that CSS goes out-of-the-window. They’re looking at the core HTML markup. And if it’s not semantic, they may have a difficult time navigating it. With Drupal, markup is automatically semantic — which breeds comprehension for translation engines, search engines, and screen readers.

Drupal’s accessibility page also notes some core changes made to increase accessibility. These include things such as color contrasting. WCAG requires that color contrasting be at least 4.5:1 for normal text and 7:1 for enhanced contrast. Drupal complies with those guidelines. Many other changes are on the developer side, such as drag and drop functions and automated navigation buttons.

Of course, Drupal also provides developer handbooks, theming guides, and instructional PDFs for developers. Some of the accessibility is done on the developer’s end, so it’s important to work with a developer who leverages accessibility during their design process.

Drupal’s Support for the Accessibility Community

In addition to following WCAG guidelines, Drupal supports community-driven modules that add additional accessibility support. Here are a few examples of Drupal modules that focus on accessibility:

There are hundreds. The main thing to remember is that Drupal supports both back-end, front-end, and community-driven accessibility. And they’ve committed to continuously improving their accessibility capabilities over time. Drupal’s most recent update — the heavily anticipated Drupal 9 — carries on this tradition. Drupal has even announced that Drupal 10 will continue to expand upon accessibility.

Do You Want to Build an Accessible Website

Drupal is on the cutting-edge of CMS accessibility. But they can’t make you accessible alone. You need to build your website from the ground up to comply with accessibility. A good chunk of the responsibility is in the hands of your developer. Are you looking to build a robust, functional, beautiful, and accessible website? 

Contact us. We’ll help you expand your reach.

The post How Drupal manages Accessibility appeared first on .

Tag1 Consulting: How Drupal can make true shared components a reality - part 1

Main Drupal Feed - Wed, 07/08/2020 - 12:59

Front-end development workflows have seen considerable innovation in recent years, with technologies like React disseminating revolutionary concepts like declarative components in JSX and more efficient document object model (DOM) diffing through Virtual DOMs. Nonetheless, while this front-end development revolution has led to significant change in the developer experiences we see in the JavaScript landscape and to even more momentum in favor of decoupled Drupal architectures in the Drupal community, it seems that many traditional CMSs have remained behind the curve when it comes to enabling true shared component ecosystems through developer experiences that focus on facilitating shared development practices across back and front end. At DrupalCon Amsterdam 2019, Fabian Franz (Senior Technical Architect and Performance Lead at Tag1) delivered a session entitled "Components everywhere: Bridging the gap between back end and front end" that delved into his ideal vision for enabling such shared components in Drupal's own native rendering layer. Fabian joined Michael Meyers (Managing Director at Tag1), and me (Preston So, Editor in Chief at Tag1; Senior Director, Product Strategy at Oracle; and author of Decoupled Drupal in Practice) for a Tag1 Team Talks episode highlighting the progress other ecosystems have made in the face of this problem space...

Read more preston Wed, 07/08/2020 - 05:59

WPTavern: New Gatsby Source WordPress Plugin Now in Beta

Wordpress Planet - Tue, 07/07/2020 - 22:33

Gatsby announced its new source plugin (v4) for WordPress is now in beta. The plugin has been completely revamped to improve headless WordPress setups where Gatsby powers the frontend. It also integrates with Gatsby Cloud to provide real-time previews and incremental builds.

The Gatsby team has had a long journey towards creating an integration for WordPress sites that would satisfy more complex use cases. There are currently three different avenues for using Gatsby with WordPress, each with different benefits and drawbacks:

  • Gatsby Source WordPress + WP REST API
  • Gatsby Source GraphQL + WPGraphQL
  • Gatsby Source WordPress (v4) + WPGraphQL

The first approach relies on the WP REST API to fetch all data (posts, terms, media, etc) and cache the data in Gatsby’s node cache. The second method allows developers to write GraphQL queries to fetch data from the Gatsby cache and render that data in templates.

According to Gatsby engineer and WPGraphQL creator Jason Bahl, the first two approaches are only adequate for basic use cases.

“When you start adding more advanced functionality, such as Advanced Custom Fields Flex Fields, the WP REST API starts to fall apart and become very difficult to use in a decoupled way,” Bahl said. “The WP REST API has a Schema that can allow plugins and themes to extend the WP REST API and declare what type of data any given endpoint will expose. This is helpful for decoupled applications to know ahead of time what kind of data to expect.

“The problem is that plugins and themes can extend the WP REST API without making use of the Schema, or by simply defining field types in the Schema as `object` or `array` Types. This means there’s no easy way for decoupled applications, including Gatsby, to know what to expect from those fields. Gatsby relies on consistent data, and the WP REST API isn’t consistent. The shape of the data returned from endpoints (especially when plugins extend the REST API) is unpredictable and that is problematic for decoupled applications.”

WPGraphQL was created as an alternative to the WP REST API, addressing many of these pain points with its enforced Schema. This benefits decoupled tools like Gatsby because they can introspect the Schema to determine what data is available before requesting any.

“So even cases such as Advanced Custom Fields Flex Fields, where the data being returned could be one of many possible Flex Field Layouts, Gatsby can still know what the possible data is before asking for the data,” Bahl said. “The enforced Schema of WPGraphQL allows decoupled tools to ship with confidence and eliminates entire classes of bugs.”

The Gatsby Source GraphQL + WPGraphQL approach has some improvements over using the WP REST API but was limited in that it doesn’t cache data to the Gatsby node cache. This prevents WordPress sites from being able to utilize Gatsby’s cloud-based commercial offerings for previews and incremental builds. Bahl explained how the new Gatsby Source WordPress plugin (v4) + WPGraphQL is the “best of both worlds:”

It uses WPGraphQL on the WordPress server to expose WordPress data in a Typed GraphQL Schema. Gatsby Source WordPress v4 uses GraphQL Introspection to read the Schema from the WordPress site and builds a nearly identical Schema in Gatsby. It then fetches data using WPGraphQL and caches the data in Gatsby. Users then use GraphQL to interact with the Gatsby cache and get data to render in Components in their Gatsby site.

The new integration gives content creators the ability to click “preview” to see their changes live in the Gatsby-powered site. Publishing no longer requires a full site rebuild. It will simply push out the changes to the affected pages. Changes will be live in seconds, similar to how users expect WordPress to work without the headless integration. The new plugin, combined with Gatsby Cloud, provide a better marriage of the content creation experience with Gatsby’s React + GraphQL developer experience, while delivering fast static pages on the frontend.

If you want to test the beta of the new Gatsby Source WordPress plugin, you can find it (and its dependencies) on GitHub. The WPGraphQL and WPGatsby plugins are also required.

WordPress.org blog: WordPress 5.5 Beta 1

Wordpress Planet - Tue, 07/07/2020 - 21:49

WordPress 5.5 Beta 1 is now available for testing!

This software is still in development, so it’s not recommended to run this version on a production site. Consider setting up a test site to play with the new version.

You can test the WordPress 5.5 beta in two ways:

The current target for final release is August 11, 2020. This is only five weeks away. Your help is needed to ensure this release is tested properly.

Testing for bugs is an important part of polishing the release during the beta stage and a great way to contribute. Here are some of the big changes and features to pay close attention to while testing.

Block editor: features and improvements

WordPress 5.5 will include ten releases of the Gutenberg plugin, bringing with it a long list of exciting new features. Here are just a few:

  • Inline image editing – Crop, rotate, and zoom photos inline right from image blocks.
  • Block patterns – Building elaborate pages can be a breeze with new block patterns. Several are included by default.
  • Device previews – See how your content will look to users on many different screen sizes.
  • End block overwhelm. The new block inserter panel displays streamlined categories and collections. As a bonus, it supports patterns and integrates with the new block directory right out of the box.
  • Discover, install, and insert third-party blocks from your editor using the new block directory.
  • A better, smoother editing experience with: 
    • Refined drag-and-drop
    • Block movers that you can see and grab
    • Parent block selection
    • Contextual focus highlights
    • Multi-select formatting lets you change a bunch of blocks at once 
    • Ability to copy and relocate blocks easily
    • And, better performance
  • An expanded design toolset for themes.
  • Now add backgrounds and gradients to more kinds of blocks, like groups, columns, media & text
  • And support for more types of measurements — not just pixels. Choose ems, rems, percentages, vh, vw, and more! Plus, adjust line heights while typing, turning writing and typesetting into the seamless act.

In all, WordPress 5.5 brings more than 1,500 useful improvements to the block editor experience. 

To see all of the features for each release in detail check out the release posts: 7.5, 7.6, 7.7, 7.8, 7.9, 8.0, 8.1, 8.2, 8.3, and 8.4.

Wait! There’s more! XML sitemaps

XML Sitemaps are now included in WordPress and enabled by default. Sitemaps are essential to search engines discovering the content on your website. Your site’s home page, posts, pages, custom post types, and more will be included to improve your site’s visibility.

Auto-updates for plugins and themes

WordPress 5.5 also brings auto-updates for plugins and themes. Easily control which plugins and themes keep themselves up to date on their own. It’s always recommended that you run the latest versions of all plugins and themes. The addition of this feature makes that easier than ever!

Lazy-loading images

WordPress 5.5 will include native support for lazy-loaded images utilizing new browser standards. With lazy-loading, images will not be sent to users until they approach the viewport. This saves bandwidth for everyone (users, hosts, ISPs), makes it easier for those with slower internet speeds to browse the web, saves electricity, and more.

Better accessibility

With every release, WordPress works hard to improve accessibility. Version 5.5 is no different and packs a parcel of accessibility fixes and enhancements. Take a look:

  • List tables now come with extensive, alternate view modes.
  • Link-list widgets can now be converted to HTML5 navigation blocks.
  • Copying links in media screens and modal dialogs can now be done with a simple click of a button.
  • Disabled buttons now actually look disabled.
  • Meta boxes can now be moved with the keyboard.
  • A custom logo on the front page no longer links to the front page.
  • Assistive devices can now see status messages in the Image Editor.
  • The shake animation indicating a login failure now respects the user’s choices in the prefers-reduced-motion media query.
  • Redundant Error: prefixes have been removed from error notices.
Miscellaneous Changes

Keep your eyes on the Make WordPress Core blog for 5.5-related developer notes in the coming weeks, breaking down these and other changes in greater detail.

So far, contributors have fixed more than 350 tickets in WordPress 5.5, including 155 new features and enhancements, and more bug fixes are on the way.

How You Can Help

Do you speak a language other than English? Help translate WordPress into more than 100 languages!

If you think you’ve found a bug, please post to the Alpha/Beta area in the support forums. We would love to hear from you! If you’re comfortable writing a reproducible bug report, file one on WordPress Trac. That’s also where you can find a list of known bugs.

Props to @webcommsat, @yvettesonneveld, @estelaris, and @marybaum for compiling/writing this post, @davidbaumwald for editing/proof reading, and @cbringmann, @desrosj, and @andreamiddleton for final review.

WordPress 5.5 Beta 1

Wordpress News - Tue, 07/07/2020 - 21:49

WordPress 5.5 Beta 1 is now available for testing!

This software is still in development, so it’s not recommended to run this version on a production site. Consider setting up a test site to play with the new version.

You can test the WordPress 5.5 beta in two ways:

The current target for final release is August 11, 2020. This is only five weeks away. Your help is needed to ensure this release is tested properly.

Testing for bugs is an important part of polishing the release during the beta stage and a great way to contribute. Here are some of the big changes and features to pay close attention to while testing.

Block editor: features and improvements

WordPress 5.5 will include ten releases of the Gutenberg plugin, bringing with it a long list of exciting new features. Here are just a few:

  • Inline image editing – Crop, rotate, and zoom photos inline right from image blocks.
  • Block patterns – Building elaborate pages can be a breeze with new block patterns. Several are included by default.
  • Device previews – See how your content will look to users on many different screen sizes.
  • End block overwhelm. The new block inserter panel displays streamlined categories and collections. As a bonus, it supports patterns and integrates with the new block directory right out of the box.
  • Discover, install, and insert third-party blocks from your editor using the new block directory.
  • A better, smoother editing experience with: 
    • Refined drag-and-drop
    • Block movers that you can see and grab
    • Parent block selection
    • Contextual focus highlights
    • Multi-select formatting lets you change a bunch of blocks at once 
    • Ability to copy and relocate blocks easily
    • And, better performance
  • An expanded design toolset for themes.
  • Now add backgrounds and gradients to more kinds of blocks, like groups, columns, media & text
  • And support for more types of measurements — not just pixels. Choose ems, rems, percentages, vh, vw, and more! Plus, adjust line heights while typing, turning writing and typesetting into the seamless act.

In all, WordPress 5.5 brings more than 1,500 useful improvements to the block editor experience. 

To see all of the features for each release in detail check out the release posts: 7.5, 7.6, 7.7, 7.8, 7.9, 8.0, 8.1, 8.2, 8.3, and 8.4.

Wait! There’s more! XML sitemaps

XML Sitemaps are now included in WordPress and enabled by default. Sitemaps are essential to search engines discovering the content on your website. Your site’s home page, posts, pages, custom post types, and more will be included to improve your site’s visibility.

Auto-updates for plugins and themes

WordPress 5.5 also brings auto-updates for plugins and themes. Easily control which plugins and themes keep themselves up to date on their own. It’s always recommended that you run the latest versions of all plugins and themes. The addition of this feature makes that easier than ever!

Lazy-loading images

WordPress 5.5 will include native support for lazy-loaded images utilizing new browser standards. With lazy-loading, images will not be sent to users until they approach the viewport. This saves bandwidth for everyone (users, hosts, ISPs), makes it easier for those with slower internet speeds to browse the web, saves electricity, and more.

Better accessibility

With every release, WordPress works hard to improve accessibility. Version 5.5 is no different and packs a parcel of accessibility fixes and enhancements. Take a look:

  • List tables now come with extensive, alternate view modes.
  • Link-list widgets can now be converted to HTML5 navigation blocks.
  • Copying links in media screens and modal dialogs can now be done with a simple click of a button.
  • Disabled buttons now actually look disabled.
  • Meta boxes can now be moved with the keyboard.
  • A custom logo on the front page no longer links to the front page.
  • Assistive devices can now see status messages in the Image Editor.
  • The shake animation indicating a login failure now respects the user’s choices in the prefers-reduced-motion media query.
  • Redundant Error: prefixes have been removed from error notices.
Miscellaneous Changes

Keep your eyes on the Make WordPress Core blog for 5.5-related developer notes in the coming weeks, breaking down these and other changes in greater detail.

So far, contributors have fixed more than 350 tickets in WordPress 5.5, including 155 new features and enhancements, and more bug fixes are on the way.

How You Can Help

Do you speak a language other than English? Help translate WordPress into more than 100 languages!

If you think you’ve found a bug, please post to the Alpha/Beta area in the support forums. We would love to hear from you! If you’re comfortable writing a reproducible bug report, file one on WordPress Trac. That’s also where you can find a list of known bugs.

Props to @webcommsat, @yvettesonneveld, @estelaris, and @marybaum for compiling/writing this post, @davidbaumwald for editing/proof reading, and @cbringmann, @desrosj, and @andreamiddleton for final review.

Pages