1

I have a client who would like users to be able to comment on content without being able to see any other users' comments. This is for a review system where users shouldn't feel influenced by the views of other users. I'm using Drupal 9.3.14 and a subtheme of Radix.

I have tried adding this to my theme's comment.html.twig:

{% if author_id == user.id %}
    {{ content }}
{% endif %}

That works for a while, but after a while, users report that they can see some other users' comments, but not all of them.

How can I make sure that users can always see only their own comments and no one else's?

2
  • Because you didn't implement any user based caching on that piece of content.
    – leymannx
    Commented May 29, 2022 at 13:55
  • Thanks, @leymannx. I've been looking into implementing user-based caching, but I have not been able to find any practical advice or examples for doing that. Any pointers? Is there a hook I can implement to deal with caching on comments?
    – sjhuskey
    Commented May 30, 2022 at 18:15

2 Answers 2

1

Finding hook_ENTITY_TYPE_access/hook_comment_access not working when trying to return AccessResult::forbidden()->cachePerUser() after comparing the comment owner ID and current user ID (probably related: #2879087), can you please try the following preprocess logic? As I currently have no project to properly check this out myself I'm not sure if it works that way and if #plain_text can simply be (mis-)used as a cache busting switch in a template at all.

/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_comment(&$variables) {
  $variables['own_comment'] = [
    '#plain_text' => 'no',
    '#cache' => [
      'contexts' => ['user'],
    ],
  ];
  /** @var \Drupal\comment\Entity\Comment $comment */
  $comment = $variables['elements']['#comment'];
  if ($comment->getOwner()->id() === \Drupal::currentUser()->id()) {
    $variables['own_comment']['#plain_text'] = 'yes';
  }
}
{% if own_comment['#plain_text'] == 'yes' %}
  {{ content }}
{% else %}
  {{ 'Not your comment'|t }}
{% endif %}

Maybe I'm actually doing the same you did and in the end the only way is to implement your own comments field formatter, similar to the one in the Manage comments on own content module.

2
  • Wow! Thanks for putting so much effort into that, @leymannx! Unfortunately, it appears that the variable "own_comment" is not being set, so the twig logic you included always goes to "Not your comment." I think you might be right about needing to implement my own comments field formatter. I'm going to look at the module you linked to and see what I can do.
    – sjhuskey
    Commented May 31, 2022 at 21:12
  • Metadata attached to a render element bubbles up only if rendered. If you don't have anything to render there is an alternative. Preprocess hooks have a hidden feature that you can add cache metadata to the top level: $variables['#cache']['contexts'][] = 'user';. The theme layer bubbles this up, independently from other rendered content.
    – 4uk4
    Commented Jun 2, 2022 at 7:43
0

Sorry, no code with this, just an idea to try. Focus on writing a new permission with a custom module, not modifying the html that is cached. If you hook into Drupal's permissions, then the cache may not be an issue anymore. Plus, this feels more like a permission issue than html issue.

If you install drupal/console, you can run a command lines like drupal generate:module to stub out the initial module then drupal generate:permissions to addon to that module a permission. Quick way to stub out a custom module and then put similar php logic you already have in your head, but just add it to drupal a different way.

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.