Have added a Relations class on my site courtesy of the source code found following an Umbraco TV demo.
using System; using System.Collections.Generic; using System.Text;
using umbraco.BusinessLogic; using umbraco.cms.businesslogic.web; using umbraco.cms.businesslogic.relation; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic;
namespace EventSamples {
//This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start. //All events are hooked-up using the constructor public class Relations : ApplicationBase { //Constructor public Relations() { //subscribe to the afterpublish events Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish); }
/// <summary> /// Executes after document publishing /// </summary> /// <param name="sender">The sender (a documet object).</param> /// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param> void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e) { // if the parent doesn't already have been related bool hasCopy = false; if (sender.Relations.Length > 0 && sender.Level > 1) { foreach (Relation r in sender.Parent.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { hasCopy = true; break; } } }
// if the parent documentObject have a relation if (!hasCopy && sender.Level > 1) { Document parent = new Document(sender.Parent.Id); if (parent.Relations.Length > 0) { foreach (Relation r in parent.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { sender.Copy(r.Child.Id, sender.User, true); } } } }
} }
}
This class works great for my current set up where a Welsh language version of my site is created following the copying of the English Version.
What I wondered, is it possible to include within the above code a delete script to accompany what is currently being achieved e.g when an English page is deleted, any relation within the Welsh version is also deleted.
Should be doable! You need to hook into the AfterMoveToTrash event on the document. You should be able to use something like the following on the event I think (haven't tested this though!). Note, I'm not sure if this will delete it or move it to the recycle bin.
if(sender.Relations.Length>0) { foreach(Relation r in sender.Relations) { if(r.RelType.Alias=="relateDocumentOnCopy") { sender.delete(); } } }
Thanks for getting back Tim, have added in the bit of code as suggested so it now looks like this
using System; using System.Collections.Generic; using System.Text;
using umbraco.BusinessLogic; using umbraco.cms.businesslogic.web; using umbraco.cms.businesslogic.relation; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic;
namespace EventSamples {
//This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start. //All events are hooked-up using the constructor public class Relations : ApplicationBase { //Constructor public Relations() { //subscribe to the afterpublish events Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish); }
/// <summary> /// Executes after document publishing /// </summary> /// <param name="sender">The sender (a documet object).</param> /// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param> void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e) { // if the parent doesn't already have been related bool hasCopy = false; if (sender.Relations.Length > 0 && sender.Level > 1) { foreach (Relation r in sender.Parent.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { hasCopy = true; break; } } }
// if the parent documentObject have a relation if (!hasCopy && sender.Level > 1) { Document parent = new Document(sender.Parent.Id); if (parent.Relations.Length > 0) { foreach (Relation r in parent.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { sender.Copy(r.Child.Id, sender.User, true); } } } }
//Automatically Delete if (sender.Relations.Length > 0) { foreach (Relation r in sender.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { sender.delete(); } } }
} }
}
It appears now though that since adding in the deletion part that the site now acts strange.
Previously a creation in the English site would auto create an equivalent also in the Welsh site. Now however a creation in the English site gets automatically moved to the Welsh site so moves the page not duplicate.
You've got the code in the wrong place! You need to subscribe to the AfterMoveToTrash event for the delete code!
Try this code instead (I think it should work, not 100% though, as I haven't had time to test it):
using System; using System.Collections.Generic; using System.Text;
using umbraco.BusinessLogic; using umbraco.cms.businesslogic.web; using umbraco.cms.businesslogic.relation; using umbraco.cms.businesslogic.property; using umbraco.cms.businesslogic;
namespace EventSamples {
//This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start. //All events are hooked-up using the constructor public class Relations : ApplicationBase { //Constructor public Relations() { //subscribe to the afterpublish events Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish);
void Document_AfterMoveToTrash(Document sender,MoveToTrashEventArgs e) { if (sender.Relations.Length > 0) { foreach (Relation r in sender.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { r.delete(); } } } }
/// <summary> /// Executes after document publishing /// </summary> /// <param name="sender">The sender (a documet object).</param> /// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param> void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e) { // if the parent doesn't already have been related bool hasCopy = false; if (sender.Relations.Length > 0 && sender.Level > 1) { foreach (Relation r in sender.Parent.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { hasCopy = true; break; } } }
// if the parent documentObject have a relation if (!hasCopy && sender.Level > 1) { Document parent = new Document(sender.Parent.Id); if (parent.Relations.Length > 0) { foreach (Relation r in parent.Relations) { if (r.RelType.Alias == "relateDocumentOnCopy") { sender.Copy(r.Child.Id, sender.User, true); } } } } } }
Thanks Tim, the code you supplied (bar a few errors relating to capital letters which were throwing server errors) is now implementing the copy fucntion correctly as per my original code but the delete function is still not kicking in. Looks pretty close, tried a few tweaks in the hope of it working but not getting anywhere.
If you have chance to look at it again that would be great.
Hmmmmm, I think we're actually deleting the relationship rather than the actual related item. I need to dig around in the relationships API when I get in from work, I'll let you know what I find!
Relations API guru wanted
Hi,
Have added a Relations class on my site courtesy of the source code found following an Umbraco TV demo.
This class works great for my current set up where a Welsh language version of my site is created following the copying of the English Version.
What I wondered, is it possible to include within the above code a delete script to accompany what is currently being achieved e.g when an English page is deleted, any relation within the Welsh version is also deleted.
Many Thanks
Matt
Hi Matt,
Should be doable! You need to hook into the AfterMoveToTrash event on the document. You should be able to use something like the following on the event I think (haven't tested this though!). Note, I'm not sure if this will delete it or move it to the recycle bin.
Thanks for getting back Tim, have added in the bit of code as suggested so it now looks like this
using System;
using System.Collections.Generic;
using System.Text;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.relation;
using umbraco.cms.businesslogic.property;
using umbraco.cms.businesslogic;
namespace EventSamples
{
//This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start.
//All events are hooked-up using the constructor
public class Relations : ApplicationBase
{
//Constructor
public Relations()
{
//subscribe to the afterpublish events
Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish);
}
/// <summary>
/// Executes after document publishing
/// </summary>
/// <param name="sender">The sender (a documet object).</param>
/// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param>
void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
{
// if the parent doesn't already have been related
bool hasCopy = false;
if (sender.Relations.Length > 0 && sender.Level > 1)
{
foreach (Relation r in sender.Parent.Relations)
{
if (r.RelType.Alias == "relateDocumentOnCopy")
{
hasCopy = true;
break;
}
}
}
// if the parent documentObject have a relation
if (!hasCopy && sender.Level > 1)
{
Document parent = new Document(sender.Parent.Id);
if (parent.Relations.Length > 0)
{
foreach (Relation r in parent.Relations)
{
if (r.RelType.Alias == "relateDocumentOnCopy")
{
sender.Copy(r.Child.Id, sender.User, true);
}
}
}
}
//Automatically Delete
if (sender.Relations.Length > 0)
{
foreach (Relation r in sender.Relations)
{
if (r.RelType.Alias == "relateDocumentOnCopy")
{
sender.delete();
}
}
}
}
}
}
It appears now though that since adding in the deletion part that the site now acts strange.
Previously a creation in the English site would auto create an equivalent also in the Welsh site. Now however a creation in the English site gets automatically moved to the Welsh site so moves the page not duplicate.
Any ideas?
Hiya,
You've got the code in the wrong place! You need to subscribe to the AfterMoveToTrash event for the delete code!
Try this code instead (I think it should work, not 100% though, as I haven't had time to test it):
using System;
using System.Collections.Generic;
using System.Text;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.relation;
using umbraco.cms.businesslogic.property;
using umbraco.cms.businesslogic;
namespace EventSamples
{
//This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start.
//All events are hooked-up using the constructor
public class Relations : ApplicationBase
{
//Constructor
public Relations()
{
//subscribe to the afterpublish events
Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish);
Document.AfterMoveToTrash += newDocument.MoveToTrashEventHandler(Document_AfterMoveToTrash);
}
void Document_AfterMoveToTrash(Document sender,MoveToTrashEventArgs e)
{
if (sender.Relations.Length > 0)
{
foreach (Relation r in sender.Relations)
{
if (r.RelType.Alias == "relateDocumentOnCopy")
{
r.delete();
}
}
}
}
/// <summary>
/// Executes after document publishing
/// </summary>
/// <param name="sender">The sender (a documet object).</param>
/// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param>
void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
{
// if the parent doesn't already have been related
bool hasCopy = false;
if (sender.Relations.Length > 0 && sender.Level > 1)
{
foreach (Relation r in sender.Parent.Relations)
{
if (r.RelType.Alias == "relateDocumentOnCopy")
{
hasCopy = true;
break;
}
}
}
// if the parent documentObject have a relation
if (!hasCopy && sender.Level > 1)
{
Document parent = new Document(sender.Parent.Id);
if (parent.Relations.Length > 0)
{
foreach (Relation r in parent.Relations)
{
if (r.RelType.Alias == "relateDocumentOnCopy")
{
sender.Copy(r.Child.Id, sender.User, true);
}
}
}
}
}
}
}
Thanks Tim, the code you supplied (bar a few errors relating to capital letters which were throwing server errors) is now implementing the copy fucntion correctly as per my original code but the delete function is still not kicking in. Looks pretty close, tried a few tweaks in the hope of it working but not getting anywhere.
If you have chance to look at it again that would be great.
Cheers
Matt
Hmmmmm, I think we're actually deleting the relationship rather than the actual related item. I need to dig around in the relationships API when I get in from work, I'll let you know what I find!
:)
I found the link to Hendy's excellent blog post on using the relationship API! http://blog.hendyracher.co.uk/umbraco-relation-api/
:)
There's also some helper methods in uComponents for working with relationships too: http://ucomponents.codeplex.com/wikipage?title=uQuery
Hope that helps!
is working on a reply...