2

Does anyone know how to programatically change link from:

<a href="some_url">click</a>

to:

<a onclick="window.open('some_url','_blank', 'location=no')">click</a>

so that all links created in the wordpress visual editor be opened via inappbrowser in a cordova app.

this is the closest that i can get, but still doesn't work, the '%link%' variable doesn't change to the actual link url :

add_filter('the_content', 'changeToOnclick');
function changeToOnclick($content) {
    return preg_replace('/<a [^>]*>/', "<a onclick=\"window.open('%link%', '_blank', 'location=no')\">", $content);
}

any help will be appreciated :)

2
  • If you want to replace all link then you can do this using mysql query in database. wp_posts table contains all data of wordpress page content. Use find and replace (update) query (search for the query on google). If you dont have access to DB then use this plugin that will find and replace all links for you wordpress.org/plugins/velvet-blues-update-urls – Rishabh Mar 7 '17 at 5:38
  • Thx but i dont think it serves my purpose :) – yanuar Mar 7 '17 at 11:43
3

Parsing HTML with regular expressions is not ideal. A better alternative is to use DOMDocument and DOMXpath;

This code uses DOMDocument and DOMXpath to parse and modify the HTML without relying on regular expressions. Each link in the content will have the onclick attribute added along with the appropriate window.open() code using the URL pulled from the value of the href attribute. The href attribute is then removed from the link.

add_filter( 'the_content', 'wpse_cordova_links', 10, 1 );
function wpse_cordova_links( $content ) {
    // Create an instance of DOMDocument.
    $dom = new \DOMDocument();

    // Suppress errors due to malformed HTML.
    // See http://stackoverflow.com/a/17559716/3059883
    $libxml_previous_state = libxml_use_internal_errors( true );

    // Populate $dom with $content, making sure to handle UTF-8, otherwise
    // problems will occur with UTF-8 characters.
    $dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );

    // Restore previous state of libxml_use_internal_errors() now that we're done.
    // Again, see http://stackoverflow.com/a/17559716/3059883
    libxml_use_internal_errors( $libxml_previous_state );

    // Create an instance of DOMXpath.
    $xpath = new \DOMXpath( $dom );

    // Query all links within our content.
    $links = $xpath->query( '//a' );

    // Iterate over the $links.
    foreach ( $links as $link ) {
        if ( $link->hasAttributes() ) {
            // Get the value of the href attribute
            $link_href = $link->getAttribute( 'href' );

            // Create an onlick attribute and set the value
            $link_onclick = $dom->createAttribute( 'onclick' );
            $link_onclick->value = "window.open( '" . $link_href . "', '_blank', 'location=no' );";
            $link->appendChild( $link_onclick );

            // Remove the href attribute
            $link->removeAttribute( 'href' );
        }
    }

    // Save the updated HTML
    $content = $dom->saveHTML();    

    return $content;
}

Example HTML before processing

<p><a href="http://example.com/">click</a></p>

<p>Lorem ipsum dolor sit amet, ecclesiam mittam est amet constanter approximavit te. Introivit gubernum defunctam vivum eum ego esse ait mea Christianis<br>
<a class="test-class test-other-class" href="http://example.com/1/">click me too</a> aedificatur ergo accipiet duxit ad te. Ascendi in modo invenit ubi diu requievit agi coepit. Apollonii appropinquat tation ulterius quod ait mea Christianis aedificatur ergo accipiet si mihi esse deprecor cum. Equidem deceptum in fuerat eum est in, quoque sed quod ait est in fuerat.</p>

<p><a data-test="55" href="http://example.com/2/">click me as well</a></p>

<p>Lorem ipsum dolor sit amet, ecclesiam mittam est amet constanter approximavit te. Introivit gubernum defunctam vivum eum ego esse ait mea Christianis aedificatur ergo accipiet duxit ad te. Ascendi in modo invenit ubi diu requievit agi coepit. Apollonii appropinquat tation ulterius quod ait mea Christianis aedificatur ergo accipiet si mihi esse deprecor cum. Equidem deceptum<br>
<a id="test-id" class="test-class" href="http://example.com/3/">clicky</a> in fuerat eum est in, quoque sed quod ait est in <a>This link has no href attribute</a> fuerat.</p>

