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

Laravel中如何翻译动态seo_url?解决getTranslatedAttribute报错问题

解决Laravel动态路由下getTranslatedAttribute调用报错及URL翻译问题

问题概述

在Laravel项目中配置动态路由后,尝试在Blade模板中使用getTranslatedAttribute方法翻译路由对应的seo_url时,出现错误提示:Call to a member function getTranslatedAttribute() on null,需要实现动态URL的翻译功能。

错误原因分析

  1. 空对象调用方法:$solution_details为null,即App\Solution::where('seo_url', $seo_url)->first()未查询到对应记录,直接调用getTranslatedAttribute必然报错。
  2. 查询逻辑错误:seo_url是多语言可翻译字段,直接用原始$seo_url匹配数据库中的字段,无法正确匹配对应语言的翻译值。
  3. 路由硬编码语言前缀:路由中硬编码/en/,不利于多语言扩展,也容易导致语言设置与查询逻辑脱节。

解决方案

1. 优化路由与查询逻辑

改用本地化路由分组,通过中间件统一设置语言,并使用Voyager提供的whereTranslation方法查询对应语言的seo_url:

// routes/web.php
Route::group(['prefix' => '{locale}', 'middleware' => 'setlocale'], function () {
    Route::get('/solutions/{seo_url}', function ($locale, $seo_url) {
        // 根据当前语言查询对应seo_url的解决方案
        $solution_details = App\Solution::whereTranslation('seo_url', $seo_url, $locale)->firstOrFail();
        
        // 预加载所需数据(可根据实际需求优化,比如使用缓存)
        $themes = App\Theme::all();     
        $services = App\Service::all();
        $referances = App\Referance::all();
        $blogs = App\Blog::all();
        $solutions = App\Solution::all();
        $announcements = App\Announcement::all();
        $news = App\News::all();
        $subsolutions = App\Subsolution::all(); 
        $pages = TCG\Voyager\Models\Page::all();         
        
        // 根据语言加载对应视图
        return view("tema.parallax.{$locale}.solution_detail", compact(
            'services','solution_details','themes','pages', 
            'referances' , 'blogs' , 'solutions', 'subsolutions' , 
            'news', 'announcements'
        ));
    });
});

创建SetLocale中间件统一处理语言设置:

// app/Http/Middleware/SetLocale.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\App;

class SetLocale
{
    public function handle($request, Closure $next)
    {
        $locale = $request->route('locale');
        // 限制支持的语言列表,避免非法语言传入
        if (in_array($locale, ['en', 'tr'])) {
            App::setLocale($locale);
        }
        return $next($request);
    }
}

记得在app/Http/Kernel.php的$routeMiddleware中注册中间件:

protected $routeMiddleware = [
    // 其他中间件...
    'setlocale' => \App\Http\Middleware\SetLocale::class,
];

2. 优化Blade模板,增加空值判断

在模板中先判断$solution_details是否存在,再执行后续逻辑,避免空对象调用方法:

<div class="container ms-content">
    <div class="row justify-content-between">
        <div class="row blog-sidebar grid-content col-lg-12">
            <div class="grid-sizer col-12"></div>
            
            {{-- 先校验solution_details是否存在 --}}
            @if($solution_details)
                @if ("{{ request()->locale() }}/solutions/" . $solution_details->getTranslatedAttribute('seo_url', request()->locale(), 'fallbackLocale') == Request::path())
                    <article class="grid-item col-12 pb-lg-5">
                        <div class="work-card card--is-link"> 
                            <figure class="card__img media-wrapper media-wrapper--21:9">
                                <img src="/storage/{{ $solution_details->resim }}" alt="{!! $solution_details->getTranslatedAttribute('baslik', request()->locale(), 'fallbackLocale') !!}">
                                <div class="glow-wrap"><i class="glow"></i></div>
                            </figure>
                            <br>   
                            <div class="card__content">
                                <a class="card__title">
                                    <h4>{!! $solution_details->getTranslatedAttribute('baslik', request()->locale(), 'fallbackLocale') !!}</h4>
                                </a>
                                <p class="text-sm post-excerpt">{!! $solution_details->getTranslatedAttribute('aciklama', request()->locale(), 'fallbackLocale') !!}</p>
                                <div class="post-info__footer"><span class="post-info__divider"></span></div>
                            </div>
                        </div>
                    </article>
                @endif
            @else
                {{-- 无匹配记录时的提示 --}}
                <div class="col-12 text-center py-5">
                    <h5>未找到对应的解决方案</h5>
                </div>
            @endif
        </div>
    </div>
</div>

关键优化点

  • 使用firstOrFail():查询不到记录时直接返回404页面,避免后续空值问题。
  • whereTranslation方法:正确匹配对应语言的翻译字段,解决动态URL的多语言查询问题。
  • 本地化路由分组:统一管理多语言路由,便于扩展新语言。
  • 空值判断:模板中先校验对象是否存在,再调用方法,彻底避免空对象报错。

内容的提问来源于stack exchange,提问作者Emre Kd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:05:52