Overriding the Pager rendering in Orchard
- by Bertrand Le Roy
The Pager shape that is used in Orchard to render pagination is one of those shapes that are built in code rather than in a Razor template. This can make it a little more confusing to override, but nothing is impossible. If we look at the Pager method in CoreShapes, here is what we see: [Shape]
public IHtmlString Pager(dynamic Shape, dynamic Display) {
Shape.Metadata.Alternates.Clear();
Shape.Metadata.Type = "Pager_Links";
return Display(Shape);
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
The Shape attribute signals a shape method. All it does is remove all alternates that may exist and replace the type of the shape with “Pager_Links”. In turn, this shape method is rather large and complicated, but it renders as a set of smaller shapes: a List with a “pager” class, and under that Pager_First, Pager_Previous, Pager_Gap, for each page a Pager_Link or a Pager_Current, then Pager_Gap, Pager_Next and Pager_Last.
Each of these shapes can be displayed or not depending on the properties of the pager. Each can also be overridden with a Razor template. This can be done by dropping a file into the Views folder of your theme. For example, if you want the current page to appear between square braces, you could drop this Pager-CurrentPage.cshtml into your views folder:
<span>[@Model.Value]</span>
This overrides the original shape method, which was this:
[Shape]
public IHtmlString Pager_CurrentPage(HtmlHelper Html, dynamic Display,
object Value) {
var tagBuilder = new TagBuilder("span");
tagBuilder.InnerHtml = Html.Encode(Value is string ?
(string)Value : Display(Value));
return MvcHtmlString.Create(tagBuilder.ToString());
}
And here is what it would look like:
Now what if we want to completely hide the pager if there is only one page? Well, the easiest way to do that is to override the Pager shape by dropping the following into the Views folder of your theme:
@{
if (Model.TotalItemCount > Model.PageSize) {
Model.Metadata.Alternates.Clear();
Model.Metadata.Type = "Pager_Links";
@Display(Model)
}
}
And that’s it. The code in this template just adds a check for the number of items to display (in a template, Model is the shape) and only displays the Pager_Links shape if it knows that there’s going to be more than one page.