1

I have imported a large amount of items in sitecore and used a rich text editor field to store the content text html. Currently all links in the rich text editor are like external links pointing to the other imported items as the item names have been preserved like this: http://hostname/News/Year/Item1.aspx

I am looking for a solution to change all links in the rich text editor to internal sitecore links so that the editors can change the item names afterwards. Do I need to write custom code and parse the RTE html links or is it possible to do this with a powershell script? Thanks for the help.

1
2

I think you could make it work with something similar to what I have here.

# GetItemByUrl function from https://sitecore.stackexchange.com/questions/24962/getting-an-item-using-powershell-having-only-the-url
function GetItemByUrl($url){
    $url = [System.Uri]::new($url);

    $siteContext = [Sitecore.Sites.SiteContextFactory]::GetSiteContext($url.Host, $url.PathAndQuery);

    $homePath = $siteContext.StartPath;
    if (!$homePath.EndsWith("/")){            
        $homePath += "/";
    }

    $itemPath = [Sitecore.MainUtil]::DecodeName($url.AbsolutePath);

    if ($itemPath.StartsWith($siteContext.VirtualFolder)){
        $itemPath = $itemPath.Remove(0, $siteContext.VirtualFolder.Length);
    }

    $fullPath = $homePath + $itemPath;
    return $siteContext.Database.GetItem($fullPath);
}

$anchorTagPattern = '(?is)<a[^>]*>(.*?)<\/a>';
# pattern that match any anchor, can try it here https://regexr.com/

$hrefPattern = '(?is)href=\"[^>]*(.*?)\"';
# pattern that match any href="anyContent", can try it here https://regexr.com/

$titlePattern = '(?is)>[^>]*(.*?)<';
# pattern that match any content between > and <, can try it here https://regexr.com/

$yourParentItemPath = 'master:\Content\Home\Path';
cd $yourParentItemPath;

Get-ChildItem -Recurse | ForEach-Object {
    
    $richTextContent = $_.Fields["Your Rich Text Content Field"].Value;
    $anchorTagPatternMatches = [regex]::Matches($richTextContent, $anchorTagPattern);

    if(![string]::IsNullOrEmpty($anchorTagPatternMatches)) {
        $anchorTag = $anchorTagPatternMatches[0].Groups[1].Value;
        # Whenever a match is found and a regex group is used; (), the [regex] type accelerator has a Captures property. 
        # This Captures property then has a property called Groups. 
        # This is a collection that contains lots of attributes of what was matched. 
        # The second element in that collection contains the actual value that was matched.
        
        if(![string]::IsNullOrEmpty($anchorTag)){   
            $hrefPatternMatches = [regex]::Matches($anchorTag, $hrefPattern);
            $href = $hrefPatternMatches[0].Groups[1].Value;
            # here we should end up having a value like this : href="somelink"
            # but we want the url... so we are going to remove the href

            $href = $href.Replace('href=','');
            $itemFromHref = GetItemByUrl($href);

            if(![string]::IsNullOrEmpty($itemFromHref)){
                $itemGuidFromHref = $itemFromHref._.Id
                # access item prop -> https://doc.sitecorepowershell.com/working-with-items#get-item-properties-with-field-type

                $titlePatternMatches = [regex]::Matches($anchorTag, $titlePattern);
                $title = $titlePatternMatches[0].Value;
                $title = $href.Replace('<','').Replace('>','');

                if(![string]::IsNullOrEmpty($href)){
                    $newGeneralLink = "<link text=`"$title`" title=`"`" class=`"`" linktype=`"internal`" id=`"$itemGuidFromHref`" target=`"`" />";
                    
                    $_.Editing.BeginEdit();
                    $_.Fields["Your General Link Field"].Value = $newGeneralLink;
                    # you proably want to remove the link from your richtextcontent
                    $richTextContent = $richTextContent.Replace($anchorTag,"");
                    $_.Fields["Your Rich Text Content Field"].Value = $richTextContent;    
                    $_.Editing.EndEdit() | Out-Null;
                }
            }   
        }
    }
}

Here are some things to consider:

  • I am not handling multiples links from a single RichTextEditor.
  • You should handle the way you render your links within your view/model afterwards.
  • I normally use getItem from path(https://doc.sitecorepowershell.com/working-with-items#get-item-by-path), not the other way (hence the function from the other stackexchange thread)
  • I am not aware of where the items lives (are they all under the same parent folder or nah, etc.)
  • You will probably end up adding if-else conditions on item template or path to not execute this script on all items if you want to apply this changes to a lot of content that doesnt share exactly the same parent item
  • While executing/debugging, add some Write-Host here and there to see what's happening behind the scene.

ex:

$someTemplate = 'Some Template Name';
# ... your loop
$path = $_.FullPath;
if(($path -eq $somePath) -And
    ($_.TemplateName -eq $someTemplate))
{
  #your code
}

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.