You can implemente functionality for remove unused properties.
Hope this blog will help...
https://world.optimizely.com/blogs/sanjay-katiyar/dates/2022/10/delete-unused-properties-and-content-types-in-cms-12/
Since other changes in the types are migrations, and MigrationSteps run on the app starting, this is what I do. This is for CMS 11 and below so some things might need change.
public class MigrationsYYYYMMDD : MigrationStep {
public override void AddChanges() {
DeleteProperties(typeof(WhateverPage), "Someproperty");
}
private void DeleteProperties(Type contentType, params string[] propertyNames) {
var contentTypeModel = ServiceLocator.Current.GetInstance<IContentTypeRepository>().Load(contentType);
var propertyDefinitions = contentTypeModel.PropertyDefinitions.Where(x => propertyNames.Contains(x.Name));
IPropertyDefinitionRepository propertyDefinitionRepository = null;
foreach (var propertyDefinition in propertyDefinitions) {
propertyDefinitionRepository = propertyDefinitionRepository ?? ServiceLocator.Current.GetInstance<IPropertyDefinitionRepository>();
try {
propertyDefinitionRepository.Delete(propertyDefinition.CreateWritableClone());
}
// ReSharper disable once EmptyGeneralCatchClause
// We don't care if it doesn't work, but we don't want to make the site go down, so just ignore errors here.
catch (Exception) {
}
}
}
}
Since it's a bit hard to keep track of what you deleted I have a report that runs the following code and then I copy/paste from this report into a code file and verify that all looks good. I don't think it's a good idea to automate the deletion completely since that might remove data you want to keep and there is no going back except restoring backups, and that has it's own problems. (This is for CMS 11, so might need modifications.)
var buffer = new StringBuilder();
var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
buffer.AppendLine(@"<pre>
public class Migrations" + DateTime.UtcNow.ToString("yyyyMMddhhmm") + @" : MigrationStep {
public override void AddChanges() {");
foreach (var contentType in contentTypeRepository.List()) {
if(contentType.ModelType == null) continue;
foreach (var propertyDefinition in contentType.PropertyDefinitions) {
// ExistsOnModel lies some times for unkonwn reasons... if(propertyDefinition.ExistsOnModel) continue;
if(contentType.ModelType.GetProperty(propertyDefinition.Name) != null) continue;
buffer.AppendLine($" DeleteProperties(typeof({contentType.Name}), \"{propertyDefinition.Name}\");");
}
}
buffer.AppendLine(@" }
private void DeleteProperties(Type contentType, params string[] propertyNames) {
var contentTypeModel = ServiceLocator.Current.GetInstance<IContentTypeRepository>().Load(contentType);
var propertyDefinitions = contentTypeModel.PropertyDefinitions.Where(x => propertyNames.Contains(x.Name));
IPropertyDefinitionRepository propertyDefinitionRepository = null;
foreach (var propertyDefinition in propertyDefinitions) {
propertyDefinitionRepository = propertyDefinitionRepository ?? ServiceLocator.Current.GetInstance<IPropertyDefinitionRepository>();
try {
propertyDefinitionRepository.Delete(propertyDefinition.CreateWritableClone());
}
// ReSharper disable once EmptyGeneralCatchClause
// We don't care if it doesn't work, but we don't want to make the site go down, so just ignore errors here.
catch (Exception) {
}
}
}
}</pre>");
Hi ZZ
Since the content type manager can do that, you can script it, too. For instance on a protected page or as a scheduled job.
It could do something like this:
Test this well with a backup before doing this in production (or even in test). Just in case it deletes too much.
Thanks for the input. I also need to find out the block / page name out of the content id, so I can show in the message which blocks / pages properties were part of that are deleted
var contentTypeName = _contentRepository.Get<BlockData>(new ContentReference(property.ContentTypeID));
This code line is throwing an error that content not found
I can see that the function also deletes some properties from EpiServer.Forms. How to only delete pages / blocks that are developed by us and not properties that are build into EpIServer
After executing the fucntion it also deletes the block properties which I never created
Name='Forms_ExternalSystemsFieldMappings', id='7889', ContentType='1298'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7882', ContentType='1297'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7878', ContentType='1290'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7887', ContentType='1281'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7888', ContentType='1282'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7886', ContentType='1280'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7880', ContentType='1293'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7884', ContentType='1299'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7881', ContentType='1295'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7876', ContentType='1287'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7877', ContentType='1289'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7879', ContentType='1292'), Result(TypeName='Property Field Mapping Collection', Name='Forms_ExternalSystemsFieldMappings', id='7885', ContentType='1300'), Result(TypeName='Message Template',
Hi,
Is there any way to delete page/block properties from CMS that doesn't exsist in the code anymore ?
I know you can delete it one by one from admin menu, but is there any plugin or otherway to delete all the properties that doesn't exsist in the code