You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),
        ]),
]);

问题原因

  1. 区块数组格式错误:$languageBlocks[$language->id]是关联数组,直接传给Builder::schema()时,Laravel Forms的Builder组件会将数组中的每个键值对(共4个)都作为独立的区块模板渲染,导致每个标签页重复显示4次完整区块组。
  2. 冗余逻辑干扰:$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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:43:15