OctoberCMS RainLab Blog:如何展示特定分类ID的文章?
问题描述
我在Posts.php中找到了listPosts方法,原本打算复制该方法并修改为可限制特定分类ID的公共方法,但感觉这种做法冗余。请问是否可以直接在前端调用当前方法实现特定分类文章的查询?
现有代码
Posts.php中的listPosts方法:
protected function listPosts() { $category = $this->category ? $this->category->id : null; /* * List all the posts, eager load their categories */ $isPublished = !$this->checkEditor(); $posts = BlogPost::with('categories')->listFrontEnd([ 'page' => $this->property('pageNumber'), 'sort' => $this->property('sortOrder'), 'perPage' => $this->property('postsPerPage'), 'search' => trim(input('search')), 'category' => $category, 'published' => $isPublished, 'exceptPost' => $this->property('exceptPost'), ]); /* * Add a "url" helper attribute for linking to each post and category */ $posts->each(function($post) { $post->setUrl($this->postPage, $this->controller); $post->categories->each(function($category) { $category->setUrl($this->categoryPage, $this->controller); }); }); return $posts; }
前端代码:
{% for post in posts %} <li> <h3><a href="{{ post.url }}">{{ post.title }}</a></h3> </li> {% else %} <li class="no-data">{{ noPostsMessage }}</li> {% endfor %}
烦请指点实现方向,谢谢!
解决方案
当然可以不用重复写方法!你的listPosts方法已经内置了category参数的处理逻辑,只是现在它只取组件关联的$this->category->id,我们只需要调整这个逻辑,让它支持前端传入的分类ID,就能完美复用现有方法,避免冗余。
步骤1:修改listPosts方法,支持外部传入分类ID
把原来的$category赋值逻辑改成「优先取外部传入的参数,没有的话再用组件关联的分类」,这样既保留原有功能,又新增了灵活的分类过滤能力:
protected function listPosts() { // 优先顺序:URL请求参数 > 组件属性参数 > 组件关联的分类ID $category = input('category_id') ?? $this->property('targetCategoryId') ?? ($this->category ? $this->category->id : null); $isPublished = !$this->checkEditor(); $posts = BlogPost::with('categories')->listFrontEnd([ 'page' => $this->property('pageNumber'), 'sort' => $this->property('sortOrder'), 'perPage' => $this->property('postsPerPage'), 'search' => trim(input('search')), 'category' => $category, // 沿用原来的参数名,逻辑已经更新 'published' => $isPublished, 'exceptPost' => $this->property('exceptPost'), ]); // URL辅助属性的处理逻辑保持不变 $posts->each(function($post) { $post->setUrl($this->postPage, $this->controller); $post->categories->each(function($category) { $category->setUrl($this->categoryPage, $this->controller); }); }); return $posts; }
这里提供了两种前端传入分类ID的方式,你可以根据场景选择:
- URL请求参数:适合动态切换分类(比如分类导航点击)
- 组件属性参数:适合在页面固定展示某个分类的文章
步骤2:前端调用方式
场景1:动态切换分类(URL参数)
在分类导航的链接中带上category_id参数,点击后页面会自动过滤对应分类的文章:
<a href="{{ currentUrl() }}?category_id=1">技术文章</a> <a href="{{ currentUrl() }}?category_id=2">生活随笔</a>
前端的文章循环代码不需要任何修改,posts变量会自动返回过滤后的结果。
场景2:固定展示某个分类(组件属性)
在调用Posts组件时,直接传入targetCategoryId属性:
{% component 'Posts' targetCategoryId="3" postsPerPage="6" %}
这样组件会固定返回ID为3的分类下的文章。
可选优化:将方法改为公共(按需)
如果需要在其他PHP类中也调用这个方法,可以把protected改成public,这样其他地方就能通过$this->listPosts()直接复用逻辑,但如果只是前端组件使用,保持protected完全没问题。
这种方式既保留了原有方法的所有功能,又新增了分类过滤的灵活性,完全避免了冗余代码的问题。
内容的提问来源于stack exchange,提问作者CarbonatedAlpaca
相关产品推荐
相关产品推荐

