Jump to content

Change text / linkurl output in textarea


tires
 Share

Recommended Posts

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

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;
	}
}

 

  • Like 3
Link to comment
Share on other sites

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

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").

  • Like 2
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...