I'm trying to use Razor to render content coming from a multinode tree picker where you can pick custom media items that have an image cropper property. I have tried many things, but so far without success.
In a
@foreach (var x in @Model.images)
where 'images' is the tree picker, I can get the media item with
dynamic m = @Model.MediaById(@x.InnerText);
@m.umbracoFile works just fine.
Now, to get the crops I tried several things. I tried to get the xml with
@m.GetProperty("thumbnail").Value.ToString()
This gives the error "Cannot perform runtime binding on a null reference".
I tried to use the uCompoents extension GetImageCropperUrl(string, string), but
dynamic m = new DynamicMedia(Convert.ToInt32(@x.InnerText));
this makes the script fail.
I also tried
dynamic m = new umbraco.MacroEngines.DynamicMedia(Convert.ToInt32(@x.InnerText));
but this gives the error "The best overloaded
method match for
'umbraco.MacroEngines.DynamicMedia.DynamicMedia(umbraco.MacroEngines.DynamicBackingItem)'
has some invalid argument"
Next was
var m = uQuery.GetMedia(Convert.ToInt32(@x.InnerText));
m.GetImageCropperUrl("thumbnail", "Thumbnail")
This gives the error 'umbraco.cms.businesslogic.media.Media' does not contain a definition for 'GetImageCropperUrl'
I'm having the same issue you are having, but may have made a bit more progress...
I have a custom media type with an image cropper property on it called croppedImage. For the example below, the document type has a property called leftBoxImage that points to the custom media type. I can get the XML this way:
var leftImg = Model.Media("leftBoxImage").croppedImage;
Just a quick follow up: I ended up putting the XML into an XmlDocument object:
@using System.Xml @{ var doc = new XmlDocument(); doc.LoadXml(Model.Media("leftBoxImage").croppedImage); var url = doc.DocumentElement.SelectSingleNode("//crop[@name='resized']/@url").InnerText; }
Apparently my latest posted solution for the image cropper doesn't work like I thought it would.
DynamicXml doesn't seem to play nicely with XML attributes, which "url" is. imageObj.crop will return an empty string, since the XML element has no inner text. Thus imageObj.crop.url will throw an error. Instead, you have to back out to the underlying XElement. This will work provided imageObj is defined as in my previous post:
sorry about the late reply, I was on vacation. Thank you very much for your response, I'll sure give it a try on the next project. For now I just used xslt.
Just wanted to say thank you to George for your code snippet on how to extract properties from the Image Cropper data type using RAZOR. I'm looking to just get the X and Y coordinates of the crop, but this showed me how to do it.
Although, it didn't quite work right away for me, perhaps due to some changes in 4.7.1 which is probably due to the cropper's property value now being casted not to a string, but to an umbraco.MacroEngines.DynamicXml object. (Call .ToXml() on this to get as a string now.)
So, your example code would now need to add this in as follows in 4.7.1+:
Actually, I posted too soon without looking back at my actual code that I had managed to make work.
It seems there is one more "level" to the stored Xml produced by the Image Croppper data type---the parent "crops" node which contains each of your individual "crop" nodes themselves. So the example should actually be:
(Of course, if you have more than one "crop", you'd need to be more selective and grab the correct one by name, not just the first as this example shows.)
Razor Multi-Node Tree picker with Image Cropper
Hi,
I'm trying to use Razor to render content coming from a multinode tree picker where you can pick custom media items that have an image cropper property. I have tried many things, but so far without success.
In a
@foreach (var x in @Model.images)
where 'images' is the tree picker, I can get the media item with
dynamic m = @Model.MediaById(@x.InnerText);
@m.umbracoFile works just fine.
Now, to get the crops I tried several things. I tried to get the xml with
@m.GetProperty("thumbnail").Value.ToString()
This gives the error "Cannot perform runtime binding on a null reference".
I tried to use the uCompoents extension GetImageCropperUrl(string, string), but
@m.GetImageCropperUrl("thumbnail", "Thumbnail")
is empty. Then I thought maybe I'm not getting the media item properly. So I tried, from here http://umbraco.com/follow-us/blog-archive/2011/2/24/umbraco-47-razor-feature-walkthrough-%E2%80%93-part-2
dynamic m = new DynamicMedia(Convert.ToInt32(@x.InnerText));
this makes the script fail.
I also tried
dynamic m = new umbraco.MacroEngines.DynamicMedia(Convert.ToInt32(@x.InnerText));
but this gives the error "The best overloaded method match for 'umbraco.MacroEngines.DynamicMedia.DynamicMedia(umbraco.MacroEngines.DynamicBackingItem)' has some invalid argument"
Next was
var m = uQuery.GetMedia(Convert.ToInt32(@x.InnerText));
m.GetImageCropperUrl("thumbnail", "Thumbnail")
This gives the error 'umbraco.cms.businesslogic.media.Media' does not contain a definition for 'GetImageCropperUrl'
uQuery.GetImageCropperUrl(m, "thumbnail", "Thumbnail")
makes the script fail with all methods of getting the media item.
The xslt for what I'm trying to do is very simple:
So, how do I get the crop with Razor?
I'm having the same issue you are having, but may have made a bit more progress...
I have a custom media type with an image cropper property on it called croppedImage. For the example below, the document type has a property called leftBoxImage that points to the custom media type. I can get the XML this way:
The result is a String:
I know I could parse the string, and maybe that's what I'll end up doing, but I'd love to be able to just do this:
Just a quick follow up: I ended up putting the XML into an XmlDocument object:
Just ran across this, which seems to be a better solution:
At the end of that, imageObj will represent the root node (crops). You should be able to do this:
If there's more than one crop, you can iterate through them:
Stumbled across this method here:
http://ucomponents.codeplex.com/workitem/13460
I have it working in the following macro, which uses the Related Links data type:
Apparently my latest posted solution for the image cropper doesn't work like I thought it would.
DynamicXml doesn't seem to play nicely with XML attributes, which "url" is. imageObj.crop will return an empty string, since the XML element has no inner text. Thus imageObj.crop.url will throw an error. Instead, you have to back out to the underlying XElement. This will work provided imageObj is defined as in my previous post:
But, if we're backing out to the XElement object, why even use DynamicXml, so we're back to using the XML parser, albeit a different, nicer one:
You could also use the Digibiz Advanced Media Picker to select media and crops. Here is a Razor sample (which uses a newer version of DAMP) to get the crop: http://our.umbraco.org/forum/developers/razor/18859-Question-for-an-XML-Data-Loop?p=2#comment76855.
Jeroen
Hi George,
sorry about the late reply, I was on vacation. Thank you very much for your response, I'll sure give it a try on the next project. For now I just used xslt.
Just wanted to say thank you to George for your code snippet on how to extract properties from the Image Cropper data type using RAZOR. I'm looking to just get the X and Y coordinates of the crop, but this showed me how to do it.
Although, it didn't quite work right away for me, perhaps due to some changes in 4.7.1 which is probably due to the cropper's property value now being casted not to a string, but to an umbraco.MacroEngines.DynamicXml object. (Call .ToXml() on this to get as a string now.)
So, your example code would now need to add this in as follows in 4.7.1+:
Thanks again!
Actually, I posted too soon without looking back at my actual code that I had managed to make work.
It seems there is one more "level" to the stored Xml produced by the Image Croppper data type---the parent "crops" node which contains each of your individual "crop" nodes themselves. So the example should actually be:
(Of course, if you have more than one "crop", you'd need to be more selective and grab the correct one by name, not just the first as this example shows.)
is working on a reply...