Development News

PreviousNext: Using Drupal's Entity Definition Update Manager to add bundle support to an existing content entity

Main Drupal Feed - Tue, 11/05/2019 - 03:11

On a client project we were using a custom Drupal content entity to model some lightweight reusable content.

The content entity was originally single use and did not support bundles (e.g. node entities have node-type bundles).

As the project evolved, we needed to add bundle support for the custom entity-type, despite it already being in production use.

Read on to find out how we achieved this.

by Lee Rowlands / 5 November 2019

In this example, lets call the content entity a 'set' and the bundles a 'set type'.

Create the bundle configuration entity

As we wanted this content entity to support adding new bundles via the UI, a configuration entity makes sense to allow site-builders to create the various bundles as required, so we created a new configuration entity called 'set type' as per the examples, although we used a route provider instead of a routing file. We made sure to add the bundle_of annotation to the config entity.

bundle_of = "set",Updating the content entity's annotation and fields

Once this was done, the next step was to update the content entity's annotation. We added the 'bundle' key and the 'bundle_entity_type' annotation

bundle_entity_type = "set_type", * entity_keys = { * "id" = "id", * "label" = "name", * "uuid" = "uuid", * "uid" = "user_id", * "bundle" = "type", * "langcode" = "langcode", * },

We didn't need to add a new field for our baseFieldDefinition to our content entity because we just deferred to the parent implementation. But we made sure to match up the description, label etc as desired - and that we called setInitialValue. As we're planning to add a new column to the entity's tables in the database, we need to populate the type column for existing records. Now with entities that don't support bundles, Drupal defaults to the entity ID for the bundle. e.g. for the 'user' entity, the bundle is always 'user' because User entities don't support bundles. So we knew our existing 'set' entities would have to have a bundle of 'set' too. But our new ones could have whatever we liked. So this is why our field definition for 'type' had to have look like so

$fields['type']->setInitialValue('set')Update hooks to get everything in place

