How to get a reference to a parent block from current block

Member since: 2010

From what I see, in the controller, I have CurrentBlock.Property.OwnerLink, which gives me the ID of the current block.

However, 

var contentRepo = ServiceLocator.Current.GetInstance<IContentRepository>();
var parents = contentRepo.GetAncestors(ownerLink);

gives me the parent folder in the block structure (the one seen on the right of edit mode, for example "Global Library", "Folder for general blocks", ...), not the page structure.

What I need to do is to access a property on the parent block.

#65101 Jan 21, 2013 10:56
  • Member since: 2010

    Does anyone know how to do this?

    #65136 Jan 22, 2013 10:03
  • Member since: 2004

    In MVC there is a context item stored on the request, you can get it from:

    requestContext.HttpContext.Items[ContentContext.ContentContextKey] as Stack<ContentPropertiesStack>

    It basically is a stack where you can get information about nested parents and nested properties. So you can e.g. know when rendering a specific property if that property is nested within ContentAreas and/or nested in other properties (case when rendering block properties). 

    You should though be aware that for the information to be accurate you should either render through PropertyFor/BeginEditSection-EndEditSection. If you have custom rendering you need to call static Push/Pop methods on ContentContext when rendering a content/property to get correct info from class.

     

    In WebForms you could traverse the Control collection upwards to find e.g. IContentSource implementations.

     

    Be also aware that the above suggestions are kind of "internal" details and can be changed in future.

    #65154 Jan 22, 2013 14:23
  • Member since: 2007

    Marjia, i am trying to do exactly what you were asking, using Johan's resolved answer would you be able to provide a little more information on how you achieved this?

    Regards


    Minesh

    #121390 May 08, 2015 11:42
  • Member since: 2010

    Hi, Minesh, 

    As you can see, this is a quite old post, so something has probably changed in the meantime. Please first try to access the parent block using ParentLink:

            public static IContent GetParent(this IContent content)
            {
                var parentContent = Get<IContent>(content.ParentLink);
                return parentContent;
            }

    If that doesn't give you the proper IContent, then you might give it a try what Johan proposed. (But I think yourblock.GetParent() should work nowadays, I just don't have time to try it out). This is the method I used earlier (that was 7.0, so I think you won't need it, but here it is):

    public int GetNoOfChildrenInRow(RequestContext requestContext)
           {
               var parentStack = requestContext.HttpContext.Items[ContentContext.ContentContextKey] as
                   Stack<ContentContext.ContentPropertiesStack>;
     
               if (parentStack != null)
               {
                   var parents = parentStack.ToArray();
     
                   foreach (var currentParent in parents)
                   {
                       var contentRepo = ServiceLocator.Current.GetInstance<IContentRepository>();
     
                       var parentBlock = contentRepo.Get<IContentData>(currentParent.ContentLink);
     
                       var rowBlock = parentBlock as RowBlock;
                       if (rowBlock != null)
                       {
                           return rowBlock.OneToFourBlocks.ContainsAnyBlocks()
                               ? rowBlock.OneToFourBlocks.Count : 0;
                       }
                   }
               }
     
               return 0;
           }

     

    #121404 May 08, 2015 15:53
  • Thanks all, this post answered my question of fetching a content parent, just thought i'd share the extension I ended up with:

            public static ContentReference GetContentAreaParent(this HttpRequestBase request)
            {
                //Retrieve the Request's content stack and get the 2nd element without disturbing the stack.
                var contentstack = request?.RequestContext.HttpContext.Items[ContentContext.ContentContextKey] as Stack<ContentContext.ContentPropertiesStack>;
                if (contentstack?.Count > 1)
                {
                    var parent = contentstack.ToArray()[1];
                    return parent.ContentLink;
                }
    
                return null;
            }

    #179153 Edited, Jun 01, 2017 12:43
  • Member since: 2004

    A reccomendation is to do a Peek() into the stack intead of a Pop() since otherwise you are likely to break other code that is dependent on the stack.

    #179154 Jun 01, 2017 12:59
  • Thank you for the feedback Johan, glad I shared. Since I need the 2nd value I've copied the stack to an array.

    #179157 Jun 01, 2017 13:37