Example HTML after processing

<p><a onclick="window.open( 'http://example.com/', '_blank', 'location=no' );">click</a></p>

<p>Lorem ipsum dolor sit amet, ecclesiam mittam est amet constanter approximavit te. Introivit gubernum defunctam vivum eum ego esse ait mea Christianis<br>
<a class="test-class test-other-class" onclick="window.open( 'http://example.com/1/', '_blank', 'location=no' );">click me too</a> aedificatur ergo accipiet duxit ad te. Ascendi in modo invenit ubi diu requievit agi coepit. Apollonii appropinquat tation ulterius quod ait mea Christianis aedificatur ergo accipiet si mihi esse deprecor cum. Equidem deceptum in fuerat eum est in, quoque sed quod ait est in fuerat.</p>

<p><a data-test="55" onclick="window.open( 'http://example.com/2/', '_blank', 'location=no' );">click me as well</a></p>

<p>Lorem ipsum dolor sit amet, ecclesiam mittam est amet constanter approximavit te. Introivit gubernum defunctam vivum eum ego esse ait mea Christianis aedificatur ergo accipiet duxit ad te. Ascendi in modo invenit ubi diu requievit agi coepit. Apollonii appropinquat tation ulterius quod ait mea Christianis aedificatur ergo accipiet si mihi esse deprecor cum. Equidem deceptum<br>
<a id="test-id" class="test-class" onclick="window.open( 'http://example.com/3/', '_blank', 'location=no' );">clicky</a> in fuerat eum est in, quoque sed quod ait est in <a>This link has no href attribute</a> fuerat.</p>
4
  • 1
    Thanks a lot Dave! works like a charm :) btw, can you enlighten me why parsing HTML with regular expressions is not ideal? – yanuar Mar 8 '17 at 3:07
  • You're welcome, yanuar. Glad to hear! Here's a post on StackOverflow that goes into more detail about explaining why regex is not the best way to parse HTML. In short, there are too many possibilities for edge cases which will cause the regex to not work properly, especially when the HTML could be malformed. – Dave Romsey Mar 8 '17 at 3:21
  • What a great answer. Can I make a more usable suggestion? What the OP wants is a bit nuts, you don't open up every link in a new tab! If you are going to open up new tabs they should only be for links outside of your site. – STing Mar 8 '17 at 4:16
  • @STing thank you. I agree with you in terms of traditional web development, but figured there was a particular reason for the OP's goal when working with a Cordova/PhoneGap app. – Dave Romsey Mar 8 '17 at 5:17
0

There are several plugins that will do that automatically. One is "Open External Links in New Window" (found here https://wordpress.org/plugins/open-external-links-in-a-new-window/ ). You can probably find others if you search plugins for 'external links'.

I use this on several sites, works well.

If you want to roll your own, just look at the code that they use, since all plugins are (usually) open source. But, why reinvent the wheel....?

4
  • Nowhere in the question the OP says he wants the functionality only for "external" sites – Mark Kaplun Mar 7 '17 at 5:57
  • Mark is right, I prefer not to use plugin. And the code is not only for external link, but for all link that is created through the wp visual editor. After googling around, i think i should use preg_replace, but i dont know how to write the exact code :( – yanuar Mar 7 '17 at 11:43
  • I suspect that you could modify the function in the plugin that does the work to apply it to all links, internal and external. All it would take is the appropriate add_filter() command on post/comment/page save/update. Just modify the code from one of the plugins (open source), and place it in your child theme's function.php file. – Rick Hellewell Mar 8 '17 at 0:30
  • Thankyou for the suggestion Rick, but i have a very minimal experience using code, so i can't modify plugin as you suggested :p it has been solved though, thanks all! – yanuar Mar 8 '17 at 3:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.