0

I would like to be able to hide a specific user profile.

I want to completely hide it from Drupal and search engines. How can I achieve this?

2

To hide the page from Google and search engines, you can add the robots metatag.

Add this code to a custom module to add the metatag to the specefic profile page.

function MY_MODULE_preprocess_html(&$variables) {
  $user_id = 'ID of the user to hide profile page for';

  if (\Drupal::routeMatch()->getRouteName() == 'entity.user.canonical') {
    $user = \Drupal::routeMatch()->getParameter('user');
    if ($user instanceof \Drupal\user\UserInterface && $user->id() == $user_id) {
      $robots_none = [
        '#tag' => 'meta',
        '#attributes' => [
          'name' => 'robots',
          'content' => 'none',
        ],
      ];

      $variables['page']['#attached']['html_head'][] = [$robots_none, 'robots-none'];
    }
  }
}

If you want to hide the page in Drupal too, you can create a redirect from the specific user profile page to the /system/403 page.

| improve this answer | |
  • Thanks, but I want to completely hide the page itself. How would I do that? – C.A. Vuyk Dec 18 '19 at 12:41
  • I have updated my answer, If you want to hide the page in Drupal too, you can create a redirect from that page to the 403 page using the redirect module. – user72672 Dec 18 '19 at 12:46
  • thanks for your help! – C.A. Vuyk Dec 18 '19 at 13:06
  • You're welcome, I'm glad it helped. – user72672 Dec 18 '19 at 13:06
  • I have set the robots.txt with the metatag module – C.A. Vuyk Dec 18 '19 at 17:20
3

To avoid users can access a user profile, I would implement hook_ENTITY_TYPE_access().
For the search engines, it would be sufficient to check the logged-in user isn't anonymous. For any Drupal user and the search engines, it's sufficient to check the permission the logged-in user has. (I would not hide the user profile to users who have the permission to administer users.)

In the first case, I would use code similar to the following one.

function mymodule_user_access(EntityInterface $entity, $operation, AccountInterface $account) {
  if ($operation == 'view' && $entity->id() == USER_ID && $account->isAnonymous()) {
    return AccessResult::forbidden()->cachePerUser();
  }
}

In the second case, I would use code similar to the following one.

function mymodule_user_access(EntityInterface $entity, $operation, AccountInterface $account) {
  if ($operation == 'view' && $entity->id() == USER_ID && !$account->hasPermission('administer users')) {
    return AccessResult::forbidden()->cachePerPermissions();
  }
}

(In both the cases, replace USER_ID with the actual user ID of the user profile you need to hide.)

The code checks the value of the operation, and forbids it only when it's view. In this way, the code is simpler, as it doesn't need to check users are trying to edit their own accounts, for example (which I assume it's not an operation you want to forbid).

hook_ENTITY_TYPE_access() is not invoked for pages listing more than one entity, for example a view page. In the case of user accounts, hook_ENTITY_TYPE_access() should be sufficient, but if you want to avoid that user account is listed also in a view output, the alternative is hook_query_TAG_alter() which is more complicated to implement, but it works in every case.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.