Jun 27, 2019 in Drupal 8, Snippets

I'll share with you some code on how to cache blocks per user. The secret lies in using the right cache context on the build() function of your block.

In your module called hello_block in src/Plugin/Block add a file named HelloBlock.php

namespace Drupal\hello_block\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\user\Entity\User;

/**
 * Provides a 'HELLO <FIRST NAME>' Block.
 *
 * @Block(
 *   id = "hello_block",
 *   admin_label = @Translation("Hello NAME block"),
 * )
 */
class HelloBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $account = \Drupal::currentUser();
    $user = User::load($account->id());
    $first_name = $user->get('first_name')->getString();
    return [
      '#cache' => ['contexts' => ['user']],
      '#theme' => 'hello_block',
      '#name' => $first_name
    ];
  }

}

Register a template in your helloblock.module file, by adding the following:

/**
 * Implements hook_theme().
 */
function hello_block_theme($existing, $type, $theme, $path) {
  return [
    'hello_block' => [
      'variables' => [
        'name' => NULL,
      ],
    ],
  ];
}

Now, add a file named hello-block.html.twig inside a map called templates. In this file, you can use your variable:

<h3>Hello{% if name %} {{name}}{% endif %}!</h3>

Because you're using the right cache context, the block will only get cached for every specific user. By this, you're really using the true power of drupal 8 caching. 

Want more? Read How to disable block caching in drupal 8.