Since Drupal 8.7, support for automatic entity updates has been removed, so whilst adding the field, entity keys and updating the annotation works for a new install (hint, there won't be one) it doesn't help our existing production and QA sites - so we need an update hook to bring our existing entity-type and field definitions into sync with the code versions, which also takes care of the required database table changes.

So the steps we need to do here are:

  1. install the config entity type
  2. create a new instance of it for the existing entities
  3. add the new field definition for the type field to the content entity
  4. update the content entity definition
Installing the config entity type

The docs for installing a new entity type make it clear what we need to do. Our code ended up something like this:

/** * Adds the set type. */ function your_module_update_8001() { \Drupal::entityDefinitionUpdateManager() ->installEntityType(new ConfigEntityType([ 'id' => 'set_type', 'label' => new TranslatableMarkup('Set type'), 'label_collection' => new TranslatableMarkup('Set types'), 'label_singular' => new TranslatableMarkup('set type'), 'label_plural' => new TranslatableMarkup('set types'), 'label_count' => [ 'singular' => '@count set type', 'plural' => '@count set types', ], 'handlers' => [ 'list_builder' => 'Drupal\your_module\SetTypeListBuilder', 'form' => [ 'default' => 'Drupal\your_module\Form\SetTypeForm', 'delete' => 'Drupal\Core\Entity\EntityDeleteForm', ], 'route_provider' => [ 'html' => 'Drupal\Core\Entity\Routing\AdminHtmlRouteProvider', ], ], 'admin_permission' => 'administer set type entities', 'entity_keys' => [ 'id' => 'id', 'label' => 'name', ], 'links' => [ 'add-form' => '/admin/structure/sets/add', 'delete-form' => '/admin/structure/sets/manage/{pane_set_type}/delete', 'reset-form' => '/admin/structure/sets/manage/{pane_set_type}/reset', 'overview-form' => '/admin/structure/sets/manage/{pane_set_type}/overview', 'edit-form' => '/admin/structure/sets/manage/{pane_set_type}', 'collection' => '/admin/structure/sets', ], 'config_export' => [ 'name', 'id', 'description', ], ])); }Creating the first bundle

In our first update hook we installed the config entity, now we need to make one for the existing entities, because bundle-less entities use the entity type ID as the bundle, we make sure our new type has the same ID as the entity-type.

/** * Adds a new config entity for the default set type. */ function your_module_update_8002() { $type = SetType::create([ 'id' => 'set', 'name' => 'Set', 'description' => 'Provides set panes', ]); $type->save(); }Adding the new field definition and updating the entity definition

The documentation for adding a new field definition is again very useful here, so we follow along to install our new field definition. And similarly the documentation for updating an entity type here, so our final update hook looks like this:

/** * Updates defintion for set entity. */ function your_module_update_8003() { $updates = \Drupal::entityDefinitionUpdateManager(); $definition = BaseFieldDefinition::create('entity_reference') ->setLabel('Set type') ->setSetting('target_type', 'set_type') ->setRequired(TRUE) ->setReadOnly(TRUE) ->setInitialValue('set') ->setDefaultValue('set'); $updates->installFieldStorageDefinition('type', 'your_module', 'your_module', $definition); $type = $updates->getEntityType('your_module'); $keys = $type->getKeys(); $keys['bundle'] = 'type'; $type->set('entity_keys', $keys); $type->set('bundle_entity_type', 'pane_set_type'); $updates->updateEntityType($type); }

And that's it we're done.

Wrapping up

Kudos to those who created the documentation for this, as well as my colleagues Sam Becker, Jibran Ijaz and Daniel Phin who helped me along the way. Hopefully, you find this post useful if you're ever in the same boat.

Tagged Content entities, Drupal 8, Entity Definition Update Manager, Bundles

PreviousNext: Using Drupal's Entity Definition Update Manager to add bundle support to an existing content entity

Main Drupal Feed - Tue, 11/05/2019 - 03:11

On a client project we were using a custom Drupal content entity to model some lightweight reusable content.

The content entity was originally single use and did not support bundles (e.g. node entities have node-type bundles).

As the project evolved, we needed to add bundle support for the custom entity-type, despite it already being in production use.

Read on to find out how we achieved this.

by Lee Rowlands / 5 November 2019

In this example, lets call the content entity a 'set' and the bundles a 'set type'.

Create the bundle configuration entity

As we wanted this content entity to support adding new bundles via the UI, a configuration entity makes sense to allow site-builders to create the various bundles as required, so we created a new configuration entity called 'set type' as per the examples, although we used a route provider instead of a routing file. We made sure to add the bundle_of annotation to the config entity.

bundle_of = "set",Updating the content entity's annotation and fields

Once this was done, the next step was to update the content entity's annotation. We added the 'bundle' key and the 'bundle_entity_type' annotation

bundle_entity_type = "set_type", * entity_keys = { * "id" = "id", * "label" = "name", * "uuid" = "uuid", * "uid" = "user_id", * "bundle" = "type", * "langcode" = "langcode", * },

We didn't need to add a new field for our baseFieldDefinition to our content entity because we just deferred to the parent implementation. But we made sure to match up the description, label etc as desired - and that we called setInitialValue. As we're planning to add a new column to the entity's tables in the database, we need to populate the type column for existing records. Now with entities that don't support bundles, Drupal defaults to the entity ID for the bundle. e.g. for the 'user' entity, the bundle is always 'user' because User entities don't support bundles. So we knew our existing 'set' entities would have to have a bundle of 'set' too. But our new ones could have whatever we liked. So this is why our field definition for 'type' had to have look like so

$fields['type']->setInitialValue('set')Update hooks to get everything in place

Since Drupal 8.7, support for automatic entity updates has been removed, so whilst adding the field, entity keys and updating the annotation works for a new install (hint, there won't be one) it doesn't help our existing production and QA sites - so we need an update hook to bring our existing entity-type and field definitions into sync with the code versions, which also takes care of the required database table changes.

So the steps we need to do here are:

  1. install the config entity type
  2. create a new instance of it for the existing entities
  3. add the new field definition for the type field to the content entity
  4. update the content entity definition
Installing the config entity type

The docs for installing a new entity type make it clear what we need to do. Our code ended up something like this:

/** * Adds the set type. */ function your_module_update_8001() { \Drupal::entityDefinitionUpdateManager() ->installEntityType(new ConfigEntityType([ 'id' => 'set_type', 'label' => new TranslatableMarkup('Set type'), 'label_collection' => new TranslatableMarkup('Set types'), 'label_singular' => new TranslatableMarkup('set type'), 'label_plural' => new TranslatableMarkup('set types'), 'label_count' => [ 'singular' => '@count set type', 'plural' => '@count set types', ], 'handlers' => [ 'list_builder' => 'Drupal\your_module\SetTypeListBuilder', 'form' => [ 'default' => 'Drupal\your_module\Form\SetTypeForm', 'delete' => 'Drupal\Core\Entity\EntityDeleteForm', ], 'route_provider' => [ 'html' => 'Drupal\Core\Entity\Routing\AdminHtmlRouteProvider', ], ], 'admin_permission' => 'administer set type entities', 'entity_keys' => [ 'id' => 'id', 'label' => 'name', ], 'links' => [ 'add-form' => '/admin/structure/sets/add', 'delete-form' => '/admin/structure/sets/manage/{pane_set_type}/delete', 'reset-form' => '/admin/structure/sets/manage/{pane_set_type}/reset', 'overview-form' => '/admin/structure/sets/manage/{pane_set_type}/overview', 'edit-form' => '/admin/structure/sets/manage/{pane_set_type}', 'collection' => '/admin/structure/sets', ], 'config_export' => [ 'name', 'id', 'description', ], ])); }Creating the first bundle

In our first update hook we installed the config entity, now we need to make one for the existing entities, because bundle-less entities use the entity type ID as the bundle, we make sure our new type has the same ID as the entity-type.

/** * Adds a new config entity for the default set type. */ function your_module_update_8002() { $type = SetType::create([ 'id' => 'set', 'name' => 'Set', 'description' => 'Provides set panes', ]); $type->save(); }Adding the new field definition and updating the entity definition

The documentation for adding a new field definition is again very useful here, so we follow along to install our new field definition. And similarly the documentation for updating an entity type here, so our final update hook looks like this:

/** * Updates defintion for set entity. */ function your_module_update_8003() { $updates = \Drupal::entityDefinitionUpdateManager(); $definition = BaseFieldDefinition::create('entity_reference') ->setLabel('Set type') ->setSetting('target_type', 'set_type') ->setRequired(TRUE) ->setReadOnly(TRUE) ->setInitialValue('set') ->setDefaultValue('set'); $updates->installFieldStorageDefinition('type', 'your_module', 'your_module', $definition); $type = $updates->getEntityType('your_module'); $keys = $type->getKeys(); $keys['bundle'] = 'type'; $type->set('entity_keys', $keys); $type->set('bundle_entity_type', 'pane_set_type'); $updates->updateEntityType($type); }

And that's it we're done.

Wrapping up

Kudos to those who created the documentation for this, as well as my colleagues Sam Becker, Jibran Ijaz and Daniel Phin who helped me along the way. Hopefully, you find this post useful if you're ever in the same boat.

Tagged Content entities, Drupal 8, Entity Definition Update Manager, Bundles

PreviousNext: Using Drupal's Entity Definition Update Manager to add bundle support to an existing content entity

Main Drupal Feed - Tue, 11/05/2019 - 03:11

On a client project we were using a custom Drupal content entity to model some lightweight reusable content.

The content entity was originally single use and did not support bundles (e.g. node entities have node-type bundles).

As the project evolved, we needed to add bundle support for the custom entity-type, despite it already being in production use.

Read on to find out how we achieved this.

by Lee Rowlands / 5 November 2019

In this example, lets call the content entity a 'set' and the bundles a 'set type'.

Create the bundle configuration entity

As we wanted this content entity to support adding new bundles via the UI, a configuration entity makes sense to allow site-builders to create the various bundles as required, so we created a new configuration entity called 'set type' as per the examples, although we used a route provider instead of a routing file. We made sure to add the bundle_of annotation to the config entity.

bundle_of = "set",Updating the content entity's annotation and fields

Once this was done, the next step was to update the content entity's annotation. We added the 'bundle' key and the 'bundle_entity_type' annotation

bundle_entity_type = "set_type", * entity_keys = { * "id" = "id", * "label" = "name", * "uuid" = "uuid", * "uid" = "user_id", * "bundle" = "type", * "langcode" = "langcode", * },

We didn't need to add a new field for our baseFieldDefinition to our content entity because we just deferred to the parent implementation. But we made sure to match up the description, label etc as desired - and that we called setInitialValue. As we're planning to add a new column to the entity's tables in the database, we need to populate the type column for existing records. Now with entities that don't support bundles, Drupal defaults to the entity ID for the bundle. e.g. for the 'user' entity, the bundle is always 'user' because User entities don't support bundles. So we knew our existing 'set' entities would have to have a bundle of 'set' too. But our new ones could have whatever we liked. So this is why our field definition for 'type' had to have look like so

$fields['type']->setInitialValue('set')Update hooks to get everything in place

Since Drupal 8.7, support for automatic entity updates has been removed, so whilst adding the field, entity keys and updating the annotation works for a new install (hint, there won't be one) it doesn't help our existing production and QA sites - so we need an update hook to bring our existing entity-type and field definitions into sync with the code versions, which also takes care of the required database table changes.

So the steps we need to do here are:

  1. install the config entity type
  2. create a new instance of it for the existing entities
  3. add the new field definition for the type field to the content entity
  4. update the content entity definition
Installing the config entity type

The docs for installing a new entity type make it clear what we need to do. Our code ended up something like this:

/** * Adds the set type. */ function your_module_update_8001() { \Drupal::entityDefinitionUpdateManager() ->installEntityType(new ConfigEntityType([ 'id' => 'set_type', 'label' => new TranslatableMarkup('Set type'), 'label_collection' => new TranslatableMarkup('Set types'), 'label_singular' => new TranslatableMarkup('set type'), 'label_plural' => new TranslatableMarkup('set types'), 'label_count' => [ 'singular' => '@count set type', 'plural' => '@count set types', ], 'handlers' => [ 'list_builder' => 'Drupal\your_module\SetTypeListBuilder', 'form' => [ 'default' => 'Drupal\your_module\Form\SetTypeForm', 'delete' => 'Drupal\Core\Entity\EntityDeleteForm', ], 'route_provider' => [ 'html' => 'Drupal\Core\Entity\Routing\AdminHtmlRouteProvider', ], ], 'admin_permission' => 'administer set type entities', 'entity_keys' => [ 'id' => 'id', 'label' => 'name', ], 'links' => [ 'add-form' => '/admin/structure/sets/add', 'delete-form' => '/admin/structure/sets/manage/{pane_set_type}/delete', 'reset-form' => '/admin/structure/sets/manage/{pane_set_type}/reset', 'overview-form' => '/admin/structure/sets/manage/{pane_set_type}/overview', 'edit-form' => '/admin/structure/sets/manage/{pane_set_type}', 'collection' => '/admin/structure/sets', ], 'config_export' => [ 'name', 'id', 'description', ], ])); }Creating the first bundle

In our first update hook we installed the config entity, now we need to make one for the existing entities, because bundle-less entities use the entity type ID as the bundle, we make sure our new type has the same ID as the entity-type.

/** * Adds a new config entity for the default set type. */ function your_module_update_8002() { $type = SetType::create([ 'id' => 'set', 'name' => 'Set', 'description' => 'Provides set panes', ]); $type->save(); }Adding the new field definition and updating the entity definition

The documentation for adding a new field definition is again very useful here, so we follow along to install our new field definition. And similarly the documentation for updating an entity type here, so our final update hook looks like this:

/** * Updates defintion for set entity. */ function your_module_update_8003() { $updates = \Drupal::entityDefinitionUpdateManager(); $definition = BaseFieldDefinition::create('entity_reference') ->setLabel('Set type') ->setSetting('target_type', 'set_type') ->setRequired(TRUE) ->setReadOnly(TRUE) ->setInitialValue('set') ->setDefaultValue('set'); $updates->installFieldStorageDefinition('type', 'your_module', 'your_module', $definition); $type = $updates->getEntityType('your_module'); $keys = $type->getKeys(); $keys['bundle'] = 'type'; $type->set('entity_keys', $keys); $type->set('bundle_entity_type', 'pane_set_type'); $updates->updateEntityType($type); }

And that's it we're done.

Wrapping up

Kudos to those who created the documentation for this, as well as my colleagues Sam Becker, Jibran Ijaz and Daniel Phin who helped me along the way. Hopefully, you find this post useful if you're ever in the same boat.

Tagged Content entities, Drupal 8, Entity Definition Update Manager, Bundles

WPTavern: State of the Word 2019 Recap: All Roads Lead to the Block Editor

Wordpress Planet - Mon, 11/04/2019 - 19:18

If there was one common theme in Matt Mullenweg’s State of the Word address this year at WordCamp U.S., it was that all roads lead to the block editor. His speech was primarily about blocks, blocks, more blocks, and a dash of community. This doesn’t come as a surprise because we are closing in on the one year mark of the official merge of the Gutenberg plugin into the core WordPress code. It has been a year about blocks, and nothing is changing that course.

WordCamp U.S. 2019 was held in St. Louis, Missouri, over this past weekend. The event was planned and put together by 47 organizers and 122 volunteers. There were 90 speakers who held sessions across a range of topics in multiple rooms.

For people who were not able to attend or watch via the livestream, the sessions are available via YouTube. Eventually, the videos will also make their way over to WordPress.tv

Open: The Community Code

Mullenweg opened The State of the Word by showing a documentary named Open: The Community Code, which is a film that primarily focuses on the WordPress community.

The film explores why people are so passionate about a project that is essentially just code. What drives them to organize and attend events like WordCamps? Why do they volunteer their free time contributing to an industry that sees over $10 billion in profits? What makes the WordPress community different from other projects? The film team interviewed 37 people to get to the bottom of these questions.

The team behind the project is also providing the film and all of the raw footage as open source for others to use.

The Events of the Past Year

Mullenweg primarily focused on WordPress updates and changes within the community when recapping events of the past year. Since the release of WordPress 5.0 on December 6, 2018, WordPress has had two major releases. A third major release, WordPress 5.3, is scheduled to launch on November 12.

During 2019, most heavy work went into the Gutenberg plugin, which was ported back into core WordPress. The number of contributors to Gutenberg more than doubled since WordPress 5.0 launch, an increase from 200 to 480 individuals.

The release of WordPress 5.1 introduced the first iteration of the site health page, new cron features, and a site meta table for multisite installations.

“WordPress is all about empowering users and we wanted to put the information and the tools in the hands of users as well to keep the site running in tip-top shape as we power an ever-increasing percentage of the web,” said Mullenweg of the site health feature. He further explained that it is WordPress’ responsibility to make sure users are up to date and running the latest versions of software.

Building on top of the site health introduction, WordPress 5.2 launched with a PHP fatal error protection and recovery mode. The release also bumped the minimum PHP version to 5.6 and ported all widgets to blocks.

Mullenweg then outlined the work done toward getting WordPress 5.3 ready for its November 12 launch date. The major changes include:

  • 150+ block editor improvements
  • Twenty Twenty default theme
  • Date/Time improvements and fixes
  • PHP 7.4 compatibility

As of now, 83% of all users on WordPress 5.2 or newer are running at least PHP 7. This means the WordPress project has done what it can from the user end. It is now time to start working with hosts to get sites updated to the latest version of PHP.

The block editor is now available on both Android and iOS devices. Mullenweg announced they were almost done with offline post support and that a dark mode is coming in weeks.

The community had a good year. In 2019, there were 141 WordCamp events, 34 of which were in new cities. There were 17 Kids Camps for younger contributors to get involved. There were also over 5,000 meetups and 16 do_action() charity hackathons.

The WordPress news page has been highlighting one story from HeroPress every month in the past year. HeroPress is a project that allows people to tell their stories of how they got involved with WordPress.

Mullenweg held a moment of silence for long-time community member Alex Mills (viper007bond) who passed away earlier this year after a long-fought battle with leukemia. Automattic is planning to finance a scholarship in his honor. The scholarship will go to a plugin developer to attend WordCamp U.S. who has not had an opportunity to attend.

2019: The Year of the Block Editor Slide with screenshots of Gutenberg criticism from users.

Mullenweg started focusing on the block editor after recapping the events of the past year. WordPress 5.0 was released one day before WordCamp U.S. 2018 in Nashville.

“We had people coordinating work from airplanes,” said Mullenweg. “There were impromptu groups of core developers, testing and packaging the release in the hallways. The polyglots, marketers, and support teams were just scrambling to get ready.”

He explained the reason for the biggest change to WordPress in its then 16-year history. “We came together and decided to make this big change cause we wanted to first disrupt ourselves. We wanted to empower more WordPress users to realize our mission of democratizing publishing, and wanted to make the web a more open and welcoming place.”

Not everyone was happy with the direction of WordPress and its new block editor. It was a rough year from a leadership perspective to have a vision and see it through, despite constant negative feedback. Mullenweg highlighted some of the comments that were critical of the block editor and explained that they had learned a lot from the process.

“I think that we also have a great opportunity when we make big changes in the future,” said Mullenweg. “Sort of build that trust in the conversations around testing, using GitHub for development, things like accessibility. So, I understand why we had a lot of this feedback. But, we did get through it together.”

Mullenweg highlighted that, according to Jetpack plugin stats, over 50 million posts have been written in the block editor. That amounts to around 270 thousand posts per day. It is important to note that this stat is on the lower end because it only accounts for users of the Jetpack plugin. Therefore, the number is likely much higher.

He covered the performance improvements to the editor, block motion when moving blocks, typewriter mode, block previews, and the social block. “These are like the Nascar stickers of the web,” he said of social icons. “They’re everywhere.”

The Next Steps for the Block Editor

In his address, Mullenweg covered the four phases of the Gutenberg project.

  1. Easier Editing
  2. Customization
  3. Collaboration
  4. Multilingual

The first phase was the initial launch and iteration of the block editor for content. The second stage, which we are in now, is about full site customization. This includes widgets and non-content areas, and will eventually cover areas like the site header and footer. It will be interesting to see how page-building plugins work with these upcoming changes. Some could use WordPress as the foundational, framework-type layer. Others may go their own way. Themes will also have to keep pace with the changes.

Phase three, collaboration, will introduce a feature that allows multiple authors to collaborate and co-edit posts on a site in real time. With any luck, WordPress will also build in a proper system for attributing posts to multiple authors.

The fourth and final phase cannot get here fast enough. As WordPress usage continues to grow around the world, it is past time that it offered a multilingual experience. “We’re going to tackle the Babel fish problem,” said Mullenweg.

Also on the roadmap is the concept of block patterns. Patterns would be a groups of blocks that follows common patterns seen across the web. The existing Media & Text block is an example of a common pattern, but new patterns would go far beyond something so basic. By providing patterns to users, they could simply insert a pattern and fill in their details, which should make it easy to rapidly create rich content.

Watch the State of the Word

Mullenweg’s entire presentation was done from the block editor. He used the Slides plugin created by Ella van Durpe.

Community Questions and Answers

The Q&A sessions after Mullenweg’s address was more focused on community and policy.

Rian Kinney asked whether we would see official policies on accessibility, ethics, conflicts of interest, and diversity. She wanted to know how the community could make this happen over the next year.

While a privacy policy is in the footer of WordPress.org, Mullenweg expressed his desire to not make changes than lean too heavily on policy. “That is in spite of there being a policy or not, we’ve tried to enact bigger changes in WordPress in a policy-first way in the past,” he said. “To be honest, it felt nice but didn’t always make things actually change.” He said we usually do better by working with people to make changes rather than starting with the policy.

Olivia Bisset, a young WordCamp speaker behind Lemonade Code, asked Mullenweg how we could inspire kids who are currently in school to get involved with WordPress. The project has tough competition coming from more exciting technology sectors such as robotics and other industries that are swaying the next generation.

“This is going to be on YouTube later, and boys and girls, maybe of your generation, will see you here asking a question and being a speaker at WordCamp in front of a thousand adults,” said Mullenweg. “And, you know, it’s kind of beautiful.”

Mullenweg said that we need more stories from younger people on HeroPress and that Kids Camps will help. He said that WordPress should be easier and more accessible, which are things that the current generation is more aware of and care about. He also mentioned Automattic’s recent acquisition of Tumblr, which has a larger user base of young users, as a way to introduce them to WordPress.

View the Q&A portion of The State of the Word in the following video.

Hook 42: Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019

Main Drupal Feed - Mon, 11/04/2019 - 18:30
Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019 Lindsey Gemmill Mon, 11/04/2019 - 18:30

Hook 42: Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019

Main Drupal Feed - Mon, 11/04/2019 - 18:30
Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019 Lindsey Gemmill Mon, 11/04/2019 - 18:30

Hook 42: Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019

Main Drupal Feed - Mon, 11/04/2019 - 18:30
Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019 Lindsey Gemmill Mon, 11/04/2019 - 18:30

Hook 42: Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019

Main Drupal Feed - Mon, 11/04/2019 - 18:30
Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019 Lindsey Gemmill Mon, 11/04/2019 - 18:30

Hook 42: Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019

Main Drupal Feed - Mon, 11/04/2019 - 18:30
Drupal Core Initiative Meetings Recap - October 28 - November 01, 2019 Lindsey Gemmill Mon, 11/04/2019 - 18:30

Acro Media: Making Drupal Code Standards Work for You With PhpStorm & phpcs/phpcbf

Main Drupal Feed - Mon, 11/04/2019 - 15:45
A proactive approach for cleaner Drupal coding


So you are stuck in the cruft, struggling to create some semblance of sanity within a sea of code-rot. Code standards sound like a great idea for your project, but perhaps automated enforcement tools look like more of a pain than they're worth. This post is intended for Drupal developers using PhpStorm who need fast, flexible, standards enforcement tools.

Maintaining a stringent standard for your codebase is a battle. On one hand, your code is cleaner, more unified, and easier to maintain. On the other hand, these little formatting rules cause frustration and time loss - especially if a tiny slip causes you to waste a full pipeline cycle just to pass an automated standards check. As they say, the best defence is a strong offence, and the tools proposed here will help you find and fix standards violations before they reach a pipeline.

Drupal recommends a tool called PHP Code Sniffer, aka phpcs, to scan your files for Drupal Code Standards violations. Thankfully, it also comes with a companion tool called PHP Code Beautifier and Fixer, aka phpcbf, which fixes the small, tedious violations for you.

The goal of this post is to get phpcs and phpcbf under your fingertips and into your habits. Only once you have hotkeys set-up to run these tools while coding will they become useful — instead of just annoying.

The steps are as follows:

  1. Install and set-up phpcs
  2. Create a custom combination of rulesets
  3. Integrate with PhpStorm for hotkeys and syntax highlighting
1. Install and set-up phpcs

It may seem straightforward to install phpcs globally via Composer or apt, or to simply require it in your current composer project. However, a global install is not easy to customize and share. Instead, I recommend using a standalone repo that is specifically for your code standards tools. When your standards stand alone, they are easier to edit, share with teammates, and transfer to new work environments.

Here’s a simple repo to get you started:
https://github.com/nilswloewen/drupal_code_standards

  1. If you currently have phpcs or phpcbf installed globally, uninstall them before proceeding.

  2. Quick install with example repo:

    git clone git@github.com:nilswloewen/drupal_code_standards.git
    cd drupal_code_standards
    composer install
  3. Once composer has installed phpcs for you, add it to your global path with:

    export PATH=$PATH:~/PATH/TO/drupal_code_standards/vendor/bin
    NOTE: Adjust accordingly for your shell and OS of choice.

  4. Next, you must tell phpcs which rulesets you have installed use.

    The optional tool phpcodesniffer-composer-installer will automatically detect rulesets in your composer package and set your phpcs & phpcbf installed_paths for you. This is part of the example repo and the next step should have been done for you during "composer install".

    However, to set installed paths to rulesets manually run:

    phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer,vendor/phpcompatibility/php-compatibility/PHPCompatibility

    Then confirm that phpcs knows about the rulesets within the installed paths with:

    phpcs -i

    You should see this list that confirms your rulesets:

    The installed coding standards are ... PHPCompatibility, Drupal and DrupalPractice

    You may need to set installed paths for phpcbf as well using the same process.

2. Create a custom combination of rulesets

Out of the box, phpcs can only run one standard at a time. This is a problem when working with Drupal because we have 2 standards to follow. For this post I have added a third standard, PHPCompatibility, which is helpful when upgrading php versions on legacy projects.

  1. To combine standards we first create a custom ruleset that references multiple rulesets. Note that this is already included in the example repo as phpcs-custom-standards.xml.

    <?xml version="1.0"?>
    <ruleset name="Custom code standards">
    <rule ref="Drupal"/>
    <rule ref="DrupalPractice"/>
    <rule ref="PHPCompatibility"/>
    </ruleset>
  2. Then set this standard as your default. Use an absolute path to ensure your standard will be found no matter what context phpcs is called from.

    phpcs --config-set default_standard ~/PATH/TO/drupal_code_standards/phpcs-custom-standard.xml See the example standard for a few other helpful settings.
3. Integrate with PhpStorm for hotkeys and syntax highlighting

There are two levels of integration with PhpStorm: Passive and Active.

Passive

Passive code analysis with PhpStorm Inspections will give you syntax highlighting and hover-over explanations of the file you are currently working on.

This is quite helpful when dealing with one file at a time, but when you need to get an entire directory to pass standards, you need a way to hunt for violations.

Active

Active analysis when you use phpcs to scan many files at once. You can do this through the terminal with a command like:

phpcs ~/module # Scans all applicable files in dir.
phpcs ~/module/example.php # Scans only a specific file.

However, it’s a pain to open a terminal window, navigate to the file you are working on, and then type a command. You’ll probably forget or neglect to check your work because of these extra steps involved. A better way to run phpcs is to set-up hotkeys within PhpStorm to scan your files instantly.

Configure PhpStorm inspections
  1. Register phpcs and phpcbf as PHP Quality Tools.

    Settings | Languages and Frameworks | PHP | Quality Tools | Code Sniffer



  2. Enable the inspection.

    Settings | Editor | Inspection | PHP | Quality Tools

  • Set the extension list to match what Drupal standard sets: source

    php,module,inc,install,test,profile,theme,css,info,txt,md,yml
  • DO NOT set the "Installed standard paths", as this overrides what you have previously set in the command line.
  • The refresh list button on "Coding Standard" should mimic what "phpcs -i" shows. Choose "Custom" Coding Standard and then click the ellipses to choose the path to your custom standards file (i.e. phpcs-custom-standards.xml).
  • Click OK and your inspections should be working!
Configure hotkeys
  1. Register phpcs and phpcbf as external tools.

    Settings | Tools | External Tools

    The "$FilePath" argument runs the tool against the file you are currently working on, or against a selected folder when in project view.

  2. Double check that this step works by running the tool from the main menu.

    Tools | External Tools | phpcs

  3. This is the special sauce. Configure a keyboard shortcut for your new tools.

    Settings | Keymap | External Tools

  4. Right click on the external tool you just registered and add a keyboard shortcut. "Ctrl+Alt+Shift+Comma" was simply a combination that was not used anywhere else in my setup.

Bringing it all together

Now you can actively use phpcs and phpcbf while you code! I frequently use the phpcbf hotkey while writing new code to do the tedious stuff for me, such as creating doc blocks and pushing whitespace around. Here's an example:

With phpcs and phpcbf now under your fingertips you are set to be much more assertive in your application of code standards!

Taking it to the next level

If you are using Gitlab for CI/CD, which I hope you are, another great strategy for enforcing standards is to create a pre-deployment job that scans your custom code for violations. This will keep your team (and you) in check by stopping standards violations from being auto-deployed.

After a few super annoying pipeline failures for minor syntax errors, you will want this next level of enforcement — git pre-commit hooks. I highly recommend using grumphp to manage this for you.

Best of luck keeping your code readable and up to snuff!

End-to-end Drupal services

As a full service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce design, customer experience, software development and hosting architecture. If you’re looking for a Drupal agency dedicated to code and project quality, check us out. We would love the opportunity to talk.

Acro Media: Making Drupal Code Standards Work for You With PhpStorm & phpcs/phpcbf

Main Drupal Feed - Mon, 11/04/2019 - 15:45
A proactive approach for cleaner Drupal coding


So you are stuck in the cruft, struggling to create some semblance of sanity within a sea of code-rot. Code standards sound like a great idea for your project, but perhaps automated enforcement tools look like more of a pain than they're worth. This post is intended for Drupal developers using PhpStorm who need fast, flexible, standards enforcement tools.

Maintaining a stringent standard for your codebase is a battle. On one hand, your code is cleaner, more unified, and easier to maintain. On the other hand, these little formatting rules cause frustration and time loss - especially if a tiny slip causes you to waste a full pipeline cycle just to pass an automated standards check. As they say, the best defence is a strong offence, and the tools proposed here will help you find and fix standards violations before they reach a pipeline.

Drupal recommends a tool called PHP Code Sniffer, aka phpcs, to scan your files for Drupal Code Standards violations. Thankfully, it also comes with a companion tool called PHP Code Beautifier and Fixer, aka phpcbf, which fixes the small, tedious violations for you.

The goal of this post is to get phpcs and phpcbf under your fingertips and into your habits. Only once you have hotkeys set-up to run these tools while coding will they become useful — instead of just annoying.

The steps are as follows:

  1. Install and set-up phpcs
  2. Create a custom combination of rulesets
  3. Integrate with PhpStorm for hotkeys and syntax highlighting
1. Install and set-up phpcs

It may seem straightforward to install phpcs globally via Composer or apt, or to simply require it in your current composer project. However, a global install is not easy to customize and share. Instead, I recommend using a standalone repo that is specifically for your code standards tools. When your standards stand alone, they are easier to edit, share with teammates, and transfer to new work environments.

Here’s a simple repo to get you started:
https://github.com/nilswloewen/drupal_code_standards

  1. If you currently have phpcs or phpcbf installed globally, uninstall them before proceeding.

  2. Quick install with example repo:

    git clone git@github.com:nilswloewen/drupal_code_standards.git
    cd drupal_code_standards
    composer install
  3. Once composer has installed phpcs for you, add it to your global path with:

    export PATH=$PATH:~/PATH/TO/drupal_code_standards/vendor/bin
    NOTE: Adjust accordingly for your shell and OS of choice.

  4. Next, you must tell phpcs which rulesets you have installed use.

    The optional tool phpcodesniffer-composer-installer will automatically detect rulesets in your composer package and set your phpcs & phpcbf installed_paths for you. This is part of the example repo and the next step should have been done for you during "composer install".

    However, to set installed paths to rulesets manually run:

    phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer,vendor/phpcompatibility/php-compatibility/PHPCompatibility

    Then confirm that phpcs knows about the rulesets within the installed paths with:

    phpcs -i

    You should see this list that confirms your rulesets:

    The installed coding standards are ... PHPCompatibility, Drupal and DrupalPractice

    You may need to set installed paths for phpcbf as well using the same process.

2. Create a custom combination of rulesets

Out of the box, phpcs can only run one standard at a time. This is a problem when working with Drupal because we have 2 standards to follow. For this post I have added a third standard, PHPCompatibility, which is helpful when upgrading php versions on legacy projects.

  1. To combine standards we first create a custom ruleset that references multiple rulesets. Note that this is already included in the example repo as phpcs-custom-standards.xml.

    <?xml version="1.0"?>
    <ruleset name="Custom code standards">
    <rule ref="Drupal"/>
    <rule ref="DrupalPractice"/>
    <rule ref="PHPCompatibility"/>
    </ruleset>
  2. Then set this standard as your default. Use an absolute path to ensure your standard will be found no matter what context phpcs is called from.

    phpcs --config-set default_standard ~/PATH/TO/drupal_code_standards/phpcs-custom-standard.xml See the example standard for a few other helpful settings.
3. Integrate with PhpStorm for hotkeys and syntax highlighting

There are two levels of integration with PhpStorm: Passive and Active.

Passive

Passive code analysis with PhpStorm Inspections will give you syntax highlighting and hover-over explanations of the file you are currently working on.

This is quite helpful when dealing with one file at a time, but when you need to get an entire directory to pass standards, you need a way to hunt for violations.

Active

Active analysis when you use phpcs to scan many files at once. You can do this through the terminal with a command like:

phpcs ~/module # Scans all applicable files in dir.
phpcs ~/module/example.php # Scans only a specific file.

However, it’s a pain to open a terminal window, navigate to the file you are working on, and then type a command. You’ll probably forget or neglect to check your work because of these extra steps involved. A better way to run phpcs is to set-up hotkeys within PhpStorm to scan your files instantly.

Configure PhpStorm inspections
  1. Register phpcs and phpcbf as PHP Quality Tools.

    Settings | Languages and Frameworks | PHP | Quality Tools | Code Sniffer



  2. Enable the inspection.

    Settings | Editor | Inspection | PHP | Quality Tools

  • Set the extension list to match what Drupal standard sets: source

    php,module,inc,install,test,profile,theme,css,info,txt,md,yml
  • DO NOT set the "Installed standard paths", as this overrides what you have previously set in the command line.
  • The refresh list button on "Coding Standard" should mimic what "phpcs -i" shows. Choose "Custom" Coding Standard and then click the ellipses to choose the path to your custom standards file (i.e. phpcs-custom-standards.xml).
  • Click OK and your inspections should be working!
Configure hotkeys
  1. Register phpcs and phpcbf as external tools.

    Settings | Tools | External Tools

    The "$FilePath" argument runs the tool against the file you are currently working on, or against a selected folder when in project view.

  2. Double check that this step works by running the tool from the main menu.

    Tools | External Tools | phpcs

  3. This is the special sauce. Configure a keyboard shortcut for your new tools.

    Settings | Keymap | External Tools

  4. Right click on the external tool you just registered and add a keyboard shortcut. "Ctrl+Alt+Shift+Comma" was simply a combination that was not used anywhere else in my setup.

Bringing it all together

Now you can actively use phpcs and phpcbf while you code! I frequently use the phpcbf hotkey while writing new code to do the tedious stuff for me, such as creating doc blocks and pushing whitespace around. Here's an example:

With phpcs and phpcbf now under your fingertips you are set to be much more assertive in your application of code standards!

Taking it to the next level

If you are using Gitlab for CI/CD, which I hope you are, another great strategy for enforcing standards is to create a pre-deployment job that scans your custom code for violations. This will keep your team (and you) in check by stopping standards violations from being auto-deployed.

After a few super annoying pipeline failures for minor syntax errors, you will want this next level of enforcement — git pre-commit hooks. I highly recommend using grumphp to manage this for you.

Best of luck keeping your code readable and up to snuff!

End-to-end Drupal services

As a full service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce design, customer experience, software development and hosting architecture. If you’re looking for a Drupal agency dedicated to code and project quality, check us out. We would love the opportunity to talk.

Acro Media: Making Drupal Code Standards Work for You With PhpStorm & phpcs/phpcbf

Main Drupal Feed - Mon, 11/04/2019 - 15:45
A proactive approach for cleaner Drupal coding


So you are stuck in the cruft, struggling to create some semblance of sanity within a sea of code-rot. Code standards sound like a great idea for your project, but perhaps automated enforcement tools look like more of a pain than they're worth. This post is intended for Drupal developers using PhpStorm who need fast, flexible, standards enforcement tools.

Maintaining a stringent standard for your codebase is a battle. On one hand, your code is cleaner, more unified, and easier to maintain. On the other hand, these little formatting rules cause frustration and time loss - especially if a tiny slip causes you to waste a full pipeline cycle just to pass an automated standards check. As they say, the best defence is a strong offence, and the tools proposed here will help you find and fix standards violations before they reach a pipeline.

Drupal recommends a tool called PHP Code Sniffer, aka phpcs, to scan your files for Drupal Code Standards violations. Thankfully, it also comes with a companion tool called PHP Code Beautifier and Fixer, aka phpcbf, which fixes the small, tedious violations for you.

The goal of this post is to get phpcs and phpcbf under your fingertips and into your habits. Only once you have hotkeys set-up to run these tools while coding will they become useful — instead of just annoying.

The steps are as follows:

  1. Install and set-up phpcs
  2. Create a custom combination of rulesets
  3. Integrate with PhpStorm for hotkeys and syntax highlighting
1. Install and set-up phpcs

It may seem straightforward to install phpcs globally via Composer or apt, or to simply require it in your current composer project. However, a global install is not easy to customize and share. Instead, I recommend using a standalone repo that is specifically for your code standards tools. When your standards stand alone, they are easier to edit, share with teammates, and transfer to new work environments.

Here’s a simple repo to get you started:
https://github.com/nilswloewen/drupal_code_standards

  1. If you currently have phpcs or phpcbf installed globally, uninstall them before proceeding.

  2. Quick install with example repo:

    git clone git@github.com:nilswloewen/drupal_code_standards.git
    cd drupal_code_standards
    composer install
  3. Once composer has installed phpcs for you, add it to your global path with:

    export PATH=$PATH:~/PATH/TO/drupal_code_standards/vendor/bin
    NOTE: Adjust accordingly for your shell and OS of choice.

  4. Next, you must tell phpcs which rulesets you have installed use.

    The optional tool phpcodesniffer-composer-installer will automatically detect rulesets in your composer package and set your phpcs & phpcbf installed_paths for you. This is part of the example repo and the next step should have been done for you during "composer install".

    However, to set installed paths to rulesets manually run:

    phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer,vendor/phpcompatibility/php-compatibility/PHPCompatibility

    Then confirm that phpcs knows about the rulesets within the installed paths with:

    phpcs -i

    You should see this list that confirms your rulesets:

    The installed coding standards are ... PHPCompatibility, Drupal and DrupalPractice

    You may need to set installed paths for phpcbf as well using the same process.

2. Create a custom combination of rulesets

Out of the box, phpcs can only run one standard at a time. This is a problem when working with Drupal because we have 2 standards to follow. For this post I have added a third standard, PHPCompatibility, which is helpful when upgrading php versions on legacy projects.

  1. To combine standards we first create a custom ruleset that references multiple rulesets. Note that this is already included in the example repo as phpcs-custom-standards.xml.

    <?xml version="1.0"?>
    <ruleset name="Custom code standards">
    <rule ref="Drupal"/>
    <rule ref="DrupalPractice"/>
    <rule ref="PHPCompatibility"/>
    </ruleset>
  2. Then set this standard as your default. Use an absolute path to ensure your standard will be found no matter what context phpcs is called from.

    phpcs --config-set default_standard ~/PATH/TO/drupal_code_standards/phpcs-custom-standard.xml See the example standard for a few other helpful settings.
3. Integrate with PhpStorm for hotkeys and syntax highlighting

There are two levels of integration with PhpStorm: Passive and Active.

Passive

Passive code analysis with PhpStorm Inspections will give you syntax highlighting and hover-over explanations of the file you are currently working on.

This is quite helpful when dealing with one file at a time, but when you need to get an entire directory to pass standards, you need a way to hunt for violations.

Active

Active analysis when you use phpcs to scan many files at once. You can do this through the terminal with a command like:

phpcs ~/module # Scans all applicable files in dir.
phpcs ~/module/example.php # Scans only a specific file.

However, it’s a pain to open a terminal window, navigate to the file you are working on, and then type a command. You’ll probably forget or neglect to check your work because of these extra steps involved. A better way to run phpcs is to set-up hotkeys within PhpStorm to scan your files instantly.

Configure PhpStorm inspections
  1. Register phpcs and phpcbf as PHP Quality Tools.

    Settings | Languages and Frameworks | PHP | Quality Tools | Code Sniffer



  2. Enable the inspection.

    Settings | Editor | Inspection | PHP | Quality Tools

  • Set the extension list to match what Drupal standard sets: source

    php,module,inc,install,test,profile,theme,css,info,txt,md,yml
  • DO NOT set the "Installed standard paths", as this overrides what you have previously set in the command line.
  • The refresh list button on "Coding Standard" should mimic what "phpcs -i" shows. Choose "Custom" Coding Standard and then click the ellipses to choose the path to your custom standards file (i.e. phpcs-custom-standards.xml).
  • Click OK and your inspections should be working!
Configure hotkeys
  1. Register phpcs and phpcbf as external tools.

    Settings | Tools | External Tools

    The "$FilePath" argument runs the tool against the file you are currently working on, or against a selected folder when in project view.

  2. Double check that this step works by running the tool from the main menu.

    Tools | External Tools | phpcs

  3. This is the special sauce. Configure a keyboard shortcut for your new tools.

    Settings | Keymap | External Tools

  4. Right click on the external tool you just registered and add a keyboard shortcut. "Ctrl+Alt+Shift+Comma" was simply a combination that was not used anywhere else in my setup.

Bringing it all together

Now you can actively use phpcs and phpcbf while you code! I frequently use the phpcbf hotkey while writing new code to do the tedious stuff for me, such as creating doc blocks and pushing whitespace around. Here's an example:

With phpcs and phpcbf now under your fingertips you are set to be much more assertive in your application of code standards!

Taking it to the next level

If you are using Gitlab for CI/CD, which I hope you are, another great strategy for enforcing standards is to create a pre-deployment job that scans your custom code for violations. This will keep your team (and you) in check by stopping standards violations from being auto-deployed.

After a few super annoying pipeline failures for minor syntax errors, you will want this next level of enforcement — git pre-commit hooks. I highly recommend using grumphp to manage this for you.

Best of luck keeping your code readable and up to snuff!

End-to-end Drupal services

As a full service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce design, customer experience, software development and hosting architecture. If you’re looking for a Drupal agency dedicated to code and project quality, check us out. We would love the opportunity to talk.

Acro Media: Making Drupal Code Standards Work for You With PhpStorm & phpcs/phpcbf

Main Drupal Feed - Mon, 11/04/2019 - 15:45
A proactive approach for cleaner Drupal coding


So you are stuck in the cruft, struggling to create some semblance of sanity within a sea of code-rot. Code standards sound like a great idea for your project, but perhaps automated enforcement tools look like more of a pain than they're worth. This post is intended for Drupal developers using PhpStorm who need fast, flexible, standards enforcement tools.

Maintaining a stringent standard for your codebase is a battle. On one hand, your code is cleaner, more unified, and easier to maintain. On the other hand, these little formatting rules cause frustration and time loss - especially if a tiny slip causes you to waste a full pipeline cycle just to pass an automated standards check. As they say, the best defence is a strong offence, and the tools proposed here will help you find and fix standards violations before they reach a pipeline.

Drupal recommends a tool called PHP Code Sniffer, aka phpcs, to scan your files for Drupal Code Standards violations. Thankfully, it also comes with a companion tool called PHP Code Beautifier and Fixer, aka phpcbf, which fixes the small, tedious violations for you.

The goal of this post is to get phpcs and phpcbf under your fingertips and into your habits. Only once you have hotkeys set-up to run these tools while coding will they become useful — instead of just annoying.

The steps are as follows:

  1. Install and set-up phpcs
  2. Create a custom combination of rulesets
  3. Integrate with PhpStorm for hotkeys and syntax highlighting
1. Install and set-up phpcs

It may seem straightforward to install phpcs globally via Composer or apt, or to simply require it in your current composer project. However, a global install is not easy to customize and share. Instead, I recommend using a standalone repo that is specifically for your code standards tools. When your standards stand alone, they are easier to edit, share with teammates, and transfer to new work environments.

Here’s a simple repo to get you started:
https://github.com/nilswloewen/drupal_code_standards

  1. If you currently have phpcs or phpcbf installed globally, uninstall them before proceeding.

  2. Quick install with example repo:

    git clone git@github.com:nilswloewen/drupal_code_standards.git
    cd drupal_code_standards
    composer install
  3. Once composer has installed phpcs for you, add it to your global path with:

    export PATH=$PATH:~/PATH/TO/drupal_code_standards/vendor/bin
    NOTE: Adjust accordingly for your shell and OS of choice.

  4. Next, you must tell phpcs which rulesets you have installed use.

    The optional tool phpcodesniffer-composer-installer will automatically detect rulesets in your composer package and set your phpcs & phpcbf installed_paths for you. This is part of the example repo and the next step should have been done for you during "composer install".

    However, to set installed paths to rulesets manually run:

    phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer,vendor/phpcompatibility/php-compatibility/PHPCompatibility

    Then confirm that phpcs knows about the rulesets within the installed paths with:

    phpcs -i

    You should see this list that confirms your rulesets:

    The installed coding standards are ... PHPCompatibility, Drupal and DrupalPractice

    You may need to set installed paths for phpcbf as well using the same process.

2. Create a custom combination of rulesets

Out of the box, phpcs can only run one standard at a time. This is a problem when working with Drupal because we have 2 standards to follow. For this post I have added a third standard, PHPCompatibility, which is helpful when upgrading php versions on legacy projects.

  1. To combine standards we first create a custom ruleset that references multiple rulesets. Note that this is already included in the example repo as phpcs-custom-standards.xml.

    <?xml version="1.0"?>
    <ruleset name="Custom code standards">
    <rule ref="Drupal"/>
    <rule ref="DrupalPractice"/>
    <rule ref="PHPCompatibility"/>
    </ruleset>
  2. Then set this standard as your default. Use an absolute path to ensure your standard will be found no matter what context phpcs is called from.

    phpcs --config-set default_standard ~/PATH/TO/drupal_code_standards/phpcs-custom-standard.xml See the example standard for a few other helpful settings.
3. Integrate with PhpStorm for hotkeys and syntax highlighting

There are two levels of integration with PhpStorm: Passive and Active.

Passive

Passive code analysis with PhpStorm Inspections will give you syntax highlighting and hover-over explanations of the file you are currently working on.

This is quite helpful when dealing with one file at a time, but when you need to get an entire directory to pass standards, you need a way to hunt for violations.

Active

Active analysis when you use phpcs to scan many files at once. You can do this through the terminal with a command like:

phpcs ~/module # Scans all applicable files in dir.
phpcs ~/module/example.php # Scans only a specific file.

However, it’s a pain to open a terminal window, navigate to the file you are working on, and then type a command. You’ll probably forget or neglect to check your work because of these extra steps involved. A better way to run phpcs is to set-up hotkeys within PhpStorm to scan your files instantly.

Configure PhpStorm inspections
  1. Register phpcs and phpcbf as PHP Quality Tools.

    Settings | Languages and Frameworks | PHP | Quality Tools | Code Sniffer



  2. Enable the inspection.

    Settings | Editor | Inspection | PHP | Quality Tools

  • Set the extension list to match what Drupal standard sets: source

    php,module,inc,install,test,profile,theme,css,info,txt,md,yml
  • DO NOT set the "Installed standard paths", as this overrides what you have previously set in the command line.
  • The refresh list button on "Coding Standard" should mimic what "phpcs -i" shows. Choose "Custom" Coding Standard and then click the ellipses to choose the path to your custom standards file (i.e. phpcs-custom-standards.xml).
  • Click OK and your inspections should be working!
Configure hotkeys
  1. Register phpcs and phpcbf as external tools.

    Settings | Tools | External Tools

    The "$FilePath" argument runs the tool against the file you are currently working on, or against a selected folder when in project view.

  2. Double check that this step works by running the tool from the main menu.

    Tools | External Tools | phpcs

  3. This is the special sauce. Configure a keyboard shortcut for your new tools.

    Settings | Keymap | External Tools

  4. Right click on the external tool you just registered and add a keyboard shortcut. "Ctrl+Alt+Shift+Comma" was simply a combination that was not used anywhere else in my setup.

Bringing it all together

Now you can actively use phpcs and phpcbf while you code! I frequently use the phpcbf hotkey while writing new code to do the tedious stuff for me, such as creating doc blocks and pushing whitespace around. Here's an example:

With phpcs and phpcbf now under your fingertips you are set to be much more assertive in your application of code standards!

Taking it to the next level

If you are using Gitlab for CI/CD, which I hope you are, another great strategy for enforcing standards is to create a pre-deployment job that scans your custom code for violations. This will keep your team (and you) in check by stopping standards violations from being auto-deployed.

After a few super annoying pipeline failures for minor syntax errors, you will want this next level of enforcement — git pre-commit hooks. I highly recommend using grumphp to manage this for you.

Best of luck keeping your code readable and up to snuff!

End-to-end Drupal services

As a full service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce design, customer experience, software development and hosting architecture. If you’re looking for a Drupal agency dedicated to code and project quality, check us out. We would love the opportunity to talk.

Acro Media: Making Drupal Code Standards Work for You With PhpStorm & phpcs/phpcbf

Main Drupal Feed - Mon, 11/04/2019 - 15:45
A proactive approach for cleaner Drupal coding


So you are stuck in the cruft, struggling to create some semblance of sanity within a sea of code-rot. Code standards sound like a great idea for your project, but perhaps automated enforcement tools look like more of a pain than they're worth. This post is intended for Drupal developers using PhpStorm who need fast, flexible, standards enforcement tools.

Maintaining a stringent standard for your codebase is a battle. On one hand, your code is cleaner, more unified, and easier to maintain. On the other hand, these little formatting rules cause frustration and time loss - especially if a tiny slip causes you to waste a full pipeline cycle just to pass an automated standards check. As they say, the best defence is a strong offence, and the tools proposed here will help you find and fix standards violations before they reach a pipeline.

Drupal recommends a tool called PHP Code Sniffer, aka phpcs, to scan your files for Drupal Code Standards violations. Thankfully, it also comes with a companion tool called PHP Code Beautifier and Fixer, aka phpcbf, which fixes the small, tedious violations for you.

The goal of this post is to get phpcs and phpcbf under your fingertips and into your habits. Only once you have hotkeys set-up to run these tools while coding will they become useful — instead of just annoying.

The steps are as follows:

  1. Install and set-up phpcs
  2. Create a custom combination of rulesets
  3. Integrate with PhpStorm for hotkeys and syntax highlighting
1. Install and set-up phpcs

It may seem straightforward to install phpcs globally via Composer or apt, or to simply require it in your current composer project. However, a global install is not easy to customize and share. Instead, I recommend using a standalone repo that is specifically for your code standards tools. When your standards stand alone, they are easier to edit, share with teammates, and transfer to new work environments.

Here’s a simple repo to get you started:
https://github.com/nilswloewen/drupal_code_standards

  1. If you currently have phpcs or phpcbf installed globally, uninstall them before proceeding.

  2. Quick install with example repo:

    git clone git@github.com:nilswloewen/drupal_code_standards.git
    cd drupal_code_standards
    composer install
  3. Once composer has installed phpcs for you, add it to your global path with:

    export PATH=$PATH:~/PATH/TO/drupal_code_standards/vendor/bin
    NOTE: Adjust accordingly for your shell and OS of choice.

  4. Next, you must tell phpcs which rulesets you have installed use.

    The optional tool phpcodesniffer-composer-installer will automatically detect rulesets in your composer package and set your phpcs & phpcbf installed_paths for you. This is part of the example repo and the next step should have been done for you during "composer install".

    However, to set installed paths to rulesets manually run:

    phpcs --config-set installed_paths vendor/drupal/coder/coder_sniffer,vendor/phpcompatibility/php-compatibility/PHPCompatibility

    Then confirm that phpcs knows about the rulesets within the installed paths with:

    phpcs -i

    You should see this list that confirms your rulesets:

    The installed coding standards are ... PHPCompatibility, Drupal and DrupalPractice

    You may need to set installed paths for phpcbf as well using the same process.

2. Create a custom combination of rulesets

Out of the box, phpcs can only run one standard at a time. This is a problem when working with Drupal because we have 2 standards to follow. For this post I have added a third standard, PHPCompatibility, which is helpful when upgrading php versions on legacy projects.

  1. To combine standards we first create a custom ruleset that references multiple rulesets. Note that this is already included in the example repo as phpcs-custom-standards.xml.

    <?xml version="1.0"?>
    <ruleset name="Custom code standards">
    <rule ref="Drupal"/>
    <rule ref="DrupalPractice"/>
    <rule ref="PHPCompatibility"/>
    </ruleset>
  2. Then set this standard as your default. Use an absolute path to ensure your standard will be found no matter what context phpcs is called from.

    phpcs --config-set default_standard ~/PATH/TO/drupal_code_standards/phpcs-custom-standard.xml See the example standard for a few other helpful settings.
3. Integrate with PhpStorm for hotkeys and syntax highlighting

There are two levels of integration with PhpStorm: Passive and Active.

Passive

Passive code analysis with PhpStorm Inspections will give you syntax highlighting and hover-over explanations of the file you are currently working on.

This is quite helpful when dealing with one file at a time, but when you need to get an entire directory to pass standards, you need a way to hunt for violations.

Active

Active analysis when you use phpcs to scan many files at once. You can do this through the terminal with a command like:

phpcs ~/module # Scans all applicable files in dir.
phpcs ~/module/example.php # Scans only a specific file.

However, it’s a pain to open a terminal window, navigate to the file you are working on, and then type a command. You’ll probably forget or neglect to check your work because of these extra steps involved. A better way to run phpcs is to set-up hotkeys within PhpStorm to scan your files instantly.

Configure PhpStorm inspections
  1. Register phpcs and phpcbf as PHP Quality Tools.

    Settings | Languages and Frameworks | PHP | Quality Tools | Code Sniffer



  2. Enable the inspection.

    Settings | Editor | Inspection | PHP | Quality Tools

  • Set the extension list to match what Drupal standard sets: source

    php,module,inc,install,test,profile,theme,css,info,txt,md,yml
  • DO NOT set the "Installed standard paths", as this overrides what you have previously set in the command line.
  • The refresh list button on "Coding Standard" should mimic what "phpcs -i" shows. Choose "Custom" Coding Standard and then click the ellipses to choose the path to your custom standards file (i.e. phpcs-custom-standards.xml).
  • Click OK and your inspections should be working!
Configure hotkeys
  1. Register phpcs and phpcbf as external tools.

    Settings | Tools | External Tools

    The "$FilePath" argument runs the tool against the file you are currently working on, or against a selected folder when in project view.

  2. Double check that this step works by running the tool from the main menu.

    Tools | External Tools | phpcs

  3. This is the special sauce. Configure a keyboard shortcut for your new tools.

    Settings | Keymap | External Tools

  4. Right click on the external tool you just registered and add a keyboard shortcut. "Ctrl+Alt+Shift+Comma" was simply a combination that was not used anywhere else in my setup.

Bringing it all together

Now you can actively use phpcs and phpcbf while you code! I frequently use the phpcbf hotkey while writing new code to do the tedious stuff for me, such as creating doc blocks and pushing whitespace around. Here's an example:

With phpcs and phpcbf now under your fingertips you are set to be much more assertive in your application of code standards!

Taking it to the next level

If you are using Gitlab for CI/CD, which I hope you are, another great strategy for enforcing standards is to create a pre-deployment job that scans your custom code for violations. This will keep your team (and you) in check by stopping standards violations from being auto-deployed.

After a few super annoying pipeline failures for minor syntax errors, you will want this next level of enforcement — git pre-commit hooks. I highly recommend using grumphp to manage this for you.

Best of luck keeping your code readable and up to snuff!

End-to-end Drupal services

As a full service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce design, customer experience, software development and hosting architecture. If you’re looking for a Drupal agency dedicated to code and project quality, check us out. We would love the opportunity to talk.

TomThorp.me Blog: Mismatched Entity Error

Main Drupal Feed - Mon, 11/04/2019 - 13:06
If you are getting a "Mismatched entity and/or field definitions" error in your Drupal status page, then this maybe the solution you are looking for.

Pages