Jump to content
tires

Change text / linkurl output in textarea

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?

 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

One last thing:
Is it possible to add a target="_blank" automatically to all my the new links?

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...