Media Picker - with dynamic start node - is it possible?
It would be great if the new Umbraco 7 media picker could have the Start Node set dynamically.
For example, I have a News Item document that will have images specific to it, so I'm thinking I would like to have one media folder per news item, so that the user could quickly upload and pick images specific to that news item.
At document creation time, I'm thinking I could create a folder in the media section (under another folder called News Items), give it a name of the document id, and set a Folder Picker data type (on the same document) to point to it. Then, on the same document, I'd like to have a Multiple Media Picker that displays using the media id in the Folder Picker as the starting folder.
Is anything like this currently possible?
I'm thinking I'll need to write a Property Editor to provide the functionality, but wanted to check I'm not missing something first.
You should also check the ContentService_Saved event in UmbracoEvents.cs. If the document type is gallery I create a new media folder and set that as the start node for the media picker.
Thanks Jereon. I've been frantically finishing off another project, so haven't had a chance to delve into this yet. Will do over the next day or so and will respond back here for sure.
One question I have around all this, is: Does it mean that using your solution will mean the media picker's start node will be affected at a global level? In other words, if after setting the start node for a news item I then open a document that isn't a news item but that also has a media picker, will the picker use the last saved start node id, the one that was set by the news item load or save?
Obviously the ideal situation is that it is only changed for the current request, but I'm not clear if that's the case. I'm also a little worried about multiple users accessing the same document at the same time, or using media picker on different documents at the same time.
Thanks to your examples I have managed to get this working.
Many thanks for taking the time to respond. If anyone wants to see the code, let me know. I got everything I needed from Jeroen's examples. This example contained the logic for setting the media node id on a per request basis. This example contained the logic for creating media folders (although that can also be found in the Content and Media events documentation.
For some reason your comment hasn't shown up. Anyway, the code you asked for:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Umbraco.Core.Logging;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using System.Configuration;
using WebProj.Data.PetaPoco;
using WebProj.Data;
namespace WebProj.Web.Handlers
{
public class NewsItemWebApiHandler : System.Net.Http.DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
switch (request.RequestUri.AbsolutePath.ToLower())
{
case "/umbraco/backoffice/umbracoapi/content/getempty":
case "/umbraco/backoffice/umbracoapi/content/getbyid":
return SetNewsItemMediaPickerStartNode(request, cancellationToken);
default:
return base.SendAsync(request, cancellationToken);
}
}
private Task<HttpResponseMessage> SetNewsItemMediaPickerStartNode(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
try
{
var data = response.Content;
var content = ((ObjectContent)(data)).Value as ContentItemDisplay;
if (content.ContentTypeAlias == "NewsItem")
{
// get the document properties
var imagesFolderName = content.Properties.FirstOrDefault(x => x.Alias == "imagesFolderName");
var imagesFolderId = content.Properties.FirstOrDefault(x => x.Alias == "imagesFolderId");
// create the images folder if not created already
if (imagesFolderName != null && imagesFolderId != null)
{
if (string.IsNullOrEmpty((string)imagesFolderName.Value))
{
var mediaService = ApplicationContext.Current.Services.MediaService;
var imagesFolder = mediaService.CreateMediaWithIdentity(Guid.NewGuid().ToString(), int.Parse(ConfigurationManager.AppSettings["NewsItemParentFolderId"]), "Folder");
mediaService.Save(imagesFolder);
imagesFolderName.Value = imagesFolder.Name;
imagesFolderId.Value = imagesFolder.Id;
}
}
// set the start node of the images media picker
var mediaPicker = content.Properties.FirstOrDefault(x => x.Alias == "images");
if (mediaPicker != null && imagesFolderId != null)
{
if (mediaPicker.Config.ContainsKey("startNodeId"))
{
mediaPicker.Config["startNodeId"] = imagesFolderId.Value.ToString();
}
else
{
mediaPicker.Config.Add("startNodeId", imagesFolderId.Value.ToString());
}
}
}
}
catch (Exception ex)
{
LogHelper.Error<NewsItemWebApiHandler>("Could not change the media picker start node.", ex);
}
return response;
});
}
}
}
Media Picker - with dynamic start node - is it possible?
It would be great if the new Umbraco 7 media picker could have the Start Node set dynamically.
For example, I have a News Item document that will have images specific to it, so I'm thinking I would like to have one media folder per news item, so that the user could quickly upload and pick images specific to that news item.
At document creation time, I'm thinking I could create a folder in the media section (under another folder called News Items), give it a name of the document id, and set a Folder Picker data type (on the same document) to point to it. Then, on the same document, I'd like to have a Multiple Media Picker that displays using the media id in the Folder Picker as the starting folder.
Is anything like this currently possible?
I'm thinking I'll need to write a Property Editor to provide the functionality, but wanted to check I'm not missing something first.
Hello,
This is possible, but it's a bit hacky. Have a look at this issue: http://issues.umbraco.org/issue/U4-2670#comment=67-15418
I've implemented this in the Hybrid Framework. If you watch this video I explain how it works: https://www.youtube.com/watch?v=Enni9r0whCE
Jeroen
Hello,
Did you watch the video?
You should also check the ContentService_Saved event in UmbracoEvents.cs. If the document type is gallery I create a new media folder and set that as the start node for the media picker.
Jeroen
Thanks Jereon. I've been frantically finishing off another project, so haven't had a chance to delve into this yet. Will do over the next day or so and will respond back here for sure.
One question I have around all this, is: Does it mean that using your solution will mean the media picker's start node will be affected at a global level? In other words, if after setting the start node for a news item I then open a document that isn't a news item but that also has a media picker, will the picker use the last saved start node id, the one that was set by the news item load or save?
Obviously the ideal situation is that it is only changed for the current request, but I'm not clear if that's the case. I'm also a little worried about multiple users accessing the same document at the same time, or using media picker on different documents at the same time.
Thanks!
Mark
Hello,
The media picker start node is only changed for the current request. Per request the code checks the document type alias and property alias and based on that returns a different start node. That code can be found here: https://github.com/jbreuer/Hybrid-Framework-for-Umbraco-v7-Best-Practises/blob/master/Umbraco.Extensions/Utilities/WebApiHandler.cs
Jeroen
Hi Jeroen,
Thanks to your examples I have managed to get this working.
Many thanks for taking the time to respond. If anyone wants to see the code, let me know. I got everything I needed from Jeroen's examples. This example contained the logic for setting the media node id on a per request basis. This example contained the logic for creating media folders (although that can also be found in the Content and Media events documentation.
Mark
Hi Carina,
For some reason your comment hasn't shown up. Anyway, the code you asked for:
is working on a reply...