make_clickable()WP 0.71

Converts non-clickable links in the text - http://ссылка into clickable ones (an HTML link). Also converts text starting with: www, ftp, email into links.

Converts strings starting with http://, www, ftp, email into the corresponding HTML link code.

Takes into account cases when the URI is already clickable in the text and does not replace it again.

Does not process text inside tags: <code>, <pre>, <script>, <style>.

Passes the returned string through the PHP function trim() - removes spaces at the ends of the string. I once had difficulties with this behavior. Since version 3.8. trailing spaces are not removed.

By default in WP it is applied to comment text:

add_filter( 'comment_text', 'make_clickable', 9 );
1 time — 0.000662 sec (slow) | 50000 times — 6.64 sec (fast) | PHP 7.1.11, WP 4.9.8

No Hooks.

Returns

String. Modified text with HTML links.

Usage

$text = make_clickable( $text );
$text(string) (required)
The text to be filtered.

Examples

0

#1 Turn a link (URL) in the text into a clickable HTML link:

<?php
$ret = "Some text http://example.com/page-108 and some other text.";
echo make_clickable( $ret );
?>

As a result of this example we get:

Some text <a href="http://example.com/page-108" rel="nofollow">http://example.com/page-108</a> and some other text.
0

#2 Make the links (URLs) clickable and with target blank

Let's turn all URLs in the content to clickable links and with target=_blank attribute (to open the links in a new tab). Use links_add_target().

<?php
$content = "Some text http://example.com/page-108 and some other text";
echo links_add_target( make_clickable( $content ) );
?>

As a result of this example we get:

Some text <a href="http://example.com/page-108" rel="nofollow" target="_blank">http://example.com/page-108</a> and some other text.

Changelog

Since 0.71 Introduced.

make_clickable() code WP 7.0

function make_clickable( $text ) {
	$r               = '';
	$textarr         = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // Split out HTML tags.
	$nested_code_pre = 0; // Keep track of how many levels link is nested inside <pre> or <code>.
	foreach ( $textarr as $piece ) {

		if ( preg_match( '|^<code[\s>]|i', $piece )
			|| preg_match( '|^<pre[\s>]|i', $piece )
			|| preg_match( '|^<script[\s>]|i', $piece )
			|| preg_match( '|^<style[\s>]|i', $piece )
		) {
			++$nested_code_pre;
		} elseif ( $nested_code_pre
			&& ( '</code>' === strtolower( $piece )
				|| '</pre>' === strtolower( $piece )
				|| '</script>' === strtolower( $piece )
				|| '</style>' === strtolower( $piece )
			)
		) {
			--$nested_code_pre;
		}

		if ( $nested_code_pre
			|| empty( $piece )
			|| ( '<' === $piece[0] && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) )
		) {
			$r .= $piece;
			continue;
		}

		// Long strings might contain expensive edge cases...
		if ( 10000 < strlen( $piece ) ) {
			// ...break it up.
			foreach ( _split_str_by_whitespace( $piece, 2100 ) as $chunk ) { // 2100: Extra room for scheme and leading and trailing parentheses.
				if ( 2101 < strlen( $chunk ) ) {
					$r .= $chunk; // Too big, no whitespace: bail.
				} else {
					$r .= make_clickable( $chunk );
				}
			}
		} else {
			$ret = " $piece "; // Pad with whitespace to simplify the regexes.

			$url_clickable = '~
				([\\s(<.,;:!?])                                # 1: Leading whitespace, or punctuation.
				(                                              # 2: URL.
					[\\w]{1,20}+://                                # Scheme and hier-part prefix.
					(?=\S{1,2000}\s)                               # Limit to URLs less than about 2000 characters long.
					[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+         # Non-punctuation URL character.
					(?:                                            # Unroll the Loop: Only allow punctuation URL character if followed by a non-punctuation URL character.
						[\'.,;:!?)]                                    # Punctuation URL character.
						[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++         # Non-punctuation URL character.
					)*
				)
				(\)?)                                          # 3: Trailing closing parenthesis (for parenthesis balancing post processing).
				(\\.\\w{2,6})?                                 # 4: Allowing file extensions (e.g., .jpg, .png).
			~xS';
			/*
			 * The regex is a non-anchored pattern and does not have a single fixed starting character.
			 * Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
			 */

			$ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret );

			$ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret );
			$ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret );

			$ret = substr( $ret, 1, -1 ); // Remove our whitespace padding.
			$r  .= $ret;
		}
	}

	// Cleanup of accidental links within links.
	return preg_replace( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', '$1$3</a>', $r );
}