I'm not sure I understand your requirement, it is essentially to only allow blocks to be created from the "create a new block" link in a content area?
What I have is a scenario were I have a block that should not be availbale in the ordinary create block list. Is should only be available inside a contentarea inside another block
Lets say I have an area with
[AllowedTypes(typeof(ItemBlock))]
That ItemBlock is not something I would like to appear in the list when creating block inside the assets panel. So I add the AvailableInEditMode = false. But when I do that the block is nolonger available inside the area as well sadly.
So is there a way of creating blocks like that but hide them from the list of availbale types when working inside the assets pane?
I don't think this is possible out the box. The only approach I can think of is to use security to lock the blocks down so only certain users can create them?
David
Ah yes thought of that as well but in this case it should not be an access thingy :) would have been nice to just hide blocks from the list of availabletypes but be able to use them inside an contentarea if they were allowed by the attribute for that specific case.
Well a feature request then :)
Did anyone find a solution for this issue ? Basically you cant create blocks as property and also hide from appearing them in Edit mode
Hi Mukesh,
If I understand correctly, your scenario is slightly different to the original question. If you're using a block as a property type you can set AvailableInEditMode = false and that block will not appear in the list of available blocks when you click to create a new block but the appropriate fields will still appear on the content type using that block as a property type.
To answer the original question - my understanding is that you'd like to have a block type which can't be created directly within the blocks panel but can be created by clicking on the "create a new block" link at the bottom of a content area. If that's correct then you could create your own version of the ContentTypeAvailabilityService which checks where your block is going to be created. If it's created under a ContentFolder then we know it's being created through the asset panel otherwise it's being created via the "create a new block" link.
For reasons which I explain here I prefer to intercept the default ContentTypeAvailabilityService and add my additional functionality. The ContentTypeAvailabilityService might look something like this (though I'd probably use an attribute rather than hard code the type name):
public class CustomContentTypeAvailabilityService : ContentTypeAvailabilityService
{
private readonly ContentTypeAvailabilityService _defaultContentTypeAvailabilityService;
public CustomContentTypeAvailabilityService(ContentTypeAvailabilityService defaultContentTypeAvailabilityService)
{
_defaultContentTypeAvailabilityService = defaultContentTypeAvailabilityService;
}
public override AvailableSetting GetSetting(string contentTypeName)
{
return _defaultContentTypeAvailabilityService.GetSetting(contentTypeName);
}
public override bool IsAllowed(string parentContentTypeName, string childContentTypeName)
{
return _defaultContentTypeAvailabilityService.IsAllowed(parentContentTypeName, childContentTypeName);
}
public override IList<ContentType> ListAvailable(string contentTypeName, IPrincipal user)
{
return FilterAvailableList(_defaultContentTypeAvailabilityService.ListAvailable(contentTypeName, user), true);
}
public override IList<ContentType> ListAvailable(IContent content, bool contentFolder, IPrincipal user)
{
var isInAssetFolder = content is ContentFolder;
return FilterAvailableList(_defaultContentTypeAvailabilityService.ListAvailable(content, contentFolder, user), isInAssetFolder);
}
private IList<ContentType> FilterAvailableList(IList<ContentType> list, bool isInAssetFolder)
{
for (var i = list.Count-1; i >= 0; i--)
{
var contentType = list[i];
if (contentType.Name.Equals("MySpecialBlock") && isInAssetFolder)
{
list.RemoveAt(i);
}
}
return list;
}
}
Which could be registered during initialisation like this:
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ContentTypeAvailabilityInitialization : IConfigurableModule
{
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Services.Intercept<ContentTypeAvailabilityService>(
(locator, defaultContentTypeAvailabilityService) => new CustomContentTypeAvailabilityService(defaultContentTypeAvailabilityService));
}
public void Initialize(InitializationEngine context) { }
public void Uninitialize(InitializationEngine context) { }
}
Hope that helps.
Is it possible to hide a block from the list of avaliable types but still have it available when combined with the AllowedTypes attribute for a contentArea? Has anyone done a solution for that?