Copied to clipboard

Flag this post as spam?

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


  • James McIntosh 9 posts 29 karma points
    Nov 22, 2013 @ 16:53
    James McIntosh
    0

    U7 - Umbraco.RelatedLinks now returning System.char instead of xml

    In Umbraco 6.x the Umbraco.RelatedLinks Data Type returned a xml dataset (http://our.umbraco.org/documentation/using-umbraco/backoffice-overview/property-editors/built-in-property-editors/Related-Links) that could be iterated over to build up the links in whatever way you wanted. We have just installed Umbraco 7 and when testing out some of our components we have found that the Umbraco.RelatedLinks data type now seems to return System.Char rather than xml.

     

    For Example, when the below code outputs System.char

    if (@item.HasProperty("relatedItems")) {
    foreach (var link in @item.relatedItems) { 
    @link.GetType()
    }
    }

     

    When I output what is contained within the so called string object it returns what appears to be a Key Value Map.

    [ { "caption": "Test Page", "link": "1095", "newWindow": false, "internal": "1095", "edit": false, "isInternal": true, "iternalName": "Feature 1", "type": "internal", "title": "Test Page" } ]

    I can't find anything in the documentation that says Umbraco 7 has changed the way this should work.. So anyone got any ideas as to why this has changed? Or if I'm missing something?


  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 22, 2013 @ 20:38
    Jeavon Leopold
    0

    Hi James,

    Welcome to Our!

    As I understand it, all of the complex property editors which have been rewritten in AngularJs will now store their data as JSON. There is also a new JSON converter which will convert the data to a dynamic object which you can use in your Razor, I saw Per demo this recently but I've not tried it yet. I'll see if I can come back to you with a working sample ASAP :-)

    Jeavon

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 23, 2013 @ 00:28
    Jeavon Leopold
    0

    Hi James,

    So after some experimenting, I have the following snippet working (I'm sure it can be improved)

    @{
        var featuredLinks = CurrentPage.featuredLinks;
        foreach (var linkItem in featuredLinks)
        {
            string linkUrl;
            string linkTarget;
    
            if ((bool)linkItem.isInternal)
            {
                linkUrl = Umbraco.NiceUrl(int.Parse((string)linkItem.link));
                linkTarget = string.Empty;
            }
            else
            {
                linkUrl = linkItem.link;
                linkTarget = " target=\"_blank\"";
            }
    
            <a href="@linkUrl"@Html.Raw(linkTarget)>@linkItem.caption</a>                 
        }
    }
    

    Of course this is snippet assumes that the propertyAlias is called "featuredLinks". I am using the dynamic CurrentPage object here, so far I've not worked out how to do this using the strongly typed Model.Content.

    Hope this is helpful.

    Jeavon

  • James McIntosh 9 posts 29 karma points
    Nov 25, 2013 @ 17:02
    James McIntosh
    0

    Hi Jeavon,

     

    Thanks very much for your post. Was very helpful. For some reason, it never clicked that it was JSON that was being returned. 

    We use the related links to give the header links in our template, so its the same across all pages. I'm modified the the code you kindly presented a little so it looks at the homepage node and grabs the links from there for each page. So thank you for that.

    Just out of curiousity for future, do you recommend any particular method for reading JSON in Umbraco? Just wondered if there was a best practice approach for it with umbraco?

     

    Thanks,

    James

     

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 25, 2013 @ 17:14
    Jeavon Leopold
    0

    Hi James,

    I believe that all core v7 property editors that store their data as JSON will automatically return deserialized using JSONConvert

    I personally would prefer for the editors to be returning more usable properties and in native types, I think I'm going to need to create a new v7 version of my property editor converter package that will do just that :-)

    Glad you are up and running with it now though!

    Jeavon

  • Comment author was deleted

    Nov 28, 2013 @ 11:42

    Yeah I've tried to make sure the old razor code to output related links data still works :) so it doesn't matter if it's xml or json you can just loop it with razor since it returns a dynamic object

    For xslt you'll need something extra http://www.nibble.be/?p=341

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 28, 2013 @ 11:59
    Jeavon Leopold
    0

    Hey Tim,

    I actually had a good look at your conversions in the source to work out what was going on, however I certainly couldn't get any existing Mvc Razor samples (Typed or Dynamic) to work with the new returned object.

    For example using dynamics in v6:

    @{
        if (CurrentPage.HasValue("relatedLinks") && CurrentPage.relatedLinks.Any())
        {
            <ul>
                @foreach (var item in CurrentPage.relatedLinks)
                {
                    var linkUrl = (item.type.Equals("internal")) ? Umbraco.NiceUrl(int.Parse(item.link)) : item.link;
                    var linkTarget = (item.newwindow.Equals("1")) ? " target=\"_blank\"" : string.Empty;
                    <li><a href="@linkUrl" @Html.Raw(linkTarget)>@item.title</a></li>
                }
            </ul>
        }
    }      
    

    Thanks,

    Jeavon

  • Comment author was deleted

    Nov 28, 2013 @ 12:16

    Cool thanks for the details :) will check it out

  • Comment author was deleted

    Nov 28, 2013 @ 12:19

    This works

          foreach (var item in CurrentPage.test)
            {
                var linkUrl = (item.type.Equals("internal")) ? Umbraco.NiceUrl(int.Parse(item.link)) : item.link;
                var linkTarget = (item.newWindow.Equals("1")) ? " target=\"_blank\"" : string.Empty;
                <li><a href="@linkUrl" @Html.Raw(linkTarget)>@item.title</a></li>
            }
    

    SO just changing item.newwindow to item.newWindow

  • Comment author was deleted

    Nov 28, 2013 @ 12:20

    And Any() also doesn't work so maybe we'll add an extension method on Newtonsoft.Json.Linq.JArray

  • Comment author was deleted

    Nov 28, 2013 @ 12:22

    Issue created http://issues.umbraco.org/issue/U4-3746 (for the any)

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 28, 2013 @ 12:51
    Jeavon Leopold
    0

    Not quite for me:

    • the string extensions (e.g. .Equals) don't work,but don't throw YSOD
    • newWindow is now returning True or False instead of 1 or 0
    • int.Parse can't take the JValue so it has to be cast e.g. Umbraco.NiceUrl(int.Parse((string)item.link)) or directly Umbraco.NiceUrl((int)item.link)

    Closest working I could get this sample as is:

    @{
        if (CurrentPage.HasValue("relatedLinks"))
        {
            <ul>
                @foreach (var item in CurrentPage.relatedLinks)
                {                   
                var linkUrl = (item.type == "internal") ? Umbraco.NiceUrl(int.Parse((string)item.link)) : item.link;
                var linkTarget = (item.newWindow == true) ? " target=\"_blank\"" : string.Empty;
                <li><a href="@linkUrl" @Html.Raw(linkTarget)>@item.title</a></li>
                }
            </ul>
        }
    }      
    
  • Comment author was deleted

    Nov 28, 2013 @ 12:57

    Ok should test further just just getting the YSOD out of the way, guess a convertor is the way to go then to make sure it's the same data

  • James McIntosh 9 posts 29 karma points
    Nov 28, 2013 @ 13:05
    James McIntosh
    0

    Hi guys, 

    its interesting to see several things not quite working as they should.. 

    As I said we had our initial code working fine in 6.1.2 and then once we setup a belle instance it stopped, so we have a few work arounds now (mainly a variation of what Jeavon posted). The code pretty much just grabs the related links that have been added to the home page so the links are always shown at the top of the page. But using this approach no longer works as @item.menuItems returns the json string rather than the respresentative object (which Jeavon also posted).

    @{
    foreach(var item in @Model.AncestorsOrSelf(1)){
    if (@item.name == "HomePage")
    {
    if (@item.HasProperty("menuItems"))
    {
    foreach (var link in @item.menuItems)

    @link.title 
    }
    }
    }
    }
    }
  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 28, 2013 @ 13:16
    Jeavon Leopold
    1

    I just got a Typed (ish) snippet working using Newtonsoft, it's actually pretty nice

    @using Newtonsoft.Json.Linq
    @if (Model.Content.HasValue("relatedLinks"))
    {
        <ul>
            @foreach (var item in Model.Content.GetPropertyValue<JArray>("relatedLinks"))
            {
                var linkUrl = (item.Value<string>("type") == "internal") ? Umbraco.NiceUrl(item.Value<int>("link")) : item.Value<string>("link");
                var linkTarget = item.Value<bool>("newWindow") ? " target=\"_blank\"" : string.Empty;
                <li><a href="@linkUrl" @Html.Raw(linkTarget)>@(item.Value<string>("title"))</a></li>
            }
        </ul>
    }    
    
  • Comment author was deleted

    Nov 28, 2013 @ 13:18

    Nice :)

  • James McIntosh 9 posts 29 karma points
    Nov 28, 2013 @ 13:23
    James McIntosh
    0

    Nice one Jeavon.

    We are just figuring out umbraco and trying to understand all its bit and bobs. Need to spend a lot of time reading. Do you guys suggest any particularly good sources apart from this site and Umbraco tv?

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 28, 2013 @ 13:23
    Jeavon Leopold
    1

    Slightly improved with the new "isInternal" property

    if (Model.Content.HasValue("relatedLinks"))
    {
        <ul>
            @foreach (var item in Model.Content.GetPropertyValue<JArray>("relatedLinks"))
            {
                var linkUrl = (item.Value<bool>("isInternal")) ? Umbraco.NiceUrl(item.Value<int>("link")) : item.Value<string>("link");
                var linkTarget = item.Value<bool>("newWindow") ? " target=\"_blank\"" : string.Empty;
                <li><a href="@linkUrl" @Html.Raw(linkTarget)>@(item.Value<string>("title"))</a></li>
            }
        </ul>
    }    
    

    Time to create a new page of documentation I think!

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Nov 28, 2013 @ 13:26
    Jeavon Leopold
    0

    Hi James,

    I would say Umbraco.tv and the documentation (especially the MVC section) & forum sections of this site are the place to learn.

    Jeavon

  • Comment author was deleted

    Nov 28, 2013 @ 13:27

    And first v7 vids should start to appear on the tv site in december but since it's all about mvc current vids also apply to v7 (just not the correct UI)

  • James McIntosh 9 posts 29 karma points
    Nov 28, 2013 @ 13:28
    James McIntosh
    0

    Excellent, Thanks Guys

  • Comment author was deleted

    Nov 28, 2013 @ 13:28

    and of course community blogs like http://www.nibble.be/ http://creativewebspecialist.co.uk/, ... rss feed with those is available here http://our.umbraco.org/rss/communityblogs

  • Comment author was deleted

    Nov 28, 2013 @ 13:29

    and best to get a good head start is to attend an official training course http://umbraco.com/products/training/schedule.aspx

  • James McIntosh 9 posts 29 karma points
    Jan 06, 2014 @ 18:22
    James McIntosh
    0

    Hi Guys,

    Just thought I would highlight something I have found. When the related links has a link in it that refers to an internal link it was returning an error, upon investigation it turns out that the line of code below was the problem. In my case, for every internal link the item.Value<int>("link") was returning "http://" and not the internal id, therefore, causing an error as it could not convert the string to an int.

    var linkUrl = (item.Value<bool>("isInternal")) ? Umbraco.NiceUrl(item.Value<int>("link")) : item.Value<string>("link");
    

    I got around the problem by referring to the internal id attribute for internal links instead and it now links to the correct internal document.

    var linkUrl = (item.Value<bool>("isInternal")) ? Umbraco.NiceUrl(item.Value<int>("internal")) : item.Value<string>("link");
    

    Cheers,

    James

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Jan 07, 2014 @ 09:39
    Jeavon Leopold
    0

    Hi James,

    I have tried to replicate this issue but haven't been able to. When a link is internal for me, then the link property always contains the node id. Any idea how you ended up with it containing http:// instead?

    Jeavon

  • James McIntosh 9 posts 29 karma points
    Jan 07, 2014 @ 09:54
    James McIntosh
    0

    Hi Jeavon,

    I'm not sure why its picking up http:// I have extracted a sample of the json coming back for both an external and internal link below:

    { "caption": "Home", "link": "http://www.google.com", "newWindow": false, "edit": false, "isInternal": true, "type": "external", "title": "Home", "internal": "1092", "internalName": "HomePage" }
    
    { "caption": "A-Z Index", "link": "http://", "newWindow": false, "edit": false, "isInternal": true, "type": "external", "title": "A-Z Index", "internal": "1095", "internalName": "Feature 1" }
    

    For some reason the internal link attribute has been set to "http://" and the document ID is now returned in the internal attribute. In Umbraco, I have just used the gui tool to select the internal document which means I am unable to enter anything for the link value.

    Thanks, James

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Jan 07, 2014 @ 13:43
    Jeavon Leopold
    0

    Interesting both have type of "external", did you select internal for the second one?

  • James McIntosh 9 posts 29 karma points
    Jan 07, 2014 @ 13:59
    James McIntosh
    0

    Hi Jeavon,

    Good spot your right it does say its still external, yet the isInternal flag is set to true.

    For the second link, I used the "choose internal page" option, then the "Choose" option from the "Choose or enter external link" and then selected the appropriate internal page.

    I have setup another link where I delete the "http://" text from the external URL textbox and then follow the process of selecting an internal page and it is set as an Internal link (see below). So I think I know what the problem is/was: These links were originally set as external links to test out the functionality before we had internal pages, the links were then changed to point to internal pages. So I am thinking maybe changing this over has confused Umbraco?

    { "caption": "Test Internal", "link": "1092", "newWindow": false, "internal": "1092", "edit": false, "isInternal": true, "iternalName": "Test", "type": "internal", "title": "Test Internal" }
    
  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Jan 07, 2014 @ 15:52
    Jeavon Leopold
    0

    Hi James,

    Hurrah, I have been able to replicate this and indeed it's a bug in Umbraco which I have now fixed and submitted a pull request for :-)

    https://github.com/umbraco/Umbraco-CMS/pull/281

    Thanks,

    Jeavon

  • James McIntosh 9 posts 29 karma points
    Jan 07, 2014 @ 15:55
    James McIntosh
    0

    Hi Jeavon,

    Excellent, glad I wasn't going off my head haha!

    At least I know the work around in the mean time ;o)

    Thanks for your help.

    Thanks,

    James

Please Sign in or register to post replies

Write your reply to:

Draft