Complate category page and tag page.

pull/146/head
ruibaby 2019-04-21 15:35:16 +08:00
parent 336b5bea71
commit 6fa03b0f21
8 changed files with 125 additions and 54 deletions

View File

@ -33,7 +33,10 @@ public class CommentTagDirective implements TemplateDirectiveModel {
int top = Integer.parseInt(params.get("top").toString()); int top = Integer.parseInt(params.get("top").toString());
switch (method) { switch (method) {
case "latest": case "latest":
env.setVariable("categories", builder.build().wrap(builder.build().wrap(builder.build().wrap(commentService.pageLatest(top))))); env.setVariable("categories", builder.build().wrap(commentService.pageLatest(top)));
break;
case "count":
env.setVariable("count", builder.build().wrap(commentService.count()));
break; break;
default: default:
break; break;

View File

@ -1,11 +1,10 @@
package run.halo.app.model.freemarker.tag; package run.halo.app.model.freemarker.tag;
import freemarker.core.Environment; import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody; import freemarker.template.*;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import run.halo.app.model.support.HaloConst;
import run.halo.app.service.PostService;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -19,9 +18,26 @@ import java.util.Map;
@Component @Component
public class PostTagDirective implements TemplateDirectiveModel { public class PostTagDirective implements TemplateDirectiveModel {
private final PostService postService;
public PostTagDirective(PostService postService) {
this.postService = postService;
}
@Override @Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
// TODO Complete article tag directive. final DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);
if (params.containsKey(HaloConst.METHOD_KEY)) {
String method = params.get(HaloConst.METHOD_KEY).toString();
switch (method) {
case "count":
env.setVariable("count", builder.build().wrap(postService.count()));
break;
default:
break;
}
}
body.render(env.getOut());
} }
} }

View File

@ -39,6 +39,7 @@ public interface CategoryService extends CrudService<Category, Integer> {
* @param slugName slug name * @param slugName slug name
* @return Category * @return Category
*/ */
@NonNull
Category getBySlugName(@NonNull String slugName); Category getBySlugName(@NonNull String slugName);
/** /**

View File

@ -1,12 +1,13 @@
package run.halo.app.service; package run.halo.app.service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import run.halo.app.model.entity.Category; import run.halo.app.model.entity.Category;
import run.halo.app.model.entity.Post; import run.halo.app.model.entity.Post;
import run.halo.app.model.entity.PostCategory; import run.halo.app.model.entity.PostCategory;
import run.halo.app.service.base.CrudService; import run.halo.app.service.base.CrudService;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import run.halo.app.service.base.CrudService;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -48,6 +49,16 @@ public interface PostCategoryService extends CrudService<PostCategory, Integer>
@NonNull @NonNull
List<Post> listPostBy(@NonNull Integer categoryId); List<Post> listPostBy(@NonNull Integer categoryId);
/**
* Pages post by category slug name.
*
* @param categoryId category id must not be null
* @param pageable pageable
* @return page of post
*/
@NonNull
Page<Post> pagePostBy(@NonNull Integer categoryId, Pageable pageable);
/** /**
* Merges or creates post categories by post id and category id set if absent. * Merges or creates post categories by post id and category id set if absent.
* *

View File

@ -1,5 +1,10 @@
package run.halo.app.service.impl; package run.halo.app.service.impl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import run.halo.app.model.entity.Category; import run.halo.app.model.entity.Category;
import run.halo.app.model.entity.Post; import run.halo.app.model.entity.Post;
import run.halo.app.model.entity.PostCategory; import run.halo.app.model.entity.PostCategory;
@ -9,9 +14,6 @@ import run.halo.app.repository.PostRepository;
import run.halo.app.service.PostCategoryService; import run.halo.app.service.PostCategoryService;
import run.halo.app.service.base.AbstractCrudService; import run.halo.app.service.base.AbstractCrudService;
import run.halo.app.utils.ServiceUtils; import run.halo.app.utils.ServiceUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -88,6 +90,17 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
return postRepository.findAllById(postIds); return postRepository.findAllById(postIds);
} }
@Override
public Page<Post> pagePostBy(Integer categoryId, Pageable pageable) {
Assert.notNull(categoryId, "Category id must not be null");
Assert.notNull(pageable, "Page info must not be null");
// Find all post ids
Set<Integer> postIds = postCategoryRepository.findAllCategoryIdsByPostId(categoryId);
return postRepository.findAllByIdIn(postIds, pageable);
}
@Override @Override
public List<PostCategory> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> categoryIds) { public List<PostCategory> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> categoryIds) {
Assert.notNull(postId, "Post id must not be null"); Assert.notNull(postId, "Post id must not be null");

View File

@ -1,6 +1,11 @@
package run.halo.app.web.controller.content; package run.halo.app.web.controller.content;
import cn.hutool.core.util.PageUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.SortDefault;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -11,12 +16,13 @@ import run.halo.app.model.entity.Category;
import run.halo.app.model.entity.Post; import run.halo.app.model.entity.Post;
import run.halo.app.model.entity.Tag; import run.halo.app.model.entity.Tag;
import run.halo.app.model.enums.PostStatus; import run.halo.app.model.enums.PostStatus;
import run.halo.app.model.vo.CommentVO;
import run.halo.app.service.*; import run.halo.app.service.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List; import java.util.List;
import static org.springframework.data.domain.Sort.Direction.DESC;
/** /**
* Blog archive page controller * Blog archive page controller
* *
@ -38,16 +44,20 @@ public class ContentArchiveController {
private final PostTagService postTagService; private final PostTagService postTagService;
private final OptionService optionService;
public ContentArchiveController(PostService postService, public ContentArchiveController(PostService postService,
CommentService commentService, CommentService commentService,
ThemeService themeService, ThemeService themeService,
PostCategoryService postCategoryService, PostCategoryService postCategoryService,
PostTagService postTagService) { PostTagService postTagService,
OptionService optionService) {
this.postService = postService; this.postService = postService;
this.commentService = commentService; this.commentService = commentService;
this.themeService = themeService; this.themeService = themeService;
this.postCategoryService = postCategoryService; this.postCategoryService = postCategoryService;
this.postTagService = postTagService; this.postTagService = postTagService;
this.optionService = optionService;
} }
/** /**
@ -62,7 +72,7 @@ public class ContentArchiveController {
@GetMapping("{url}") @GetMapping("{url}")
public String post(@PathVariable("url") String url, public String post(@PathVariable("url") String url,
@RequestParam(value = "cp", defaultValue = "1") Integer cp, @RequestParam(value = "cp", defaultValue = "1") Integer cp,
HttpServletRequest request, @SortDefault(sort = "createTime", direction = DESC) Sort sort,
Model model) { Model model) {
Post post = postService.getBy(PostStatus.PUBLISHED, url); Post post = postService.getBy(PostStatus.PUBLISHED, url);
@ -75,13 +85,19 @@ public class ContentArchiveController {
model.addAttribute("prePost", prePost); model.addAttribute("prePost", prePost);
}); });
List<Category> categories = postCategoryService.listCategoryBy(post.getId()); List<Category> categories = postCategoryService.listCategoryBy(post.getId());
List<Tag> tags = postTagService.listTagsBy(post.getId()); List<Tag> tags = postTagService.listTagsBy(post.getId());
Page<CommentVO> comments = commentService.pageVosBy(post.getId(), PageRequest.of(cp, optionService.getCommentPageSize(), sort));
final int[] pageRainbow = PageUtil.rainbow(cp, comments.getTotalPages(), 3);
model.addAttribute("is_post", true); model.addAttribute("is_post", true);
model.addAttribute("post", post); model.addAttribute("post", post);
model.addAttribute("categories", categories); model.addAttribute("categories", categories);
model.addAttribute("tags", tags); model.addAttribute("tags", tags);
model.addAttribute("comments", comments);
model.addAttribute("pageRainbow", pageRainbow);
return themeService.render("post"); return themeService.render("post");
} }
} }

View File

@ -1,5 +1,9 @@
package run.halo.app.web.controller.content; package run.halo.app.web.controller.content;
import cn.hutool.core.util.PageUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.web.SortDefault; import org.springframework.data.web.SortDefault;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -8,12 +12,12 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import run.halo.app.model.entity.Category; import run.halo.app.model.entity.Category;
import run.halo.app.model.entity.Post;
import run.halo.app.service.CategoryService; import run.halo.app.service.CategoryService;
import run.halo.app.service.PostService; import run.halo.app.service.OptionService;
import run.halo.app.service.PostCategoryService;
import run.halo.app.service.ThemeService; import run.halo.app.service.ThemeService;
import java.util.List;
import static org.springframework.data.domain.Sort.Direction.DESC; import static org.springframework.data.domain.Sort.Direction.DESC;
/** /**
@ -26,28 +30,29 @@ public class ContentCategoryController {
private final CategoryService categoryService; private final CategoryService categoryService;
private final PostService postService;
private final ThemeService themeService; private final ThemeService themeService;
private final PostCategoryService postCategoryService;
private final OptionService optionService;
public ContentCategoryController(CategoryService categoryService, public ContentCategoryController(CategoryService categoryService,
PostService postService, ThemeService themeService,
ThemeService themeService) { PostCategoryService postCategoryService,
OptionService optionService) {
this.categoryService = categoryService; this.categoryService = categoryService;
this.postService = postService;
this.themeService = themeService; this.themeService = themeService;
this.postCategoryService = postCategoryService;
this.optionService = optionService;
} }
/** /**
* Render category list page * Render category list page
* *
* @param model model * @return template path: theme/{theme}/categories.ftl
* @return template path: /{theme}/categories.ftl
*/ */
@GetMapping @GetMapping
public String categories(Model model) { public String categories() {
final List<Category> categories = categoryService.listAll();
model.addAttribute("categories", categories);
return themeService.render("categories"); return themeService.render("categories");
} }
@ -56,12 +61,12 @@ public class ContentCategoryController {
* *
* @param model model * @param model model
* @param slugName slugName * @param slugName slugName
* @return template path: /{theme}/category.ftl * @return template path: theme/{theme}/category.ftl
*/ */
@GetMapping(value = "{slugName}") @GetMapping(value = "{slugName}")
public String categories(Model model, public String categories(Model model,
@PathVariable("slugName") String slugName) { @PathVariable("slugName") String slugName) {
return this.categories(model, slugName, 1, Sort.by(DESC, "postDate")); return this.categories(model, slugName, 1, Sort.by(DESC, "createTime"));
} }
/** /**
@ -70,14 +75,24 @@ public class ContentCategoryController {
* @param model model * @param model model
* @param slugName slugName * @param slugName slugName
* @param page current page number * @param page current page number
* @return template path: /{theme}/category.ftl * @return template path: theme/{theme}/category.ftl
*/ */
@GetMapping("{slugName}/page/{page}") @GetMapping("{slugName}/page/{page}")
public String categories(Model model, public String categories(Model model,
@PathVariable("slugName") String slugName, @PathVariable("slugName") String slugName,
@PathVariable("page") Integer page, @PathVariable("page") Integer page,
@SortDefault(sort = "postDate", direction = DESC) Sort sort) { @SortDefault(sort = "createTime", direction = DESC) Sort sort) {
// TODO Complete this api in the future // Get category by slug name
return ""; final Category category = categoryService.getBySlugName(slugName);
final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort);
Page<Post> posts = postCategoryService.pagePostBy(category.getId(), pageable);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_categories", true);
model.addAttribute("posts", posts);
model.addAttribute("rainbow", rainbow);
model.addAttribute("category", category);
return themeService.render("category");
} }
} }

