Copied to clipboard

Flag this post as spam?

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


  • Keith Petersen 67 posts 111 karma points
    Oct 15, 2011 @ 00:00
    Keith Petersen
    0

    Razor best practice way to check if a node exists

    I'm using the Digibiz Advanced Media Picker in 4.7.1. I want to check whether a mediaItem node contains an image or a file. In this situation it will be only 1 item of either type. I've tried several different ways to check if if a node named "image" exists. Every method results in more or less the same error: 'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'Image'

    Here's the code. It's probably something simple since I'm new with this.

    @{
    if (Model.HasValue("linkedLargeMap") && Model.HasValue("mediumMap")) {
    var largeItems = Model.linkedLargeMap.mediaItem;
    var mediumItems = Model.mediumMap.mediaItem;

    if (largeItems.Count() != 0 && mediumItems.Count() != 0) {


    <p>@largeItems[0].ToString()</p>

    dynamic largeMedia;
    if (largeItems[0].Image == null) /* trying to check null here */
    {
    largeMedia = largeItems[0].File;
    } else {
    largeMedia = largeItems[0].Image;
    }

    var mediumImage = mediumItems[0].Image;

    <a href="@largeMedia.umbracoFile" class="noIcon captioned" title="View Full Size"><img src="@mediumImage.umbracoFile" alt="@Model.Parent.Name map" />View Full Size Map</a>
    }
    }
    }
  • Keith Petersen 67 posts 111 karma points
    Oct 17, 2011 @ 19:42
    Keith Petersen
    0

    Surely someone has an idea on how to do this.

  • Justin Spradlin 139 posts 347 karma points
    Oct 17, 2011 @ 23:06
    Justin Spradlin
    0

    I was wondering the same thing the other day. I pulled down the cultiv Razor demos and wanted to allow both image and files to be picked and later rendered,I could not figure out a good way to iterate over the elements of the collection to determine what types each node was. I wanted to render <img> for images and <a> for files. I could not find a good way to do it either. 

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Oct 18, 2011 @ 15:59
    Sebastiaan Janssen
    0

    Here's an example where I test if crops exist, of course the same can be applied to the existence of the Image property. Note that I also check if the crops section actually is filled, with XML (crops.GetType().ToString() == "System.String") even if it exists: if it is not of type string then it most probably has been cast to XML:  

     

    @if (Model.HasValue("gallery"))
    {
        @RenderGallery(Model)
    }
    
    @helper RenderGallery(dynamic node)
    {
        dynamic mediaItems = node.Gallery.mediaItem;
    
        if (mediaItems.Count() != 0)
        {
            <div class="slider-wrapper theme-default">
                <div id="slider" class="nivoSlider">
                @foreach (var item in mediaItems)
                {
                    var image = item.Image;
                    var crops = image.crop;
    
                    if (crops == null || crops.GetType().ToString() == "System.String")
                    {
                        <img src="@image.umbracoFile" alt="@image.Name" title="@image.Name" />                
                    }
                    else
                    {
                        <img src="@crops.Find("@name""Gallery").url" alt="@image.Name" title="@image.Name" />
                    }
                }
                </div>
            </div>
        }
    }

     

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Oct 18, 2011 @ 16:00
    Sebastiaan Janssen
    1

    Here's an example where I test if crops exist, of course the same can be applied to the existence of the Image property. Note that I also check if the crops section actually is filled, with XML (crops.GetType().ToString() == "System.String") even if it exists: if it is not of type string then it most probably has been cast to XML:  

     

    @if (Model.HasValue("gallery"))
    {
        @RenderGallery(Model)
    }
    
    @helper RenderGallery(dynamic node)
    {
        dynamic mediaItems = node.Gallery.mediaItem;
    
        if (mediaItems.Count() != 0)
        {
            <div class="slider-wrapper theme-default">
                <div id="slider" class="nivoSlider">
                @foreach (var item in mediaItems)
                {
                    var image = item.Image;
                    var crops = image.crop;
    
                    if (crops == null || crops.GetType().ToString() == "System.String")
                    {
                        <img src="@image.umbracoFile" alt="@image.Name" title="@image.Name" />                
                    }
                    else
                    {
                        <img src="@crops.Find("@name""Gallery").url" alt="@image.Name" title="@image.Name" />
                    }
                }
                </div>
            </div>
        }
    }

     

  • Keith Petersen 67 posts 111 karma points
    Oct 18, 2011 @ 19:24
    Keith Petersen
    0

    I've tried following your example above as closely as I can (with the foreach loop, etc.) and still get the same error. It's not even getting to the conditional: it fails at var image = item.Image; . If there's an image instead of a file, it fails at that variable. I looked at the XML in umbraco.config and it appears correct for DAMP.

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

    @{
    if (Model.HasValue("linkedLargeMap") && Model.HasValue("mediumMap"))
    {
    dynamic largeItems = Model.linkedLargeMap.mediaItem;
    dynamic mediumItems = Model.mediumMap.mediaItem;

    if (largeItems.Count() != 0 && mediumItems.Count() != 0)
    {
    var mediumImage = mediumItems[0].Image;

    foreach (var item in largeItems)
    {
    var image = item.Image;
    var file = item.File;

    if (file == null || file.GetType().ToString() == "System.String")
    {
    <a href="@image.umbracoFile" class="noIcon captioned" title="View Full Size">
    <img src="@mediumImage.umbracoFile" alt="@Model.Parent.Name map" />View Full Size
    Map</a>
    }
    else
    {
    <a href="@file.umbracoFile" class="noIcon captioned" title="View Full Size">
    <img src="@mediumImage.umbracoFile" alt="@Model.Parent.Name map" />View Full Size
    Map</a>
    }
    }
    }
    }
    }
  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Oct 18, 2011 @ 20:30
    Dan Diplo
    0

    Off topic sligthtly, but just a quick point to Seb who said:

    "Note that I also check if the crops section actually is filled, with XML (crops.GetType().ToString() == "System.String") even if it exists: if it is not of type string then it most probably has been cast to XML"

    Instead of :

    if (crops.GetType().ToString() == "System.String") { ... }

    couldn't you just do:

    if (crops is string) { ... }

    and if you want to check whether it's XML can't you just do

    if (crops is DynamicXml) { .... }

    ?

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Oct 18, 2011 @ 20:38
    Sebastiaan Janssen
    0

    @keith Could you please provide the xml for DAMP with a file and an image? You could try to check if item.HasValue("Image")? That might work, not sure at the moment. 

    @DanDiplo: Damn, I KNEW when I was typing it that someone would ask that exact question haha! Haven't had a chance to try that though, will do tomorrow.

  • Keith Petersen 67 posts 111 karma points
    Oct 19, 2011 @ 00:26
    Keith Petersen
    0

    When I try HasValue("Image") I get No overload for method 'HasValue' takes '1' arguments. It's like none of the Razor methods exist for the object, but the mediaItem object seems ok and says it's of type DynamicXml .

    <ConservationMapDetail id="1599" parentID="1597" level="5" writerID="2" creatorID="2" nodeType="1586" template="1587" sortOrder="1" createDate="2011-10-11T16:50:45" updateDate="2011-10-17T10:28:03" nodeName="Map Detail" urlName="map-detail" writerName="Keith Petersen" creatorName="Keith Petersen" path="-1,1229,1547,1575,1597,1599" isDoc="">
    <linkedLargeMap>
    <DAMP fullMedia="">
    <mediaItem>
    <File id="1601" version="d95ef38d-7a4c-45ad-9b14-acc783804161" parentID="1581" level="4" writerID="2" nodeType="1033" template="0" sortOrder="2" createDate="2011-10-11T16:55:52" updateDate="2011-10-11T16:55:53" nodeName="Chichaqua bottoms greenbelt" urlName="chichaquabottomsgreenbelt" writerName="Keith Petersen" nodeTypeAlias="File" path="-1,1551,1572,1581,1601">
    <umbracoFile>/media/7184/chichaqua-bottoms-greenbelt.pdf</umbracoFile>
    <umbracoExtension>pdf</umbracoExtension>
    <umbracoBytes>658280</umbracoBytes>
    </File>
    </mediaItem>
    </DAMP>
    </linkedLargeMap>
    <mediumMap>
    <DAMP fullMedia="">
    <mediaItem>
    <Image id="1600" version="2d26d5cd-3017-4b67-99a4-8b66eed62142" parentID="1580" level="4" writerID="2" nodeType="1032" template="0" sortOrder="4" createDate="2011-10-11T16:54:11" updateDate="2011-10-11T16:54:12" nodeName="Chichaqua bottoms greenbelt" urlName="chichaquabottomsgreenbelt" writerName="Keith Petersen" nodeTypeAlias="Image" path="-1,1551,1572,1580,1600">
    <umbracoFile>/media/7179/chichaqua-bottoms-greenbelt.png</umbracoFile>
    <umbracoWidth>605</umbracoWidth>
    <umbracoHeight>783</umbracoHeight>
    <umbracoBytes>48388</umbracoBytes>
    <umbracoExtension>png</umbracoExtension>
    </Image>
    </mediaItem>
    </DAMP>
    </mediumMap>
    <bodyText><![CDATA[]]></bodyText>
    <umbracoNaviHide>0</umbracoNaviHide>
    <enableTabNavigation>0</enableTabNavigation>
    </ConservationMapDetail>
  • Justin Spradlin 139 posts 347 karma points
    Oct 19, 2011 @ 04:25
    Justin Spradlin
    2

    I know this is kind of a hack but I used the DynamicXml.XPath to get a new DynamicXml node back for the two types. Here is my script that is working. Notice that if a match is return it is returned inside a <results></results> element that is why I added the line inside the if statements to set image = image.Image or file = file.File. This is an update to the Cultiv Razor demo page for the DAMP picker.

    @using umbraco.MacroEngines
    @inherits umbraco.MacroEngines.DynamicNodeContext
    <h2>@Model.Name</h2>
    <h3>
        Digibiz Advanced Media Picker</h3>
    @{
        if (Model.HasValue("Media"))
        {
            dynamic mediaItems = Model.Media.mediaItem;
            if (mediaItems.Count() != 0)
            {
        <ul>
            @foreach (var item in mediaItems)
            {
    
                dynamic image = item.XPath("Image");
                dynamic file = item.XPath("File");
    
                if (!string.IsNullOrEmpty(image.InnerText))
                {
                    image = image.Image; 
                <li>Original image: <a href="@image.umbracoFile">@image.nodeName</a> (@image.umbracoBytes
                    bytes)<br />
                    @*                         If the type of the mediacropper is not XML (but a string) then there                          are no crops defined, so I should not try to find the crops.                     *@
                    @{ var crops = image.mediaCropper; }
                    @if (crops.GetType().ToString() != "System.String")
                    {
                        <text>Crops:</text><br />
                        <img src="@crops.Find("@name""Thumbnail").url" alt="@image.nodeName"/><br />
                        <img src="@crops.Find("@name""Header").url" alt="@image.nodeName"/>
                    }
                </li>
                }
                else if (!string.IsNullOrEmpty(file.InnerText))
                {
                    file = file.File; 
                    <li><a href="@file.umbracoFile">@file.nodeName</a></li>
                    
                }
    
            }
        </ul>
            }
        }
    }
    
  • Keith Petersen 67 posts 111 karma points
    Oct 19, 2011 @ 23:58
    Keith Petersen
    0

    Your hack works for me too. Thanks! I'm baffled why you and I have to use this hack while Sebastiaan and others apparently don't have a problem.

  • Craig100 1136 posts 2523 karma points c-trib
    Jun 21, 2012 @ 18:07
    Craig100
    0

    Getting hold of these crops is an absolute nightmare, with or without DAMP. I've spent the last several days picking tiny bits and peices out of the forum and everntually rolling my own that doesn't look like any of them . It's TOO difficult! I now have a slightly different scenario and I'm off on a major hunt again because nothing I've already got works. Although I can see what I'm aiming for in the umbraco.config I can't get to it!!!!!!  Is there anywhere this frustration can be given more prominence so something can be done about it. It shouldn't be this difficult, it's not XSLT!

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jun 21, 2012 @ 18:11
    Jeroen Breuer
    0

    Could you give more specific things you don't like? Currently Umbraco is looking at every possible way to improve v4 so some substantiated feedback will be very welcome :). Did you see the Razor Components package? That might help :).

    Jeroen

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Jun 21, 2012 @ 19:11
    Dan Diplo
    0

    Whilst it's not a solution to crops, I much prefer using ImageGen for dynamically creating images. It's very easy to use with Razor, especially if you write a few helper functions.

  • Craig100 1136 posts 2523 karma points c-trib
    Jun 21, 2012 @ 21:09
    Craig100
    0

    Thanks for the quick response guys.

    @Dan. I'm using imageGen to ensure whatever crop is selected is output at the correct size.  Cropping I see as selecting an area of the correct ratio.

    @Jeroen. Enjoyed your talk at CG12 which is why I'm starting to use DAMP and Image Cropper for the first time.  However, it seems to be extraordinarily difficult to hit a crop, no consistant approach.  Below I show a bit of an umbraco.config file which I use to work out what is contained in what and then I have this Macro (which doesn't yet work) trying to hit the crops.  You don't seem to be able just to go down the XML tree in dot notation and then get what you want.  I've added the inherits and using statements at the top as a scatter gun approach from reading possibly outdated forum posts.  Clear documentation and a consistent, clear approach would work wonders for guys like me who want to use Umbraco more but don't get the chance because of their clients wishes. So I'm not THAT experienced at knowing the inner tricks of Umbraco, hence the wish for better documentation. I'm sure I'm not alone.

    The Macro to create a Gallery index page of Picture page child pages:

     

    @inherits umbraco.MacroEngines.DynamicNodeContext
    @using DigibizAdvancedMediaPicker;
    @{
     //Check the currentpage has children
      var theCount = @Model.Descendants("PicturePage").Count();
     if (theCount > 0)
        {
           var width = Parameter.w;
           var height = Parameter.h;
           var count = 1;
           var figClass = "";
           
            <div class="galleryContainerDiv">
               @foreach (var picturePage in Model.Descendants("PicturePage").Where("Visible"))
                {
                    if(count == 4){
                     figClass = "class=\"fourthFigure\"";
                     count = 0;
                   }
                     <figure @Html.Raw(figClass)>
                    @{
                      if (picturePage.HasValue("image1"))
                     {
                       dynamic mediaItems = Model.image1.mediaItem;
                       if (mediaItems.Count() != 0) //THIS IS NEVER > 0 EVEN THOUGH image1.mediaItems EXISTS IN THE XML
                       {
                         var image = mediaItems.Image;
                           
                         @: <a href="@picturePage.Url" title="@picturePage.PictureTitle">
                   
                         var theCrop = DAMP_Helper.GetImageCropperUrl(image, "Gallery Image");
                         if(theCrop != null || theCrop .GetType().ToString() != "System.String")
                         {                                            
                            @:<img src="/ImageGen.ashx?image=@theCrop&amp;AltImage=noimage-newslist.gif&amp;width=@width&amp;height=@height" width="@width"height="@height" alt="@picturePage.PictureTitle">           
                           }
                         @:</a>
                       }
                      else
                      {
                       @: No Images
                       }
                      }
                     }        
                       <figcaption>
                          <a href="@picturePage.Url" title="@picturePage.PictureTitle">
                          @picturePage.PictureTitle</a>
                       </figcaption>
                   </figure>
                   figClass = "";
                   count++;
               }
           </div>
       }
     else
     {
      @:No Picture Pages set up
    }
    }

    The associated XML, picture pages are children of the page I'm on, I'm trying to list out a certain crop of the image for each picture page:-

    <PicturePage id="1163" parentID="1150" level="4" writerID="0" creatorID="0" nodeType="1160" template="1162" sortOrder="1" createDate="2012-06-08T13:14:47" updateDate="2012-06-21T18:00:43" nodeName="My First Picture" urlName="my-first-picture" writerName="admin" creatorName="admin" path="-1,1053,1143,1150,1163" isDoc="">
              <pictureTitle>My First Picture</pictureTitle>
              <image1>
                <DAMP fullMedia="">
                  <mediaItem>
                    <Image id="1128" version="b8fd0f0d-b0fc-46e3-b6c9-11d668fce727" parentID="1118" level="4" writerID="0" nodeType="1032" template="0" sortOrder="2" createDate="2012-06-07T19:00:00" updateDate="2012-06-07T19:00:00" nodeName="Piece 1 (2012)" urlName="piece1(2012)" writerName="admin" nodeTypeAlias="Image" path="-1,1111,1112,1118,1128">
                      <umbracoFile>/media/741/OI_Papageno-and-Papagena.jpg</umbracoFile>
                      <umbracoWidth>500</umbracoWidth>
                      <umbracoHeight>442</umbracoHeight>
                      <umbracoBytes>52114</umbracoBytes>
                      <umbracoExtension>jpg</umbracoExtension>
                      <imageCropper>
                        <crops date="2012-06-07T19:00:00">
                          <crop name="Home Thumbnails" x="0" y="59" x2="500" y2="381" url="/media/741/OI_Papageno-and-Papagena_Home Thumbnails.jpg" />
                          <crop name="News Item" x="29" y="0" x2="471" y2="442" url="/media/741/OI_Papageno-and-Papagena_News Item.jpg" />
                          <crop name="Contact Page" x="0" y="96" x2="500" y2="346" url="/media/741/OI_Papageno-and-Papagena_Contact Page.jpg" />
                          <crop name="Gallery Image" x="29" y="0" x2="471" y2="442" url="/media/741/OI_Papageno-and-Papagena_Gallery Image.jpg" />
                          <crop name="Zoomable Image" x="0" y="104" x2="500" y2="337" url="/media/741/OI_Papageno-and-Papagena_Zoomable Image.jpg" />
                          <crop name="Submenu Thumbnails" x="0" y="21" x2="500" y2="421" url="/media/741/OI_Papageno-and-Papagena_Submenu Thumbnails.jpg" />
                        </crops>
                      </imageCropper>
                    </Image>
                  </mediaItem>
                </DAMP>
              </image1>
              <details><![CDATA[Embellished GliclĂ©e on Canvas
    Limited Edition of 195 / signed and numbered
    10" x 16" (unframed)]]></details>
              <description><![CDATA[
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
    ac fringilla nulla. Etiam pharetra vulputate imperdiet. Curabitur
    iaculis vehicula tempus. Nulla vel eros at magna ullamcorper
    eleifend. Phasellus quis mauris non metus auctor pellentesque eget
    sit amet elit. Sed tincidunt, enim et vulputate ultrices, nisi
    lorem accumsan lacus, nec aliquet justo eros vitae elit. Sed
    consequat volutpat dignissim.</p>
    ]]></description>
              <backgroundImage />
              <pageTitle>My First Picture</pageTitle>
              <metaDescription />
              <metaKeywords />
              <hideSubNav>0</hideSubNav>
              <xmldumpAllowed>0</xmldumpAllowed>
              <umbracoNaviHide>0</umbracoNaviHide>
              <hideFromSearchAndSitemap>0</hideFromSearchAndSitemap>
            </PicturePage>

    To my mind it by the time I've established the node exists (which I haven't by the way!!!) by using if(picturePage.HasValue("image1")) then I should be able to get to the image with picturePage.image1.Image.umbracoFile and the crops using the DAMP function as var theCrop = DAMP_Helper.GetImageCropperUrl(picturePage.image1.Image, "Gallery Image"); but it doesn't happen.  

    Each time I look for a crop in either a child page or within the Model page, it's nearly always different, can never use the same technique twice. I appreciate that it CAN work, it's just that without significant effort in this area alone it doesn't appear to be at all intuitive or logical with my level of knowledge. I'm a web developer of 17 years standing, so not a total novice, but not a "hard core computer programmer".

    I hope this can be made easier or at least more discoverable in the upcoming releases.

    Thanks,

    Craig

     

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jun 21, 2012 @ 23:27
    Jeroen Breuer
    1

    Hi Craig,

    What version of Umbraco are you using? The Razor implementation changed a couple of times through the latest versions. Perhaps it's better to start with a more easy example for DAMP. Did you try the DAMP 2.0 Samples package? If you have an empty Umbraco version with DAMP 2.0 you can install this package and it shows some nice examples. In this video you can see how to install it: http://www.screenr.com/gz0s. You can find the Razor example here: http://damp.codeplex.com/SourceControl/changeset/view/86116#1970702. I hope this can help you.

    Jeroen

  • Craig100 1136 posts 2523 karma points c-trib
    Jun 21, 2012 @ 23:35
    Craig100
    0

    Hi Jeroen,

    It's a 4.7.2 site. I now have that example working. There were some significant errors in it that I hadn't noticed. However, the comments about general difficulty stand I think.

    Thanks for the links.  I couldn't get the Razor samples package working when I first tried a few months ago, (i think I messaged you about it at the time).  I installed the CultiveRaxorExamples site and that was very informative but nothing worked when transferred to my work hence the major travels around the forum.

    The codeplex link you gave looks good, I will definitely study that when I get some brain power back tomorrow.

    Thanks for your support. I'm looking forward to presenting this work to a designer that's never seen DAMP before, I think he's going to be blown away:)

    Craig

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jun 21, 2012 @ 23:43
    Jeroen Breuer
    0

    Glad you got it working :). Perhaps start a topic here about what you would like to see improved in Razor: https://groups.google.com/forum/#!forum/umbraco-dev.

    I remember the topic from the sample package :). Problem was that the sample package only works if you keep the checkboxes after installing checked. That will ensure media items will always have all the crops. If they don't have the crops you'll get an error in Razor.

    Jeroen

Please Sign in or register to post replies

Write your reply to:

Draft