Laravel控制器通过foreach循环向Blade返回数据,实现帖子按分类归类展示
我看了你的代码,发现几个关键问题导致没法正确按分类关联展示帖子,咱们一步步来修正:
首先说下原代码的问题点:
- 循环逻辑错误:你在嵌套循环里把整个查询结果数组(
$postsWithCatQuery/$smallpostsWithCatQuery)push到目标数组里,而不是匹配的单个帖子数据;而且第二个循环还误把$postsWithCatQuery当成了小帖子的查询结果,应该用$smallpostsWithCatQuery。 - 数据结构不合理:原代码生成的是扁平数组,没法直接对应“分类-帖子”的层级关系,Blade里遍历会混乱。
- 查询冗余:两次查询逻辑重复,写法可以优化。
修正后的控制器代码
我们先构建「分类ID → 对应大/小帖子」的映射数组,再和你的分类列表关联,这样结构更清晰:
// 获取当前语言下的大缩略图帖子(注意修正join的等号,避免语法隐患) $bigPosts = DB::table('posts') ->join('post_translations', 'posts.id', '=', 'post_translations.post_id') ->join('language', 'post_translations.language_id', '=', 'language.id') ->where('language.local', App::getLocale()) ->where('big_thumbnail', 1) ->latest('post_date') ->get(); // 获取当前语言下的小缩略图帖子 $smallPosts = DB::table('posts') ->join('post_translations', 'posts.id', '=', 'post_translations.post_id') ->join('language', 'post_translations.language_id', '=', 'language.id') ->where('language.local', App::getLocale()) ->whereNull('big_thumbnail') ->latest('post_date') ->limit(2) ->get(); // 初始化分类-帖子映射数组 $postsByCategory = []; // 把大帖子按分类分组 foreach ($bigPosts as $post) { $catId = $post->category_id; if (!isset($postsByCategory[$catId])) { $postsByCategory[$catId] = ['big' => [], 'small' => []]; } $postsByCategory[$catId]['big'][] = $post; } // 把小帖子按分类分组 foreach ($smallPosts as $post) { $catId = $post->category_id; if (!isset($postsByCategory[$catId])) { $postsByCategory[$catId] = ['big' => [], 'small' => []]; } $postsByCategory[$catId]['small'][] = $post; } // 关联你的分类列表,确保只保留存在的分类 $categorizedPosts = []; foreach ($cate as $category) { $catId = $category->category_id; $categorizedPosts[] = [ 'category' => $category, 'posts' => $postsByCategory[$catId] ?? ['big' => [], 'small' => []] ]; } // 把整理好的数据传给视图 return view('你的视图名称', compact('categorizedPosts'));
修正后的Blade模板代码
现在可以按「分类 → 大帖子 → 小帖子」的层级遍历,逻辑更直观:
@foreach($categorizedPosts as $item) <!-- 先展示分类名称(假设分类有name字段,根据你的实际字段调整) --> <h2>{{ $item['category']->name }}</h2> <!-- 遍历大缩略图帖子 --> @foreach($item['posts']['big'] as $post_b) <div class="post sports-post post-separator-border"> <div class="post-wrap"> <!-- 图片链接修正:加上引号,用post的id(原代码用post_id,注意你的字段名是否正确) --> <a class="image" href="{{ route('front.post_view', [$post_b->id]) }}"> <img src="{{ $post_b->image }}" alt="{{ $post_b->title }}"> </a> <div class="content"> <!-- 这里补充你的帖子内容,比如标题、日期等 --> <h3><a href="{{ route('front.post_view', [$post_b->id]) }}">{{ $post_b->title }}</a></h3> <p>{{ $post_b->excerpt }}</p> <span class="post-date">{{ $post_b->post_date }}</span> </div> </div> </div> @endforeach <!-- 遍历小缩略图帖子 --> @foreach($item['posts']['small'] as $post_s) <div class="post small-post"> <div class="post-wrap"> <a class="image" href="{{ route('front.post_view', [$post_s->id]) }}"> <img src="{{ $post_s->image }}" alt="{{ $post_s->title }}"> </a> <div class="content"> <h4><a href="{{ route('front.post_view', [$post_s->id]) }}">{{ $post_s->title }}</a></h4> <span class="post-date">{{ $post_s->post_date }}</span> </div> </div> </div> @endforeach @endforeach
额外建议
如果你的项目用了Eloquent模型(比如Post、Category、PostTranslation),可以定义关联关系,代码会更简洁:
- 在
Post模型里定义category()关联和translations()关联 - 用
with()预加载关联,避免N+1查询
内容的提问来源于stack exchange,提问作者user15568390
相关产品推荐
相关产品推荐

