diff --git a/src/main/java/run/halo/app/model/freemarker/tag/CommentTagDirective.java b/src/main/java/run/halo/app/model/freemarker/tag/CommentTagDirective.java index 3b6ab3423..21c46fb49 100644 --- a/src/main/java/run/halo/app/model/freemarker/tag/CommentTagDirective.java +++ b/src/main/java/run/halo/app/model/freemarker/tag/CommentTagDirective.java @@ -33,7 +33,10 @@ public class CommentTagDirective implements TemplateDirectiveModel { int top = Integer.parseInt(params.get("top").toString()); switch (method) { 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; default: break; diff --git a/src/main/java/run/halo/app/model/freemarker/tag/PostTagDirective.java b/src/main/java/run/halo/app/model/freemarker/tag/PostTagDirective.java index c3db55117..abcdb9d51 100644 --- a/src/main/java/run/halo/app/model/freemarker/tag/PostTagDirective.java +++ b/src/main/java/run/halo/app/model/freemarker/tag/PostTagDirective.java @@ -1,11 +1,10 @@ package run.halo.app.model.freemarker.tag; import freemarker.core.Environment; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; +import freemarker.template.*; import org.springframework.stereotype.Component; +import run.halo.app.model.support.HaloConst; +import run.halo.app.service.PostService; import java.io.IOException; import java.util.Map; @@ -19,9 +18,26 @@ import java.util.Map; @Component public class PostTagDirective implements TemplateDirectiveModel { + private final PostService postService; + + public PostTagDirective(PostService postService) { + this.postService = postService; + } + @Override 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()); } } diff --git a/src/main/java/run/halo/app/service/CategoryService.java b/src/main/java/run/halo/app/service/CategoryService.java index 78a2a43b7..3bf9167f7 100755 --- a/src/main/java/run/halo/app/service/CategoryService.java +++ b/src/main/java/run/halo/app/service/CategoryService.java @@ -39,6 +39,7 @@ public interface CategoryService extends CrudService { * @param slugName slug name * @return Category */ + @NonNull Category getBySlugName(@NonNull String slugName); /** diff --git a/src/main/java/run/halo/app/service/PostCategoryService.java b/src/main/java/run/halo/app/service/PostCategoryService.java index 70492ac52..f7536a9ff 100644 --- a/src/main/java/run/halo/app/service/PostCategoryService.java +++ b/src/main/java/run/halo/app/service/PostCategoryService.java @@ -1,12 +1,13 @@ 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.Post; import run.halo.app.model.entity.PostCategory; 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.List; @@ -48,6 +49,16 @@ public interface PostCategoryService extends CrudService @NonNull List 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 pagePostBy(@NonNull Integer categoryId, Pageable pageable); + /** * Merges or creates post categories by post id and category id set if absent. * diff --git a/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java b/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java index 2de9ebdd0..cedff1871 100644 --- a/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java @@ -1,5 +1,10 @@ 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.Post; 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.base.AbstractCrudService; 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.stream.Collectors; @@ -88,6 +90,17 @@ public class PostCategoryServiceImpl extends AbstractCrudService 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 postIds = postCategoryRepository.findAllCategoryIdsByPostId(categoryId); + + return postRepository.findAllByIdIn(postIds, pageable); + } + @Override public List mergeOrCreateByIfAbsent(Integer postId, Set categoryIds) { Assert.notNull(postId, "Post id must not be null"); diff --git a/src/main/java/run/halo/app/web/controller/content/ContentArchiveController.java b/src/main/java/run/halo/app/web/controller/content/ContentArchiveController.java index a6dca025e..4c00754d3 100644 --- a/src/main/java/run/halo/app/web/controller/content/ContentArchiveController.java +++ b/src/main/java/run/halo/app/web/controller/content/ContentArchiveController.java @@ -1,6 +1,11 @@ package run.halo.app.web.controller.content; +import cn.hutool.core.util.PageUtil; 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.ui.Model; 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.Tag; import run.halo.app.model.enums.PostStatus; +import run.halo.app.model.vo.CommentVO; import run.halo.app.service.*; -import javax.servlet.http.HttpServletRequest; -import java.util.Date; import java.util.List; +import static org.springframework.data.domain.Sort.Direction.DESC; + /** * Blog archive page controller * @@ -38,16 +44,20 @@ public class ContentArchiveController { private final PostTagService postTagService; + private final OptionService optionService; + public ContentArchiveController(PostService postService, CommentService commentService, ThemeService themeService, PostCategoryService postCategoryService, - PostTagService postTagService) { + PostTagService postTagService, + OptionService optionService) { this.postService = postService; this.commentService = commentService; this.themeService = themeService; this.postCategoryService = postCategoryService; this.postTagService = postTagService; + this.optionService = optionService; } /** @@ -62,7 +72,7 @@ public class ContentArchiveController { @GetMapping("{url}") public String post(@PathVariable("url") String url, @RequestParam(value = "cp", defaultValue = "1") Integer cp, - HttpServletRequest request, + @SortDefault(sort = "createTime", direction = DESC) Sort sort, Model model) { Post post = postService.getBy(PostStatus.PUBLISHED, url); @@ -75,13 +85,19 @@ public class ContentArchiveController { model.addAttribute("prePost", prePost); }); + List categories = postCategoryService.listCategoryBy(post.getId()); List tags = postTagService.listTagsBy(post.getId()); + Page 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("post", post); model.addAttribute("categories", categories); model.addAttribute("tags", tags); + model.addAttribute("comments", comments); + model.addAttribute("pageRainbow", pageRainbow); return themeService.render("post"); } } diff --git a/src/main/java/run/halo/app/web/controller/content/ContentCategoryController.java b/src/main/java/run/halo/app/web/controller/content/ContentCategoryController.java index c15b3f9ea..8003918f7 100644 --- a/src/main/java/run/halo/app/web/controller/content/ContentCategoryController.java +++ b/src/main/java/run/halo/app/web/controller/content/ContentCategoryController.java @@ -1,5 +1,9 @@ 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.web.SortDefault; 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.RequestMapping; 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.PostService; +import run.halo.app.service.OptionService; +import run.halo.app.service.PostCategoryService; import run.halo.app.service.ThemeService; -import java.util.List; - import static org.springframework.data.domain.Sort.Direction.DESC; /** @@ -26,28 +30,29 @@ public class ContentCategoryController { private final CategoryService categoryService; - private final PostService postService; - private final ThemeService themeService; + private final PostCategoryService postCategoryService; + + private final OptionService optionService; + public ContentCategoryController(CategoryService categoryService, - PostService postService, - ThemeService themeService) { + ThemeService themeService, + PostCategoryService postCategoryService, + OptionService optionService) { this.categoryService = categoryService; - this.postService = postService; this.themeService = themeService; + this.postCategoryService = postCategoryService; + this.optionService = optionService; } /** * Render category list page * - * @param model model - * @return template path: /{theme}/categories.ftl + * @return template path: theme/{theme}/categories.ftl */ @GetMapping - public String categories(Model model) { - final List categories = categoryService.listAll(); - model.addAttribute("categories", categories); + public String categories() { return themeService.render("categories"); } @@ -56,12 +61,12 @@ public class ContentCategoryController { * * @param model model * @param slugName slugName - * @return template path: /{theme}/category.ftl + * @return template path: theme/{theme}/category.ftl */ @GetMapping(value = "{slugName}") public String categories(Model model, @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 slugName slugName * @param page current page number - * @return template path: /{theme}/category.ftl + * @return template path: theme/{theme}/category.ftl */ @GetMapping("{slugName}/page/{page}") public String categories(Model model, @PathVariable("slugName") String slugName, @PathVariable("page") Integer page, - @SortDefault(sort = "postDate", direction = DESC) Sort sort) { - // TODO Complete this api in the future - return ""; + @SortDefault(sort = "createTime", direction = DESC) Sort sort) { + // Get category by slug name + final Category category = categoryService.getBySlugName(slugName); + + final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort); + Page 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"); } } diff --git a/src/main/java/run/halo/app/web/controller/content/ContentTagController.java b/src/main/java/run/halo/app/web/controller/content/ContentTagController.java index 95a65d5a2..3899790f0 100644 --- a/src/main/java/run/halo/app/web/controller/content/ContentTagController.java +++ b/src/main/java/run/halo/app/web/controller/content/ContentTagController.java @@ -1,5 +1,6 @@ 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; @@ -10,10 +11,10 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; 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.vo.PostListVO; 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.ThemeService; @@ -31,18 +32,15 @@ public class ContentTagController { private final TagService tagService; - private final PostService postService; + private final PostTagService postTagService; private final OptionService optionService; private final ThemeService themeService; - public ContentTagController(TagService tagService, - PostService postService, - OptionService optionService, - ThemeService themeService) { + public ContentTagController(TagService tagService, PostTagService postTagService, OptionService optionService, ThemeService themeService) { this.tagService = tagService; - this.postService = postService; + this.postTagService = postTagService; this.optionService = optionService; this.themeService = themeService; } @@ -67,7 +65,7 @@ public class ContentTagController { @GetMapping(value = "{slugName}") public String tags(Model model, @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, @PathVariable("slugName") String slugName, @PathVariable("page") Integer page, - @SortDefault(sort = "postDate", direction = DESC) Sort sort) { + @SortDefault(sort = "createTime", direction = DESC) Sort sort) { Tag tag = tagService.getBySlugNameOfNonNull(slugName); - int size = optionService.getPostPageSize(); - Pageable pageable = PageRequest.of(page - 1, size, sort); + final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort); + Page posts = postTagService.pagePostsBy(tag.getId(), pageable); + final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3); - Page posts; - // TODO get posts by tag - //final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3); -// model.addAttribute("is_tags", true); -// model.addAttribute("posts", posts); -// model.addAttribute("rainbow", rainbow); -// model.addAttribute("tag", tag); + model.addAttribute("is_tags", true); + model.addAttribute("posts", posts); + model.addAttribute("rainbow", rainbow); + model.addAttribute("tag", tag); return themeService.render("tag"); } }