Passing a variable to a master template in laravel - laravel

In laravel i have defined a route like this
Route::get('/', array(){
'as' => 'index',
'uses' => 'HomeController#index'
});
The function index() in the HomeController contains
public function index(){
$index = new ExampleModel;
$data = $index->getExampleList();
return View::make('public.index');
}
Now the problem is i have a master layout called happypath inside layouts folder in my views which yields this public.index content and i need to pass this $data to layouts.happypath. How do i do this ?

You can use a view composer for example:
namespace App\Providers;
use App\ExampleModel;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
protected $exampleModel;
public function __construct(ExampleModel $exampleModel)
{
$this->exampleModel = $exampleModel;
}
public function boot()
{
view()->composer('layouts.happypath', function ($view) {
$view->with('publicIndex', $this->exampleModel->getExampleList());
});
}
public function register()
{
//
}
}
So, every time you use/render the layouts.happypath the $publicIndex variable will be attached within the layout. Also you need to add the ComposerServiceProvider class in your config/app.php file in the providers array. You may access/reference the data using $publicIndex variable in your layout. There are other ways like global shared $information using view()->share(...) method to share a peace of data all over the views but this may help you.

I could not figure out the ComposerServiceProvider View::composer thing. So i basically solved it like this in Laravel 4.2. Added this code to the BaseController.php
protected $menuList;
public function __construct() {
$response = API::pool([
['GET', API::url('level')],
]);
$index = new Index();
$index->setCourseList($response[0]->json()['Category']);
$result = $index->getCourseList();
View::share('result', $result); //This line shares the $result globally across all the views in laravel 4.2
}

This can be done with a Service Provider. You can either use an existing one or create a new one.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\ExampleModel;
class ViewServiceProvider extends ServiceProvider
{
public function boot()
{
$index = new ExampleModel;
$data = $index->getExampleList();
view()->share('public.index', $data);
}
public function register()
{
}
}
Source: EasyLaravel.com

Related

Laravel 5.8 add data to a layout variable via controller constructor

I am trying to add data to a layout variable via a controller constructor. The reason I want to do this is because I always need to add categories to the topmenu when this controller is called.
No success so far. I add data to a layout via a view composer like this.
namespace App\Http\ViewComposers;
use Illuminate\View\View;
use App\Menu;
class MenuComposer
{
public function compose(View $view)
{
if (in_array($view->getName(), ['layouts.master', 'layouts.master-post', 'layouts.error']))
{
$menu = Menu::menu('topmenu');
view()->with('topmenu', $menu);
// view()->share('topmenu', $menu); not working either
}
}
}
I want to extend the data in a Controller constructor.
namespace App\Http\Controllers\Post;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\View\View;
class PostController extends Controller {
public function __construct(View $view)
{
$view->offsetGet('topmenu');
// $view->gatherData() not working either
}
Whatever I try, Laravel throws an exception:
Target [Illuminate\Contracts\View\Engine] is not instantiable while building [App\Http\Controllers\Post\PostController, Illuminate\View\View].
What I did in the serviceprovider boot function:
view()->share('topmenu', [
'items' => $newItemsToAdd
]);
In the viewComposer I did:
$extraItems = view()->shared('topmenu');
if (!empty($extraItems)) {
$items = aray_merge($items, $extraItems);
}
}

How to transfer data to parent template without code duplication,

I have main layout which contains a header, nav, footer and ofc many blade templates with
inherited from him. My problem: i have categories which i need to connect in my navbar, also in many children templates, maybe it can be done somehow globally without duplication code.
It's my 'HomeContoller' return index template, but if i return my categories with $categories my main layout can't see this variable
public function index()
{
$posts = Post::paginate(10);
$popularPosts = Post::orderByViews()->take(6)->get();
return view('front.index', ['posts' => $posts, 'popularPosts' => $popularPosts]);
}
Now i return to layout.blade my $categories by this method.
#php
$categories = App\Category::all();
#endphp
For this particular case I would suggest the View Composer - especially, if you scroll a bit down on that page you'll see Attaching A Composer To Multiple Views - you could use:
View::composer('*', function ($view) {
$view->with('categories', App\Category::all());
});
You can register it under any of the existing providers for instance AppServiceProvider under the boot method:
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
View::composer('*', function ($view) {
$view->with('categories', App\Category::all());
});
}
}

How to share one method to all controllers in Laravel?

