Laravel Blade Template #extends - php

In my views i am extending a default blade template which acts as my Master Template. I have a ViewComposer setup which serves this template with a number of variables.
I have come to a situation where i need to access one of these variables within my index.blade.php which is the page initiating the #extends function.
Do the variable passed via the ViewComposer reach the scope of the initial view? Or will i need to create another ViewComposer to pass the same variable.
ViewComposer
<?php
namespace App\Http\ViewComposers;
use Illuminate\View\View;
use Illuminate\Http\Request;
use App\Repositories\UserRepository;
use Sentinel;
use App\ProjectUsers;
class MasterComposer
{
/**
* The user repository implementation.
*
* #var UserRepository
*/
protected $users;
private $request;
/**
* Create a new profile composer.
*
* #param UserRepository $users
* #return void
*/
public function __construct(Request $request)
{
$this->request = $request;
// Dependencies automatically resolved by service container...
$uid = Sentinel::getUser()->id;
$this->users = ProjectUsers::where("user_id", '=', $uid)->get();
}
/**
* Bind data to the view.
*
* #param View $view
* #return void
*/
public function compose(View $view)
{
$view->with('projects', $this->users);
$view->with('activeProject', $this->request->session()->get("activeProject"));
}
}
ComposerServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider {
/**
* Register bindings in the container.
*
* #return void
*/
public function boot() {
// Using class based composers...
view ()->composer ( 'admin/layouts/default', 'App\Http\ViewComposers\MasterComposer' );
}
/**
* Register the service provider.
*
* #return void
*/
public function register() {
//
}
}
index.blade.php
#extends('admin/layouts/default')
{{ $activeProject }}
This ultimately give me an undefined variable error.
Undefined variable: activeProject (View: /home/laravel/public_html/base/resources/views/admin/index.blade.php)

Yes, all variables which are available in the master layout will be passed to any of its children.

Since you're using #extends in your content layout you can use this
#extends('admin/layouts/default', ['activeProject' => $activeProject])
If this doesn't work you might need to pass it through your controller

Related

Laravel 5.6 Inject variable with Service Provider in a group of routes

I have a part of site that starts with specific prefix /manage.
Can I somehow like with AppServiceProvider view-composers inject a variable in all routes from that prefix?
I tried to do it by passing this variable to layout of all that routes. But then I met a problem. I use this variable in blade view of specific page, and it returns me variable not defined.
Then, I inspect laravel debugger and saw the order of loading of blade files. And it was :
1. Current page view
2. Layout view
3. Sidebars and other stuff
So, the fact that current page is loaded before layout, cause error of undefined variable.
So, how can I solve that ? Thanks.
Code from my Service provider :
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\CT;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
view()->composer(['website.implicare.ct.show', 'website.implicare.ct.petition.index', 'layouts.ct'], function($view) {
$ct = request()->ct;
$permissions = [];
foreach($ct->userPermissions(auth()->id()) as $userPermission) {
if($userPermission->pivot->ct_id == $ct->id) {
array_push($permissions, $userPermission->name);
}
}
$view->with('permissions', $permissions);
});
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
create ComposerServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public $theme = 'mytheme';
public function boot()
{
view()->composer($this->theme.'.includes.navbar', 'App\Http\ViewComposers\MenuComposer');
view()->composer($this->theme.'.includes.header', 'App\Http\ViewComposers\MenuComposer');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}

How to access current placeholder value?

Symfony 3.4.
I have annotations for my controller:
/**
*
* #Route("/{prefix}", requirements={"prefix":"daily_task|event"})
*/
class TaskController extends Controller
and want to access current {prefix} value directly from controller's methods (which aren't routed actions). How to get it's value?
Finally: $this->get('request_stack')->getCurrentRequest()->get('prefix')
Symfony will pass you the variables automatically if you use them as function parameters, like this:
/**
*
* #Route("/{prefix}", requirements={"prefix":"daily_task|event"})
*/
class TaskController extends Controller {
/**
* #Route("/{_locale}/some/path", name="_some_route_name")
*/
public function actualAction($prefix, $_locale) { /* ... */ }
}
Alternatively you can use the whole request like this:
/**
*
* #Route("/{prefix}", requirements={"prefix":"daily_task|event"})
*/
class TaskController extends Controller {
/**
* #Route("/{_locale}/some/path", name="_some_route_name")
*/
public function actualAction(Request $request) {
$prefix = $request->get('prefix');
}
}

ViewComposer Doesn't Work

