15

In Drupal 7 we can simply check if the current user is logged-in in a theme by checking $GLOBAL['user']->uid or using user_is_logged_in().

How can I check if a user is logged-in in a page template, in Drupal 8?

A solution is to manually check in hook_preprocess_page(), but since this is very popular, I think Drupal provides something by default for the Twig theme engine.

25

If you just to check the current user is logged-in, you can use $variables['logged_in'], which is generally available in all the template files.

For example, the mark.html.twig file uses the following code, although the only documented variable is status.

{% if logged_in %}
  {% if status is constant('MARK_NEW') %}
    <span class="marker">{{ 'New'|t }}</span>
  {% elseif status is constant('MARK_UPDATED') %}
    <span class="marker">{{ 'Updated'|t }}</span>
  {% endif %}
{% endif %}

The variable is explicitly documented in other template files, such as html.html.twig, page.html.twig, and node.html.twig.

The variable is available in all the template files, since it is initialized in _template_preprocess_default_variables() that invokes user_template_preprocess_default_variables_alter() (an implementation of hook_template_preprocess_default_variables_alter()), which contains the following code.

  $user = \Drupal::currentUser();

  $variables['user'] = clone $user;
  // Remove password and session IDs, since themes should not need nor see them.
  unset($variables['user']->pass, $variables['user']->sid, $variables['user']->ssid);

  $variables['is_admin'] = $user->hasPermission('access administration pages');
  $variables['logged_in'] = $user->isAuthenticated();

_template_preprocess_default_variables() is called by template_preprocess(), which is the function called for theme hooks implemented as templates; this guarantees the variable is available in all the template files.

Keep in mind that macros don't have access to the current template variables, so trying to access logged_in in the code of a macro would not have any effect.
Between the template files used from Drupal core modules, the ones using a macro are:

  • menu.html.twig

    {% macro menu_links(items, attributes, menu_level) %}
      {% import _self as menus %}
      {% if items %}
        {% if menu_level == 0 %}
          <ul{{ attributes }}>
        {% else %}
          <ul>
        {% endif %}
        {% for item in items %}
          <li{{ item.attributes }}>
            {{ link(item.title, item.url) }}
            {% if item.below %}
              {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
            {% endif %}
          </li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endmacro %}
    
  • book-tree.html.twig

    {% macro book_links(items, attributes, menu_level) %}
      {% import _self as book_tree %}
      {% if items %}
        {% if menu_level == 0 %}
          <ul{{ attributes }}>
        {% else %}
          <ul>
        {% endif %}
        {% for item in items %}
          <li{{ item.attributes }}>
            {{ link(item.title, item.url) }}
            {% if item.below %}
              {{ book_tree.book_links(item.below, attributes, menu_level + 1) }}
            {% endif %}
          </li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endmacro %}
    
  • menu--toolbar.html.twig

    {% macro menu_links(items, attributes, menu_level) %}
      {% import _self as menus %}
      {% if items %}
        {% if menu_level == 0 %}
          <ul{{ attributes.addClass('toolbar-menu') }}>
        {% else %}
          <ul class="toolbar-menu">
        {% endif %}
        {% for item in items %}
          {%
            set classes = [
              'menu-item',
              item.is_expanded ? 'menu-item--expanded',
              item.is_collapsed ? 'menu-item--collapsed',
              item.in_active_trail ? 'menu-item--active-trail',
            ]
          %}
          <li{{ item.attributes.addClass(classes) }}>
            {{ link(item.title, item.url) }}
            {% if item.below %}
              {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
            {% endif %}
          </li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endmacro %}
    

For example, changing the last macro with the following code would not have the expected result.

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    {% if menu_level == 0 %}
      <ul{{ attributes.addClass('toolbar-menu') }}>
    {% else %}
      <ul class="toolbar-menu">
    {% endif %}
    {% for item in items %}
      {%
        set classes = [
          'menu-item',
          logged_in ? 'menu-item--logged-in-user',
          item.is_expanded ? 'menu-item--expanded',
          item.is_collapsed ? 'menu-item--collapsed',
          item.in_active_trail ? 'menu-item--active-trail',
        ]
      %}
      <li{{ item.attributes.addClass(classes) }}>
        {{ link(item.title, item.url) }}
        {% if item.below %}
          {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
        {% endif %}
      </li>
    {% endfor %}
    </ul>
  {% endif %}
{% endmacro %}
  • The variable is surely available in all the template files I am afraid you are wrong regarding this. If the template does not mention it in the comments, there must be a reason, right? Because I tried on menu.html.twig (which does not mention it in the comments) and did not work. While using Twig Extender it works. – No Sssweat Sep 16 '16 at 9:00
  • _template_preprocess_default_variables() is called for every template Drupal outputs, so the variables it adds are present in all the template files. Documentation doesn't document all the default variables, as far as I can see. – kiamlaluno Sep 16 '16 at 9:05
  • 2
    @kiamlaluno whenever you have free time, try {% if logged_in %} on menu.html.twig and you'll see it doesn't work. Didn't work for me. – No Sssweat Sep 16 '16 at 9:06
6

You can with the Twig Extender module. Quote from its project page:

Add a simple plugin system to add new twig extensions (Filter and Functions). Provides a new service provider for "twig.extensions" to add new plugins.

Function: is_user_logged_in

Check if user is logged in.

{% if user_is_logged_in() %}
Hello user
{% else %}
Please login
{% endif %}
  • only 57 use and beta :(. maybe thee better solution is ` $vars['is_login'] = !\Drupal::currentUser()->isAnonymous(); ` in preprocess_page ? what is your opinion? – Yusef Mohamadi Jul 13 '16 at 13:22
  • 2
    There is no need of a module for that functionality, since Drupal core has already it. See my answer. – kiamlaluno Jul 13 '16 at 17:09
  • @kiamlaluno Yes, I agree with you, this requirement is very popular and I was sure drupal had provided something for it. – Yusef Mohamadi Jul 14 '16 at 6:35
1

For everybody trying to use logged_in from menu.twig.html; you need to call it from outside the menus.menu_links() macro as the logged_in variable is out of scope within the macro.

1

You can check if the user is authenticated like so:

For example, I have created the following function in themename.theme.

# Function to get user logged info
function tropical_preprocess_page(&$variables){
  // if user is authenticated
  if($variables['user']->isAuthenticated()){
    # gets username
  $user_logged_in_name = $variables['user']->getDisplayName();
  # creates value to ouput in the DOM & capitalize first letter
  $variables['user_logged_in_name'] = ucfirst($user_logged_in_name);

  # gets user email
  $user_email = $variables['user']->getEmail();
  $variables['user_email'] = $user_email;

  // get user picture
  $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
  $variables['user_picture'] = $user->get('user_picture')->entity->url();

  // Check if user is logged in
  $user_logged = $variables['user']->isAuthenticated();
  $variables['user_logged'] = $user_logged;
  }
}

After that, you can create the logic within the Twig file like so:

<div class="user-logged-greeting">
  {% if user_logged %}
    <h2>Welcome back, {{ user_logged_in_name }}!</h2>
    <p>The email for this user is: <strong>{{ user_email }}<strong></p>
    <img src="{{ user_picture }}" width="50" height="50">
  {% endif %}
</div>

If the user is logged in, you will get the greeting message along with username, email & avatar picture. If user is not logged in, it won't show up anything.

Let me know if that helps and/or if I can edit this post for better understanding.

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.