View File

@ -1,5 +1,6 @@
package run.halo.app.web.controller.content; package run.halo.app.web.controller.content;
import cn.hutool.core.util.PageUtil;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
@ -10,10 +11,10 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import run.halo.app.model.entity.Post;
import run.halo.app.model.entity.Tag; import run.halo.app.model.entity.Tag;
import run.halo.app.model.vo.PostListVO;
import run.halo.app.service.OptionService; import run.halo.app.service.OptionService;
import run.halo.app.service.PostService; import run.halo.app.service.PostTagService;
import run.halo.app.service.TagService; import run.halo.app.service.TagService;
import run.halo.app.service.ThemeService; import run.halo.app.service.ThemeService;
@ -31,18 +32,15 @@ public class ContentTagController {
private final TagService tagService; private final TagService tagService;
private final PostService postService; private final PostTagService postTagService;
private final OptionService optionService; private final OptionService optionService;
private final ThemeService themeService; private final ThemeService themeService;
public ContentTagController(TagService tagService, public ContentTagController(TagService tagService, PostTagService postTagService, OptionService optionService, ThemeService themeService) {
PostService postService,
OptionService optionService,
ThemeService themeService) {
this.tagService = tagService; this.tagService = tagService;
this.postService = postService; this.postTagService = postTagService;
this.optionService = optionService; this.optionService = optionService;
this.themeService = themeService; this.themeService = themeService;
} }
@ -67,7 +65,7 @@ public class ContentTagController {
@GetMapping(value = "{slugName}") @GetMapping(value = "{slugName}")
public String tags(Model model, public String tags(Model model,
@PathVariable("slugName") String slugName) { @PathVariable("slugName") String slugName) {
return this.tags(model, slugName, 1, Sort.by(DESC, "postDate")); return this.tags(model, slugName, 1, Sort.by(DESC, "createTime"));
} }
/** /**
@ -82,19 +80,17 @@ public class ContentTagController {
public String tags(Model model, public String tags(Model model,
@PathVariable("slugName") String slugName, @PathVariable("slugName") String slugName,
@PathVariable("page") Integer page, @PathVariable("page") Integer page,
@SortDefault(sort = "postDate", direction = DESC) Sort sort) { @SortDefault(sort = "createTime", direction = DESC) Sort sort) {
Tag tag = tagService.getBySlugNameOfNonNull(slugName); Tag tag = tagService.getBySlugNameOfNonNull(slugName);
int size = optionService.getPostPageSize(); final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort);
Pageable pageable = PageRequest.of(page - 1, size, sort); Page<Post> posts = postTagService.pagePostsBy(tag.getId(), pageable);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
Page<PostListVO> posts; model.addAttribute("is_tags", true);
// TODO get posts by tag model.addAttribute("posts", posts);
//final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3); model.addAttribute("rainbow", rainbow);
// model.addAttribute("is_tags", true); model.addAttribute("tag", tag);
// model.addAttribute("posts", posts);
// model.addAttribute("rainbow", rainbow);
// model.addAttribute("tag", tag);
return themeService.render("tag"); return themeService.render("tag");
} }
} }