Umbraco automatically copy documents from related parents on publish

Michael Roma on Jul 17, 2015

This functionality allows you to use the Relation Type functionality in Umbraco to automatically copy new documents to parents that were related previously. This is most useful for language specific versions of your site where it will copy and relate new documents that are created after your original copy. Click here to download the source First define constants for the Relate Documents on Copy relation type alias

// define relation types
public class RelationTypes
{
    public const string RelateDocumentOnCopy = “relateDocumentOnCopy”;
}
Next, create a class to attach to Umbraco eventing for Publish and Copied content events
// events
public class Events: ApplicationEventHandler
{
    // construtor
    public Events()
    {
        // content publish
        ContentService.Published += ContentService_Published;

        // content copied
        ContentService.Copied += ContentService_Copied;
    }

    // we will define these below
    void ContentService_Copied(IContentService sender, CopyEventArgs e) { }
    void ContentService_Published(IPublishingStrategy sender, PublishEventArgs e) { }
}
Define the event to add the relation on when a new document is created and the user selects to relate to original
void ContentService_Copied(IContentService sender, CopyEventArgs e)
{
    // check if relating to original
    if (e.RelateToOriginal)
    {
        // relate on copy
        var rs = ApplicationContext.Current.Services.RelationService;
        rs.Relate(e.Original, e.Copy, RelationTypes.RelateDocumentOnCopy);
    }
}
Define the vent to copy a newly published document over to it’s parent’s relation
void ContentService_Published(IPublishingStrategy sender, PublishEventArgs e)
{
    // get the services
    var rs = ApplicationContext.Current.Services.RelationService;
    var cs = ApplicationContext.Current.Services.ContentService;
                
    // go through each document published
    foreach (var c in e.PublishedEntities)
    {                    
        // check if not the first level                
        if (c.Level > 1 && !rs.GetByParentId(c.Id).Any())
        {
            // get the parent                    
            foreach (var parentRelation in rs.GetByParentId(c.ParentId).Where(x => x.RelationType.Alias == RelationTypes.RelateDocumentOnCopy))
            {
                // copy the item if not already a relation
                cs.Copy(c, parentRelation.ChildId, true);
            }
        }
    }
}