4

I run a Drupal 7 website with Forum, Blog, Comment core modules enabled and a custom module (generates a block with Flash game and blocks with player rating) written by me.

The website is dedicated to a Russian card game and users often mention card colors in their comments when discussing some card riddle or a game:

enter image description here

Most users are older folks, who don't understand anything like HTML tags, so I have only enabled plain text comments for them.

My quesion is: in the plain text Comments - how to recognize the strings like K♥ or 7♦ and color them red?

The PHP code would be something like:

preg_replace(/(1?[0789JQKA][♥♦])/, '<font color="red">\1</font>', $str);

(I can improve the regex later) - but where/how to apply it in Drupal 7?

  • 3
    OK, why on earth is there an 'off-topic' close vote on this question? Come on people, read the question first :) – Clive May 23 '13 at 11:42
4

What you are looking for seems to be Text filters and Input Formats.

Processing textual content for output in a browser is one of Drupal's most critical tasks. Without such processing we would all have to become masters at typing in HTML text! This section of the handbook explains what filters and input formats are, why they are important, how they are used, and why they impact site security.

Or you can just dump regex in template.php or comment.tpl.php - it's way simpler and way less clean, but works.

  • 1
    For an example of how to add an input filter see the drupal.org/project/examples module's filter example. – rooby May 23 '13 at 11:45
  • 1
    Also, if you go the filter route with the plain text filter, make sure your filter comes after the plain text filter. – rooby May 23 '13 at 11:47
  • 2
    @AlexanderFarber Grab a copy of the Examples module; it has a fully fledged custom filter example included (filter_example) – Clive May 23 '13 at 12:08
  • 1
    @AlexanderFarber - no no no, you should never modify modules and templates from Drupal's core or from Drupal.org. Inherit from them or fork them and then modify. But I'd only advise it if you really really fail at making filter. – Mołot May 23 '13 at 12:17
  • 2
    @AlexanderFarber Install the Devel module and use the dpm() function. You'll never go back to var_dump :) – Clive May 23 '13 at 13:13
5

If you need it to be configurable/re-usable then a custom filter is the way to go as Mołot said. The idea is that the raw data is always stored, and the filter is applied upon display. This is all well and good, but if you don't ever need the original text I find this method to be an unnecessary performance overhead (especially when you involve regexs, as most filters do).

The other way is to intercept the comment body before it's saved, and apply your filter then. For this you can use hook_comment_presave():

function MYMODULE_comment_presave($comment) {
  $comment->comment_body[$comment->language][0]['value'] = string_replacement_function($comment->comment_body[$comment->language][0]['value']);
}

I know this method is 'frowned upon' (heaven forbid we alter someone's input, even if we want to control what goes in the database!), and I can think of at least 2 people who will downvote this if/when they see it.

I think the benefits/drawbacks of both methods are pretty clear, though, so I'd advise you make a decision based on your use-case. If the module you implement to do this isn't being released back into the wild, I see no benefit in taking the extra performance hit here.

But if you think you'll ever want to use this method to filter text elsewhere on the site (e.g. in node bodies), a custom filter would make more sense.

  • 1
    This is especially a good solution if users cannot edit their comments after they have commented, because they will never see your altered version of the code, so you never have to undo your alteration of their content. – rooby May 23 '13 at 11:45
  • @rooby Good point, I didn't think of that – Clive May 23 '13 at 11:47
  • @rooby - actually it's only a bad solution if they can edit ;) Clive - with good caching it's hardly a performance impact, as filtered text should sit in cache for a long time, possibly until edited. Of course then there is that little difference between "should" and "will".. – Mołot May 23 '13 at 11:55
  • 1
    @Mołot Indeed, mileage will vary with this method. I can see this being a "I just need this to happen in one place" sort of request so I wanted to offer the simpler method as an alternative. The method you've outlined will always be the best practice, most re-usable method without question – Clive May 23 '13 at 12:02
  • 2
    I upvoted your answer myself because I like to see many different valid answers. Just wanted to elaborate a tiny bit more on the performance side of the problem. And I must admit that cache fails, gets regenerated etc and is in no way stable. That's what it does, by it's very nature. Your solution avoids it, and that's a good thing. – Mołot May 23 '13 at 12:09

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.