WordPress给外链添加添加nofollow和新窗口打开属性,可以设置白名单,白名单只添加target="_blank"。

代码一:

// 外链nofollow和target="_blank",支持白名单
add_filter('the_content', 'wl_the_content');
function wl_the_content($content) {
    // 定义白名单,不在白名单内的链接会被替换为nofollow
    $whitelist = array("so.com", "baidu.com");
    // $whitelist = array();
    // 将白名单转换为正则表达式
    if (!empty($whitelist)) {
        $whitelist_regex = '/(' . implode('|', array_map('preg_quote', $whitelist)) . ')/i';
    } else {
        $whitelist_regex = false;
    }
    // 获取当前页面链接主机名,用于忽略本站链接
    $current_host = wp_parse_url(home_url(), PHP_URL_HOST);
    // 定义替换链接的正则表达式
    $regex = '/<a\s+(?:[^>]*?\s+)?href=(["\'])(.*?)\1[^>]*?>/i';
    // 解析文章内容,获取所有链接
    $new_content = preg_replace_callback($regex, function ($matches) use ($current_host, $whitelist_regex) {
        $url = $matches[2];
        // 判断是本站地址,如果是,则直接返回原链接
        if (strpos($url, $current_host) !== false) {
            return $matches[0];
        }
        // 如果存在白名单,并且链接在白名单内,则只添加target="_blank"属性
        if ($whitelist_regex && preg_match($whitelist_regex, $url)) {
            return '<a href="' . esc_url($url) . '" target="_blank">';
        } else {
            return '<a href="' . esc_url($url) . '" target="_blank" rel="nofollow">';
        }
    }, $content);
    return $new_content;
}

代码二:

// 外链nofollow和target="_blank",支持白名单
add_filter('the_content', 'wl1_the_content');
function wl1_the_content($content) {
    // 定义白名单,不在白名单内的链接会被替换为nofollow
    $whitelist = array("so.com", "baidu.com");
    // $whitelist = array();
    // 获取当前页面链接主机名,用于忽略本站链接
    $current_host = wp_parse_url(home_url(), PHP_URL_HOST);
    // 定义替换链接的正则表达式
    $regex = '/<a\s+(?:[^>]*?\s+)?href=(["\'])([^"\']*)\1[^>]*?>/i';
    // 解析文章内容,获取所有链接
    preg_match_all($regex, $content, $matches, PREG_SET_ORDER);
    // 如果文章中没有链接,直接返回原内容
    if (empty($matches)) {
        return $content;
    }
    // 遍历所有链接,根据白名单和忽略列表替换链接属性
    $new_links = array();
    foreach ($matches as $match) {
        $url = $match[2];

        // 判断是本站地址,如果是,则直接返回原链接
        if (strpos($url, $current_host) !== false) {
            $new_links[] = $match[0];
            continue;
        }
        // 判断是否在白名单内
        $in_whitelist = false;
        foreach ($whitelist as $domain) {
            if (strpos($url, $domain) !== false) {
                $in_whitelist = true;
                break;
            }
        }
        // 如果在白名单内,则只添加target="_blank"属性
        if ($in_whitelist) {
            $new_links[] = '<a href="' . esc_url($url) . '" target="_blank">';
        } else {
            $new_links[] = '<a href="' . esc_url($url) . '" target="_blank" rel="nofollow">';
        }
    }
    // 使用替换后的链接替换原始链接
    $content = str_replace(array_column($matches, 0), $new_links, $content);
    return $content;
}

旧内容:可以使用

白名单里的链接回添加target="_blank";

忽略名单里的链接直接返回原链接,一般填本站链接就行;

其他链接全部添加rel="nofollow"和target="_blank"/

注意:白名单和忽略名单不能为空,因为没做为空的判断,如果白名单没有想要填的链接,那可以随便填一个链接。

// 外链nofollow和target="_blank",支持白名单
add_filter('the_content','wl_the_content');
function wl_the_content($content){
    // 定义白名单,不在白名单内的链接会被替换为nofollow
    $whitelist = array("so.com", "baidu.com"); 
    // 定义忽略列表,不处理的网址
    $ignorelist = array("gmloc.me"); 
    // 定义替换链接的正则表达式
    $regex = '/<a\s+(?:[^>]*?\s+)?href=(["\'])(.*?)\1[^>]*?>/i';
    // 替换链接
    $content = preg_replace_callback($regex, function($matches) use ($whitelist, $ignorelist) {
        $url = $matches[2];
        // 判断是否在忽略列表内,如果在,则直接返回原链接
        foreach ($ignorelist as $ignore) {
            if (strpos($url, $ignore) !== false) {
                return $matches[0];
            }
        }
        // 判断是否在白名单内
        $in_whitelist = false;
        foreach ($whitelist as $domain) {
            if (strpos($url, $domain) !== false) {
                $in_whitelist = true;
                break;
            }
        }
        // 如果在白名单内,则只添加target="_blank"属性
        if ($in_whitelist) {
            $replacement = '<a href="' . $url . '" target="_blank">';
        } else {
            $replacement = '<a href="' . $url . '" target="_blank" rel="nofollow">';
        }
        return $replacement;
    }, $content);
    return $content;
}

