Laravel - How to pass variable to layout partial view - php

I have a partial view in master layout which is the navigation bar. I have a variable $userApps. This variable checks if the user has enabled apps (true), if enabled then I would like to display the link to the app in the navigation bar.
homepage extends master.layout which includes partials.navbar
My code in the navbar.blade.php is this:
#if ($userApps)
// display link
#endif
However I get an undefined variable error. If I use this in a normal view with a controller it works fine after I declare the variable and route the controller to the view. I dont think I can put a controller to a layout since I cant route a controller to a partial view, so how do I elegantly do this?

What version of Laravel you use? Should be something like this for your case:
#include('partials.navbar', ['userApps' => $userApps])
Just for a test purpose, I did it locally, and it works:
routes.php
Route::get('/', function () {
// passing variable to view
return view('welcome')->with(
['fooVar' => 'bar']
);
});
resources/views/welcome.blade.php
// extanding layout
#extends('layouts.default')
resources/views/layouts/default.blade.php
// including partial and passing variable
#include('partials.navbar', ['fooVar' => $fooVar])
resources/views/partials/navbar.blade.php
// working with variable
#if ($fooVar == 'bar')
<h1>Navbar</h1>
#endif
So the problem must be in something else. Check your paths and variable names.

The other answers did not work for me, or seem to only work for older versions. For newer versions such as Laravel 7.x, the syntax is as follows.
In the parent view:
#include('partial.sub_view', ['var1' => 'this is the value'])
In the sub view:
{{ $var1 }}

I have gone through all the answers but below is the best way to do because you can also run queries in serviceProvider.
You need to create a separate service or you can use AppServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
View::composer('layouts.admin-layout', function ($view) {
$view->with('name', 'John Doe');
});
}
}
In your layout
{{$name}}

This approach is very simple:
In parent view :
#include('partial.sub_view1', ['This is value1' => $var1])
In sub view :
{{ $var1 }}

You can use view composer to send your variable to partial view.
Check the laravel documentation on laravel.com about view composer.
Also you can check the following link that will help you resolve this problem.
https://scotch.io/tutorials/sharing-data-between-views-using-laravel-view-composers

Related

Laravel Pass Variables to 'master.blade'

I have created a file called 'master.blade.php' that has the menu, and main aspects of my website. I then have files using #extends and #sections. I know how to pass variables using #extends
#extends('master', ['settings' => $settings])
However I am unsure how to pass a variable to the master without having to this on every single page. Is there anyway to do this without having to do it on every page that uses the master? Something like middleware or along those lines?
You can use boot method from AppServiceProvider :
public function boot() {
View::share('settings', 'value');
}
See official documentation here
Or if you want to pass only master :
public function boot()
{
view()->composer('layouts.master', function($view)
{
$view->with('settings', 'value');
});
}

Laravel language switcher, pass additional parameters to a route

