3

How can I show Node Hits (Statistics_Counter) in Drupal 8 in a specific place?
I enabled statistics module and I now want to show user hits of a node (node view number/node visits count) in the submitted area instead of in the node links area.

I do this already in Drupal 7 with below code in node.tpl.php:

<?php print (int) $content['links']['statistics']['#links']['statistics_counter']['title']; ?>

What is the equivalent code for Drupal 8?

7

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>

We've removed statistics count from links while printing using without() function links|without('statistics_counter')

  • Thank you for your efforts, but i don't know where is the problem that howsoever I trying to get a result, i can't become success. – Mojtaba Reyhani Mar 2 '16 at 11:03
  • What issues are you facing? you can try debugging twig templates to see valid template names, etc. eg. you can try doing content|without('links') in node.html.twig file to see if links are getting hidden. Make sure to "rebuild cache" by navigating to "Admin => Configuration => Development => Performance". – Yogesh Mar 2 '16 at 13:23
  • 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. – Mojtaba Reyhani Mar 6 '16 at 4:50
  • You can check, node module in Drupal8 Core for how does it attach the comment count to node variable for printing and based on that you can print the comment count. You can check above example for reference and print in node.html.twig. – Yogesh Mar 11 '16 at 9:15
1

Of course @Yogesh solution was correct and still is correct but statistics_get() is deprecated and it's better to use Drupal services instead of old-fashion calling functions, as in the following line.

$statistics = \Drupal::service('statistics.storage.node')->fetchView($vars['node']->id());
$totalCount  = $statistics->getTotalCount();
$dayCount  = $statistics->getDayCount();
$timestampCount  = $statistics->getDayTimestamp();

Note: Current version of Drupal is 8.4

1

statistics_get() has been deprecated in Drupal 8.2.x and it will be removed before Drupal 9.0. While it is possible to use statistics_get() in all the Drupal 8 branches, if you want to write code that requires less changes to be ported to Drupal 9, you should use code similar to the following one.

function mymodule_preprocess_node(&$variables) {
  $variables['node_view_count'] = 0;
  if (!empty($variables['node'])) {
    // Get the number of times the current node has been viewed.
    /** @var \Drupal\statistics\StatisticsViewsResult $statistics */
    $statistics = \Drupal::service('statistics.storage.node')
      ->fetchView($variables['node']->id());
    if ($statistics instanceof StatisticsViewsResult) {
      $variables['node_view_count'] = $statistics->getTotalCount();
    }
  }
}

Since \Drupal::service('statistics.storage.node')->fetchView($variables['node']->id()) can return FALSE if there isn't any data about the node, it's necessary to verify what it returned to avoid getting an error about accessing a method from a variable not containing an object.

In the node.html.twig template, the node_view_count value can be used using code similar to the following one.

  <header>
    {{ title_prefix }}
    {% if label and not page %}
      <h2{{ title_attributes.addClass('node__title') }}>
        <a href="{{ url }}" rel="bookmark">{{ label }}</a>
      </h2>
    {% endif %}
    {{ title_suffix }}
    {% if display_submitted %}
      <div class="node__meta">
        {{ author_picture }}
        <span{{ author_attributes }}>
          {% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
        </span>
        {% if node_view_count %}
          {% trans %}
            Viewed {{ node_view_count }} time
          {% plural node_view_count %}
            Viewed {{ node_view_count }} times
          {% endtrans %}
        {% endif %}
        {{ metadata }}
      </div>
    {% endif %}
  </header>

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.