Wednesday, 24 September 2014

Delete Language Branch from all pages and site in EPiServer

Suppose you have large content (e.g. 3000 pages) in your EPiServer CMS project, supporting multiple languages e.g. English (en), French (fr) and Italian (it). Pages might be created using different page types.
You want to delete a language branch e.g. French (fr) from all pages where it’s used and from the website. You don’t know exactly how many pages use French (fr) language.

One problem you will usually encounter is when you simply want to delete the language branch from all pages at once to go page by page and then delete it. You try to delete language branch from Admin>Config>Manage Website Languages, and end up getting the following error

“The language is used in language settings on the following pages and cannot be deleted: Root [1], Home [3]...”



Solution:

In the above case you have to go through all pages and remove French language branch using Version Gadget in EPiServer 7, and this process will take forever if CMS is contains many pages. In a nutshell it is not possible to achieve the above mentioned task at least in the UI to delete all pages of a specific language branch at once. So you have to write a small job in EPiServer to loop through your pages, and delete that specific language branch.
There are "delete language" methods in both the EPiServer.DataFactory and EPiServer.DataAbstraction.ContentStore namespaces. These methods take a PageReference or ContentReference as parameter. It means they will only delete the language for the specified page, and not all pages in the content tree.

E.g. EPiServer.DataFactory.DeleteLanguageBranch: http://world.episerver.com/Documentation/Class-library/?documentId=cms/7/c8ac5c2b-ff67-869d-e6f3-8703e864f387
EPiServer.DataAbstraction.ContentStore.DeleteLanguage:
http://world.episerver.com/Documentation/Class-library/?documentId=cms/7/0feec2ec-d9b3-39bb-4bb6-40f8f8a791d6

I hope you have got an idea from the above mentioned description, and what needs to be done. We are going to adapt the approach “divide and conqeur” to achieve our goal. Make sure to empty trash just to be on the safe side.

To start the process make sure you disable French (fr) language in root as follow




1 - Get all page types in EPiServer
2 - Get all pages using FindPagesWithCriteria Method using page types
     (published and   unpublished).
3 - Loop through all the pages from Step 2
4 - Delete the pages
5 - Create EPiServer scheduled job and wrap you the above mention logic from previous steps.
6 - Execute the job

By following the above mentioned steps we will have our code to delete that specific language branch from the pages. Keep in mind that the above approach will not work on pages whose master language is the language you want to delete. Let start our journey to get rid of French language:

Step 1. To get all page types in EPiServer you can get the code from my published post here.
Step 2. Now we have all page types in EPiServer. The next step is to get all pages against the page type using the FindPagesWithCriteria. First we need to create criteria and add the criteria to PropertyCriteriaCollection object that FindPagesWithCriteria method required. We have to get all pages from Root page. Getting pages from Home page is not recommended as there might be pages outside Home page and under Root page. In the below code PAGETYPEID is the ID of page type you get in Step 1

var criterias = new PropertyCriteriaCollection();
var criteria = new PropertyCriteria
{
Condition = CompareCondition.Equal,
Name = "PageTypeID",
Type = PropertyDataType.PageType,
Value = PAGETYPEID,
Required = true
};
criterias.Add(criteria);
var pageItems = DataFactory.Instance.FindPagesWithCriteria(PageReference.RootPage, criterias, "fr");

pageItems object contains all the pages against the relevant page type with language branch French (“fr”)

Step 3 & 4. We are going to loop through all the items in pageItems object from step 2 and delete them. As I mentioned earlier, you cannot delete the pages whose master language branch is the language you want to delete. So when you will try to delete these types of pages, it will throw an exception. So it is better to put your delete code in try-catch statement. We are going to use EPiServer.DataFactory.DeleteLanguageBranch method

try
{
 foreach (var pageItem in pageItems)
 {
   var datafactory = new DataFactory();
   datafactory.DeleteLanguageBranch(pageItem.PageLink, new LanguageSelector("fr").LanguageBranch, AccessLevel.Delete);
 }
}
catch (Exception)
{
}

So now we have code to delete French (fr) language from the EPiServer CMS

Step 5. To create Scheduled job in EPiServer you can get an idea/ instructions from EPiServer official FAQ post.
Once you have a code to create EPiServer scheduled job we can wrap up our code to delete language branch from pages in it the scheduled job. So in the end the full code looks something like this

[EPiServer.PlugIn.ScheduledPlugIn(
        DisplayName = "Delete French Content From Site",
        Description = "",
        SortIndex = 1)]
    public class RemoveLanguageScheduleJob
    {
        public static string Execute()
        {
            var pageTypes = PageType.List();

            var failedCount = 0;
            var successCount = 0;
            var totalPages = 0;

            var languageToDelete = new LanguageSelector("fr").LanguageBranch;

            foreach (var pageType in pageTypes)
            {

                var criterias = new PropertyCriteriaCollection();

                var criteria = new PropertyCriteria
                {
                    Condition = CompareCondition.Equal,
                    Name = "PageTypeID",
                    Type = PropertyDataType.PageType,
                    Value = pageType.ID.ToString(CultureInfo.InvariantCulture),
                    Required = true
                };
                criterias.Add(criteria);
                var pageItems = DataFactory.Instance.FindPagesWithCriteria(PageReference.RootPage, criterias,
                    languageToDelete);

                try
                {
                    foreach (var pageItem in pageItems)
                    {
                        if (pageItem.LanguageBranch == languageToDelete)
                        {
                            var datafactory = new DataFactory();
                            datafactory.DeleteLanguageBranch(pageItem.PageLink, languageToDelete, AccessLevel.Delete);
                            successCount = successCount + 1;
                        }
                        totalPages = totalPages + 1;
                    }
                }
                catch (Exception)
                {
                    totalPages = totalPages + 1;
                    failedCount = failedCount + 1;
                }
            }
            var resultMessage =
                string.Format(" Total Pages: {0} | Successfull Deleted: {1} | Unsuccessfull Attempts: {2}", totalPages,
                    successCount, failedCount);
            return resultMessage;
        }
    }


/Adnan

About the Author

Adnan Zameer, Lead Developer at Optimizley UK, is a certified Microsoft professional, specializing in web app architecture. His expertise includes Optimizley CMS and Azure, showcasing proficiency in crafting robust and efficient solutions.

0 comments :

Post a Comment