6

I have a controller rendering which is referenced by the standard values on most of my page templates and I need to substitute it everywhere it is used to use a different controller rendering instead.

I want to do this in a safe way without deleting the item. I know I could delete it and then use the Sitecore out of the box 'linke to another item' option that is given in the popup when confirming the delete. However I want to keep my existing item for the time being.

I have seen posts such as this: https://community.sitecore.net/technical_blogs/b/sitecorejohn_blog/posts/programmatically-update-layout-details-with-the-sitecore-asp-net-cms

But I wondered if there is an easier/better/safer way to do this.

Also I know I need to consider both the Renderings and Final renderings fields as I using Sitecore 8.1 update 2.

-- Update --

Additional information is that the rendering in question is synced with Unicorn to Staging and Prod so the solution here needs to account for this item existing in other environments. Ideally I'd do it once locally and unicorn would track the changes and push the change out to Staging and Production. One issue though is that we don't have all content locally and we don't sync content with unicorn (just templates, layouts etc).

  • You can just update the rendering to have a different name and point to a different file. All references are by ID, so as long as the parameters and datasources can remain the same, it shouldn't be an issue. – zzzzBov Oct 17 '16 at 18:30
  • Thats the problem, I need to update the ID, not the name. I need to point all references to a new rendering all together. The name and controller are actually the same - or will be the same once I've replaced the rendering. – Adam Seabridge Oct 17 '16 at 19:43
  • Renderings are just items. Update the rendering item, don't create a new one. – zzzzBov Oct 17 '16 at 20:51
  • I've tried that, it's corrupt in some way as whatever I do to update the existing item it causes my controller to break. A copy of it also breaks. Same controller code in a new controller rendering works perfectly. Hence me needing to switch it out. – Adam Seabridge Oct 17 '16 at 21:31
  • "whatever I do to update the existing item it causes my controller to break" so why aren't you asking how to solve that problem? It sounds like you've got an XY problem just because you may have hit a minor error. – zzzzBov Oct 18 '16 at 0:51
6

There are OOTB options. Take a look at this answer here.

Removing all references to an item using OOTB tools

All of the proposed answers will require you to (temporarily) delete the item and rely on Sitecore's remapping tool. But you won't lose your rendering.

As far as safe goes; it's the safest way I can think of. And requires no coding.

  • Ok so essentially what your saying I need to do here is backup (serialise) my item, then delete it - use the out of the Box -> link to another item to update the references to my new item. Then re-import my item from the backup? My concern is that I need to do this on Staging and Production also and there will be additional content there that we don't have in our current development environment and I need to ensure this happens 100% for all references to this item. – Adam Seabridge Oct 17 '16 at 16:30
  • Thanks for your suggestion. I've updated my question above to explain further. – Adam Seabridge Oct 17 '16 at 16:42
  • 1
    Ok, that changes things. However I would still argue; performing this operation directly on prod is still the better option. And even if you delete the rendering in question; next deploy with Unicorn would bring it back - no harm done. – Mark Cassidy Oct 17 '16 at 17:05
  • Thanks Mark. It may be my only option to do on each environment: Export the old rendering as a package then delete it through Sitecore. Use update references option when deleting to point to the new rendering. Import old rendering back. Repeat on Staging and Production. Then when doing a Unicorn Sync on the next deployment some changes will already have gone across to Staging / Prod (updates to add reference to new rendering on standard values etc). But where the final renderings have been updated on content and reference this then doing this on Prod beforehand will update these too. Seem ok? – Adam Seabridge Oct 17 '16 at 19:48
  • Mark - although I managed to figure out a better solution and didn't need to do this I did do a POC of this approach and it worked pretty well so I've marked this as the correct answer. Thanks for your help. – Adam Seabridge Oct 19 '16 at 22:43
2

If you have to replace everything, take the existing rendering and have it point to the new controller class. Then, create a new rendering using the old controller class and make that available to use in your placeholders.

  • The problem with this is that It is the controller rendering item that is causing me problems (I suspect is is corrupted in some way). The controller code is perfectly fine as it works when I use it in a new controller rendering and I have matched all the settings up the same too and my new controller rendering works perfectly. I just need to replace all uses of it with my new one. – Adam Seabridge Oct 17 '16 at 19:34
1

You can call me crazy, but this is how I would solve this problem.

I implemented a solution for you.

Skip operations in Sitecore. If you need to sync all changes into unicorn eventually and update other environments then do your job there (on the disk not in the databse).

$OLD_RENDERING_ID = "DCEE78E1-1843-5456-A13A-F10A12191630"
$NEW_RENDERING_ID = "87182F78-4399-5896-8D59-9D6A45282F8A"

$SERIALIZATION_FOLDER = "c:\your\serialization\"

function Replace-Rendering($item){
    Write-Host $item
    $oldValue = [System.IO.File]::ReadAllText($_.FullName)
    $newValue = $oldValue  -replace $OLD_RENDERING_ID,$NEW_RENDERING_ID
    [System.IO.File]::WriteAllText($item.FullName, $newValue)
}

gci -Path $SERIALIZATION_FOLDER -r |
    ? { $_.Extension -eq ".yml" } |
    ? { [System.IO.File]::ReadAllText($_.FullName).Contains($OLD_RENDERING_ID) -eq $true } |
    % { Replace-Rendering $_ }

Pros:

  • You don't have to remove old rendering
  • You don't need to care about missing item references in link database if you are using Sitecore relink solution
  • You have got full control. You can see immediately what and where is changed before you change anything in database (dirty state is not in database)

Note:

My code is not bullet proof. It will probably change the ID on the old Rendering item as well, you can revert changes manually.

I wanted to keep solution as clean as possible thus I skipped unnecessary if/else.

  • thanks for taking the time to write up a solution for this. This would be a great option if all my content were also in Unicorn. However unfortunately there are thousands of pages that are not in our local development environment or staging but are in production so I don't think this is going to work for us unless I'm missing something. – Adam Seabridge Oct 17 '16 at 19:33
  • In the first sentence of your questions there is info about templates standard values only. You wrote about content later. Assuming that you are not changing rendering fields on content items (field values are taken from standard values) then my solution should work, otherwise not. I assume you do't have unicorn on prod. env? My second options would be PowerShell script for SPE, if this is also not installed on your instance then the last resort is to write c# script and run it from some aspx page, however there will be much more to do in terms of handling StandardValues, Renderings fields – Alan Płócieniak Oct 17 '16 at 19:52
  • Yes, sorry I did update my question later to include further information. We do do a unicorn sync to staging and to prod from dev. However we exclude everything below the /Content node. So I think this is going to be a lot more difficult than just using Unicorn unfortunately. Marks solution above might work for me or as you say SPE. I'm nervous about doing either of these though I've not used SPE much and this rendering is on every page in my solution and I need to ensure all instances of it are replaced. Performance/Timeouts during the update might be a problem too. – Adam Seabridge Oct 17 '16 at 19:59
  • Then what do you think about making content freeze. Creating new config for unicorn (for content node) and then running my script on files and pulling serialized content back to Sitecore? Maybe there won't be that much to pull back if you are using Standard Values? So you can for example sync single items (you can create temporary git repository there to see what changed). I am not sure how unicorn syncing influence on performance, so you would need to check this on staging first. Perhaps this solution would make you more comfortable than using SPE. – Alan Płócieniak Oct 17 '16 at 20:11
  • Yeah thats not a bad shout. I might pull a backup of the DB down tomorrow and try that and see what I get synced. – Adam Seabridge Oct 17 '16 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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