Filament 2多语言标签页动态生成内容区块重复问题求助
问题
需要根据语言数量动态生成标签页,每个标签页内仅生成一组内容区块(段落、按钮、图片、元素数量各一个),但当前实现会让每个语言标签页重复生成4次相同的区块组。
原代码
$tabs = []; $lang = []; foreach ($languages as $key => $language) { if ($key < $languages->count()) { if (!array_key_exists($language->id, $lang)) { $lang = array_merge($lang, [ $language->id]); \Log::info('Processing language: ' . $language->id); // Check if blocks for the current language have already been created if (!isset($languageBlocks[$language->id])) { // If not, create blocks and store them in the array $languageBlocks[$language->id] = [ 'paragraph' => self::makeParagraphBlock($language), 'button_name' => self::makeButtonBlock($language), 'image' => self::makeImageBlock($language), 'elements_number' => self::makeElementsNumberBlock($language), ]; } // Use the stored blocks for the current language $blocks = $languageBlocks[$language->id]; $tabs = array_merge($tabs, [ Forms\Components\Tabs\Tab::make(__($language->name[$language->id]->text))->schema([ Forms\Components\Builder::make('content') ->label('Tartalom') ->collapsible() ->schema($blocks), ]) ]); } } else { break; } } return $form->schema([ Forms\Components\Card::make() ->schema([ Forms\Components\TextInput::make('id')->hidden(), Forms\Components\Card::make() ->schema([ Forms\Components\TextInput::make('content_blocks')->label('Blok név'), ]), Forms\Components\Tabs::make('Localization')->tabs($tabs), ]), ]);
问题原因
- 区块数组格式错误:
$languageBlocks[$language->id]是关联数组,直接传给Builder::schema()时,Laravel Forms的Builder组件会将数组中的每个键值对(共4个)都作为独立的区块模板渲染,导致每个标签页重复显示4次完整区块组。 - 冗余逻辑干扰:
$lang数组的去重逻辑冗余,且if ($key < $languages->count())和break完全多余,foreach本身会遍历完整个集合。
修复方案
修改数组格式并简化循环逻辑:
$tabs = []; $languageBlocks = []; foreach ($languages as $language) { // 跳过已处理的语言(避免重复生成标签页) if (isset($languageBlocks[$language->id])) { continue; } \Log::info('Processing language: ' . $language->id); // 为当前语言创建区块,用索引数组存储区块实例 $languageBlocks[$language->id] = [ self::makeParagraphBlock($language), self::makeButtonBlock($language), self::makeImageBlock($language), self::makeElementsNumberBlock($language), ]; // 生成对应语言的标签页,每个标签页仅加载一次区块组 $tabs[] = Forms\Components\Tabs\Tab::make(__($language->name[$language->id]->text)) ->schema([ Forms\Components\Builder::make('content') ->label('Tartalom') ->collapsible() ->schema($languageBlocks[$language->id]), ]); } return $form->schema([ Forms\Components\Card::make() ->schema([ Forms\Components\TextInput::make('id')->hidden(), Forms\Components\Card::make() ->schema([ Forms\Components\TextInput::make('content_blocks')->label('Blok név'), ]), Forms\Components\Tabs::make('Localization')->tabs($tabs), ]), ]);
修改说明
- 移除冗余的
$lang数组和无效判断,用isset($languageBlocks[$language->id])直接判断是否已处理该语言,逻辑更简洁。 - 将关联数组改为索引数组存储区块实例,确保Builder组件只渲染一组区块模板。
- 用
$tabs[] = ...替代array_merge,提升代码性能和可读性。
内容的提问来源于stack exchange,提问作者Silimon Barabas Szili
相关产品推荐
相关产品推荐

