How to Make Your IDE Autocomplete (even when it's not)

Most of the time, an IDE is going to autocomplete and save your bacon. "What is that?" "How do I get that?" "Wasn't there a method for..." Are all super common things that run through my head, and 99% of the time my IDE bails me out. I was chatting on Drupal Slack yesterday with a colleague and it occurred to me that there is one really specific case in Drupal 8/9 where the IDE almost NEVER bails you out though, and that's in a preprocess hook.

The Issue

If you aren't super familiar, preprocess hooks basically all have a $variables array that gets passed by reference. As an example, here's a preprocess block hook example from the GovCon theme:

https://github.com/Drupal4Gov/Drupal-GovCon-2017/blob/develop/docroot/themes/custom/twentynineteen/twentynineteen.theme#L60

/**
 * Implements template_preprocess_block().
 */
function twentynineteen_preprocess_block(&$variables) {
  // Custom block type helper classes.
  if (isset($variables['elements']['content']['#block_content'])) {
    $block_content = $variables['elements']['content']['#block_content'];
    $bundle = $block_content->bundle();
    $bundle_class = str_replace('_', '-', $bundle);
    $variables['attributes']['class'][] = Html::cleanCssIdentifier('block--bundle-' . $bundle_class);
    $variables['attributes']['data-bundle-class'] = $bundle_class;
  }
}

In this example, believe it or not, there's an instance of the Block content bundle. Where? You might ask. It's not super duper obvious. In this case, it's $variables['elements']['content']['#block_content']. In my example code, you can see that we're doing the ->bundle() method on this. BUT when I try and type on it, as you can see in this screen shot, there is no autocomplete.

Screen Shot 2020-10-07 at 8.47.21 AM.png

Why? Because the IDE doesn't know that $variables['elements']['content']['#block_content'] is actually an instance of a class. Let's fix it!

The Solution

The solution is super simple: you just need to add a comment before your code so that the IDE knows that $variables['elements']['content']['#block_content'] is a class. The comment should look something like this:

/** @var Drupal\block_content\Entity\BlockContent $block_content */

If you don't know how to find the namespace of the class, you can autocomplete this like you would any use statement. Once I've done this, now I can autocomplete on my $block_content variable (as seen in this screen shot).

Screen Shot 2020-10-07 at 8.22.43 AM.png

This is a super simple hack for an IDE but it's an incredibly useful one. The block preprocess hook is a pretty easy one, but not all of them are. The hook in question yesterday was for the filter_caption (which I've never used before). Using the above comment method we discovered that the method to get at what we wanted was actually jsonSerialize! Not something I would have expected, but the IDE showed us the way to go thanks to the autocompletion on the Class being used.

Do you need to do this for every variable you write in an IDE? No, definitely not. Typically an IDE will autocomplete automatically (that's the point). But in that rare situation (or the incredibly common one with preprocess hooks) that you have something that isn't autocompleting, hopefully this will help you out.

Special thanks to Shelane French for this topic!

Photo by Burst from StockSnap

Related Content