[SOLVED] How to make external links nofollow and target _blank by default if using source code toggle in editor?

Recommended Posts

I've set the ProcessPageEditLink module to ensure that external links are nofollow and target is _blank. Below is an image showing those settings. This works PERFECTLY for links that I add in via the editor, but the problem is that when I toggle editor to "source code" and add in links that way, it won't default to making the external links nofollow and target _blank. It only works when I put the link in via the link button in the editor.  

The reason this is a bit of an issue is that most affiliate links (which is exactly what you would want to apply this to) are usually given by the company as source code, so I am adding them in by toggling editor to "source code". In that situation, I just can't get the links to default to nofollow and target _blank.

Some solutions I tried:

  • I can add in those attributes manually to my source code, which works, but it's frustrating to do it on each and every link that I'm putting in.
  • Another option that seems to work is clicking on the link inside the editor AFTER toggling out of the source code mode window, and opening up the new link in the editor and hitting "submit", which forces the editor to re-edit the link with the attributes added. But likewise, this is rather clunky and time-consuming, plus I have to remember to do it every time.

However, being a newbie to ProcessWire maybe I have overlooked something. Have I been doing something wrong, or is there a workaround that someone could suggest? I'm hoping to figure this out early on, since I'll be using affiliate links in my new website. Thanks for any help that anyone can provide. 


Share this post

Link to post
Share on other sites

There are probably many different ways to do this, but perhaps the easiest might be to make use of this module (or modify it to your exact needs):

This won't actually save the rel="nofollow" to the link in the database, but will instead add it to all external links when the link is rendered on the frontend. 


  • Like 1

Share this post

Link to post
Share on other sites

Another option which avoids the need to parse and modify the links on every frontend page load (as a textformatter does), you could just do it once when a page is saved.

The example below (add to /site/ready.php) uses Simple HTML DOM as the parser:

// Change 'body' to whatever your CKEditor field is named
$wire->addHookAfter('Pages::saveReady', function(HookEvent $event) {
    $page = $event->arguments(0);
    // Return if body field absent or unchanged
    if(!$page->body || !$page->isChanged('body')) return;
    // Load Simple HTML DOM from site root
    require_once $this->config->paths->root . 'simple_html_dom.php';
    // Create DOM from body field
    $html = str_get_html($page->body);
    // Get all the links
    $links = $html->find('a');
    foreach($links as $link) {
        $href = $link->href;
        // For any link that is not relative and does not start with the site httpRoot...
        if(strpos($href, '/') !== 0 && strpos($href, $this->urls->httpRoot) !== 0) {
            // Set rel and target attributes
            $link->rel = 'nofollow';
            $link->target = '_blank';
    // Set the results to the body field
    $page->body = $html->save();


  • Like 5

Share this post

Link to post
Share on other sites

Thanks everyone for these answers. @adrian I liked the idea of the module, but when I looked at a discussion thread of the module, it says it should only be used on PW 2.x and not 3.x. Indeed, the module itself is only listed as compatible up to 2.7. I'm not sure if that means I still could use it successfully in my site, or that I might break things if I try that. I'll think about that. Even if it works, I'm a little hesitant to use a module that isn't designed to be used with future PW releases. Thanks for the info and I'll definitely keep thinking about this.

@Robin S Great, thanks for this code. I had never thought to use a separate HTML parser, and I love the idea that it does it when the page is saved. Very nice. Thanks for showing me how it should be done, as this is beyond what I would have been able to figure out on my own. Thank you so much.

Share this post

Link to post
Share on other sites

OK, I tried out the code from @Robin S and it works perfectly! :D It's an incredibly powerful and elegant solution, especially since it works on page save instead of front-end load. Besides trying out a standard link, I also tested it out with actual affiliate links and banners, which are a lot more complex-looking than a standard link, and it worked perfectly. For anyone in the same situation as me who wants to use Robin's solution, you should remember to first un-set the nofollow and _blank link attributes in ProcessPageEditLink (i.e. don't have those in the two boxes in the pic I showed in the original post up top). Then, just do what Robin said. It all just works!

I'll mark this as solved. Thanks again Robin S! 

  • Like 2

Share this post

Link to post
Share on other sites

@Violet, I just made a fix to the code snippet...

// Return if body field absent or unchanged
if(!$page->body || !$page->isChanged('body')) return;


  • Like 2

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By csaba
      Pleased to meet you,my name is Csaba and I'm from Hungary.
      I've just installed processwire to more places.
      I created new parent and children pages.
      The children page links are not displayed on the right side of the parent pages.
      The sample About page is ok, Child page example 1 and Child page example 2 links are visible and live.
      But my child pages are not displayed on the parent pages.
      Please help!
    • By jsantari
      Is it possible in the  ProcessPageEditLink to define multiple classes as a group. I've tried to add more the one class to a line but this breaks things. Only single classes on a line seem to work. Using a css framework like Bootstrap it would be good to be able to create a class check box for example for the combined classes: btn btn-success btn-sm.
    • By godmok
      Hi everyone,
      I have a problem with a member site where I put a link in CKEditor field thatshould go to a users profile page. The profile page is a site with one urlSegment, that contains the name of the user from the admin.
      The structure looks like this:
      -profiles --username (urlSegment) -some page (CKEditor field with a link to /profiles/username) -admin (PW admin area) --users ---username (user profile) So "some page" has a CKEditor field with a link to a profile page. Now the problem is, that this link source is always changed to the admin path and not the profiles (with urlSegment). A guest user can not look into this. Can this be deactivated, or is it wanted to work like this?
      My solution now is to create an additional page under "profiles" that is linked by a pagefield in the user profile. So a Link will always link to the "real" page under "profiles". Could there be a easier solution than creating an extra page as there is already one under admin but still let the links in CKEditor untouched?
    • By EyeDentify
      Hello Fellow forum members.

      I wanted to share two links to a guide and a cheatsheet concerning Crontab and Cronjobs.
      This is a result of me doing some research in how Cronjobs work and how to use it and i thought i share for other beginners use.

      So the guide that got me started and is a good reference is:
      A Comprehensive Crash Course Into Cronjobs (sitepoint)
      And also i found this sort of cheatsheet and database of cronjob configurations handy:
      Corntab - the Crontab GUI
      I hope these tips can help any beginners like myself get up and running with cronjobs.
    • By gerritvanaaken
      I’m searching for a proper solution for the following problem:
      My client has a lot of pages with internal links. We do not use CK Editor but a standard textarea with Markdown and some Hanna Code. We even have a Hanna Code for internal links, like so 
      [[link id="42" text="Some internal page"]] Anyway. My client does not want to have broken internal links, so he asked me either
      "Before I delete a page, it would be nice to know if this page is linked from any other page within the system." or
      "Is there a link checker/crawler module, which detects broken internal links in and which I can fire up globally in the admin" Has anyone similiar problems? How would you solve this?