Copied to clipboard

Flag this post as spam?

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


  • jacob phillips 130 posts 372 karma points
    Jan 28, 2014 @ 01:54
    jacob phillips
    0

    Relation Types + Partial View Macro + Umbraco 6

    I have this old XSLT from Umbraco version 4.5 that gets node ids given a relation type. It worked through the "ps" namespace below:

    <xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxml="urn:schemas-microsoft-com:xslt"
    xmlns:ps="urn:percipientstudios-com:xslt"
    

    Later in the XSLT, I can get the node ids by relation type, like this:

        <xsl:variable name="rotatorImages" select="ps:GetRelatedNodes($nodeid, 'RotatorImage')"/> 
    

    I want to rewrite this XSLT to run in a Razor Partial View File.

    Inside of a for-loop, I have access to my node ids (stored in @item).

    I have tried a couple different things that I found, but can't get it to work.

    I tried this:

    Umbraco Relations Documentation

    I added these usings in my Razor Partial View:

    using umbraco.cms.businesslogic.relation;
    using umbraco.BusinessLogic;
    

    But as soon as I try to use it, like this:

    var relType = RelationType.GetByAlias("RotatorImage");
    

    I get error.

    I thought I could filter by the type "RotatorImage" (that's the Alias of my Relation Type), so I can get at the image related to each node like this:

    var relType = RelationType.GetByAlias("myRelation");
    var relations = Relation.GetRelations(item.Id, relType);
    

    .....

    So if I can't do that, I also found this on GitHub:

    Relation Service Documentation

    So in this case, I got these usings statements:

    @using Umbraco.Core.Services
    @using Umbraco.Core.Models
    @using Umbraco
    

    Then, I can get at my relations, by @item.Id like this:

    var s = ApplicationContext.Current.Services.RelationService.GetByParentId(item.Id);
    

    But how can I get at the nodeId of s? I believe my s object is a Relation object in Umbraco.Core.Models.Relation.

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jan 28, 2014 @ 17:32
    Jeavon Leopold
    100

    Hi Jacob,

    How about:

    var s = ApplicationContext.Current.Services.RelationService.GetByParentId(item.Id);
    
    foreach (var relationItem in s)
    {
        <p>@relationItem.ChildId</p>
    }
    

    Jeavon

  • jacob phillips 130 posts 372 karma points
    Jan 28, 2014 @ 19:26
    jacob phillips
    0

    Thanks, I realize that each node may have several relations and I need id of relation type "RotatorImage" which has an id of '3'.

    I got this:

    var s = ApplicationContext.Current.Services.RelationService.GetByParentId(item.Id);
    var rotatorImageId = 0; 
    foreach (var relationItem in s)
    {
       if(relationItem.RelationTypeId == 3)
       {
          rotatorImageId = relationItem.ChildId;
       }
    }
    <p>@rotatorImageId</p>
    

    This works, but I am just curious....

    For better self-documentation, it would be nice to use .RelationType == "RotatorImage" or even better, use a method that allows filtering by RelationType. For the former, I see that both .RelationType and .RelationType.ToString() returns literally:

    "Umbraco.Core.Models.RelationType"
    

    That is an object? And for the latter, I don't see how to filter the relations on a given node, by type.

    It seems like since var s above holds all my relations, I should be able to filter on a specific one of those relations, by it's type. But none of the methods seem to do that directly.

    For example, I could get a relation type object for my Relation Type w/ id = 3 (that's "RotatorImage"):

    var t = ApplicationContext.Current.Services.RelationService.GetRelationTypeById(3);
    

    And then use some method like:

    s.GetAllRelationsByRelationType(t)
    

    But my 's' variable does not have the method GetAllRelationsByRelationType (I'm looking up the object methods and properties using VS intellisense).

    Anyways, what we got gets me through this, so no big deal. But if the answer is obvious or my understanding is way off, please let me know!

    thanks Jeavon

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jan 28, 2014 @ 21:26
    Jeavon Leopold
    0

    Hi Jacob,

    You could do something like this:

    var rotatorImageId = 0; 
    var s = ApplicationContext.Current.Services.RelationService.GetByParentId(item.Id).FirstOrDefault(x => x.RelationTypeId == 3);
    if (s != null)
    {
        rotatorImageId = s.ChildId;
    }
    

    Also there many other methods from the RelationService and they are documentated here

    Jeavon

  • jacob phillips 130 posts 372 karma points
    Jan 28, 2014 @ 23:46
    jacob phillips
    0

    Thanks for reference and I tried the above...

    I can't get it to work, but have narrowed it down to this:

    .FirstOrDefault(x => x.RelationTypeId == 3)
    

    Do I need to include a using statement for Linq, like @using System.Linq or something?

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 03, 2014 @ 11:28
    Jeavon Leopold
    0

    Hi Jacob,

    I was testing with the below and it works for me without any using statement:

    @{
        var item = Model.Content;
        var rotatorImageId = 0;
        var s = ApplicationContext.Current.Services.RelationService.GetByParentOrChildId(item.Id).FirstOrDefault(x => x.RelationTypeId == 1);
        if (s != null)
        {
            rotatorImageId = s.ChildId;
        }
    }  
    

    Jeavon

  • jacob phillips 130 posts 372 karma points
    Feb 04, 2014 @ 00:03
    jacob phillips
    0

    Thx Jeavon,

    I tried this exactly w/in the context that item.Id is known to be good:

    var rotatorImageId = 0; 
    
    var s = ApplicationContext.Current.Services.RelationService.GetByParentOrChildId(item.Id).FirstOrDefault(x => x.RelationTypeId == 3);
    if (s != null)
    {
        rotatorImageId = s.ChildId;
    }
    

    And I get error. This works:

    var rotatorImageId = 0; 
    var s = ApplicationContext.Current.Services.RelationService.GetByParentId(item.Id);
    
    
    foreach (var relationItem in s)
    {
       if(relationItem.RelationTypeId == 3)
       {
          rotatorImageId = relationItem.ChildId;
       }
    }
    

    No big deal, it's working.

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 04, 2014 @ 10:19
    Jeavon Leopold
    0

    Hi Jacob,

    Strange it doesn't work for you. Does it cause an error or just nothing displays?

    Jeavon

  • jacob phillips 130 posts 372 karma points
    Feb 04, 2014 @ 17:23
    jacob phillips
    0

    Jeavon,

    I'm using the Umbraco Partial View Macro Files editor. When I load the page that uses this macro, the page works, but where the Macro would be I just get:

    Error loading Partial View script (file: ~/Views/MacroPartials/rCycleHighlightsRotator.cshtml) 
    
  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 04, 2014 @ 17:33
    Jeavon Leopold
    0

    Hi Jacob,

    Could you check your log4net (\App_Data\Logs\UmbracoTraceLog.txt) file to see if there is some more info in there?

    Jeavon

  • jacob phillips 130 posts 372 karma points
    Feb 04, 2014 @ 17:37
    jacob phillips
    0

    Last error is:

    2014-02-04 08:22:00,885 [8] WARN  umbraco.macro - [Thread 10] Error loading Partial View (file: ~/Views/MacroPartials/rCycleHighlightsRotator.cshtml). Exception: System.Web.HttpCompileException (0x80004005): c:\inetpub\wwwroot\capradio\Views\MacroPartials\rCycleHighlightsRotator.cshtml(80): error CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
       at System.Web.Compilation.AssemblyBuilder.Compile()
       at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()
       at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
       at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
       at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
       at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
       at System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.FileExists(String virtualPath)
       at Microsoft.Web.Mvc.ViewEngineFixWorker`1.GetPathFromSpecificName(ControllerContext controllerContext, String name, String cacheKey, String[]& searchedLocations)
       at Microsoft.Web.Mvc.ViewEngineFixWorker`1.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations)
       at Microsoft.Web.Mvc.ViewEngineFixWorker`1.FindPartialView(ControllerContext controllerContext, String partialViewName, Boolean useCache)
       at System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths)
       at Umbraco.Web.Mvc.ControllerExtensions.EnsureViewObjectDataOnResult(ControllerBase controller, ViewResultBase result)
       at Umbraco.Web.Mvc.ControllerExtensions.RenderViewResultAsString(ControllerBase controller, ViewResultBase viewResult)
       at Umbraco.Web.Macros.PartialViewMacroEngine.Execute(MacroModel macro, INode currentPage)
       at umbraco.macro.LoadPartialViewMacro(MacroModel macro)
       at umbraco.macro.renderMacro(Hashtable pageElements, Int32 pageId)
    
  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 04, 2014 @ 19:28
    Jeavon Leopold
    0

    Ah, I think I know what it is. How do you set what "item" is?

  • jacob phillips 130 posts 372 karma points
    Feb 04, 2014 @ 19:59
    jacob phillips
    0
        var dynamicPublishedMNTPNodeList = new List<string>();
        foreach (var id in CurrentPage.cprHighlights)
        {
            dynamicPublishedMNTPNodeList.Add(id.InnerText);
        }
        var dynamicMNTPCollection = Umbraco.Content(dynamicPublishedMNTPNodeList);
        @foreach (var item in dynamicMNTPCollection)
        {...}
    

    item is accessed in the foreach loop

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 04, 2014 @ 20:53
    Jeavon Leopold
    0

    Ah yes, that is it, as you have used dynamic CurrentPage instead of Model.Content we need to cast the Id to use the lambda expression. It would be like this:

    var s = ApplicationContext.Current.Services.RelationService.GetByParentId((int)item.Id).FirstOrDefault(x => x.RelationTypeId == 3);
    

    Phew, I never like it when I can't work out why something works for one person but not another! :-)

  • jacob phillips 130 posts 372 karma points
    Feb 05, 2014 @ 17:48
    jacob phillips
    0

    Yes, it works. Success. Thx.

Please Sign in or register to post replies

Write your reply to:

Draft