Copied to clipboard

Flag this post as spam?

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


  • Toni Becker 146 posts 425 karma points
    Mar 27, 2011 @ 09:48
    Toni Becker
    0

    Question for an XML Data Loop

    Ok hy everybody.

    Here's my problem. I'm using the DAMP Picker and adding mutliple Instance of Image to an article.

    When i loop through the content with only 1 Picture everything works fine and the XML and Razor is looking like that:

    XML Output:

    <multiImage>
            <DAMP fullMedia="">
              <mediaItem>
                <Image id="1308" version="27418d84-19de-49d4-a706-cf95c4cde909" parentID="1251" level="3" writerID="0" nodeType="1032" template="0" sortOrder="9" createDate="2011-03-26T14:49:48" updateDate="2011-03-26T14:49:48" nodeName="anpassung" urlName="anpassung" writerName="admin" nodeTypeAlias="Image" path="-1,1249,1251,1308">
                  <umbracoFile>/media/1824/anpassung.jpg</umbracoFile>
                  <umbracoWidth>585</umbracoWidth>
                  <umbracoHeight>185</umbracoHeight>
                  <umbracoBytes>10675</umbracoBytes>
                  <umbracoExtension>jpg</umbracoExtension>
                </Image>
              </mediaItem>
            </DAMP>
          </multiImage>

     

    RAZOR:

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using umbraco.MacroEngines;

    <a href="@umbraco.library.NiceUrl(Model.linkPicker)">
    <img src="@Model.multiImage.mediaItem.Image.umbracoFile"/>

    Okay and now the Problem.

    When i loop with

     @foreach (var varName or some predefined Var..)
    {
    <img src="@Model.multiImage.mediaItem.Image.umbracoFile"/>
    }

    nothings returned.

    This is the XML:

    <multiImage>
            <DAMP fullMedia="">
              <mediaItem>
                <Image id="1308" version="27418d84-19de-49d4-a706-cf95c4cde909" parentID="1251" level="3" writerID="0" nodeType="1032" template="0" sortOrder="9" createDate="2011-03-26T14:49:48" updateDate="2011-03-26T14:49:48" nodeName="anpassung" urlName="anpassung" writerName="admin" nodeTypeAlias="Image" path="-1,1249,1251,1308">
                  <umbracoFile>/media/1824/anpassung.jpg</umbracoFile>
                  <umbracoWidth>585</umbracoWidth>
                  <umbracoHeight>185</umbracoHeight>
                  <umbracoBytes>10675</umbracoBytes>
                  <umbracoExtension>jpg</umbracoExtension>
                </Image>
              </mediaItem>
            </DAMP>
          </multiImage>
    <multiImage>
            <DAMP fullMedia="">
              <mediaItem>
                <Image id="1309" version="27418d84-19de-49d4-a706-cf95c4cde909" parentID="1251" level="3" writerID="0" nodeType="1032" template="0" sortOrder="9" createDate="2011-03-26T14:49:48" updateDate="2011-03-26T14:49:48" nodeName="anpassung" urlName="anpassung" writerName="admin" nodeTypeAlias="Image" path="-1,1249,1251,1308">
                  <umbracoFile>/media/1824/anpassung.jpg</umbracoFile>
                  <umbracoWidth>585</umbracoWidth>
                  <umbracoHeight>185</umbracoHeight>
                  <umbracoBytes>10675</umbracoBytes>
                  <umbracoExtension>jpg</umbracoExtension>
                </Image>
              </mediaItem>
            </DAMP>
          </multiImage>

    How i can solve this problem?

    Thanks for every help.

     

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Mar 28, 2011 @ 08:25
    Sebastiaan Janssen
    0

    How about doing something like (untested):

    @foreach (var image in Model.multiImage) {
        //Do your thing
    }

    Does that work?

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 08:34
    Toni Becker
    0

    Thanks for your advice. When i put it in nothings rendering.

    tried this way:

    @foreach (var image in Model.multiImage) {
    <img src="@image.umbracoFile"/>
    }

    Other Ideas? I've looked in to uql but can't see how to solve it this way. Razor supports looking up the Xml tree inside my umbraco.config.

    Could it be done via dynamic node or list ?

    Sitting here for hours since yesterday without any result. Searching through a bunch of forums without results. Hmpf :)

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Mar 28, 2011 @ 09:01
    Sebastiaan Janssen
    0

    Yeah, I've just experimented a bit and the only way I can get the results out is with a workaround:

    @{   
        var count = 0; 
        foreach (var item in Model.multiImage)
        {
            count = count + 1;
        }
    }
    
    @for (int i = 0; i < count; i++)
    {
        <img src="@Model.multiImage[i].Image.umbracoFile" />
    }
  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 09:41
    Toni Becker
    0

    Testing in 5 Minutes and give you a feedback. Thanks for the reply. :)

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 10:00
    Toni Becker
    0

    Thanks for your quick replies. Okay nothing rendered. But no problem if theres some time here is the XML Markup explained to solve this issue. Because if its work, would be great way for Image galleries using DAMP (New).

    Here comes the Markup:
    //** This is the Documenttype for the entire list of images
    <Imagerender id="1311" parentID="1089" level="2" writerID="0" creatorID="0" nodeType="1310" template="1309" sortOrder="11" createDate="2011-03-27T11:48:29" updateDate="2011-03-27T11:49:05" nodeName="MultipleImg" urlName="multipleimg" writerName="admin" creatorName="admin" path="-1,1089,1311" isDoc="">
        
    //**This is the Documenttype for the Image and holds the properties:
    <Multiimage id="1312" parentID="1311" level="3" writerID="0" creatorID="0" nodeType="1298" template="1299" sortOrder="1" createDate="2011-03-27T11:49:13" updateDate="2011-03-28T09:44:23" nodeName="Beitrag 1" urlName="beitrag-1" writerName="admin" creatorName="admin" path="-1,1089,1311,1312" isDoc="">

    //** Property with name multiImage by type DAMP Media Picker      
    <multiImage>

    //** Here starts the outPut from DAMP which can store multiple Items in one Picker
              <DAMP fullMedia="">
                <mediaItem>
                  <Image id="1306" version="64c52dfe-4601-452c-ac44-6643a461e933" parentID="1251" level="3" writerID="0" nodeType="1032" template="0" sortOrder="8" createDate="2011-03-26T11:13:13" updateDate="2011-03-26T11:13:14" nodeName="beratung" urlName="beratung" writerName="admin" nodeTypeAlias="Image" path="-1,1249,1251,1306">
                    <umbracoFile>/media/1807/beratung.jpg</umbracoFile>
                    <umbracoWidth>585</umbracoWidth>
                    <umbracoHeight>185</umbracoHeight>
                    <umbracoBytes>23498</umbracoBytes>
                    <umbracoExtension>jpg</umbracoExtension>
                  </Image>
                </mediaItem>
                <mediaItem>
                  <Image id="1308" version="27418d84-19de-49d4-a706-cf95c4cde909" parentID="1251" level="3" writerID="0" nodeType="1032" template="0" sortOrder="9" createDate="2011-03-26T14:49:48" updateDate="2011-03-26T14:49:48" nodeName="anpassung" urlName="anpassung" writerName="admin" nodeTypeAlias="Image" path="-1,1249,1251,1308">
                    <umbracoFile>/media/1824/anpassung.jpg</umbracoFile>
                    <umbracoWidth>585</umbracoWidth>
                    <umbracoHeight>185</umbracoHeight>
                    <umbracoBytes>10675</umbracoBytes>
                    <umbracoExtension>jpg</umbracoExtension>
                  </Image>
                </mediaItem>
              </DAMP>
            </multiImage>
            <linkPicker>1090</linkPicker>
          </Multiimage>
        </Imagerender>

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Mar 28, 2011 @ 10:39
    Sebastiaan Janssen
    0

    Ah yes, looks like I made a mistake in the img source, this should do the trick, I hope (can't test at the moment):

    <img src="@Model.multiImage[i].mediaItem.Image.umbracoFile" />

    If that doesn't work, just play around a bit with Model.multImage[i], shouldn't be too hard to figure out.

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 11:56
    Toni Becker
    0

    Hmpf won't work. Tested out alot of combinations with [i] but no rendering.

    What about using a dynamicnode?

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using umbraco.MacroEngines;
    @using System.Linq;

    @*{
       dynamic node = new umbraco.MacroEngines.DynamicNode(1311);
    }

    @foreach(var page in node.Children) {                            
                                     @page.Id
                                    <a href="@umbraco.library.NiceUrl(page.linkPicker)">Link</a>
                                 <img src="@page.multiImage.mediaItem[0].Image.umbracoFile"/>
                                    }

    <a href="@umbraco.library.NiceUrl(Model.Multiimage[0].linkPicker)">
    <img src="@Model.Multiimage.multiImage.mediaItem.Image.umbracoFile"/>
    *@

     

    With the foreach and the [0] it works but only pulls out the first image in the array if i set to none, no rendering.

    So the solution, if it's possible loop through the mediaItems wich have the properties and count through with [i].

    Btw the @for is not a regular razor-syntax? or am i wrong.

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 13:29
    Toni Becker
    0

    Okay here's what i have so far:

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using umbraco.MacroEngines;
    @using System.Linq;
    @{
       dynamic node = new umbraco.MacroEngines.DynamicNode(1049);
    }

    @foreach(var page in node.Children) {                             
                                     @page.Id
                                    
                                 <img src="@page.imageUpload.mediaItem[0].Image.umbracoFile"/>
    }

        This works but only for one Image insde the mediaItem[0].
    Referencing to the second with mediaItem[1] works too. But how to make this dynamicly looping through the mediaItems.

    Hmpf some Ideas :) this way?

     

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 13:39
    Toni Becker
    0

    So this works at first, but only rendering 1 image, but need the complete Pictures :):

    @{  
      dynamic node = new umbraco.MacroEngines.DynamicNode(1049);
        var count 0;
      }
      
       @foreach (var item in node.Children)
        {
            count count 1;
         for (int i 0i counti++)
    {
        <img src="@item.imageUpload.mediaItem[i].Image.umbracoFile" />
    }
        }
  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 13:46
    Toni Becker
    0

    Okay next Step available, but when i have 3 Pictures i manually have to increase the var count to number 2 and it's rendering fine the 3 pictures, but when i remove 1 picture i drops an error:

    is there a way to dynamiclly increase the var count = ..   ?

    @{  
      dynamic node = new umbraco.MacroEngines.DynamicNode(1049);
        var count = 2;
      }
      
       @foreach (var item in node.Children)
        {
            count = count + 1;
           for (int i = 0; i < count; i++)
          {
          <img src="@item.imageUpload.mediaItem[i].Image.umbracoFile" />
          }
        }

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Mar 28, 2011 @ 14:16
    Sebastiaan Janssen
    0

    To get the count of the number of mediaItems, I do a foreach loop before the for loop. Yes, @for is "normal"  Razor syntax, in essence Razor is C#, so you can just use C#'s for loops. Why do you suddenly need Children? I though DAMP was on the current page?

    So the complete code should be:

    @{   
        var count = 0; 
        foreach (var item in Model.multiImage)
        {
            count = count + 1;
        }
    }
    
    @for (int i = 0; i < count; i++)
    {
        <img src="@Model.imageUpload.mediaItem[i].Image.umbracoFile" />
    }

    Or, if the mediaItem property is in child nodes (if I understand your structure correctly:

    @foreach (var item in node.Children) 
    {
        var count = 0; 
        foreach (var image in item.imageUpload.multiImage)
        {
                count = count + 1;
        }
    
        for (int i = 0; i < count; i++)
        {
            <img src="item.imageUpload.mediaItem[i].Image.umbracoFile" />
        }
    }

     

     

  • Alex 78 posts 136 karma points
    Mar 28, 2011 @ 14:25
    Alex
    0

    You could use this to get the image count too, not sure which is neater! :-s

     

    ((IEnumerable<XElement>)Model.multiImage.BaseElement.Elements()).Count()
  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 14:35
    Toni Becker
    0

    yeeha!!!!!!!!!! got it workin!!!! N1 and thanks for the help!!!!

    Here comes the code:

    @{  
      dynamic node = new umbraco.MacroEngines.DynamicNode(1049);
      }

      
    @foreach (var item in node.Children)
        {
         int count = 0;
         foreach (var image in item.imageUpload)
         { count = count + 1; }
         for (int i = 0; i < count; i++)
           {
            
           <img src="@item.imageUpload.mediaItem[i].Image.umbracoFile" />
           }
         }

    So i will make a screencast and show you what to do with that nice little snippet.

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Mar 28, 2011 @ 14:50
    Sebastiaan Janssen
    0

    @Alex hehe, looks nasty! ;-)

    @Toni it's hacky though I don't like the code. Would be easier to use XSLT for this at the moment. Maybe I've missed something, but I think the DynamicXml implementation could use some polish so that you could just do a foreach like you would expect.

  • Alex 78 posts 136 karma points
    Mar 28, 2011 @ 15:28
    Alex
    0

    I am thinking there must be a way to do it using the DynamicXml XPath method, for example

    @foreach(dynamic d in Model.multiImageMultiple.XPath("mediaItem/Image"))
        {
           @d.umbracoFile.ToString();  
        }

    That works if you have more than 1 image picked but throws an error otherwise saying umbracoFile is not a property of DynamicXml. It obviously has something to do with the way DynamicXml return multiple nodes as apposed to one node.

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Mar 28, 2011 @ 15:35
    Sebastiaan Janssen
    0

    @Alex yeah, as I understood it, DynamicXml was made so that you could completely avoid XPath statements. I've asked Gareth to have a look at this thread, let's see what he thinks.

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 15:46
    Toni Becker
    0

    Okay made a screencast and show you what i've meant for the ability of this snippet and future development. e.g. filebase or something else.

    Here's the Link http://www.youtube.com/watch?v=H129KEw8JE0

  • Toni Becker 146 posts 425 karma points
    Mar 28, 2011 @ 15:47
    Toni Becker
    0

    You can check with an if statement and when there's only 1 image you use the normal Method otherwise choose the dynamic xml i think it's neat solution with short code.

  • Alex 78 posts 136 karma points
    Mar 28, 2011 @ 16:03
    Alex
    0

    @Sebastiaan Yep, I think it is going to need some more work before it's at that stage.

    @Toni Nice work on the screencast, will find time to sit through it later tonight. Glad we could help.

    This will also work by the way

    @foreach(dynamic d in Model.multiImageMultiple.XPath("mediaItem"))
        {
          if (d.BaseElement.Name == "Image")
          {
            @d.umbracoFile
          }
          else
          {
            @d.Image.umbracoFile
          }
        }
  • Alex 78 posts 136 karma points
    Mar 28, 2011 @ 17:11
    Alex
    0

    In fact you don't have to use the XPath, this works fine for me.

    @foreach(dynamic d in Model.multiImage.mediaItem)
        {
          if (d.BaseElement.Name == "Image")
          {
            @d.umbracoFile
          }
          else
          {
            @d.Image.umbracoFile
          }
        }
  • Toni Becker 146 posts 425 karma points
    Mar 29, 2011 @ 07:01
    Toni Becker
    0

    okay nice solution and very short snippet, but this is not rendering out something in my solution :(

  • Toni Becker 146 posts 425 karma points
    Mar 29, 2011 @ 07:59
    Toni Becker
    0

    Okay little bit optimized my code:
    When there was only 1 Picture it throws an error, solution use an if statement and check the count.
    I think you could evaluate this also by checking if its DynamicXML or not, but for me this works perfect:

    Here comes the code:

    @foreach (var item in node.Children)
        {
         int count = 0;
         foreach (var image in item.imageUpload)
         { count = count + 1; }
         for (var i = 0; i < count; i++)
           {
            if (count == 1)
            {
           <img src="@item.imageUpload.mediaItem.Image.umbracoFile" />
             }
            else
            {
             <img src="@item.imageUpload.mediaItem[i].Image.umbracoFile" />
             }
           }    
         }

     

  • Alex 78 posts 136 karma points
    Mar 29, 2011 @ 09:45
    Alex
    1

    Hmm strange that it doesn't work for you, I replicated (I think) your situation and the following code works ok, I have also added a check to make sure at least 1 image is selected. Probably no dofference to your method in terms of performace though, I just can't help tweaking! :)

     <umbraco:Macro  runat="server" language="cshtml">
        @using umbraco.MacroEngines
        @foreach(dynamic img in Model.Children)
        {
          if(img.imageUpload.ToString() != "")
          {
            foreach(dynamic d in img.imageUpload.mediaItem)
            {
              if (d.BaseElement.Name == "Image")
              { <img src="@d.umbracoFile" /> }
              else
              { <img src="@d.Image.umbracoFile" /> }
            }
          }
          else
          { <span>No images selected</span> }
       }
    </umbraco:Macro>

     

  • Toni Becker 146 posts 425 karma points
    Mar 29, 2011 @ 10:47
    Toni Becker
    0

    n1 to Alex works like a hellmachine :) cleaner and nice syntax than mine. will use this one :)

  • Alex 78 posts 136 karma points
    Mar 29, 2011 @ 14:56
    Alex
    1

    Glad you got it working. As you know the problem is around how the DynamicXml object returns a single element as opposed to multiple, I think when there are multiple entries they get wrapped by a "root" node to make the XML valid. Perhaps there is a reason why it was done this way but I think it may have been better to add the "root" node wrapper regardless of the number of items being returned that way you wouldn't have to check the BaseElement type as you would always have to allow for the "root" node and use the second option.

    I am probably misunderstanding the case and I am sure Gareth could clear the situation up and the reasoning behind it.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    May 12, 2011 @ 12:55
    Jeroen Breuer
    0

    Just wanted to post a sample that works with 1 or multiple items in DAMP:

    <ul class="photoalbum">

    @*Loop through all the selected photo album images from DAMP.*@
    @foreach (dynamic d in Model.photos)
    {
    <li>
    <a href="@d.Image.umbracoFile" rel="gallery">
    <img src="@DAMP_Helper.GetImageCropperUrl(d, "photoAlbum")" width="190" height="190" align="left" alt="@d.Image.alt" border="0" class="styled" />
    </a>
    </li>
    }

    </ul>

    Btw the "root" node problem will be fixed in 4.7.1. See this topic: http://our.umbraco.org/forum/developers/razor/20024-Root-node-removed-problem-in-DynamicXml#comment76195

    Jeroen

  • Niklas Hjelm 104 posts 125 karma points
    Aug 14, 2011 @ 12:30
    Niklas Hjelm
    0

    @Alex

    Hi Alex! I've been using your example where you don't check if the image is null. This has been working fine but when I try to use your new example I can't get it to show anything. I'm guessing it has to do with the first foreach

    @foreach(dynamic img in Model.Children)

    Any clues?

    Thanks / Niklas

  • Paul Stewart 50 posts 71 karma points
    May 09, 2012 @ 14:55
    Paul Stewart
    0

    See if I want to only display the first xml entry how would I achieve that? 

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    May 09, 2012 @ 14:57
    Jeroen Breuer
    0

    Could you post how your xml looks like? You can find it in the umbraco.config file. Than we can help you better.

    Jeroen

Please Sign in or register to post replies

Write your reply to:

Draft