3

I am trying to add some code (after an item is created - but that is not relevant) that manipulates the layout fields. To be precise, I want to change the datasource of some renderings (based on a few criteria). My problem is that I would like to do this for both shared and final layout.

My code for the shared layout is working. It is based on var layout = LayoutDefinition.Parse(item[Sitecore.FieldIDs.LayoutField]); which gives me the LayoutDefinition. I can loop over all devices, all renderings and change the datasources. When something changed, I edit the item and overwrite the layout field with the new value that I get with layout.ToXml().

So I thought/hoped I could do the same with the Sitecore.FieldIDs.FinalLayoutField. But that seems not the case. When parsed, the LayoutDefinition from the final layout field is quite different from the actual value. Does anyone have an idea why? And how I can get around this?

ps: I did consider using the actual xml value and parsing it, but that does seem like such an ugly solution..

Edit: the actual values I'm working with:

  • Raw value of final rendering:
<r xmlns:p="p" xmlns:s="s" p:p="1"><d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}">
  <r uid="{9B197064-13D1-4BB6-AD47-2F770696404E}" p:after="r[@uid='{A6059F4C-2B62-4640-8723-BA7C87AA13D1}']" s:ds="{A419D90D-2315-4096-BECE-67AB3CDF6566}" s:id="{00160D4B-055D-4C4F-B8F1-D4E55B072294}" s:ph="/main/content2{b1ff55e7-8288-45c0-9994-f7eec00d56fc}" />
  <r uid="{6DD5BA3B-73E1-4F7A-A0EF-F2FB45F3A79F}" s:ds="{A419D90D-2315-4096-BECE-67AB3CDF6566}" s:par="" />
</d></r>
  • Value of item[Sitecore.FieldIDs.FinalLayoutField]:
<r xmlns:p=\"p\" xmlns:s=\"s\" p:p=\"1\"><d id=\"{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}\">
  <r uid=\"{9B197064-13D1-4BB6-AD47-2F770696404E}\" p:after=\"r[@uid='{A6059F4C-2B62-4640-8723-BA7C87AA13D1}']\" s:ds=\"{A419D90D-2315-4096-BECE-67AB3CDF6566}\" s:id=\"{00160D4B-055D-4C4F-B8F1-D4E55B072294}\" s:ph=\"/main/content2{b1ff55e7-8288-45c0-9994-f7eec00d56fc}\" />
  <r uid=\"{6DD5BA3B-73E1-4F7A-A0EF-F2FB45F3A79F}\" s:ds=\"{A419D90D-2315-4096-BECE-67AB3CDF6566}\" s:par=\"\" />
</d></r>

Which seems to match my raw value...

  • Value of LayoutDefinition.Parse(item[Sitecore.FieldIDs.FinalLayoutField]):
<r xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"  p:p=\"1\" xmlns:p=\"p\"><d id=\"{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}\" /></r>

Where are my renderings??

5
  • Did you check shared layout & final layout in raw value ? Hope you may be aware that whenever there is no changes in final layout, it would look empty in raw values. In this case both would differ AFAIK :) Feb 21, 2017 at 17:41
  • 1
    My final layout has a value (checked in raw) with the rendering and datasource I had set. When parsed into a LayoutDefinition it looks different from the raw value.
    – Gatogordo
    Feb 21, 2017 at 17:44
  • did you try this ? string ly = Sitecore.Data.Fields.LayoutField.GetFieldValue(item.Fields["__Renderings"]); LayoutDefinition layout = LayoutDefinition.Parse(ly); Feb 22, 2017 at 10:06
  • @BalajiKuppuswamy I think the _renderings field is not for the final layout. I can't merge the layouts as I need to write the info back into the field after changing it..
    – Gatogordo
    Feb 22, 2017 at 13:22
  • LayoutDefinition.Parse is meant to parse well-formed rendering XML, not delta. It won't know what to do with attributes like s:ds and s:id. Therefore it discards these elements. I think you'll have to work with the XML as you stated, and consider that the datasource can be in both a ds and a s:ds attribute.
    – maz
    Mar 27, 2017 at 14:35

2 Answers 2

1

Think your problem occurs because of how the layout API works https://doc.sitecore.net/sitecore_experience_platform/developing/developing_with_sitecore/versioned_layouts/the_versioned_layout_api_changes

From the article:

Prior to Sitecore 8, the public static string GetFieldValue([NotNull] Field field) method only returned layout data from the shared __Renderings field. In Sitecore 8 and later, this method can return layout data either from the shared __Renderings field or from the versioned __Final Renderings field.

The method does not return the raw value of the field. It uses the layout patching workflow to calculate the resulting layout, and it returns this layout.

This goes both for the "getter" and "setter" and also impacts on the constructor.

Not sure if this completly covers your issue, but it is definitely where you should start.

0

Final Renderings field is a delta from the Shared renderings. This article https://www.cognifide.com/our-blogs/sitecore/complex-layouts-in-sitecore-using-standard-values-hierarchy/ includes code that works with the deltas.

This isn't a 100% match for your particular problem, but it shows the mechanics that I think match your solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.