0

I have an entity with a text-type attribute called contactInfo. Users can only submit text without html when entering these details in a form. Often an email address is entered somewhere in this textarea (together with more details).

Now when I display this contactInfo I would like adjust any email address to an email address with a mailto hyperlink. For example

Email us at: example@email.com. 

should become:

Email us at: <a href="mailto:example@email.com">example@email.com</a>.

How to go about this? Can I do this directly in Twig with some RegEx or Replace filter? Or should I really do this in the controller?

Dirk J. Faber
  • 4,360
  • 5
  • 20
  • 58
  • If I were you i'd adjust the input already before storing it in the database, otherwise u could do this by creating your own template class – DarkBee Nov 22 '18 at 12:46

1 Answers1

2

You can create a twig filter, something like "mailTo" and do something like

<?php
   namespace App\Twig;

    use Twig\Extension\AbstractExtension;
    use Twig\TwigFilter;

    class AppExtension extends AbstractExtension
    {
        public function getFilters()
        {
            return array(
                new TwigFilter('mailTo', array($this, 'mailTo'), array('is_safe' => 'html')),
            );
        }

        public function mailTo(string $text)
        {
            if(preg_match_all('/[\p{L}0-9_.-]+@[0-9\p{L}.-]+\.[a-z.]{2,6}\b/u',$text,$mails)){
    foreach($mails[0]as $mail ){
        $text = str_replace($mail,'<a href="mailto:'.$mail.'">'.$mail.'</a>',$text);
    }
}


            return $text;
        }
    }

And then use it like this in your template

contactInfo|mailTo

Either way, don't store "mailto:" or html tags in database when those are always gonna be the same...

documentation on twig custom filters https://symfony.com/doc/current/templating/twig_extension.html

Yoann MIR
  • 811
  • 5
  • 17
  • As OP stated `Users can only submit text without html` – DarkBee Nov 22 '18 at 13:41
  • But they don't need to ... that's not how twig filter works, he can add dynamically html tags and render it with raw filter – Yoann MIR Nov 22 '18 at 15:44
  • OP's enduser would not know about any variables so he/she would be forced to type something like `bla bla bla mail me at {{ 'info@example.com' | mailTo }}`. Not very convenient – DarkBee Nov 22 '18 at 17:52
  • The filter is applied on all the text block. I tested it with a sentence like " my mails are test@blah.com and and mail.second@test.org etc etc etc " and it works just fine... preg_match_all can retrieve any email occurence and you can iterate and replace eah with the html link, then you. the result is render with the raw filter so HTMl tags are not escaped. you should give it a try at least – Yoann MIR Nov 22 '18 at 19:52
  • This new edited version is quite good actually! The only thing that needs to change is the regex because some email addresses end with a double extension (example@some.co.uk). – Dirk J. Faber Nov 22 '18 at 20:05
  • 2
    Well if OP strips all the html first before applying `raw` then yeah. You could also mark the filter as safe e.g. `new TwigFilter('mailTo', array($this, 'mailTo'), array('is_safe' => 'html'));` – DarkBee Nov 22 '18 at 20:22
  • 1
    @Dirk J. Faber if you have a better regexp, i can add it, this one is the first i found for the example but, like you say, it's not perfect – Yoann MIR Nov 23 '18 at 08:25