in src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapes.cs [153:304]
public async Task<IHtmlContent> Pager_Links(Shape shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, DisplayContext DisplayContext,
string PagerId,
int Page,
int PageSize,
double TotalItemCount,
int? Quantity,
object FirstText,
object PreviousText,
object NextText,
object LastText,
object GapText,
bool ShowNext,
string ItemTagName,
IDictionary<string, string> ItemAttributes
// parameter omitted to workaround an issue where a NullRef is thrown
// when an anonymous object is bound to an object shape parameter
/*object RouteValues*/)
{
var currentPage = Page;
if (currentPage < 1)
currentPage = 1;
var pageSize = PageSize;
var numberOfPagesToShow = Quantity ?? 0;
if (Quantity == null || Quantity < 0)
numberOfPagesToShow = 7;
var totalPageCount = pageSize > 0 ? (int)Math.Ceiling(TotalItemCount / pageSize) : 1;
// return shape early if pager is not needed.
if (totalPageCount < 2)
{
shape.Metadata.Type = "List";
return await DisplayAsync(shape);
}
var firstText = FirstText ?? S["<<"];
var previousText = PreviousText ?? S["<"];
var nextText = NextText ?? S[">"];
var lastText = LastText ?? S[">>"];
var gapText = GapText ?? S["..."];
var httpContextAccessor = DisplayContext.ServiceProvider.GetService<IHttpContextAccessor>();
var httpContext = httpContextAccessor.HttpContext;
var routeData = new RouteValueDictionary(Html.ViewContext.RouteData.Values);
if (httpContext != null)
{
var queryString = httpContext.Request.Query;
if (queryString != null)
{
foreach (var key in from string key in queryString.Keys where key != null && !routeData.ContainsKey(key) let value = queryString[key] select key)
{
routeData[key] = queryString[key];
}
}
}
// specific cross-requests route data can be passed to the shape directly (e.g., OrchardCore.Users)
var shapeRoute = (object)((dynamic)shape).RouteData;
if (shapeRoute != null)
{
var shapeRouteData = shapeRoute as RouteValueDictionary;
if (shapeRouteData == null)
{
var route = shapeRoute as RouteData;
if (route != null)
{
shapeRouteData = new RouteValueDictionary(route.Values);
}
}
if (shapeRouteData != null)
{
foreach (var rd in shapeRouteData)
{
routeData[rd.Key] = rd.Value;
}
}
}
var firstPage = Math.Max(1, Page - (numberOfPagesToShow / 2));
var lastPage = Math.Min(totalPageCount, Page + (int)(numberOfPagesToShow / 2));
var pageKey = String.IsNullOrEmpty(PagerId) ? "page" : PagerId;
shape.Classes.Add("pager");
shape.Metadata.Alternates.Clear();
shape.Metadata.Type = "List";
// first and previous pages
if ((Page > 1) && (routeData.ContainsKey(pageKey)))
{
routeData.Remove(pageKey); // to keep from having "page=1" in the query string
}
// first
shape.Add(await New.Pager_First(Value: firstText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page < 2));
// previous
if ((Page > 1) && (currentPage > 2))
{ // also to keep from having "page=1" in the query string
routeData[pageKey] = currentPage - 1;
}
shape.Add(await New.Pager_Previous(Value: previousText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page < 2));
// gap at the beginning of the pager
if (firstPage > 1 && numberOfPagesToShow > 0)
{
shape.Add(await New.Pager_Gap(Value: gapText, Pager: shape));
}
// page numbers
if (numberOfPagesToShow > 0 && lastPage > 1)
{
for (var p = firstPage; p <= lastPage; p++)
{
if (p == currentPage)
{
routeData[pageKey] = currentPage;
shape.Add(await New.Pager_CurrentPage(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: shape));
}
else
{
if (p == 1)
routeData.Remove(pageKey);
else
routeData[pageKey] = p;
shape.Add(await New.Pager_Link(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: shape));
}
}
}
// gap at the end of the pager
if (lastPage < totalPageCount && numberOfPagesToShow > 0)
{
shape.Add(await New.Pager_Gap(Value: gapText, Pager: shape));
}
// Next
routeData[pageKey] = Page + 1;
shape.Add(await New.Pager_Next(Value: nextText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page >= totalPageCount && !ShowNext));
// Last
routeData[pageKey] = totalPageCount;
shape.Add(await New.Pager_Last(Value: lastText, RouteValues: new RouteValueDictionary(routeData), Pager: shape, Disabled: Page >= totalPageCount));
return await DisplayAsync(shape);
}