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> } } }
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.
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:
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:
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.
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
@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.
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 .
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: <ahref="@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/><imgsrc="@crops.Find("@name", "Thumbnail").url"alt="@image.nodeName"/><br/><imgsrc="@crops.Find("@name", "Header").url"alt="@image.nodeName"/>
}
</li>
}
elseif (!string.IsNullOrEmpty(file.InnerText))
{
file = file.File;
<li><ahref="@file.umbracoFile">@file.nodeName</a></li>
}
}
</ul>
}
}
}
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!
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 :).
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.
@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 = "";
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;
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.
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.
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:)
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.
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.
Surely someone has an idea on how to do this.
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.
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:
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:
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.
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 :
couldn't you just do:
and if you want to check whether it's XML can't you just do
?
@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.
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 .
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.
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.
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!
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
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.
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:
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
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
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
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
is working on a reply...