Add blog index with pagination
This commit is contained in:
parent
68fa2cf1c7
commit
b8f371e3e8
5 changed files with 78 additions and 6 deletions
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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?}");
|
||||
|
|
18
Website/ViewModels/BlogViewModel.cs
Normal file
18
Website/ViewModels/BlogViewModel.cs
Normal 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; }
|
||||
}
|
||||
}
|
29
Website/Views/Blog/Page.cshtml
Normal file
29
Website/Views/Blog/Page.cshtml
Normal 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>
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue