Pagination with Umbraco
# help-with-umbraco
p
Hey everyone, my question today is about pagination. I wondered what the best way would be to create one. The situation is as following: I have a topic Page with many articles. I've built a viewcomponent to display these articles and load the data from the articleController. Now my question is. Where would you integrate the pagination. Would you take the pagination inside of the ViewComponent or Outside of it so it calls the VC with the Values. I'm not sure what would be the best way to communicate between pagination click and controller / VC.
s
I usually do it in a RenderController, let me find an example.
p
Thanks @Sebastiaan
I came up with this solution.. didnt test it yet but it might work... The only problem i see so far now is the pageSize beeing passed as FromQuery. Is there any different way to do this? I dont want the user to set his page size by itself.
h
for pagesize I have a setting on the document node that is the parent, I just pass the pagenum in the query string
so in rendercontroller I just do
int pageSize = CurrentPage.Value<int>("intPageSize");
s
Oops, was called away! This is mine for my blog:
Copy code
csharp
using System;
using System.Linq;
using Cultiv.Site.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;
using Umbraco.Cms.Web.Common.PublishedModels;

namespace Cultiv.Site.Controllers
{
    public class BlogOverviewController : RenderController
    {
        private readonly IVariationContextAccessor _variationContextAccessor;
        private readonly ServiceContext _serviceContext;
        private readonly IFileSystem _fileSystem;
        
        public BlogOverviewController(ILogger<BlogOverviewController> logger, 
            ICompositeViewEngine compositeViewEngine, 
            IUmbracoContextAccessor umbracoContextAccessor,
            IVariationContextAccessor variationContextAccessor, 
            ServiceContext context, IFileSystem fileSystem)
            : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
            _variationContextAccessor = variationContextAccessor;
            _serviceContext = context;
            _fileSystem = fileSystem;
        }
        
        [HttpGet]
        public IActionResult Index([FromQuery(Name = "page")] int page = 1)
        {
            var publishedValueFallback = new PublishedValueFallback(_serviceContext, _variationContextAccessor);
            var model = new BlogOverviewModel(CurrentPage, publishedValueFallback) { Page = page };
            var allBlogPosts = model.Children.ToList();
            
            var skip = 10 * model.Page - 10;

            var test = _fileSystem.GetFullPath("~/");
            
            model.TotalPages = Convert.ToInt32(Math.Ceiling(allBlogPosts.Count / 10.0));
            model.PreviousPage = model.Page - 1;
            model.NextPage = model.Page + 1;
            model.IsFirstPage = model.Page <= 1;
            model.IsLastPage = model.Page >= model.TotalPages;
            
            var selection = allBlogPosts.OrderByDescending(x => x.CreateDate)
                .Skip(skip)
                .Take(10)
                .Select(publishedContent => publishedContent as BlogPost)
                .ToList();

            model.PagedBlogPosts = selection;

            return CurrentTemplate(model);
        }
    }
}
And so to use this you should name your controller after the alias of your article overview page (probably
ArticlesController
or
ArticleOverviewController
).
The model:
Copy code
csharp
using System.Collections.Generic;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Web.Common.PublishedModels;

namespace Cultiv.Site.Models
{
    public class BlogOverviewModel : PublishedContentWrapped 
    {
        public BlogOverviewModel(IPublishedContent content, IPublishedValueFallback publishedValueFallback) : base(content, publishedValueFallback)
        { }

        public int Page { get; set; }
        public int TotalPages { get; set; }
        public int PreviousPage { get; set; }
        public int NextPage { get; set; }
        public bool IsFirstPage { get; set; }
        public bool IsLastPage { get; set; }
        public IEnumerable<BlogPost> PagedBlogPosts { get; set; }
    }
}
p
Thanks alot @Sebastiaan you've helped me a lot! 🙂 Have a great weekend!
s
Glad to hear! Have a good one yourself!
d
If it helps this is also how I have rendered mine with Bootstrap
h
I extracted mine into a viewcomponent so can just plonk the pager anywhere
s
We often use X.pagedlist and use ajax calls with a surface controller to load the next page
j
I also prefer mine in a ViewComponent 🙂
d
I think I should do that too Also @AaronSadlerUK showed me a nice pagination tag helper but I enjoyed learning to write it from scratch with some help from gpt and copilot
j
Please post!
j
Thanks, Aaron!
d
So I asked ChatGPT to help me move my code into a view component and it kept insisting that's a razor helper would be a better option for my purposes. I then asked it lots of questions to justify the case for each and now I am very confused whether I should use a razor helper a view component or a controller. The purpose of my site is to be very simple for people new to Umbraco so I have been trying to keep the code simple but I would agree something like pagination should be reusable. Any advice or reasons not to use the Razor helper. It even shows I can pass values from the view such as items per page.
h
Did you ask about view controller or view component? View component is what you want
d
Sorry, yes I asked for a view component as people had been suggesting but it seems to be implying it's overkill for my purposes and I should use a Razor Helper in a cshtml file until my pagination requires data integration such as filtering.
j
ChatGPT isn’t always right; but it’s always VERY CERTAIN it’s right I think it’s fair to say use your best judgment and take it from there. But if you want an example I’m sure we can help you (but not me today - I’m driving home from camping over a long weekend )
h
Not sure why it is overkill, view components are just a better implementation of partial views. I will post an example tomorrow
52 Views