I need to build a history for visitors so they can see which pages they've visited (ideally filtered by type). To do this, it seems that the correct combo is to use Flag module and then Rules.

I'd anticipate that I'd create a new rule config where I'd ensure the content was of a certain type, ensure a flag existed, then automatically mark the flag each time the content of that type was visited. I'd also have to update the time if an 'already-flagged' content was visited again (ie. so it appears at the top of a 'history' list).

I've messed around with Rules in Drupal 8 and I didn't get far at all. I could obviously add a rule for 'node is viewed', and then condition of it being the right type. But then I got stuck.

I need to be able to do things like see if there's a flag available, see the current value of the flag for that user, automatically set/update the flag, etc. I couldn't figure out how to do any of this.

Help? :)

  • I ended up abandoning rules because it seemed unnecessarily complicated. Instead I wrote a simple module (see below) to do this. I'm leaving this open in case someone wants to describe the method for anyone who is trying to do the same thing and must use Rules.
    – Feature
    Mar 22, 2018 at 16:21
  • Rules is 'unnecessarily complicated' just like Views is 'unnecessarily complicated'. If you're a developer then writing an explicit DB query is far easier and more efficient than configuring a custom View. But then in order to modify or customize or enhance the the resulting page you also need a developer. But if you do things in Views then almost anyone can customize and enhance the View. Likewise with Rules - if you're a developer you may be able to hack a quick solution, but that will not be extensible and maintainable by anyone other than a developer.
    – anonymous
    Apr 25, 2020 at 23:31

1 Answer 1


Honestly I gave up pretty quickly since it seemed unnecessarily complicated. I created a very basic module that handles the marking/unmarking via the Flag API. It has a single hook that looks like this:

function mymodule_node_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {

  //UPON VIEWING 'mytype' NODES  
  if($entity->getType() == 'mytype'){ 

    $uid = \Drupal::currentUser()->id(); //current user
    $flag_id = 'history'; //flag type is named history
    $flag_service = \Drupal::service('flag');
    $flag = $flag_service->getFlagById($flag_id);

    if($flag->isFlagged($entity) == '1'){
        //unflag then reflag to update date
        $flag_service->unflag($flag, $entity);
        $flag_service->flag($flag, $entity);
    } else {
        //flag it for the first time
        $flag_service->flag($flag, $entity);
  • 1
    hook_node_view() does not work that way - it is only called when the node is first rendered, then never called again until the node is re-rendered. So if the cached node is being served (as it almost always is) this hook will not fire. So your solution will not work in general.
    – anonymous
    Jan 1, 2022 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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