MVC nested content

lawrence whittemore asked on February 19, 2021 16:31

I'm sure this is a basic question, but as someone moving from Portal to MVC I have no idea how to do something like this.

Anyway, I have a page type called Story, and a page type called slide that lives below it. I am able to get the view for my story to work (we're building a one page site so they all show at once) Now I need to figure out how to get the slide page type to show within each of the story page types. I could do this easy in portal with a hierarchal viewer... but am lost at doing something similar in MVC

Thanks!

Recent Answers


lawrence whittemore answered on February 19, 2021 17:05

So.. I am getting there with the using the @Html.Action("GetSlides", "Slide") to get the partial view... Now I need to figure out how to pass some id or something into the action so that I only get slides for the current story.

0 votesVote for this answer Mark as a Correct answer

eSiteful Corporation answered on February 19, 2021 17:16

You say you're building a one page site, so that could change a lot about how your views are arranged and served to the user, but in general, you'd have a Story controller for each story where you want to display the slides. In that controller, get the Slide children of the current TreeNode, then feed those into a ViewModel for the Story view.

var slideNodes = DocumentHelper.GetDocuments<CMS.DocumentEngine.Types.MyNamespace.Slide>().Path(currentNode.NodeAliasPath, PathTypeEnum.Children).OrderBy("NodeLevel ASC, NodeOrder ASC");

You could feed them directly into the ViewModel for the Story controller from there, or best practice would be to create another ViewModel for the individual slides.

storyViewModel.slides = slideNodes.Select(n => new MySlideViewModel() { Title = n.Title, Image = n.Image });

Also best practice would be to use the DocumentQueryService rather than the DocumentHelper directly, as well as the CacheService to lighten the load for future requests. Hope that points you in the right direction!

0 votesVote for this answer Mark as a Correct answer

eSiteful Corporation answered on February 19, 2021 18:03 (last edited on February 19, 2021 18:05)

Per your comment, I'd prefer to use Html.RenderPartial() in the parent view, where I can pass the list of slides directly to it; otherwise, you'll need to add the story ID as a parameter to the ActionMethod and pass it as a route value in the Action/RenderAction call.

public ActionResult GetSlides(int storyID)

And in your view...

Html.Action("GetSlides", "Slide", new { nodeID = Model.NodeID })

I'd personally prefer to be more specific with my action method names. For instance, if my GetSlides action method is on my Slides controller, I'd name it GetSlidesByStory(int storyID), because you may need methods to get slides by other criteria, like GetSlidesByCategory(). Or, I would consider making this an action method on my Story controller, like GetStorySlides(int slideID).

0 votesVote for this answer Mark as a Correct answer

lawrence whittemore answered on February 19, 2021 18:58

Thanks for you help. I got it working the way I wanted. Not sure if it is the most elegant, but I have this on my view @Html.Action("GetSlides", "Slide", new { id = story.NodeID }) and then my ActionResult looks like this

public ActionResult GetSlides(int id)
    {

        var slides = StorySlideProvider.GetStorySlides()
            .Columns("StorySlideID", "Title", "Summary", "Image", "Description", "Quote", "NodeParentID")     
            .WhereEquals("NodeParentID", id)
            .OrderBy("NodeOrder");

        var model = slides.Select(item => new SlideViewModel()
        {
            StorySlideID = item.StorySlideID,
            Title = item.Title,
            Summary = item.Summary,
            Image = item.Image,
            Description = item.Description,
            NodeParentID = item.NodeParentID

        }); ;


        return PartialView("_slides", model);
    }
0 votesVote for this answer Mark as a Correct answer

eSiteful Corporation answered on February 19, 2021 19:10

Nice job, looks good! My only suggestion for elegance is still to be more specific with the action method name, especially because it's on the Slide controller. I'd personally move it to the Story controller as GetStorySlides(), or rename it to GetSlidesByStory() on the Slide controller.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.