London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!
London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!
Hi,
You could try to use FindPagesWithCriteria:
var criterias = new PropertyCriteriaCollection(); var criteria = new PropertyCriteria(); criteria.Condition = CompareCondition.Equal; criteria.Name = "PageTypeID"; criteria.Type = PropertyDataType.PageType; criteria.Value = _cotentTypeRepository.Load<RoomTypeList>().ID.ToString(); criteria.Required = true; criterias.Add(criteria); ServiceLocator.Current.GetInstance<IPageCriteriaQueryService>() .FindAllPagesWithCriteria(ContentReference.RootPage, criterias , null, LanguageSelector.AutoDetect());
I don't think FindPagesWithCriteria works with Blocks yet.
It's still a bit messy but this is what I've done:
public IEnumerable<T> GetBlocksOfType<T>() where T : BlockData { BlockType blockTypeForT = ServiceLocator.Current.GetInstance<BlockTypeRepository>().Load<T>(); IList<ContentUsage> contentUsages = ServiceLocator.Current.GetInstance<IContentModelUsage>().ListContentOfContentType(blockTypeForT); var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>(); var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>(); List<IContent> blocks = contentUsages .Select(contentUsage => contentUsage.ContentLink.ToReferenceWithoutVersion()) .Distinct() .Select(contentReference => contentLoader.Get<IContent>(contentReference)).ToList(); new FilterPublished().Filter(blocks); new FilterAccess().Filter(blocks); return blocks.OfType<T>(); new FilterPublished().Filter(iContents); new FilterAccess().Filter(iContents); return iContents.OfType<T>(); }
And simply call with
IEnumerable<TeaserBlock> content = GetBlocksOfType<TeaserBlock>();
As you notice ListContentOfContentType gives you all versions of the blocks. Hence I make a Select on ToReferenceWithoutVersion and a Distinct.
Instead of your Where on Deleted and Publish I send the content through the built in Filters in EPiServer. In my case my Blocks might not have Templates, hence I use Publish and Access but In if you have Templates/Views for your blocks as well you could simply do FilterForVisitor since it's a composite of the filters Publish, Access and Template.
Due to the proxy management of Blocks in EPiServer you need to cast back and forth between IContent and T. I prefer using OfType instead of Cast. But that might be me being paranoid.
EPiServer give a disclaimer in the xml comment at class level, but this seems to work:
var db = ServiceLocator.Current.GetInstance<EPiServer.DataAccess.Internal.ContentListDB>(); return db.ListContentOfContentType(contentType, onlyPublished);
I would NOT recommend that. Try to avoid parts of the Episerver API that is within an "internal" namespace.
EPiServer.DataAccess.Internal.ContentListDB
if a block is on a page that is unpublished, i cannot get reference to that page. Any idea ?
I may have missed the deep dive lesson on the EPiServer repository API's and figured there should be a simple way to retreive all blocks of a certain type that are published. But no, there seem to be no such thing and the other examples on this forum either perform horribly or are bad implementations that doesn't consider multiple versions, publish status and so on.
This is my routine at the moment, does anyone have any advice to make this a bit cleaner?
Thanks