Someone moved to another job, how would you search and replace a property on all pages it ocurrs? Find all pages where property "ContactPerson" equals "Person A", replace it with "Person B".
Create a usercontrol that finds nodes of the DocumentType in question, cycle through all of them and replace the text when needed:
Quick and dirty way would be
using System;
using umbraco;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
namespace GlobalConnect.usercontrols.umbraco
{
public partial class ChangeProperty : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
var type = DocumentType.GetByAlias("AliasOfDoctype");
var docIds = Document.getAllUniqueNodeIdsFromObjectType(type);
foreach (var docId in docIds)
{
var doc = new Document(docId);
if (doc.getProperty("ContactPerson").Value == "Person A")
{
doc.getProperty("ContactPerson").Value = "Person B";
doc.Publish(Page.User as User);
library.UpdateDocumentCache(docId);
}
}
}
}
}
Warning this has not been tested, use at own risk.
You might want to make this a two-step proces: first get the documents that would be altered with the code, and print out the nodenames, and the property value in a repeater or something like that.
Then have a button below that executes the code above when clicked.
Forgot to mention that this usercontrol is designed to be used through the Umbraco backend. Set it op in a dashboard tab through the dashboard.config file.
My bad - I looked at an old more general example - I tested the following code, so it should work better. It only loads the list of id's, but you can probably merge it with code from my first post to make it work.
I went this way, a vb-function in xlst. There is a preview-parameter (doChange=false), it searches nodeFactory nodes, so unpublished ones will not be changed. I use more than one document type with the same property alias, so I loop through all docs:
Public Function searchAndReplacePropertyValue(ByVal nodeId As Integer, ByVal searchForDatatypeAlias As String, ByVal searchForValue As String, ByVal replaceWithValue As String, ByVal doReplace As Boolean) As String
Dim myNode = New Node(nodeId)
Dim resultHtml As New Text.StringBuilder
If myNode.Children.Count > 0 Then
resultHtml.Append("<ul>")
For Each thisNode As Node In myNode.Children
Dim replaceValue As Boolean = False
If Not (thisNode.GetProperty(searchForDatatypeAlias) Is Nothing) Then
If thisNode.GetProperty(searchForDatatypeAlias).Value = searchForValue Then replaceValue = True
If replaceValue Then
resultHtml.Append("<li style='color:red;'>")
Else
resultHtml.Append("<li style='color:black;'>")
End If
resultHtml.Append("<strong>")
resultHtml.Append(thisNode.Name)
resultHtml.Append("</strong>")
resultHtml.Append(" : ")
resultHtml.Append(thisNode.GetProperty(searchForDatatypeAlias).Value)
If replaceValue And doReplace Then
Dim thisDocument As New Document(thisNode.id)
thisDocument.getProperty(searchForDatatypeAlias).Value = replaceWithValue
thisDocument.Publish(thisDocument.User)
umbraco.library.PublishSingleNode(thisDocument.id)
End If
End If
If thisNode.Children.Count > 0 Then resultHtml.Append(searchAndReplacePropertyValue(thisNode.Id, searchForDatatypeAlias, searchForValue, replaceWithValue, doReplace))
resultHtml.Append("</li>")
Next thisNode
resultHtml.Append("</ul>")
End If
Return resultHtml.ToString()
End Function
We had to do this for a client once, but instead of replacing a value in a specific property, it was across multiple (text) fields. So we did this real quick-n-dirty script ... direct on the SQL Server (2005) database 'cmsPropertyData' table:
--BEGIN TRAN;
DECLARE @rootNodeId NVARCHAR(50);
SET @rootNodeId = '1050';
DECLARE @search NVARCHAR(50);
SET @search = 'Person A';
DECLARE @replace NVARCHAR(50);
SET @replace = 'Person B';
UPDATE
cmsPropertyData
SET
dataNvarchar = REPLACE(dataNvarchar, @search, @replace),
dataNtext = CAST(REPLACE(CAST(dataNtext as NVARCHAR(4000)), @search, @replace) AS NTEXT)
FROM
cmsPropertyData AS d
INNER JOIN umbracoNode AS n ON n.id = d.contentNodeId
WHERE
n.path LIKE ('-1,%' + @rootNodeId + '%')
AND
(
d.dataNvarchar LIKE ('%' + @search + '%')
OR
d.dataNtext LIKE ('%' + @search + '%')
)
;
--ROLLBACK TRAN
This applies to all property data - regardless of where it was used; doc-types, media-types, etc.
After running this script, we had to republish all the content pages. Job done ... not very pretty, (it was a desperate measure!)
Search and replace property value
Hi!
Someone moved to another job, how would you search and replace a property on all pages it ocurrs? Find all pages where property "ContactPerson" equals "Person A", replace it with "Person B".
Regards
Create a usercontrol that finds nodes of the DocumentType in question, cycle through all of them and replace the text when needed:
Quick and dirty way would be
Warning this has not been tested, use at own risk.
You might want to make this a two-step proces: first get the documents that would be altered with the code, and print out the nodenames, and the property value in a repeater or something like that.
Then have a button below that executes the code above when clicked.
Regards
Jesper Hauge
Forgot to mention that this usercontrol is designed to be used through the Umbraco backend. Set it op in a dashboard tab through the dashboard.config file.
.Jesper
Cool! Seems perfectly what I want, I'll test asap, and get back. Thanks alot! I think I will publish with doc.User though, if that is possible.
DocumentType.GetByAlias("AliasOfDoctype"); and var docIds = Document.getAllUniqueNodeIdsFromObjectType(type); was new too me.
Testing, wondering why I cannot get my array of nodeid\s, this always becomes zero
My bad - I looked at an old more general example - I tested the following code, so it should work better. It only loads the list of id's, but you can probably merge it with code from my first post to make it work.
ascx file:
Codebehind:
Thanks Jesper, getContentOfContentType is da funk. :-)
I went this way, a vb-function in xlst. There is a preview-parameter (doChange=false), it searches nodeFactory nodes, so unpublished ones will not be changed. I use more than one document type with the same property alias, so I loop through all docs:
Public Function searchAndReplacePropertyValue(ByVal nodeId As Integer, ByVal searchForDatatypeAlias As String, ByVal searchForValue As String, ByVal replaceWithValue As String, ByVal doReplace As Boolean) As String Dim myNode = New Node(nodeId) Dim resultHtml As New Text.StringBuilder If myNode.Children.Count > 0 Then resultHtml.Append("<ul>") For Each thisNode As Node In myNode.Children Dim replaceValue As Boolean = False If Not (thisNode.GetProperty(searchForDatatypeAlias) Is Nothing) Then If thisNode.GetProperty(searchForDatatypeAlias).Value = searchForValue Then replaceValue = True If replaceValue Then resultHtml.Append("<li style='color:red;'>") Else resultHtml.Append("<li style='color:black;'>") End If resultHtml.Append("<strong>") resultHtml.Append(thisNode.Name) resultHtml.Append("</strong>") resultHtml.Append(" : ") resultHtml.Append(thisNode.GetProperty(searchForDatatypeAlias).Value) If replaceValue And doReplace Then Dim thisDocument As New Document(thisNode.id) thisDocument.getProperty(searchForDatatypeAlias).Value = replaceWithValue thisDocument.Publish(thisDocument.User) umbraco.library.PublishSingleNode(thisDocument.id) End If End If If thisNode.Children.Count > 0 Then resultHtml.Append(searchAndReplacePropertyValue(thisNode.Id, searchForDatatypeAlias, searchForValue, replaceWithValue, doReplace)) resultHtml.Append("</li>") Next thisNode resultHtml.Append("</ul>") End If Return resultHtml.ToString() End Function
We had to do this for a client once, but instead of replacing a value in a specific property, it was across multiple (text) fields. So we did this real quick-n-dirty script ... direct on the SQL Server (2005) database 'cmsPropertyData' table:
This applies to all property data - regardless of where it was used; doc-types, media-types, etc.
After running this script, we had to republish all the content pages. Job done ... not very pretty, (it was a desperate measure!)
Just wanted to show off an alternative approach.
Cheers, Lee.
Just ran this script and truncated over 700 of my articles to the first 4000 characters. This should use nvarchar(max)!
Awesome bit of SQL, going into my snippets folder - thanks
Hi All,
An old thread but relevant to my current problem.
I have a site with circa 1100 nodes of content. The document types are quite indepth and contain many property types.
A change in terminology has meant that several values that are selected via Drop Down lists need to be updated across the board.
I've done some pretty hairy SQL stuff directly against the cmsPropertyData in the past but that is not something I want to repeat.
First question: is anyone aware if there any packages / tools out there that can carry out this kind of change? Have not been lucky so far.
If not, then a user control of some sort (as per this thread) is probably the way to go.
Confession: I have no experience of user controls - I've had a go with XSL and Razor but never delved into .NET.
I am not even sure if it is possible to use Razor to update values in the Database?
Many thanks, Ben
is working on a reply...