Try our conversational search powered by Generative AI!

Update references to page before deleting it

Vote:
 

I'm trying to update all the references to a page we'd like to delete to another page, in order not to break any link on the website once the page is removed.

In order to do so, I created a scheduled job where I first get all the pages and blocks with a reference to the page to delete, using the GetReferencesToContent method, but I'm then unable to update the property as I don't know which property of the element contains the reference.

Is there a way to achieve that properties update or is there an easier way to update the links to a page without having to use a scheduled job or doing the modification manually ?

Thanks in advance !

Loïc

#195305
Edited, Jul 19, 2018 15:17
Vote:
 

Hi. Super easy fix would be to just setup a 301 redirect for the page you are deleting. 

-John

#196828
Sep 13, 2018 0:15
Vote:
 

And to further extend on John's advice, this job can become even easier if you install and use the Geta 404 Handler. https://github.com/Geta/404handler it is one of the most widely used Epierver community addons, and will enable you or the customer to do all of this type of management through the interface without needing to do any development work.

#196832
Sep 13, 2018 0:28
Vote:
 

A late answer but perhaps someone else migth get use of it. Since links witin CMS are stored in a format based on the ContentGuid one trick could be to first get the guid of the page that is to be deleted. Then the delete the page (you have to really delete it, not just moving it to wastebasket). Then create a new page but before saving it assign IContent.ContentGuid to the same guid that the previous (now deleted) page had. 

The trick is that since the new page now has the same Guid based identifier as the previous one had then all other pages that was previously linked to the old page ill now link to the new page automatically (since the ContentGuid is the same).

#196843
Sep 13, 2018 9:28
Vote:
 

I've done following with success:

First get all references of the page you're deleting:

var repository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
var referenceList = repository.GetReferencesToContent(new ContentReference(oldPageId), true)

Then loop over it and for each page/block loop over it's properties, change all places where there's a reference to old page and save.

var oldPageId = 5;
var newPageId = 20;	
foreach (var reference in referenceList)
{
	var content = _repository.Get<IContent>(reference.OwnerID);
	var original = _repository.Get(reference.OwnerID, reference.OwnerLanguage);
	var clone = (ContentData)original.CreateWritableClone();		
	foreach (var property in content.Property)
	{
		var prop = property.Name;
		if (typeof(ContentReference) == type && (ContentReference)original[prop] == new ContentReference(oldPageId))
		{
			clone[prop] = new ContentReference(newPageId);
		}
		else if (typeof(PageReference) == type && (PageReference)original[prop] == new PageReference(oldPageId))
		{
			clone[prop] = new PageReference(newPageId);
		}
	}
	_repository.Save((IContent)clone, SaveAction.Publish, AccessLevel.NoAccess);
}

I would do this inside a Controller that I access protect with something like this:

[GuiPlugIn(
        Area = PlugInArea.AdminMenu,
        Url = "/ReplaceReferences", 
        DisplayName = "Replace references")]
    [Authorize(Roles = "CmsAdmins, WebAdmins, Administrators")]

I've also replaced references inside XHTML fields, let me know if you need code for this as well. :)

#196847
Edited, Sep 13, 2018 10:15
Vote:
 

Hello Goran. I'm having issues updating old references all over the website (including XHTML). Can you please provide your solution for XHTML please? :)

Also, I was able to update some of the references but somehow if I try to delete the old page, I still got the popup alerting me that it has references to it even if those blocks were updated. Any idea why this is happening?

#196966
Edited, Sep 18, 2018 15:12
Vote:
 

Here's code for XHTML and to update references as well. Darren helped me with reference updating by altering the save action (https://world.episerver.com/forum/developer-forum/-Episerver-75-CMS/Thread-Container/2018/9/publishing-from-code-doesn39t-update-references/), so please vote up his answer if it's working. It didn't for me though. 

var oldPageId = 5;
var newPageId = 20;	
foreach (var reference in referenceList)
{
	var content = _repository.Get<IContent>(reference.OwnerID);
	var original = _repository.Get(reference.OwnerID, reference.OwnerLanguage);
	var clone = (ContentData)original.CreateWritableClone();
	var oldLink = _repository.Get<PageData>(new ContentReference((oldPageId)))).LinkURL;
        var replaceLink = _repository.Get<PageData>(new ContentReference(newPageId)).LinkURL;
	foreach (var property in content.Property)
	{
		var prop = property.Name;
		if (typeof(ContentReference) == type && (ContentReference)original[prop] == new ContentReference(oldPageId))
		{
			clone[prop] = new ContentReference(newPageId);
		}
		else if (typeof(PageReference) == type && (PageReference)original[prop] == new PageReference(oldPageId))
		{
			clone[prop] = new PageReference(newPageId);
		}
		else if (typeof(XhtmlString) == type && ((XhtmlString)original[prop]).ToHtmlString().Contains(oldLink))
		{
			var html = ((XhtmlString)original[prop]).ToHtmlString().Replace(oldLink, replaceLink);
			(XhtmlString)clone[prop] = html;
		}
	}
	var saveAction = SaveAction.CheckIn | SaveAction.Publish | SaveAction.ForceNewVersion;
	_repository.Save((IContent)clone, saveAction, AccessLevel.NoAccess);
}
#196986
Edited, Sep 19, 2018 9:04
Vote:
 

Thank you Goran. Your solution works like a charm. The problem with references still found after update remains. I checked the other thread and none of them are working for me.

#197002
Sep 19, 2018 12:15
Vote:
 

Awesome! :) 

It might be a bug in Episerver 11. Make sure to follow the other thread. I will update it when I have new findings. :)

#197003
Sep 19, 2018 12:18
Vote:
 

I made it work with some guidance from Johan here: https://world.episerver.com/forum/developer-forum/-Episerver-75-CMS/Thread-Container/2018/9/publishing-from-code-doesn39t-update-references/. And you can also mark my reply as Answer. :)

#197021
Edited, Sep 19, 2018 14:51
Vote:
 

Hey Goran. I just found out a bug here. When the page you want to migrate from has a shortcut set, the LinkURL returned by episerver will be the link of the page that is redirected to. This means that no xhtml content will be updated.

Also, i found out that the internal link used by episerver to set the references is actually based on the Guid of the PageData. So, i was able to create this small workaround

oldLink = "/link/" + sourcePage.ContentGuid.ToString().Replace("-", "") + ".aspx";
replaceLink = "/link/" + targetPage.ContentGuid.ToString().Replace("-", "") + ".aspx";

This way, the oldLink will be the link used in xhtml to reference the shortcut page, not the link of the shortcut target.

Here is what I had before:

No shortcut set: /link/4ca5846ddb63408a9715db78932790de.aspx

Shortcut set: /link/5c99680f22e9491cbb4492260ba3bc28.aspx

#197196
Sep 26, 2018 8:27
Vote:
 

Thanks Alex! That is indeed better, to handle the shortcuts as well. Good job! :)

#197198
Sep 26, 2018 8:45
Vote:
 

Hi Loic!

Like the code shows you must iterate over all properties and check each one. 

foreach (var property in content.Property)
#197199
Sep 26, 2018 8:47
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.