diff --git a/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php index 26454762ea284310d0b502b527a607f10562468d..0232545473217c8d7fa4f5c3f34db24161b86fac 100644 --- a/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php +++ b/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php @@ -58,6 +58,18 @@ protected function setUp() { $this->adminUser2 = $this->drupalCreateUser($this->perms); } + /** + * Tests toolbar cache integration. + */ + public function testCacheIntegration() { + $this->installExtraModules(['dynamic_page_cache']); + $this->drupalLogin($this->adminUser); + $this->drupalGet('test-page'); + $this->assertSame('MISS', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache')); + $this->drupalGet('test-page'); + $this->assertSame('HIT', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache')); + } + /** * Tests toolbar cache contexts. */ diff --git a/core/modules/user/src/ToolbarLinkBuilder.php b/core/modules/user/src/ToolbarLinkBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..4f7dedd53c4f60b750e36f65d39b2a2ee63b3965 --- /dev/null +++ b/core/modules/user/src/ToolbarLinkBuilder.php @@ -0,0 +1,86 @@ +account = $account; + } + + /** + * Lazy builder callback for rendering toolbar links. + * + * @return array + * A renderable array as expected by the renderer service. + */ + public function renderToolbarLinks() { + $links = [ + 'account' => [ + 'title' => $this->t('View profile'), + 'url' => Url::fromRoute('user.page'), + 'attributes' => [ + 'title' => $this->t('User account'), + ], + ], + 'account_edit' => [ + 'title' => $this->t('Edit profile'), + 'url' => Url::fromRoute('entity.user.edit_form', ['user' => $this->account->id()]), + 'attributes' => [ + 'title' => $this->t('Edit user account'), + ], + ], + 'logout' => [ + 'title' => $this->t('Log out'), + 'url' => Url::fromRoute('user.logout'), + ], + ]; + $build = [ + '#theme' => 'links__toolbar_user', + '#links' => $links, + '#attributes' => [ + 'class' => ['toolbar-menu'], + ], + '#cache' => [ + 'contexts' => ['user'], + ], + ]; + + return $build; + } + + /** + * Lazy builder callback for rendering the username. + * + * @return array + * A renderable array as expected by the renderer service. + */ + public function renderDisplayName() { + return [ + '#markup' => $this->account->getDisplayName(), + ]; + } + +} diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 2d7d24a006386d024b3c1aba91975cb98e846dd2..cabe189e5a744ba1843cd8031245a866d86b8ea6 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -9,7 +9,6 @@ use Drupal\Component\Render\PlainTextOutput; use Drupal\Component\Utility\Unicode; use Drupal\Core\Asset\AttachedAssetsInterface; -use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Render\Element; @@ -1328,41 +1327,6 @@ function user_cookie_delete($cookie_name) { function user_toolbar() { $user = \Drupal::currentUser(); - // Add logout & user account links or login link. - $links_cache_contexts = []; - if ($user->isAuthenticated()) { - $links = [ - 'account' => [ - 'title' => t('View profile'), - 'url' => Url::fromRoute('user.page'), - 'attributes' => [ - 'title' => t('User account'), - ], - ], - 'account_edit' => [ - 'title' => t('Edit profile'), - 'url' => Url::fromRoute('entity.user.edit_form', ['user' => $user->id()]), - 'attributes' => [ - 'title' => t('Edit user account'), - ], - ], - 'logout' => [ - 'title' => t('Log out'), - 'url' => Url::fromRoute('user.logout'), - ], - ]; - // The "Edit user account" link is per-user. - $links_cache_contexts[] = 'user'; - } - else { - $links = [ - 'login' => [ - 'title' => t('Log in'), - 'url' => Url::fromRoute('user.page'), - ], - ]; - } - $items['user'] = [ '#type' => 'toolbar_item', 'tab' => [ @@ -1374,26 +1338,12 @@ function user_toolbar() { 'class' => ['toolbar-icon', 'toolbar-icon-user'], ], '#cache' => [ - 'contexts' => [ - // Cacheable per user, because the current user's name is shown. - 'user', - ], + // Vary cache for anonymous and authenticated users. + 'contexts' => ['user.roles:anonymous'], ], ], 'tray' => [ '#heading' => t('User account actions'), - 'user_links' => [ - '#cache' => [ - // Cacheable per "authenticated or not", because the links to - // display depend on that. - 'contexts' => Cache::mergeContexts(['user.roles:authenticated'], $links_cache_contexts), - ], - '#theme' => 'links__toolbar_user', - '#links' => $links, - '#attributes' => [ - 'class' => ['toolbar-menu'], - ], - ], ], '#weight' => 100, '#attached' => [ @@ -1403,6 +1353,32 @@ function user_toolbar() { ], ]; + if ($user->isAnonymous()) { + $links = [ + 'login' => [ + 'title' => t('Log in'), + 'url' => Url::fromRoute('user.page'), + ], + ]; + $items['user']['tray']['user_links'] = [ + '#theme' => 'links__toolbar_user', + '#links' => $links, + '#attributes' => [ + 'class' => ['toolbar-menu'], + ], + ]; + } + else { + $items['user']['tab']['#title'] = [ + '#lazy_builder' => ['user.toolbar_link_builder:renderDisplayName', []], + '#create_placeholder' => TRUE, + ]; + $items['user']['tray']['user_links'] = [ + '#lazy_builder' => ['user.toolbar_link_builder:renderToolbarLinks', []], + '#create_placeholder' => TRUE, + ]; + } + return $items; } diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index aede2f462ba695e80750c320cfa1e326834f0ed0..058daa03bb22056195d1978e63b65d0debe6332b 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -68,3 +68,6 @@ services: arguments: ['@current_user', '@entity.manager'] tags: - { name: 'context_provider' } + user.toolbar_link_builder: + class: Drupal\user\ToolbarLinkBuilder + arguments: ['@current_user']