Add blog index with pagination

This commit is contained in:
Robert Marshall 2019-04-28 11:06:15 +01:00
parent 68fa2cf1c7
commit b8f371e3e8
5 changed files with 78 additions and 6 deletions

View file

@ -11,6 +11,7 @@ namespace Website.Controllers
{
public class BlogController : Controller
{
const int MaxPostsPerPage = 10;
private readonly BlogRepository _repo;
public BlogController(BlogRepository repo)
@ -18,9 +19,13 @@ namespace Website.Controllers
_repo = repo;
}
public IActionResult Index()
public async Task<IActionResult> Page(int page)
{
return View();
var offset = (page - 1) * MaxPostsPerPage;
var posts = (await _repo.GetLatestPostsAsync(MaxPostsPerPage, offset)).Select(p => new BlogPostViewModel(p));
var maxPages = (await _repo.GetCountAsync()) / MaxPostsPerPage;
var model = new BlogViewModel(posts, page, maxPages);
return View(model);
}
public async Task<IActionResult> View(int id)

View file

@ -3,6 +3,7 @@ using System.Linq;
using Dapper;
using Website.Models;
using Website.Data.States;
using System.Collections.Generic;
namespace Website.Data
{
@ -21,12 +22,24 @@ namespace Website.Data
}
}
public async Task<BlogPost> GetLatestPostAsync() {
const string query = "SELECT * FROM blog_posts WHERE post_content<>'' AND post_deleted=0 ORDER BY post_timestamp DESC LIMIT 1";
public async Task<IEnumerable<BlogPost>> GetLatestPostsAsync(int limit, int offset) {
const string query = "SELECT * FROM blog_posts WHERE post_content<>'' AND post_deleted=0 ORDER BY post_timestamp DESC LIMIT @offset,@limit";
using (var connection = _dbProvider.NewConnection()) {
connection.Open();
var result = await connection.QueryAsync<BlogPostState>(query);
return new BlogPost(result.First());
var results = await connection.QueryAsync<BlogPostState>(query, new{limit, offset});
return results.Select(result => new BlogPost(result));
}
}
public async Task<BlogPost> GetLatestPostAsync() => (await GetLatestPostsAsync(1, 0)).First();
public async Task<int> GetCountAsync()
{
var query="SELECT COUNT(*) FROM blog_posts WHERE post_content<>'' AND post_deleted=0";
using(var connection = _dbProvider.NewConnection()) {
connection.Open();
var result = await connection.QueryAsync<int>(query);
return result.First();
}
}
}

View file

@ -57,6 +57,13 @@ namespace Website
app.UseMvc(routes =>
{
routes.MapRoute(
name: "blogPages",
template: "blog/{action}/{page:int}",
new { controller = "Blog", action = "Page", page = 1 });
routes.MapRoute(
name: "blogView",
template: "blog/view/{url}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace Website.ViewModels
{
public class BlogViewModel
{
public BlogViewModel(IEnumerable<BlogPostViewModel> posts, int page, int maxPages)
{
Posts = posts;
Page = page;
MaxPages = maxPages;
}
public IEnumerable<BlogPostViewModel> Posts { get; }
public int Page { get; }
public int MaxPages { get; }
}
}

View file

@ -0,0 +1,29 @@
@model BlogViewModel;
@{
ViewData["Title"] = "Blog";
}
@section ButtonsLeft {
@if (Model.Page > 1) {
<button onclick="window.location.href='/blog/page/@(Model.Page-1)'" title="Previous Page">
<img src="/images/previous.svg" alt="Previous" />
</button>
}
}
@section ButtonsRight {
@if (Model.Page < Model.MaxPages) {
<button onclick="window.location.href='/blog/page/@(Model.Page+1)'" title="Next Page">
<img src="/images/next.svg" alt="Next" />
</button>
}
}
@foreach (var post in Model.Posts) {
<article>
<h2><a href="/blog/view/@post.Url">@post.Title</a></h2>
@Html.Raw(post.Content)
<small>Posted on @post.Timestamp.ToString()</small>
<p><a href="/blog/view/@post.Url">Read more...</a></p>
</article>
}