Page that lists links to pdfs

Vote:
 

Hello, I am new to episerver and CMS frameworks in general. I was hoping one of you could help me out and point me in the right direction with a bit of functionality I am trying to achieve.

 

I will be uploading a series of pdf documents to the site (i want to be able to use the media management tool seen here http://prntscr.com/3imt9r). These pdfs will be associated with one to many categories.

Now, I want to build a page that lsits all the pdfs associated with a specifc category (there will be one page per category). The list will look something like this http://prntscr.com/3imuzi

 

What would be the best way to achieve said functionality.

 

Thanks in advance

#86039
May 12, 2014 21:59
Vote:
 

Welcome Alex

You use the contentloader along with the contentassetshelper.  you just get the children of the folder

#86040
May 13, 2014 4:32
Vote:
 
http://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=81106&epslanguage=en

    Take a look at that link.  that should help you achieve your task.  If it still doesn't make sense feel free to keep posting and we will help you as much as we can

#86041
Edited, May 13, 2014 4:36
Vote:
 

Let's say that file browser can be generalized and be created as block - you can drag it on the page and configure which folder to enlist (reference to that folder will be in `MediaFolder` property.

public class FileBrowserBlock : BaseBlockData
{
    [Display(Name = "Media folder", Order = 10)]
    [UIHint(UIHint.MediaFolder)]
    public virtual ContentReference MediaFolder { get; set; }
}

    

 

You may better need a controller for that.

public class FileBrowserBlockController : BlockController<FileBrowserBlock>
{
    private readonly IContentLoader loader;

    public FileBrowserBlockController(IContentLoader loader)
    {
        this.loader = loader;
    }
}

    

It's always good to have a view model:

public class FileBrowserBlockViewModel
{
    public FileBrowserBlockViewModel()
    {
        Files = new List<PdfFileMedia>();
    }

    public List<PdfFileMedia> Files { get; set; }
}

    

 

This will ensure that you have a access to content loader already injected in your controller.

Then you may have a default action on it that will enlist all PDF files:

public override ActionResult Index(FileBrowserBlock currentBlock)
{
    var model = new FileBrowserBlockViewModel();
    var rootFolder = loader.Get<ContentFolder>(currentBlock.MediaFolder);

    

Than you can enlist all files in that folder:

model.Files = rootFolder.GetChildren<PdfFileMedia>().Where(m => m.Category.Contains(Category.Find("Name of the catogory").ID));

    

`GetChildren` could defined as an extension method to `ContentFolder` type (may become really handy later):

public static IEnumerable<T> GetChildren<T>(this ContentFolder folder) where T : IContentData
{
    return ContentReference.IsNullOrEmpty(folder.ContentLink) ?
           Enumerable.Empty<T>() : 
           ServiceLocator.Current.GetInstance<IContentLoader>().GetChildren<T>(folder.ContentLink);
}

    

Then it's just a matter of painting the list on the screen :)

#86045
May 13, 2014 8:16
Vote:
 

Thanks for the help everyone. I'm going to give it a go right now and let you know what solution worked best for me.

#86080
May 13, 2014 16:02
Vote:
 

Valdis Iljuconoks solution is the one you want to follow.  

#86081
May 13, 2014 16:20
Vote:
 

Valdis, I implemented a solution very similar to yours but now I get a strange error when the page renders that I don't understand.

 

The error is:

The model item passed into the dictionary is of type 'Castle.Proxies.LearningMaterialBlockProxy', but this dictionary requires a model item of type 'EPiServer.Templates.Alloy.Models.ViewModels.LearningMaterialBlockViewModel'.

 

Here is my code:

LearningMaterialBlock.cs

[ContentType(DisplayName = "LearningMaterialBlock", GUID = "11f6b61e-e780-49d7-a894-d8117f491c04", Description = "")]
    public class LearningMaterialBlock : SiteBlockData
    {
        [Display(Name = "Category", Order = 1)]
        public virtual CategoryList Category { get; set; }
    }

    

LearningMaterialBlockController.cs

public class LearningMaterialBlockController : BlockController<LearningMaterialBlock>
    {
        private readonly IContentLoader loader;

        public LearningMaterialBlockController(IContentLoader loader)
        {
            this.loader = loader;
        }

        public override ActionResult Index(LearningMaterialBlock currentBlock)
        {
            var model = new LearningMaterialBlockViewModel();
            var rootFolder = loader.Get<ContentFolder>(SiteDefinition.Current.GlobalAssetsRoot);
            model.Files = rootFolder.GetChildren<ListableItem>().Where(m => m.Category.Contains(currentBlock.Category.First()));

            return PartialView(model);
        }
    }

    

LearningMaterialBlockViewModel.cs

public class LearningMaterialBlockViewModel
    {
        public LearningMaterialBlockViewModel()
        {
            Files = new List<ListableItem>();
        }

        public IEnumerable<ListableItem> Files { get; set; }
    }

    

LearningMaterialBlock.cshtml

@model EPiServer.Templates.Alloy.Models.ViewModels.LearningMaterialBlockViewModel

@using EPiServer.Core
@using EPiServer.Web.Mvc.Html
@using EPiServer.Templates.Alloy.Models.Media

<div>
    @foreach (ListableItem item in Model.Files)
    {
        <div>
            <a href="">@item.Title</a>
            <p>@item.Description</p>
        </div>
    }
</div>

    

 

#86088
Edited, May 13, 2014 17:25
Vote:
 

This is tricky sometimes. Solution: name your view different as your block type - apply Mvc particial naming convetions - start with "_". Then:

return View("~/Views/Shared/Blocks/_Name-of-your-view.cshtml", model);

    

This is because EPiServer is optimizing: and if it sees view with the same name as your block type - it *will* skip your controller and pass proxy class directly as model.

#86089
May 13, 2014 17:52
Vote:
 

Okay. I understand now. What I had to do to fix this was what Valdis Iljuconoks mentioned and also, I had to go into episerver admin -> content type -> LearningMaterial -> settings and set the MVC template to the LearningMaterialBlockController.

 

Thanks for your help Valdis. You're a rock star.

#86092
May 13, 2014 18:55
Vote:
 

I would suggest to do everything from the code. It will eliminate manual steps once you deploy your site to production.

#86093
May 13, 2014 19:19
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.