I really can't think of an elegant solution to fix this problem so here it is:
I followed this tutorial https://www.youtube.com/watch?v=KqzGKg8IxE4 to create a localization option for my website. However, integrating the auth was cancer and now I'm faced with an even greater issue regarding the routing for pages that require a get parameter.
Here is my blade code inside the app.blade.php for the language switcher:
<language-switcher
locale="{{ app()->getLocale() }}"
link-en="{{ route(Route::currentRouteName(), 'en') }}"
link-bg="{{ route(Route::currentRouteName(), 'bg') }}"
></language-switcher>
And here are some of my routes
Route::redirect('/', '/en');
Route::get('email/verify', 'Auth\VerificationController#show')->name('verification.notice');
Route::get('email/verify/{id}/{hash}', 'Auth\VerificationController#verify')->name('verification.verify');
Route::get('email/resend', 'Auth\VerificationController#resend')->name('verification.resend');
Route::group([
"prefix" => '{language}',
'where' => ['language' => '(en||bg)'],
], function () {
//Auth routes
Auth::routes();
//Returns to home
Route::get('/', 'HomeController#index')->name('home');
//Handles the faq routes
Route::resource('faq', 'FaqController');
});
Route::get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset');
Route::post('password/reset', 'Auth\ResetPasswordController#reset')->name('password.update');
});
It works well for pages that don't require any get parameters to work with ex: Login / Register / Home page, however if i use something that requires like, faq.edit, which takes an {id} parameters - the language switcher will throw an error because I haven't passed an {id} parameter to it.
The only solution I can think of is adding the language-switcher inside the child blade view and from there I pass the required parameters, however that implies that I have to add the language-switcher to every child view instead of only once at the parent.
You can achieve it with the following steps:
Implement a URL generator macro which will make much easier to generate your URLs which must be identical except language
Get the current route's parameters
Merge the chosen language into them
<?php
namespace App\Providers;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
UrlGenerator::macro('toLanguage', function (string $language) {
$currentRoute = app('router')->current();
$newRouteParameters = array_merge(
$currentRoute->parameters(), compact('language')
);
return $this->route($currentRoute->getName(), $newRouteParameters);
});
}
}
And in your Blade file
#inject('app', 'Illuminate\Contracts\Foundation\Application')
#inject('urlGenerator', 'Illuminate\Routing\UrlGenerator')
<language-switcher
locale="{{ $app->getLocale() }}"
link-en="{{ $urlGenerator->toLanguage('en') }}"
link-bg="{{ $urlGenerator->toLanguage('bg') }}"
></language-switcher>
You'll notice I used contracts injection instead of using facades. More informations here https://laravel.com/docs/7.x/contracts#contracts-vs-facades
And if you don't known Laravel macros, more informations here https://tighten.co/blog/the-magic-of-laravel-macros

How do I use a controller for a "partial" view in Laravel?

Here is my situation. I have a layout.blade.php which most of my pages use. Within this file, I have some partial pieces that I include, like #include('partials.header'). I am trying to use a controller to send data to my header.blade.php file, but I'm confused as to exactly how this will work since it is included in every view that extends layout.blade.php.
What I am trying to do is retrieve a record in my database of any Game that has a date of today's date, if it exists, and display the details using blade within the header.
How can I make this work?
I think to define those Game as globally shared is way to go.
In your AppServiceProvider boot method
public function boot()
{
view()->composer('partials.header', function ($view) {
view()->share('todayGames', \App\Game::whereDay('created_at', date('d')->get());
});
// or event view()->composer('*', Closure) to share $todayGames accross whole blade
}
Render your blade as usual, partial.header blade
#foreach ($todayGames as $game)
// dostuffs
#endforeach
In Laravel you can create a service class method that acts like a controller and use #inject directive to access this in your partial view. This means you do not need to create global variables in boot(), or pass variables into every controller, or pass through the base view layout.blade.php.
resources/views/header.blade.php:
#inject('gamesToday', 'App\Services\GamesTodayService')
#foreach ($gamesToday->getTodayGames() as $game)
// display game details
#endforeach
While it's different value you retrieved belong of the game chosen, you can do something like that:
Controller
$data = Game::select('id', 'name', 'published_date')->first();
return view('game')->with(compact('data'));
layout.blade.php
<html><head></head><body>
{{ $date }}
</body></html>
game.blade.php
#extend('layout')
#section('date', $data->date)
#section('content')
#endsection
The better solution would be this
Under your app folder make a class named yourClassNameFacade. Your class would look like this.
class yourClassNameFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'keyNameYouDecide';
}
}
Then go to the file app/Providers/AppServiceProvider.php and add to the register function
public function register()
{
$this->app->bind('keyNameYouDecide', function (){
//below your logic, in my case a call to the eloquent database model to retrieve all items.
//but you can return whatever you want and its available in your whole application.
return \App\MyEloquentClassName::all();
});
}
Then in your view or any other place you want it in your application you do this to reference it.
view is the following code:
{{ resolve('keyNameYouDecide') }}
if you want to check what is in it do this:
{{ ddd(resolve('keyNameYouDecide')) }}
anywhere else in your code you can just do:
resolve('keyNameYouDecide'))

