Add nofollow attribute to each <a> tag with external link after the page was rendered

816 views Asked by At

Customer has requested, that all links to external pages in our sitecore solution should have a nofollow attribute. Which pipeline should I use to have an access to response html (to change the links before they will be delivered with markup to browser)? Or is there any better solution to accomplish this?

JavaScript is not much helpful here because I am not sure if all search engines are able to run JavaScript.

RenderField processor is also not usable, due to many custom tags in our code

1

There are 1 answers

8
Jan Bluemink On BEST ANSWER

You can use the Sitecore.Pipelines.HttpRequest And patch after the ExecuteRequest.

On this point you have the fully rendered html, including all cached components from the HTML cache.

Edit add a Example:

#region Using
using System;
using System.IO;

using Sitecore.Pipelines.HttpRequest;

#endregion

namespace MySpace.Sitecore.Pipelines
{

    public class MyProcessor : HttpRequestProcessor
    {

        public override void Process(HttpRequestArgs args)
        {

            if (!global::Sitecore.Context.PageMode.IsPageEditor)
            {
                if (!args.Context.Request.RawUrl.Contains(".") || (args.Context.Request.RawUrl.ToLower().Contains(".aspx") && !args.Context.Request.RawUrl.ToLower().StartsWith("/sitecore")))
                {
                    args.Context.Response.Filter = new MyInterestFilter(args.Context.Response.Filter);
                }
            }
        }

        #region Stream filter

        public class MyInterestFilter : Stream
        {

            public MyInterestFilter(Stream sink)
            {
                _sink = sink;
            }

            private Stream _sink;

            #region Properites

            public override bool CanRead
            {
                get { return true; }
            }

            public override bool CanSeek
            {
                get { return true; }
            }

            public override bool CanWrite
            {
                get { return true; }
            }

            public override void Flush()
            {
                _sink.Flush();
            }

            public override long Length
            {
                get { return 0; }
            }

            private long _position;

            public override long Position
            {
                get { return _position; }
                set { _position = value; }
            }

            #endregion

            #region Methods

            public override int Read(byte[] buffer, int offset, int count)
            {
                return _sink.Read(buffer, offset, count);
            }

            public override long Seek(long offset, SeekOrigin origin)
            {
                return _sink.Seek(offset, origin);
            }

            public override void SetLength(long value)
            {
                _sink.SetLength(value);
            }

            public override void Close()
            {
                _sink.Close();
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
                byte[] data = new byte[count];
                Buffer.BlockCopy(buffer, offset, data, 0, count);
                string html = System.Text.Encoding.Default.GetString(buffer);

                html = MyReplace(html);

                byte[] outdata = System.Text.Encoding.Default.GetBytes(html);
                _sink.Write(outdata, 0, outdata.GetLength(0));
            }

            public static string MyReplace(string html)
            {

                 html = html.Replace("TESTSTRING", "REPLACEDTESTSTRING");

                return html;
            }

            #endregion

        }

        #endregion

    }
}

And set a patch file in the App_Config include directory somethings like this:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor type="MySpace.Sitecore.Pipelines.MyProcessor, MySpace.Sitecore" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ExecuteRequest, Sitecore.Kernel']"/>
      </httpRequestBegin>
    </pipelines>
  </sitecore>
</configuration>