U4-1274 - Umbraco.Field not replacing localLink when a IPublishedContent is passed as first param

Created by Matt Brailsford 28 Nov 2012, 11:13:56 Updated by Sebastiaan Janssen 14 Dec 2012, 12:15:01

Relates to: U4-1304

There seems to be a bug wherby whenever an IPublisgedContent node is passes into Umbraco.Field, any properties with rte content and links using the localLink format do not get replaced when rendering.

As an interim solution, I am having to do the following:

@(new HtmlString(TemplateUtilities.ParseInternalLinks(Umbraco.Field(Model.WidgetContent, "bodyText").ToString())))

But we should probably figure out why it's no replacing and make sure it does.

Matt

Comments

Shannon Deminick 08 Dec 2012, 22:20:47

This definitely seems strange because the .Field method actually uses the old legacy webforms umbraco:item method which should automatically parse the links. I've actually got a comment in there :) //because we are rendering the output through the legacy Item (webforms) stuff, the will already be replaced.

I'm not sure I'll have time to fix this in 6.0 so if you have time, it'd be ace to see if you can see why this isn't happening already.


Matt Brailsford 09 Dec 2012, 09:43:03

Ok, I know where the problem lies. In ItemRenderer.GetFieldContents, if you haven't set a NodeId (ie, you're accessing a property on currentPage) it uses the item.PageElements collection. This collection is populated via the umbraco.page class which uses the constructor with the PublishedContentRequest property. Therefore, the PageElements collection is populated using the actual IPublishedContent itself, which it is the Value accessor on XmlPublishedContentProperty which is currently replacing the internal links.

Now, if you pass in a NodeId, ItemRenderer does something different in GetFieldContent. It creates a page for the passed in node id so that it can grab all its fields, however this time, it uses the constructor which accepts an XmlNode, with the content for it coming from the Xml cache. So the problem is, because it's coming from the Xml cache, it hasn't yet had it's values parsed like it would have if it had been constructed using an PublishedContentRequest.

There are a couple of options then.

  1. Update GetFieldContent to construct an PublishedContentRequest and construct the page using that.
  2. Update page.populateElementData line 299 to parse internal links before populating the page.Elements collection.
  3. Something else?

I'd go ahead and fix it, but I'd like to get your feedback on what you think is the best option, as I'm aware I don't know exactly what uses all these methods, so I don't want to go changing it to find out something expects the data in the way it is currently.

Let me know what you think.

Matt


Shannon Deminick 14 Dec 2012, 05:44:34

@Matt, to fix this I created a new overload for the page to accept an IPublishedContent (since we're not dealing with a PublishedContentRequest at this point, just the doc). Then instead of looking up the item in xml, we just use the PublishedContentStoreResolver to get the published content item by id and ctor a 'page' object with that.

I also fixed the recursive bug http://issues.umbraco.org/issue/U4-1304 which took more effort but is much nicer now and works plus we have a handy new extension method on IPublishedContent = GetRecursiveValue(fieldName)

Essentially we need to replace nearly all calls of retrieving Items from the xml cache with getting the items from the Content store, i think there's a task for that somewhere.

Any chance you can test this build for both webforms and mvc ? Seems to work on my machine but need someone else to check


Priority: Normal

Type: Bug

State: Fixed

Assignee: Shannon Deminick

Difficulty: Normal

Category:

Backwards Compatible: False

Fix Submitted:

Affected versions: 4.10.0

Due in version: 6.0.0

Sprint:

Story Points:

Cycle: