Copied to clipboard

Flag this post as spam?

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


  • Bogdan 250 posts 427 karma points
    Aug 03, 2011 @ 10:29
    Bogdan
    0

    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:

    <xsl:for-each select="$currentPage/images/MultiNodePicker/nodeId">
      <xsl:variable name="media" select="umbraco.library:GetMedia(current(), true())" />
      <li><img src="{$media/thumbnail/crops/crop[@name = 'Thumbnail']/@url}" alt="" data-image="{$media/umbracoFile}" /></li>
    </xsl:for-each

    So, how do I get the crop with Razor?

  • George 30 posts 122 karma points
    Aug 08, 2011 @ 19:16
    George
    0

    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;

    The result is a String:

    <crops date="05/08/2011 17:16:28"><crop name="resized" x="30" y="27" x2="209" y2="229" url="/media/24/pumpkin-and_cat_resized.jpg" /></crops>

    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:

    @leftImage.url

     

  • George 30 posts 122 karma points
    Aug 10, 2011 @ 22:43
    George
    0

    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;
  • George 30 posts 122 karma points
    Aug 11, 2011 @ 17:33
    George
    0

    Just ran across this, which seems to be a better solution:

    @using umbraco.MacroEngines  @* needed for instantiating DynamicXml *@
    @using System.Xml.Linq  @* needed for XElement.Parse *@
    @{
    dynamic imageObj = new DynamicXml(XElement.Parse(Model.Media("leftBoxImage").croppedImage);
     }

    At the end of that, imageObj will represent the root node (crops). You should be able to do this:

    imageObj.crop.url

    If there's more than one crop, you can iterate through them:

    imageObj.crop[0].url

    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:

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

    @{
      dynamic media = new DynamicMedia(Parameter.RightColumnQuickLinks);
      dynamic links = new DynamicXml(XElement.Parse(@media.links));
    }

    <div class="quick-links">
      <h3>Quick Links</h3>
      <ul>
        @foreach (var link in links.link) {
          string target = link.newwindow == "1" ? " target=\"_blank\"" : "";
          <li>
            @if (link.type == "internal") {
              <a href="@umbraco.library.NiceUrl(int.Parse(link.link))"@Html.Raw(target)>@link.title</a>
            } else {
              <a href="@link.link"@Html.Raw(target)>@link.title</a>
            }
          </li>
        }
      </ul>
    </div>
  • George 30 posts 122 karma points
    Aug 11, 2011 @ 18:17
    George
    1

    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:

    imageObj.BaseElement.Element("crop").Attribute("url").Value

    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:

    string imageUrl =  XElement.Parse(media.croppedImage).Element("crop").Attribute("url").Value;
  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 11, 2011 @ 18:24
    Jeroen Breuer
    0

    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

  • Bogdan 250 posts 427 karma points
    Aug 25, 2011 @ 16:00
    Bogdan
    0

    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.

  • Funka! 398 posts 661 karma points
    May 03, 2012 @ 21:04
    Funka!
    0

    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+:

    string imageUrl =  XElement.Parse(media.croppedImage.ToXml()).Element("crop").Attribute("url").Value;

    Thanks again!

  • Funka! 398 posts 661 karma points
    May 03, 2012 @ 21:08
    Funka!
    0

    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:

    string imageUrl =  XElement.Parse(media.croppedImage.ToXml()).Element("crops").Element("crop").Attribute("url").Value;

    (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.)

     

Please Sign in or register to post replies

Write your reply to:

Draft