DRUPAL 8 | Private Area with Private Access

First of all create a Custom post type called ” Private Doc ” ( here you can lear how create a custom post type by editor ).

Add “Fields” that you need.

In my example add a file filed, and set so can accept file types ( txt, pdf, zip, jpg ) so you can control witch type of file can be uploaded.

And in “Field Settings” under “Number of allowed values” set as “No limits”

Now we can start add new “Private” Content.

Navigate to ” Contents ” ” Add Content “, and select ” Private Doc “, you can create new content and add files.

Let’s start to make it private by creating new template for “single” and “archive” page ( you can learn more here ).

Once created “page–private-doc.html.twig”, we can start to made all the content private, for do that wrap all content as :

{% if logged_in %}
    <main role="main" class="grid-container">
    <a id="main-content" tabindex="-1"></a>{# link is in html.html.twig #}

    <div class="layout-content">
      {{ page.content }}
    </div>{# /.layout-content #}

    {% if page.sidebar_first %}
      <aside class="layout-sidebar-first" role="complementary">
        {{ page.sidebar_first }}
      </aside>
    {% endif %}

    {% if page.sidebar_second %}
      <aside class="layout-sidebar-second" role="complementary">
        {{ page.sidebar_second }}
      </aside>
    {% endif %}

  </main>
{% else %}
You must be logged in for see price

{% endif %}

Save, clear cache, and try to navigate on out custom post type page in “incognito” mode.

If all it’s right, you should view a message like ” You must be logged in for see price “,now you can add every kind of message and style it, but what if you want to show a login form ?

Simply open your template “.theme” file, and add this :

/**
* Render login form in theme 
*/

function yourthemename_preprocess_page(&$variables) {
  $variables['login_form'] = FALSE;
  if (!\Drupal::currentUser()->id()) {
    $form = Drupal::formBuilder()->getForm(Drupal\user\Form\UserLoginForm::class) ; 
    $render = Drupal::service('renderer');
    $variables['login_form'] = $render->renderPlain($form);
  }
}
 

now you can print the form where you want  simply by adding :

{{ login_form }}

At moment, the content is “visible” for all users are logged, but what if we want that only some roles can view content ? let’s create a user role that administrator can use for register users that have access to private area.

Navigate to “Persons => Roles” and click  ” add role ” insert the role name you needed, and click “Save”, add new user “Persons => Add User” and assign the role created before.

Now we need to modify the template, open the “page–private-doc.html.twig” created before and change the file as this :

<main role="main" class="grid-container">
      {% if logged_in %} {# Check if user is logged #}
      
      {% if 'private_area_user' in user.getroles  %} {# Check if user has role #}
        <p>The user has the role "Private area".</p>
      

    <a id="main-content" tabindex="-1"></a>{# link is in html.html.twig #}
    <div class="layout-content">
      {{ page.content }}
    </div>{# /.layout-content #}

    {% if page.sidebar_first %}
      <aside class="layout-sidebar-first" role="complementary">
        {{ page.sidebar_first }}
      </aside>
    {% endif %}

    {% if page.sidebar_second %}
      <aside class="layout-sidebar-second" role="complementary">
        {{ page.sidebar_second }}
      </aside>
    {% endif %}

    {% else %} {# else, show a message for logged users that have wrong role #}
      <p>The user hasn't the role "Private area".</p>
    {% endif %}
    {% else %} {# and last a message for users that aren't logged #}
      You must be logged in for see this content
      {{ login_form }}
    {% endif %}
  </main>

If you can’t find the role of current logged user, you can add 

{% set roles = user.getroles(TRUE) %}
{{ dump(roles) }}

In template for print the current user role.

Now you can use this trick for show/hide every template parts depending of the user role.