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
|
public class BlogController : Controller
|
||||||
{
|
{
|
||||||
|
const int MaxPostsPerPage = 10;
|
||||||
private readonly BlogRepository _repo;
|
private readonly BlogRepository _repo;
|
||||||
|
|
||||||
public BlogController(BlogRepository repo)
|
public BlogController(BlogRepository repo)
|
||||||
|
@ -18,9 +19,13 @@ namespace Website.Controllers
|
||||||
_repo = repo;
|
_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)
|
public async Task<IActionResult> View(int id)
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Website.Models;
|
using Website.Models;
|
||||||
using Website.Data.States;
|
using Website.Data.States;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Website.Data
|
namespace Website.Data
|
||||||
{
|
{
|
||||||
|
@ -21,12 +22,24 @@ namespace Website.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<BlogPost> GetLatestPostAsync() {
|
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 1";
|
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()) {
|
using (var connection = _dbProvider.NewConnection()) {
|
||||||
connection.Open();
|
connection.Open();
|
||||||
var result = await connection.QueryAsync<BlogPostState>(query);
|
var results = await connection.QueryAsync<BlogPostState>(query, new{limit, offset});
|
||||||
return new BlogPost(result.First());
|
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 =>
|
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(
|
routes.MapRoute(
|
||||||
name: "default",
|
name: "default",
|
||||||
template: "{controller=Home}/{action=Index}/{id?}");
|
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