Get current route name in AppServiceProvider in Laravel 5.1

I have an installation of Laravel 5.1 and I want to share the route name with all my views. I need this for my navigation so I can highlight the corresponding navigation menu button depending on which page the user is on.
I have this code in my app\Providers\AppServiceProvider:
public function boot()
{
$path = Route::getCurrentRoute()->getName();
view()->share('current_route_name', $path);
}
and I am using this namespace:
use Illuminate\Support\Facades\Route;
but I am getting this error in my view:
Call to a member function getName() on a non-object
the interesting part is that if I write this in view it works with no problems at all:
{{ Route::getCurrentRoute()->getName() }}
Could anyone help me? am I not using the correct namespace or maybe it is not even possible to use Route at this point in the application?
Thank you!
you can use view share under view composer.
view()->composer('*', function($view)
{
$view->with('current_route_name',Route::getCurrentRoute()->getName());
});
Or
view()->composer('*', function($view)
{
view()->share('current_route_name',Route::getCurrentRoute()->getName());
})

laravel - home route

I'm learning Laravel, and for my first project I'd like to create my portfolio. However, the first task I have to do is confusing me.
So I created my templates, layout.blade.php and home.blade.php. That makes sense to me, but now how do I tell Laravel, or how do I route to home.blade.php?
I'm looking for an explanation rather then just code. I'm trying to learn.
Actually, a view in MVC application is just a part of the application and it's only for presentation logic, the UI and one doesn't call/load a view directly without the help of another part (controller/function) of the application. Basically, you make a request to a route and that route passes the control over to a controller/function and from there you show/load the view. So it's not a tutorial site and it's also not possible to explain about MVC here, you should read about it and for Laravel, it's best place to understand the basics on it's documentation, well explained with examples, anyways.
In case of Laravel, you should create a controller/class or an anonymous function in your apps/routes.php file and show the view from one of those. Just follow the given instruction step by step.
Using a Class:
To create a route to your Home Controller you should add this code in your app/routes.php
// This will call "showWelcome" method in your "HomeController" class
Route::any('/', array( 'as' => 'home', 'uses' => 'HomeController#showWelcome' ));
Then create the HomeController controller/class (create a file in your controllers folder and save this file using HomeController.php as it's name) then paste the code given below
class HomeController extends BaseController {
public function showWelcome()
{
// whatever you do, do it here
// prepare some data to use in the view (optional)
$data['page_title'] = 'Home Page';
// finally load the view
return View::make('home', $data);
}
}
If you have {{ $title }} in your home.blade.php then it'll print Home Page. So, to use a view you need a controller or an anonymous function and load the view from the controller/function.
Using an anonymous function:
Also, you can use an anonymous function instead of a controller/class to show the view from directly your route, i.e.
Route::any('/', function(){
// return View::make('home');
// or this
$data['page_title'] = 'Home Page'; // (optional)
return View::make('home', $data);
});
Using this approach, whenever you make a request to the home page, Laravel will call the anonymous function given in/as route's callback and from there you show your view.
Make sure to extend the the master/main layout in sub view (home):
Also, remember that, you have following at the first line of your home.blade.php file
#extends('layouts.layout')
It looks confusing, you may rename the main layout (layout.blade.php) to master.blade.php and use following in your home.blade.php instead
#extends('layouts.master')
Read the doc/understand basics:
You should read Laravel's documentation properly, (check templates to understand blade templating) and also read some MVC examples, that may help you too understand the basics of an MVC framework (you may find more by googling) and some good posts about MVC on SO.
Check it routing in Laravel.
You need to use route file and controllers
Create needed function in your Controller file and create a template file for example
class UserController extends BaseController {
/**
* Show the profile for the given user.
*/
public function showProfile($id)
{
$user = User::find($id);
return View::make('user.profile', array('user' => $user));
}
}
you need to create view file views/user/profile.blade.php
View::make('user.profile', array('user' => $user)) == views/user/profile.blade.php
And you should read it http://laravel.com/docs/responses and also this http://laravel.com/docs/quick#creating-a-view

Categories