ivan
ivan

Reputation: 43

Display data in view based on session

I have a table of posts with language column "lang" , i want to display in view only the posts with the language stored in session.

But what i keep getting always is only the posts with the default language (Fr)

Controller :

public function index(Request $request)

{
        if ($request->session()->has('en')) {
            $posts = Post::where('lang','=','En')
            ->with('author','tags','category','comments')
            ->latestFirst()
            ->filter(request()->only(['term', 'year', 'month']))
        }
        elseif ($request->session()->has('ar')) {
            $posts = Post::where('lang','=','Ar')
            ->with('author','tags','category','comments')
            ->latestFirst()
            ->filter(request()->only(['term', 'year', 'month']))
        }
        else  {
            $posts = Post::where('lang','=','Fr')
            ->with('author','tags','category','comments')
            ->latestFirst()
            ->filter(request()->only(['term', 'year', 'month']))
            }
  return view("blog.index", compact('posts'));
}

Upvotes: 1

Views: 77

Answers (2)

Dimitri Mostrey
Dimitri Mostrey

Reputation: 2355

That's because there is no session value with the key 'Ar' or 'En'.

You have 2 options. Through a middleware or in a trait that you can use in controller classes where needed.

Beware that if you use this option that I'm going to publish, it's a problem for search robots to pick it up as the URL is exactly the same. For my project that didn't matter, but it could for yours. If yo don't wan this, you will have to opt to add it to your routes (https://yourweb.site/en/your_urls)

If you opt to use the middleware, to change the language you have to add in any route ?lang=en or ?lang=fr only once after which your session will remember the choice.

The middleware

namespace App\Http\Middleware;

use Closure;

class Language
{
    /**
     * The availables languages.
     *
     * @array $languages
     */
    protected $languages = ['en', 'ar', 'fr'];

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->session()->has('lang'))
        {
            $request->session()->put('lang', $request->getPreferredLanguage($this->languages));
        }
        if ($request->has('lang'))
        {
            $request->session()->put('lang', $request->get('lang'));
        }
        app()->setLocale($request->session()->get('lang'));

        return $next($request);
    }
}

If a new visitor arrives, he or she will be served in the preferred language, in your case French. Any choice to another language is now preserved as session('lang') anywhere in your code.

$posts = Post::where('lang','=', session('lang', 'fr')->...

Upvotes: 1

Salim Djerbouh
Salim Djerbouh

Reputation: 11044

Get the current locale from the app instance and fallback to Fr since it's the default

public function index(Request $request)
{
    $locale = ucfirst(app()->getLocale());
    $posts = Post::where('lang', $locale)
        ->with('author', 'tags', 'category', 'comments')
        ->latestFirst()
        ->filter(request()->only(['term', 'year', 'month']));
    return view("blog.index", compact('posts'));
}

Hope this helps

Upvotes: 1

Related Questions