How to share one method to all controllers with different DI, view and parameters? I need something like this:
public function method(Model $model)
{
$baseData = [
'model' => $model,
'route' => route('$route', [$param => $model]),
];
return view($view);
}
All controllers extend App\Http\Controllers\Controller so you can just place it there
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function method(Model $model, $route, $param, $view)
{
// Declared but not used
$baseData = [
'model' => $model,
'route' => route($route, [$param => $model]),
];
return view($view);
}
}
And use it with $this->method()
For example in HomeController
<?php
namespace App\Http\Controllers;
use App\User;
class HomeController extends Controller
{
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$user = User::first();
return $this->method($user, 'home', 'user', 'welcome');
}
}
Now accessing domain.tld/home will return the welcome view
If you want to share function to all controller best way will make service in service folder of app.
step to make service:-
1.create service using artisan command
php artisan make:service service_name and define function that to share to all controller in your project.
after making service your have to register this service with provider.make a provider using artisan command.
php artisan make provider:provider_name and you will see 2 function register and boot
register function is used to register your created service and boot for call already register service
register service like this
public function register()
{
$this->app->bind('App\Services\servicename', function( $app ){
return new serviceclassname;
});
}
3.Go config folder ,open app.php where you will get providers array. In this provider you have to define you provider like App\Providers\providerclassname::class,
call this service in controllers like use App\Services\serviceclassname;
public function functionname(serviceclassname serviceobject)
{
serviceobject->functionname();
}

Returning views using controller present somewhere else other than Views folder

How to return view present somewhere other than views folder from the controller in Laravel? I am making a project divided into modules. I want to return the view of the module from the controller of the main project. How to do it?
Because currently when I try to route to other links it shows:
MethodNotAllowedHttpException in compiled.php line 8895
Routes/web.php:
Route::get('/', function () {
return view('welcome');
});
Route::post('/navpage1',[
'uses'=>'ProjectController#nextpage1',
'as'=>'navpage1'
]);
Route::post('/navpage2',[
'uses'=>'ProjectController#nextpage2',
'as'=>'navpage2'
]);
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class ProjectController extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function nextpage1()
{
return view('C:/xampp/htdocs/larve/app\Modules\Course_Entry\views\welcome');
}
public function nextpage2()
{
return view('C:/xampp/htdocs/larve/app\Modules\Log_in_blog_post\views\welcome');
}
}
App/Modules/ServiceProvider.php:
<?php namespace App\Modules;
class ServiceProvider extends \Illuminate\Support\ServiceProvider
{
public function boot()
{
$modules = config("module.modules");
while (list(,$module) = each($modules)) {
if(file_exists(__DIR__.'/'.$module.'/web.php')) {
include __DIR__.'/'.$module.'/web.php';
}
if(is_dir(__DIR__.'/'.$module.'/Views')) {
$this->loadViewsFrom(__DIR__.'/'.$module.'/Views', $module);
}
}
}
public function register(){}
}
I know something is wrong with my controller, but i am just trying to figure out how to do it...
I have given more code here: Laravel program divided into modules
change the paths in app->config->view.php.
'paths' => [
realpath(base_path('app\Modules\Log_in_blog_post\views')),
],
then use in controller:- view('welcome').

Calling a model function from a controller in Laravel 5.2

I have a model config which has the following at the top:
<?php
namespace App;
use DB;
use Illuminate\Database\Eloquent\Model;
class Config extends Model
{
protected $table = 'config';
public function getConfigVariables()
{
$config = DB::table('config')->where('is', '1')->first();
session()->put('name',$config['name']);
session()->put('infoemail',$config['infoemail']);
session()->put('copyrightowner',$config['copyrightowner']);
and I wish to call this in a controller to set up the session so in the route for the top level I set set up
Route::get('/',
[
'uses' => 'ConfigController#ConfigVariables',
'as' => 'home'
]);
The config controller method which does not work is:
public function ConfigVariables()
{
Config::getConfigVariables();
session()->put('thisyear',ReturnCurrentYear());
$footer = "&copy ".session()->get('thisyear').", ".session()->get('name');
session()->put('footer',$footer);
return view('welcome');
}
but this does not work and I am stuck!
Change
public function getConfigVariables()
to
public static function getConfigVariables()
You might want to read up how object oriented works, basically when you do Config::getConfigVariables(); you are trying to call a static method, without instantiating the class.
A good start would be here, the concept applies everywhere.

Resources