If you want to bulk manipulate by moving content from one language to another, SCORE comes with a language manipulation feature that can help. On the flip side, if you want to remove languages from your system, you can use PowerShell to automate this.
Imagine that our site is currently in English with an en version. We have been working that way for awhile and everything has been smooth – but now Marketing has decided they want to branch content out for all of North America. For this, we want to duplicate all of our content from en to en-US, en-CA, fr-CA, es-MX, etc. This also can provide us with the nifty benefit of having language locales in our URL if we choose to do so.
In this example, I will move content from the en language to the en-US language for my tenant and then remove the en content.
Part I – Pre-conditions for Language Manipulation
First, I am going to make sure that enableItemLanguageFallback
is disabled for my site. This setting is found on the site definition. You should either explicitly set this value to false, or you should remove the attribute from your site configuration.
Additionally, I need to make sure that my target language exists in Sitecore. Languages are managed at /sitecore/system/Languages
. Here I can add the predefined en-US localization.
Finally, I need to make sure that my target language does not have a fallback language selected. In this case, I navigate to /sitecore/system/Languages/en-US
and make sure that Fallback Language
does not have a value.
Keep in mind that you could enable Item Language Fallback if you wanted but, in my case, I do not want that behavior.
Part II – Migrate Content
For this step, I will start by selecting my tenant root in the Content Editor. My tenant lives at /sitecore/content/BrainJuice/BrainJuice Market Sites/US
.
From here, I make sure that I’m in the origin language (en), and I select Versions > Language > Tools.
When I open this dialog, I’ll be prompted to either create empty language versions or to create language versions and copy content. If I choose the second option, content will be copied from the current language into the target language that I select. In my case, I want to copy all content from en to en-US, and I want to include all datasources and subitems. This process should take around five minutes, depending on how large my site is and if any content already exists in the target language.
Additionally, we will need to migrate our media in the Media Library as well. The Alt
field is not shared across languages.
Part III – Migrate Templates
Since we store datasources under template standard values, we need to convert these datasources to en-US as well. To do this, I follow the same steps as above but I do it from these locations:
/sitecore/templates/BrainJuice Markets/Pages
/sitecore/templates/Branches/BrainJuice Markets
Part IV – Remove Old Language
Now that we have our templates and content in the new language, we can remove the old language from our content. For this step, I use Sitecore PowerShell Extensions. After installing Sitecore PowerShell Extensions, open the PowerShell ISE application inside Sitecore and run a command similar to this:
Remove-ItemLanguage -Path "master:\sitecore\content\BrainJuice\BrainJuice Market Sites\US" -Language "en" -Recurse Remove-ItemLanguage -Path "master:\sitecore\media library\Images\BrainJuiceMarkets" -Language "en" -Recurse
This command may take some time depending on how large your content tree is. For me, it took around five minutes.
Part V – Validation
At this point, you should approve all items in the en-US language through workflow if you have one. After that, you should be able to publish your instance and navigate to your homepage.
Also keep in mind that you may need to clear your Sitecore cache and rebuild your search indexes.
To validate what I am viewing, I temporarily added this locally to the top of all my layouts. This is not required, but it’s something I do for my own sanity.
<div class="alert alert-info"> Current language: @Sitecore.Context.Language <br /> Current database: @Sitecore.Context.Database.Name </div>
Voilà! Thanks for reading.