I have made a header.blade.php which is extended to many View pages. in header menu items come from database.So I used ViewComposer.
Here is my ComposerServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
View::composer(['cart.layouts.header'], 'App\Http\ViewComposers\CategoryComposer#compose');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
here is the CategoryComposer Class:
<?php
namespace App\Http\ViewComposers;
use Illuminate\View\View;
class CategoryComposer
{
public $categoryList = [];
/**
* Create a movie composer.
*
* #return void
*/
public function __construct()
{
$this->categoryList = \DB::table('categories')
->select('categories.*')
->get();
}
/**
* Bind data to the view.
*
* #param View $view
* #return void
*/
public function compose(View $view)
{
$view->with('categories', end($this->categoryList));
}
}
I have also registered the Service Provider in config/app
But the problem is I got error in other pages like Undefined variable: categories
Can you suggest me what could be the Error here?

How to access Sylius Services from Custom Controller

I have this Controller in a fresh sylius standard App and I am trying to access some service from the container but the container is always null.
According to the Symfony Docs, all you need to make your controller container aware is extend the Controller class, as I am doing.
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class HomepageController extends Controller
{
/**
* #var EngineInterface
*/
private $templatingEngine;
/**
* #param EngineInterface $templatingEngine
*/
public function __construct(EngineInterface $templatingEngine)
{
$this->templatingEngine = $templatingEngine;
}
/**
* #param Request $request
*
* #return Response
*/
public function indexAction(Request $request)
{
dump($this->get('sylius.factory.product'));
return $this->templatingEngine->renderResponse('#App/index.html.twig');
}
}
is there any additional configuration I need to do? Any help is welcome.

How do I solve "Target [Interface] is not instantiable" in Laravel 4?

My error message:
Illuminate \ Container \ BindingResolutionException
Target [Project\Backend\Service\Validation\ValidableInterface] is not instantiable.
I understand that interfaces and abstract classes are not instantiable so I know that Laravel should not be trying to instantiate my interface. Yet somehow it's trying to and I suspect this may be a binding issue...even though I believe I have bound it correctly and have registered it as a service provider.
I should mention that I have taken this example out of Chris Fidao's "Implementing Laravel" and it's almost identical!
This is the first couple of lines of my form class:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\ValidableInterface;
use Project\Backend\Repo\Job\JobInterface;
class JobForm {
/**
* Form Data
*
* #var array
*/
protected $data;
/**
* Validator
*
* #var \Project\Backend\Form\Service\ValidableInterface
*/
protected $validator;
/**
* Job repository
*
* #var \Project\Backend\Repo\Job\JobInterface
*/
protected $job;
public function __construct(ValidableInterface $validator, JobInterface $job)
{
$this->validator = $validator;
$this->job = $job;
}
This is the first few lines of my validator class:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\AbstractLaravelValidator;
class JobFormValidator extends AbstractLaravelValidator {
// Includes some validation rules
This is the abstract validator:
namespace Project\Backend\Service\Validation;
use Illuminate\Validation\Factory;
abstract class AbstractLaravelValidator implements ValidableInterface {
/**
* Validator
*
* #var \Illuminate\Validation\Factory
*/
protected $validator;
/**
* Validation data key => value array
*
* #var Array
*/
protected $data = array();
/**
* Validation errors
*
* #var Array
*/
protected $errors = array();
/**
* Validation rules
*
* #var Array
*/
protected $rules = array();
/**
* Custom validation messages
*
* #var Array
*/
protected $messages = array();
public function __construct(Factory $validator)
{
$this->validator = $validator;
}
This is the code where I bind it all to the app:
namespace Project\Backend\Service\Validation;
use Illuminate\Support\ServiceProvider;
use Project\Backend\Service\Form\Job\JobFormValidator;
class ValidationServiceProvider extends ServiceProvider {
public function register()
{
$app = $this->app;
$app->bind('Project\Backend\Service\Form\Job\JobFormValidator', function($app)
{
return new JobFormValidator($app['validator']);
});
}
}
This is then registered in app/config/app.php:
.....
'Project\Backend\Service\Validation\ValidationServiceProvider',
....
Finally these are the first few lines of my controller:
use Project\Backend\Repo\Job\JobInterface;
use Project\Backend\Service\Form\Job\JobForm;
class JobController extends \BaseController {
protected $jobform;
function __construct(JobInterface $job, JobForm $jobform)
{
$this->job = $job;
$this->jobform = $jobform;
}
You need to tell Laravel which instance it should use for a certain interface when injecting it into the constructor via type hinting.
You do this using the bind() method (in your service provider for example)
$app->bind('JobInterface', 'Job'); // Job being the class you want to be used
I highly recommend you watch the video here where Taylor Otwell, the creator of Laravel, explains this and some other things.
First you need to bind using
/app/Providers/AppServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
$this->app->bind('JobInterface', 'Job');
}
}
Once you complete this change
Run composer update

Categories