tires Posted July 17, 2019 Share Posted July 17, 2019 Hi! I want to change the output of some text from my textarea. In detail i want to search for all links an replace the url with a new one. For example: When there is a link in the textarea like this Some text and a <a href="https://google.com">link</a>. I want the output to be like this Some text and a <a href="/my-redirect-link/?link=https://google.com">link</a>. Which is the easiest way to achieve this? Link to comment Share on other sites More sharing options...
BitPoet Posted July 17, 2019 Share Posted July 17, 2019 This is probably a perfect case for a custom textformatter. Those are invoked when the content of a textarea is rendered. Here's an example module that prepends a custom URL to all external links. You need to enter /my-redirect-link/?link= in the module's configuration after installation and configure the field in question to use TextformatterExternalRedirect. <?php namespace ProcessWire; /** * ProcessWire External Link Redirector Textformatter * * Prefixes the URL in each external link with a local URL that redirects to the * original URL after doing whatever it is that it needs to do. * * The URL to prepend is configured in this module's settings * (Backend: Modules -> Configure -> TextformatterExternalRedirect) * * It assumes that the prepended URL ends with a GET parameter and an equal sign, * so it urlencode()s the original URL. * * Example: * Link is <a href='https://processwire.com'> * Prepend URL: /myredirector/?link= * Textformatter generates: <a href='/myredirector/?link=https%3A%2F%2Fprocessire.com'> * */ class TextformatterExternalRedirect extends Textformatter implements ConfigurableModule { public static function getModuleInfo() { return array( 'title' => 'External Link Redirect', 'version' => '0.0.4', 'summary' => "Parses links in textareas and prepends a local redirector URL", ); } public function __construct() { parent::__construct(); $this->set("prependUrl", ""); } public function format(&$str) { $str = trim($str); if(!strlen($str)) return; if(!$this->prependUrl) return; $that = $this; $str = preg_replace_callback( '/(<a[^>]+href=)(["\'])([^"\']*)(\\2)/i', function($match) use($that) { // If link is not external, we return the original link if(!$that->isExternalLink($match[3])) return $match[0]; return $match[1] . $match[2] . $that->prependUrl . urlencode($match[3]) . $match[2]; }, $str ); } public function isExternalLink($url) { foreach($this->config->httpHosts as $hostname) { // If the target host is one of our own hostnames, // this link is not external. if(preg_match("~^https?://{$hostname}~i", $url))) return false; } // Otherwise, all http(s) links are definitely external // and get redirected. if(preg_match('~^https?://~i', $url))) return true; // No match, then we have a relative url (internal) or some other // scheme (e.g. mailto) that we don't redirect. return false; } public static function getModuleConfigInputfields($data) { $inputfields = new InputfieldWrapper(); $f = wire('modules')->get("InputfieldText"); $f->attr('id+name', 'prependUrl'); $f->label = __("URL to prepend", __FILE__); $f->description = __("This URL is prepended. It is assumed that it ends with a GET parameter to which the URL-encoded original link will be passed.", __FILE__); if(isset($data["prependUrl"])) $f->attr('value', $data["prependUrl"]); $inputfields->append($f); return $inputfields; } } 3 Link to comment Share on other sites More sharing options...
tires Posted July 17, 2019 Author Share Posted July 17, 2019 THANKS A LOT!!! It works perfectly well! There was just two ")" to much ... in line 60 if(preg_match("~^https?://{$hostname}~i", $url))) return false; and in line 65 if(preg_match('~^https?://~i', $url))) return true; I changed that and made a module out of the code (see attachment), so that others can use it. To use it just unzip it and put the TextformatterExternalRedirect.module in the directory /site/modules/TextformatterExternalRedirect. TextformatterExternalRedirect.zip Link to comment Share on other sites More sharing options...
tires Posted July 17, 2019 Author Share Posted July 17, 2019 One last thing: Is it possible to add a target="_blank" automatically to all my the new links? Link to comment Share on other sites More sharing options...
BitPoet Posted July 18, 2019 Share Posted July 18, 2019 13 hours ago, tires said: One last thing: Is it possible to add a target="_blank" automatically to all my the new links? I have updated the code to add an option for that. The module is now available at GitHub. Check "Open in new window" in the module configuration to add a target="_blank" attribute (or replace an existing target attribute's value with "_blank"). 2 Link to comment Share on other sites More sharing options...
tires Posted July 18, 2019 Author Share Posted July 18, 2019 Thank you!!! This is great!!! I think this module is worth to be listed in the modules section! Link to comment Share on other sites More sharing options...
BitPoet Posted July 18, 2019 Share Posted July 18, 2019 39 minutes ago, tires said: I think this module is worth to be listed in the modules section! I already submitted it, and it's pending approval, so it should become visible in the next few days. The latest version on GitHub also lets you add custom CSS classes to the links. 1 Link to comment Share on other sites More sharing options...
tires Posted July 18, 2019 Author Share Posted July 18, 2019 Greeeeeat!!! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now