KNOWLEDGE BASE

Selection Problem With Custom Media Type Content in Umbraco 4


The Problem

You have a custom media type. You want to add a link to it in the WYSIWYG editor. 

You go to add a link as normal, except in the "Insert/Edit Link" pop up, you click on the "Media" tab. You notice that when you click on it, no url is inserted in the Url field. 

 

The problem is due to this method in the Umbraco source:

private static string findMediaLink(Media dd, string nodeLink)
{
 
Guid uploadGuid = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
 
foreach (Property p in dd.getProperties)
 
{
   
if (p.PropertyType.DataTypeDefinition.DataType.Id == uploadGuid
       
&& !String.IsNullOrEmpty(p.Value.ToString()))
   
{
     
return p.Value.ToString();
   
}
 
}
 
return "";
}

This method is called from the overrided Render(ref XmlTree tree) method in Umbraco's loadMedia class. Here is the code block: 

string nodeLink = findMediaLink(dd, dd.Id.ToString());
if (!String.IsNullOrEmpty(nodeLink))
{
    xNode
.Action = "javascript:openMedia('" + nodeLink + "');";
}
else
{
    xNode
.Action = null;
    xNode
.DimNode();
}

Notice that when findMediaLink() is called, your custom media type is never going to return  "5032a6e6-69e3-491d-bb28-cd31cd11086c" as a Guid. So your media type never gets assiged it's openMedia action, and xNode.DimNode() will always be called.

 

The Work Around

You must replace the Umbraco media tree handler with your own one. We called ours "MediaTree".

Here's how:

  • Create a class (eg. MediaTree) that inherits from loadMedia (see code below)
  • Copy and paste the Render(ref XmlTree tree), and findMediaLink(Media dd, string nodeLink) methods from loadMedia.cs into your new class
  • Modify the findMediaLink(Media dd, string nodeLink) method to get the Guid from your custom media type, and check if it is equal to p.PropertyType.DataTypeDefinition.DataType.Id (see code below)

 

Here's the class:

public class MediaTree : loadMedia
{
   
public MediaTree(string application) : base(application) { }

   
public override void Render(ref XmlTree tree)
   
{
       
Media[] docs;

       
if (m_id == -1)
            docs
= Media.GetRootMedias();
       
else
            docs
= new Media(m_id).Children;

       
foreach (Media dd in docs)
       
{
           
XmlTreeNode xNode = XmlTreeNode.Create(this);
            xNode
.NodeID = dd.Id.ToString();
            xNode
.Text = dd.Text;

           
// Check for dialog behaviour
           
if (!this.IsDialog)
           
{
               
if (!this.ShowContextMenu)
                    xNode
.Menu = null;
                xNode
.Action = "javascript:openMedia(" + dd.Id + ");";
           
}
           
else
           
{
               
if (this.ShowContextMenu)
                    xNode
.Menu = new List(new IAction[] { ActionRefresh.Instance });
               
else
                    xNode
.Menu = null;
               
if (this.DialogMode == TreeDialogModes.fulllink)
               
{
                   
string nodeLink = findMediaLink(dd, dd.Id.ToString());
                   
if (!String.IsNullOrEmpty(nodeLink))
                   
{
                        xNode
.Action = "javascript:openMedia('" + nodeLink + "');";
                   
}
                   
else
                   
{
                        xNode
.Action = null;
                        xNode
.DimNode();
                   
}
               
}
               
else
               
{
                    xNode
.Action = "javascript:openMedia('" + dd.Id.ToString() + "');";
               
}
           
}
            xNode
.HasChildren = dd.HasChildren;

           
if (this.IsDialog)
                xNode
.Source = GetTreeDialogUrl(dd.Id);
           
else
                xNode
.Source = GetTreeServiceUrl(dd.Id);

           
if (dd.ContentType != null)
           
{
                xNode
.Icon = dd.ContentType.IconUrl;
                xNode
.OpenIcon = dd.ContentType.IconUrl;
           
}

            tree
.Add(xNode);
       
}
   
}

   
private static string findMediaLink(Media dd, string nodeLink)
   
{
       
TheFarm.Umbraco.Controls.MultiMediaUploadDT mmDT =
               
new TheFarm.Umbraco.Controls.MultiMediaUploadDT();
       
Guid farmUpload = mmDT.Id;

       
Guid uploadGuid = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
       
foreach (Property p in dd.getProperties)
       
{
           
if ((p.PropertyType.DataTypeDefinition.DataType.Id == uploadGuid ||
                p
.PropertyType.DataTypeDefinition.DataType.Id == farmUpload)
               
&& !String.IsNullOrEmpty(p.Value.ToString()))
           
{
               
return p.Value.ToString();
           
}
       
}
       
return "";
   
}

}

Note: For this to work your custom media class must contain a Guid.

eg.

public override Guid Id 
{
   
get { return new Guid("{12345678-ABCD-EFGH-IJKLM-NOPQRSTUVWX}"); }
}

Now go to the database and edit the umbracoAppTree table.

public override Guid Id 
{
   
get { return new Guid("{12345678-ABCD-EFGH-IJKLM-NOPQRSTUVWX}"); }
}

That's it.


Need an Umbraco Master?

Here at Simon Antony, we have an in house certified Umbraco Grand Master available for hire. Got a problem with your site, need architecture advice, give us a call to speak to Simon directly and see how we can help

Contact Simon Today!