You do need a partial router, otherwise it will never work in "view mode".
I added an override for the "GetUniqueUrlSegment" mehtod and rolled my own url (wich was essentially "[externalid]-friendlyname") to get unique url segments to work with.
Then I called "GetBySegment" on my provider during the RoutePartial, which will match whatever content item have that particular urlsegment. I am also not sure what exaxtly I am supposed to do in the GetPartialVirtualPath method, I just used return null and it worked fine for me.
[ModuleDependency(typeof(Initializer))] public class JobOpeningRouter : IPartialRouter<IContent, JobOpening>, IInitializableModule { public void Initialize(InitializationEngine context) { RouteTable.Routes.RegisterPartialRouter(this); } public void Uninitialize(InitializationEngine context) { } public void Preload(string[] parameters) { } protected Injected<JobOpeningContentProvider> JobContentProvider { get; set; } public object RoutePartial(IContent content, SegmentContext segmentContext) { try { if(content.ContentLink.CompareToIgnoreWorkID(JobContentProvider.Service.EntryPoint)) { var segment = segmentContext.GetNextValue(segmentContext.RemainingPath); return JobContentProvider.Service.GetBySegment(content.ContentLink, segment.Next, null); } } catch(NullReferenceException) { // JobContentProvider.Service.EntryPoint sometimes throw a nullreferenceexception in certain contexts (like block edit mode..) } return content; } public PartialRouteData GetPartialVirtualPath(JobOpening content, string language, RouteValueDictionary routeValues, RequestContext requestContext) { // this is already handled by epi return null; } }
Hey Sebbe!
It seems that you need to activate ClassicLinkRoute i global asax, No need for IPartialRouter
protected override void RegisterRoutes(RouteCollection routes) { base.RegisterRoutes(routes); routes.Insert(0, ServiceLocator.Current.GetInstance<ClassicLinkRoute>()); }
Great Luc! Can't believe I haven't stumbled across that while searching for solutions to the problem!
Hi Sebbe, THANK YOU! Your pointing out of the need to override ListMatchingSegments just stopped me banging my head against the wall:)
Here is my method for that, similar to yours buut avoids the need to override LoadChildren:
protected override IList<MatchingSegmentResult> ListMatchingSegments(ContentReference parentLink, string urlSegment) { var list = new List<MatchingSegmentResult>(); bool languageSpecific; var children = LoadChildrenReferencesAndTypes(parentLink, null, out languageSpecific); foreach(var child in children) { var content = LoadContent(child.ContentLink, null); if(content is IRoutable && (content as IRoutable).RouteSegment.Equals(urlSegment, StringComparison.InvariantCultureIgnoreCase)) { list.Add(new MatchingSegmentResult() { ContentLink = content.ContentLink }); } } return list; }
Great Dan, ContentProviders can be tricky to get setup right, so i've put together a series of blog posts about it. http://devblog.gosso.se/tag/contentprovider/
Hi!
The support asked me to post a question here to check if anyone else experienced the same problem. I have been working on converting PageProviders to ContentProviders in an upgrade of a site from 6 R2 to 7.19.
The aim of the provider is to mirror content (pages) from one site to another (Holmen to Iggesund). The sites share the same code base and EPiServer-instance. The mirrored pages should be of a different pagetype than the original pages. I have looked at the implementation of the Youtube provider so the code should be quite similar to that: https://github.com/episerver/YouTubeContentProvider. I have gotten so far so that everything works like a charm in edit mode, but for some reason the routing is not working on the site. When browsing to the respective pages I first got a 404. I added an override of the method ListMatchingSegments(). As far as I can see that method now returns the correct content, but instead of the page being displayed I get a 301 redirect loop:
When I browse to http://localhost/en/Global/Press-Startpage/Mirrored-News-from-Holmen/holmen-and-sustainability
I get the response:
Object moved to here.
"holmen-and-sustainability" is the name of the page in this case (which I would like to use as routing segment). "?id=21__newsip&epslanguage=en" is added to the redirect url and I suspect that the ContentProvider once again tries to resolve the content after the redirect and the loop is a fact.
I also tried regestering a partial router, but that code doesn't trigger when I have the ListMatchingSegments() method in the ContentProvider.
Grateful for any help!
/Sebbe
Here is the ContentProvider: