Mecha CMS

Code snippet collection for developers.

Detect External Links

Author: Taufik Nurrohman · 51 Views

Tweet

External links checker for “HTML” page type.

This snippet will automatically add rel="nofollow" and target="_blank" attribute to the external links in the page description and content. You don’t need this snippet if you are using Markdown. Markdown plugin already has this feature included.

Hook::set([
    'page.description',
    'page.content'
], function($content, $lot = []) use($url) {
    // Page type is not set or has value other than “HTML”, skip!
    if (!isset($lot['type']) || $lot['type'] !== 'HTML') {
        return $content;
    }
    // No anchor(s) found, skip!
    if (strpos($content, '</a>') === false) {
        return $content;
    }
    // Get anchor element(s) from page content…
    return preg_replace_callback('#<a(?:\s[^<>]*?)?>(?:[\s\S]*?)</a>#', function($m) use($url) {
        $a = HTML::apart($m[0]);
        // No `href` attribute, skip!
        if (!isset($a[2]['href'])) {
            return $m[0];
        }
        // Check for external link(s)…
        // Based on <https://github.com/tovic/parsedown-extra-plugin>
        $href = $a[2]['href'];
        $if = strpos($href, 'https://' . $url->host) === 0 ||
              strpos($href, 'http://' . $url->host) === 0 ||
              strpos($href, '/') === 0 ||
              strpos($href, '?') === 0 ||
              strpos($href, '#') === 0 ||
              strpos($href, 'javascript:') === 0 ||
              strpos($href, '.') === 0 ||
              strpos($href, '://') === false;
        // Double check for relative protocol…
        if (strpos($href, '//') === 0 && strpos($href, '//' . $url->host) !== 0) {
            $if = false;
        }
        // If external link…
        if (!$if) {
            // Add `rel="nofollow"` attribute
            $a[2]['rel'] = 'nofollow';
            // Add `target="_blank"` attribute
            $a[2]['target'] = '_blank';
        }
        // Re-unite the anchor…
        return call_user_func_array('HTML::unite', $a);
    }, $content);
    return $content;
}, 2.1);

0 Comments

No comments yet.