How can I show node Hits (statistics_counter) in Drupal 8 in specific place?
I want to show user hits of a node (article) in submitted area rather than the end of a node in node links area? I do this already in drupal 7 with this code:
<?php print (int) $content['links']['statistics']['#links']['statistics_counter']['title']; ?> in node.tpl.php file
but i want to know how to convert this code to drupal 8 version.

Comments

yogeshchaugule8’s picture

Drupal 8 uses twig templates so variables are handled/printed in different way.

Node links sections is handled separately because of which we can not hide/remove statistics in node.html.twig file. So to print node statistics count in submitted area, you'll first need to add that to base level of node template like content, author_picture, etc. You can do this by implementing template_preprocess_node() in your theme. Below is sample code which adds new variable containing node statistics count.

    function [THEME_NAME]_preprocess_node(&$variables) {
      // Get statistics count for current node.
      $statistics = statistics_get($variables['node']->id());
      $variables['node_stats'] = \Drupal::translation()->formatPlural($statistics['totalcount'], '1 view', '@count views');
    }

Change THEME_NAME with theme you're using. This will add node_stats variable which you can use inside node.html.twig file for printing node statistics count. Below is how you can print it inside template file.

    {% if display_submitted %}
      <div class="node__meta">
        {{ author_picture }}
        <span{{ author_attributes }}>
          {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
        </span>
        <span class="node__stats">
          {{ node_stats }}
        </span>
        {{ metadata }}
      </div>
    {% endif %}

This will print the node statistics count in submitted area of content. Links section will still show the node statistics count, to remove this, you will need to create new template file (if not already created) named as links.html.twig. You can copy existing file from "Core => themes => classy => templates => navigation => links.html.twig". After which you can exclude the statistics count from printing. Make sure to rebuild cache after adding new template file. See sample output below:

      <ul{{ attributes }}>
        {%- for key, item in links|without('statistics_counter') -%}
          <li{{ item.attributes.addClass(key|clean_class) }}>
            {%- if item.link -%}
              {{ item.link }}
            {%- elseif item.text_attributes -%}
              <span{{ item.text_attributes }}>{{ item.text }}</span>
            {%- else -%}
              {{ item.text }}
            {%- endif -%}
          </li>
        {%- endfor -%}
      </ul>

Statistics count is removed from links while printing using without() function, links|without('statistics_counter')

Jeff Burnz’s picture

Good answer, perhaps $statistics should be cached, since it's a db hit every time?

Mojtaba Reyhani’s picture

Thanks very much for your help, Your answer was correct and complete, and my problem was solved.
Can you help me more, I want to show "Comment Count" also With this technique.
And thank you again for everything.

Aaron23’s picture

Me too need to display comment count for a particular node. Please, Help me

mrupsidown’s picture

statistics_get is deprecated as of 8.2.x

You should use:

/** @var \Drupal\statistics\StatisticsViewsResult $statistics */
$statistics = \Drupal::service('statistics.storage.node')->fetchView($variables['node']->id());
$variables['node_stats'] = \Drupal::translation()->formatPlural($statistics->getTotalCount(), '1 view', '@count views');

Or even better because the above fails when there is no statistics for the node (yet):

/** @var \Drupal\statistics\StatisticsViewsResult $statistics */
$statistics = \Drupal::service('statistics.storage.node')->fetchView($variables['node']->id());

if ($statistics !== FALSE) {
  $variables['node_stats'] = \Drupal::translation()->formatPlural($statistics->getTotalCount(), '1 view', '@count views');
}