Captain Kenpachi
Captain Kenpachi

Reputation: 7215

How to get values from assigned contentpart in Orchard CMS

I'm using Orchard CMS v1.8.x. We've added the FlexSlider module and to make it link to specific areas of our site, we've added a field called "Slide Link" to the FlexSliderPart object.

enter image description here

Now, that all works pretty neat. But I have absolutely no idea how to reference this new field on the front-end. The FlexSliderWidgetViewModel only contains fields for Title and ImagePath. I have no idea how to retrieve the SlideLink (and SubTitle) field:

namespace Tekno.FlexSlider.ViewModels
{
    public class FlexSliderWidgetViewModel
    {
        public string Title { get; set; }
        public string ImagePath { get; set; }


    }
}

And my View:

@using Tekno.FlexSlider.ViewModels

@{
    Style.Require("FlexSlider");
    Script.Require("FlexSlider");

    var items = (IEnumerable<FlexSliderWidgetViewModel>)Model.SlideItems;
}
<div class="flexslider">
    <ul class="slides">
        @foreach (var item in items)
        {
            <li>
                @if (item.ImagePath != "")
                {
                    <a href="@(/*what must I do here?*/)"><img src="@Display.ResizeMediaUrl(Path: item.ImagePath, Height: 400, Mode: "crop")" /></a>
                }
                <span class="slide-text">@item.Title</span>
            </li>
        }
    </ul>
    <span class="slide-text-bottom"></span>
</div>

The Driver's Display function:

protected override DriverResult Display(FlexSliderWidgetPart part, string displayType, dynamic shapeHelper)
        {
            var items = _contentManager.Query<FlexSliderPart, FlexSliderPartRecord>("FlexSlider")
                                       .Where(i => i.GroupId == part.GroupId).OrderBy(i => i.Sort)
                                       .List()
                                       .Select(i => new FlexSliderWidgetViewModel()
             {
                 ImagePath = ((MediaLibraryPickerField)i.Fields.Single(f => f.Name == "Picture"))
                                                        .MediaParts
                                                        .FirstOrDefault() == null ? "" : ((MediaLibraryPickerField)i.Fields.Single(f => f.Name == "Picture")).MediaParts.First().MediaUrl,
                 Title = i.Get<TitlePart>().Title

             });

            return ContentShape("Parts_FlexSliderWidget",
                () => shapeHelper.Parts_FlexSliderWidget(SlideItems: items));
        }

Upvotes: 0

Views: 585

Answers (1)

Hazza
Hazza

Reputation: 6591

I had a quick look at the code and you won't be able to access those fields in the way the module is currently working. Basically it is accessing the content item in the drivers display method and then creating a View Model with the two bits of data (title and image)it deems necessary to send to the view. I would recommend changing the drivers Display method to send back the entire content item instead of that view model, you can then access fields you attach from the view directly.

If you don't have access to the driver you could I suppose grab the content manager in your view and redo all the work that driver is doing so you can access the content items. I wouldn't recommend this approach though...

This probably isn't the answer you were hoping for, sorry.

EDIT

This is basically pseudo code as I don't have access to the module to actually see if it works, but it should point you in, well, some sort of direction.

protected override DriverResult Display(FlexSliderWidgetPart part, string displayType, dynamic shapeHelper)
{
    var items = _contentManager.Query<FlexSliderPart, FlexSliderPartRecord>("FlexSlider")
                               .Where(i => i.GroupId == part.GroupId).OrderBy(i => i.Sort)
                               .List();

    return ContentShape("Parts_FlexSliderWidget",
        () => shapeHelper.Parts_FlexSliderWidget(SlideItems: items));
}

then in your view:

@using Tekno.FlexSlider.ViewModels

@{
    Style.Require("FlexSlider");
    Script.Require("FlexSlider");

}
<div class="flexslider">
    <ul class="slides">
        @foreach (var part in Model.SlideItems)
        {
            dynamic item = part.ContentItem;

            <li>
                <a href="@item.FlexSliderPart.SlideLink.Value"><img src="@Display.ResizeMediaUrl(Path: item.FlexSliderPart.MediaParts[0].MediaUrl, Height: 400, Mode: "crop")" /></a>
                <span class="slide-text">@item.TitlePart.Title</span>
            </li>
        }
    </ul>
    <span class="slide-text-bottom"></span>
</div>

Important thing here is the casting the content item to a dynamic so you can access all the fields etc. I've also never used the new Media stuff in 1.8 so... don't know if I'm accessing that correctly. I don't like it ^^

Upvotes: 1

Related Questions