假如忽略名单只有本站地址,那么可以改写成如下:

// 外链nofollow和target="_blank",支持白名单
add_filter('the_content','wl_the_content');
function wl_the_content($content){
    // 定义白名单,不在白名单内的链接会被替换为nofollow
    $whitelist = array("so.com", "baidu.com"); 
    // 定义本站顶级域名,不处理的网址
    // $ignore = "gmloc.me"; 
    $ignore = $_SERVER['HTTP_HOST']; 
    // 定义替换链接的正则表达式
    $regex = '/<a\s+(?:[^>]*?\s+)?href=(["\'])(.*?)\1[^>]*?>/i';
    // 替换链接
    $content = preg_replace_callback($regex, function($matches) use ($whitelist, $ignore) {
        $url = $matches[2];
        // 判断是否是本站链接,如果是,则直接返回原链接
        if (strpos($url, $ignore) !== false) {
            return $matches[0];
        }  
        // 判断是否在白名单内
        $in_whitelist = false;
        foreach ($whitelist as $domain) {
            if (strpos($url, $domain) !== false) {
                $in_whitelist = true;
                break;
            }
        }
        // 如果在白名单内,则只添加target="_blank"属性
        if ($in_whitelist) {
            $replacement = '<a href="' . $url . '" target="_blank">';
        } else {
            $replacement = '<a href="' . $url . '" target="_blank" rel="nofollow">';
        }
        return $replacement;
    }, $content);
    return $content;
}

旧内容:不推荐

方法一、整个替换,不管a标签里有没有nofollow或target="_blank"。

// 外链nofollow和target="_blank"
add_filter('the_content','wl_the_content',999);
// 999是优先级,默认是10,如果下方代码不生效,很可能是主题里自带类似的代码,去掉999就行了,或者改成998.
function wl_the_content($content){
    preg_match_all('/href="(http.*?)"/',$content,$matches);
    if($matches){
        foreach($matches[1] as $val){
             if( strpos($val,home_url())===false && !preg_match('/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i',$val) && !preg_match('/(ed2k|thunder|Flashget|flashget|qqdl):\/\//i',$val))
             $url = preg_quote($val);
             $content=preg_replace("@<a(.*?)href=\"($url)\"(.*?)>@", "<a href=\"$val\" target=\"_blank\" rel=\"external nofollow\">",$content);
         }
     }
    return $content;
}

进阶:支持白名单

// 外链nofollow和target="_blank",支持白名单
add_filter('the_content','wl_the_content',999);
function wl_the_content($content){
    $array = array("baidu.com","so.com");// 白名单
    preg_match_all('/href="(http.*?)"/',$content,$matches);
    if($matches){
        foreach($matches[1] as $val){
            if( strpos($val,$_SERVER['HTTP_HOST'])===false && !preg_match('/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i',$val) && !preg_match('/(ed2k|thunder|Flashget|flashget|qqdl):\/\//i',$val)){
                $mode = false;
                foreach($array as $Whitelist){
                    if(strpos($val,$Whitelist)){
                        $mode = true;
                        break;     
                    }
                }
                if( $mode===false){
                    $url = preg_quote($val);
                    $content=preg_replace("@<a(.*?)href=\"($url)\"(.*?)>@", "<a href=\"$val\"target=\"_blank\" rel=\"external nofollow\">",$content);
                }
            }
        }
     }
    return $content;
}

方法二、没有nofollow或target="_blank"的a标签,自动加上。有了则不加。

// url自动添加nofollow属性和新窗口打开wordpress文章或页面内的站外链接,已有nofollow或_blank则不添加。
// 999是优先级,默认是10,如果下方代码不生效,很可能是主题里自带类似的代码,去掉999就行了,或者改成998.
add_filter( 'the_content', 'cn_nf_url_parse',999);
function cn_nf_url_parse( $content ) {
 
    $regexp = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>";
    if(preg_match_all("/$regexp/siU", $content, $matches, PREG_SET_ORDER)) {
        if( !empty($matches) ) {
            $srcUrl = get_option('siteurl');
            for ($i=0; $i < count($matches); $i++)
            {
                $tag = $matches[$i][0];
                $tag2 = $matches[$i][0];
                $url = $matches[$i][0];
                $noFollow = '';
                $pattern = '/target\s*=\s*"\s*_blank\s*"/';
                preg_match($pattern, $tag2, $match, PREG_OFFSET_CAPTURE);
                if( count($match) < 1 )
                    $noFollow .= ' target="_blank" ';
 
                $pattern = '/rel\s*=\s*"\s*[n|d]ofollow\s*"/';
                preg_match($pattern, $tag2, $match, PREG_OFFSET_CAPTURE);
                if( count($match) < 1 )
                    $noFollow .= ' rel="nofollow" ';
 
                $pos = strpos($url,$srcUrl);
                if ($pos === false) {
                    $tag = rtrim ($tag,'>');
                    $tag .= $noFollow.'>';
                    $content = str_replace($tag2,$tag,$content);
                }
            }
        }
    }
    $content = str_replace(']]>', ']]>', $content);
    return $content;
}