Laravel 4: if statement in blade layout works strange - laravel

Could someone explain me why I get blank screen with printed string "#extends('layouts.default')" if I request page normally (not ajax)?
#if(!Request::ajax())
#extends('layouts.default')
#section('content')
#endif
Test
#if(!Request::ajax())
#stop
#endif
I'm trying to solve problem with Ajax, I don't want to create 2 templates for each request type and also I do want to use blade templates, so using controller layouts doesn't work for me. How can I do it in blade template? I was looking at this Laravel: how to render only one section of a template?
By the way. If I request it with ajax it works like it should.

Yes #extends has to be on line 1.
And I found solution for PJAX. At the beginning I was not sure this could solve my problem but it did. Don't know why I was afraid to lose blade functionality if you actually can't lose it this way. If someone is using PJAX and needs to use one template with and without layout this could be your solution:
protected $layout = 'layouts.default';
public function index()
{
if(Request::header('X-PJAX'))
{
return $view = View::make('home.index')
->with('title', 'index');
}
else
{
$this->layout->title = 'index';
$this->layout->content = View::make('home.index');
}
}

Try moving #extends to line 1 and you will see the blade template will render properly.
As for solving the ajax problem, I think it's better if you move the logic back to your controller.
Example:
…
if ( Request::ajax() )
{
return Response::eloquent($books);
} else {
return View::make('book.index')->with('books', $books);
}
…
Take a look at this thread for more info: http://forums.laravel.io/viewtopic.php?id=2508

You can still run your condition short handed in the fist line like so
#extends((Request::ajax())?"layout1":"layout2")

Related

Laravel Livewire how to redirect before render

I want to redirect if Auth::user()->id is not equal to Ad->user_id
it does not work inside the mount or hydrate method.
$this->ad = Ad::where('id', $this->ad_id);
if ($this->ad->user_id != Auth::User()->id) {
return redirect()->route('dashboard');
}
You can redirect from mount() method. You can't redirect inside render as you would need to call return redirect('/') which would throw an error "render" method on [App\Http\Livewire\...] must return instance of [Illuminate\View\View]
function mount(){
if(condition fails){
return redirect()->to('someplace');
}
}
Livewire does not do backend redirects as far as I experienced, but rather uses JS to do them. So if you use the $this->redirect method, it will tell rendered component to perform the redirect. Some solutions I've seen on the web were in the render function, if you have an issue that results in a redirect being required, create an empty blade file with a simple div inside, and everywhere you need to redirect the user, set the render view as the blank one, and the FE will take the redirect. A pretty messy fix, but I did not see any better ones currently.
I tried everything but below-mentioned trick worked for me.
Rather than routing from the livewire component we can route from the livewire blade component by adding below code.
#php
$carts = \Cart::getContent();
if(count($carts) == 0)
{
$this->redirect('/shopping-cart/bag');
}
#endphp
Suggestions:
Don't use "return" while redirecting otherwise you might face some Front-end issues.
Don't use "route" while redirecting otherwise the code won't work.

Laravel Blade Template - Put php built-function or maybe laravel helper inside yield

do you ever use PHP built-in function inside blade yield ?
For example can we do something like this :
// master layouts
#yield(ucwords('title'))
// view
#section('title', $title)
Note: $title is from controller
I've already try the first example, but it doesn't work. It doesn't output the $title on my view. Right now I am using this in all of my views
// master layouts
#yield('title')
// view 1
#section('title', ucwords($title))
// view 2
#section('title', ucwords($title))
// view 3
#section('title', ucwords($title))
But I think on second example, I'm not DRY my code because I always repeating the ucwords() on each my view. Can we using it on master layout right on yield declaration?
Thank you guys, have a nice work!
You can make your own blade directive for example if you want to make a #ucfirst() then do something like this in AppServiceProvider .
Blade::directive('ucfirst', function ($expression) {
return ucfirst($expression);
});
Past this into boot()
or on each section() you can extend the main layout #section('title', ucwords($title)) or make the helpers like i mentioned above
as you mentioned above you can use yield()
#yield('title',ucwords(strtolower('Your title')))

Laravel 5.3 parse variable from controller to blade view not working

I cannot seed my blade with variables from my controller.
Look at my controller:
public function formAdd()
{
return view('restaurant.categoryAdd')->with(['myvar' => 'xxx']);
}
In my view categoryAdd:
{{$myvar}}
This way, I got a 500 error. But if I change my view to:
#if (isset($myvar))
<p>Success!</p>
#endif
There is not 500 error, the page is ok, but the 'Success!' is not returned. It means $myvar is undefined. I tested various codes, but I still cannot seed my view.
I tried:
return view('restaurant.categoryAdd')->with(['myvar' => 'xxx']);
return view('restaurant.categoryAdd')->with('myvar', 'xxx');
return view('restaurant.categoryAdd',['myvar' => 'xxx']);
obs: I'm running XAMPP, and It's the only issue I had at this time.
obs2: The problem is not the 'return view' method, It's just working. The problem is my view, It's not receiving the variable.
So try this:
In your controller:
public function formAdd() {
$variable = 'Hello';
return view('restaurant.categoryAdd')->with('myvar', $variable);
}
In your view (if HTML, simply):
<?php
print $myvar;
?>
The problem was in camelcase. I changed the view to 'categoryadd' and It's working now.

Laravel disable controller action layout

Is there a way to disable layout for certain controller method?
Im using something like $this->layout = null ,yet it still render the layout
The view im rendering obviously have a layout associate with it, i just wonder is it possbile to disable the layout from within controller method, without need to modify the blade file itself
Here is the controller:
class PurchaserController extends \BaseController
{
public function index()
{
$this->layout = null;
return View::make('purchasers.index');
}
}
The view:
#extends('layouts.master')
#section('content')
Content
#stop
Im using Laravel 4
Just remove
#extends('layouts.master')
from your view. That will prevent the view from loading.
Also - if you are using the #extends - then you dont actually need $this->layout() in your controller at all
Edit:
" i just wonder is it possbile to disable the layout from within controller method, without need to modify the blade file itself"
The idea is you do it either entirely from the controller, or entirely from the blade file. Not both together.

Can't see variable inside content view in Laravel 4 with Blade

I have a problem understanding how variables work inside the Laravel templating system, Blade.
I set the variables in the controller, I can see them in the first view I make, but not inside the next one.
I'm using a master.blade.php file that holds the header and footer of the page, yielding the content in the middle. I can use the variable inside the master.blade.php file, but not inside the content blade file (variable undefined).
For example, for the contact page:
CONTROLLER FUNCTION:
$this->data['page'] = "contact";
$this->layout->content = View::make('pages.contact');
$this->layout->with('data', $this->data);
MASTER.BLADE.PHP:
if ($data['page'] == 'contact')
{ //do something, it works }
#yield('content')
CONTACT.BLADE.PHP:
if ($data['page'] == 'contact')
{// do something. ErrorException Undefined variable: data}
Am I missing something or is it a known restriction?
Thanks!
The problem was that I was passing the variables only to the layout:
Instead of:
$this->layout->content = View::make('pages.contact');
$this->layout->with('data', $this->data);
I fixed it using:
$this->layout->content = View::make('pages.contact', array('data' => $this->data));
$this->layout->with('data', $this->data);
This way passing the variables to the layout, but also to that particular view.
Hope it helps someone.

Resources