Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Fred 14 posts 74 karma points
    Jul 06, 2015 @ 15:30
    Fred
    0

    Create Matching Media Folder with Content Folder

    Hello,

    I have a Folder Doc Type in content and i'd like it to create a matching folder in Media. I've hooked into the ContentService.Saved method so I have access to when my folder is created.

    What would be the best way to try and match this to creating a media item? I was thinking of checking through all media items and if they have the same name as the content parent and are created within a minute of each other using that as the media parent (so folders can be nested) but that sounds expensive in terms of performance

    Any help would be appreciated

  • Steven Harland 78 posts 518 karma points c-trib
    Jul 07, 2015 @ 08:23
    Steven Harland
    0

    Hi Fred,

    You could create a Relation between the two. Or have a media picker property on the document type that points to the media folder.

  • Fred 14 posts 74 karma points
    Jul 07, 2015 @ 08:30
    Fred
    0

    Hi Steven,

    I'm unsure how either of these could be used to create a matching Media folder. A relation seems to map the 2 items together but not create, and a media picker property would give me the tool to make the folder but would still need to be manually created.

    Maybe i'm wrong with Relation, could you give me an example?

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Jul 07, 2015 @ 08:44
    Ismail Mayat
    100

    Fred,

    We had to this recently on a website we built storm models. So in the content section each model node exists as a talent node type. When you create and save one of these we tap into the saved event then in media section under models media folder do a search for folder with same model name if it does not exist then we create it.

    The id of newly created media folder we store in text field in attributes tab on content node. If on save we have this idea then just get the folder directly using that id. So from performance perspective you potentially have over head first but subsequently you will not because you have an id. Also we use that idea for media pickers on talent node so that when you click to pick the media folder start is already set to the talents media folder makes for a better ui experience for editors.

    Regards

    Ismail

  • Fred 14 posts 74 karma points
    Jul 07, 2015 @ 09:08
    Fred
    0

    Hi Ismail,

    That sounds exactly what I need. Out of interest, how did you get the media picker to start at a node, as that was on my todo also

    Cheers, Fred

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Jul 07, 2015 @ 09:22
    Ismail Mayat
    0

    Fred,

    I nicked some code from the excellent mvc hybrid project see https://our.umbraco.org/projects/developer-tools/hybrid-framework-for-umbraco-v7/ and the actual code https://github.com/jbreuer/Hybrid-Framework-for-Umbraco-v7-Best-Practises/blob/master/Umbraco.Extensions/Utilities/WebApiHandler.cs so it was using this class and my code looks like

    using System;
    

    using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.UI; using Constants = Constants.Constants;

    namespace Application.BusinessLogic.Handlers {

    /// <summary>
    /// this handler which intercepts webapi calls is wired up in UmbracoEvents.Applicationstarting
    /// listens out for umbraco content api web requests
    /// code taken from https://github.com/jbreuer/Hybrid-Framework-for-Umbraco-v7-Best-Practises/blob/master/Umbraco.Extensions/Utilities/WebApiHandler.cs
    /// with some modifications
    /// </summary>
    public class WebApiHandler : System.Net.Http.DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            switch (request.RequestUri.AbsolutePath.ToLower())
            {
                case "/umbraco/backoffice/umbracoapi/content/postsave":
    
                case "/umbraco/backoffice/umbracoapi/content/getbyid":
                    return SetContentMediaPickerStartNode(request, cancellationToken);
                default:
                    return base.SendAsync(request, cancellationToken);
            }
        }
    
        /// <summary>
        /// each talent has a related media picker folder, we want to set id dynamically so we pick images from correct folder
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private Task<HttpResponseMessage> SetContentMediaPickerStartNode(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken)
                .ContinueWith(task =>
                {
                    var response = task.Result;
                    try
                    {
                        //Get the content that we want to modify.
                        var data = response.Content;
                        var content = ((ObjectContent)(data)).Value as ContentItemDisplay;
    
                        //we only want to do this for talent items
                        if (Constants.TalentDocTypes.Contains(content.ContentTypeAlias))
                        {
                            SetMediaPickerStartNode(content.Properties);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Error<WebApiHandler>("Could not change the media picker start node.", ex);
                    }
                    return response;
                }
            );
        }
    
        /// <summary>
        /// for the current item which is a model type set all the media pickers
        /// start folder to associated media folder in media section id of it is set in 
        /// the properties tab, NB if we need to have media folders that should not start 
        /// in talents media folder then you need to exclude that folder
        /// </summary>
        /// <param name="properties"></param>
        private void SetMediaPickerStartNode(IEnumerable<ContentPropertyDisplay> properties)
        {
            //Get the media pickers which we want to change the start node from.
            var mediaPickers = properties.Where(x =>
                Umbraco.Core.Constants.PropertyEditors.MediaPickerAlias.InvariantEquals(x.Editor) ||
                Umbraco.Core.Constants.PropertyEditors.MultipleMediaPickerAlias.InvariantEquals(x.Editor)
                ).ToList();
    
            //check that the current doc has got startNodeId property
            var startIdProperty =
                properties.FirstOrDefault(x => Umbraco.Core.Constants.PropertyEditors.TextboxAlias.InvariantEquals(x.Editor) &&
                                               x.Alias == Constants.DocTypesProperties.Talent.MediaStartNodeId);
    
            //ensure we have media pickers and we have a media folder start id
            if (mediaPickers.Any() && HaveMediaFolder(startIdProperty))
            {
                var startId = startIdProperty.Value.ToString();
    
                foreach (var mediaPicker in mediaPickers)
                {
                    mediaPicker.Config[Constants.MediaPickerStartNodeAlias] = startId;
                }
            }
        }
    
        /// <summary>
        /// ensure we have an id for media folder and that it exists
        /// it may be that its been deleted 
        /// </summary>
        /// <param name="startIdProperty"></param>
        /// <returns></returns>
        private bool HaveMediaFolder(ContentPropertyDisplay startIdProperty)
        {
           if(startIdProperty!=null && !string.IsNullOrEmpty(startIdProperty.Value.ToString()))
           {
               int mediaFolderId = 0;
               bool haveId = int.TryParse(startIdProperty.Value.ToString(), out mediaFolderId);
               if (haveId)
               {
                   var mediaFolder = ApplicationContext.Current.Services.MediaService.GetById(mediaFolderId);
                   if (mediaFolder != null && mediaFolder.Id != 0)
                   {
                       return true;
                   }
               }
            }
            return false;
        }
    }
    

    }

  • Fred 14 posts 74 karma points
    Jul 07, 2015 @ 09:37
    Fred
    0

    Alright brilliant, Thanks alot!

  • Fred 14 posts 74 karma points
    Jul 08, 2015 @ 16:00
    Fred
    0

    Hi Ismail,

    I've tried implementing the media picker start node, but i'm having the problem of it not working. I have it finding my media node id and running in the correct places which is great.

    Is mediaPicker.Config[Constants.MediaPickerStartNodeAlias] something that interacts with the hybrid framework and not in Umbraco by default? If not what is the hardcoded string, or is there a way to implement it that wouldn't be starting again and integrating this framework?

    Thanks, Fred

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Jul 08, 2015 @ 16:04
    Ismail Mayat
    0

    Fred,

    Replace Constants.MediaPickerStartNodeAlias with your field alias that has the node id. That bit of code is specific to my situation.

    Regards

    Ismail

  • Fred 14 posts 74 karma points
    Jul 09, 2015 @ 08:04
    Fred
    0

    Hi Ismail, the problem was i called it StartNodeId when it's startNodeId...

    anyway thank you again it's all working perfectly now, you rock!

    Fred

  • Fred 14 posts 74 karma points
    Jul 09, 2015 @ 10:37
    Fred
    0

    Hi Ismail,

    Is there anyway to have it list ancestor nodes so users can still navigate?

    it currently just says my folder name but i'd like it to be

    root/folder/myfolder so users can still decide where they'd like it uploaded to.

    Thanks, Fred

  • Ismail Mayat 4511 posts 10091 karma points MVP 2x admin c-trib
    Jul 09, 2015 @ 10:48
    Ismail Mayat
    0

    Fred,

    Don't think so, I have only used it where I need child folders.

    Regards

    Ismail

Please Sign in or register to post replies

Write your reply to:

Draft