Laravel templating engine confusion - php

I'm really confused. that's about several hours that I trying to figure out the relationships of blade system.
However I yet haven't learned all of its points.
My Question is:
I have defined the master.blade.php which contains the following code:
<!doctype HTML>
<html>
<head>
#section("header")
#show
</head>
<body>
#yield("content")
</body>
<footer>
#section("footer")
</footer>
</html>
But I do not know how should I define header and content in the following controller:
class sample extends BaseController
{
protected $layout = "layout.master";
function show()
{
// the code which goes here
}
}

In constructor of BaseController:
$this->layout->header = View::make('header');
In master.blade.php:
{{ $header }}

Related

Laravel: Pass variable to Blade Sub Component

There are many questions here that are similar to mine, such as:
Pass variable to a component Laravel 9
Cannot access Blade Component variables inside the view
Passing variable from component into a slot
but I have not found a resolution to my problem in any of them. I've also scoured the doc at: https://laravel.com/docs/9.x/blade#components
I would have thought this would be a simple task.
I have the following structure, in Resources/views:
start.blade.php (uses)
components/layout.blade.php (uses)
components/head.blade.php
From my controller, I call:
$data =
[
'total' => $total,
'uses_form' => true
];
return view('start', $data);
Inside start.blade.php, I have:
<x-layout>
<x-slot name="uses_form">
{{ $uses_form }}
</x-slot>
<!-- additional html -->
</x-layout>
Inside layout.blade.php:
<!DOCTYPE html>
<html lang="en">
<x-head :uses_form:$uses_form />
<!-- also tried: #include('includes.header', ['uses_form' => $uses_form])-->
<body>
<div class="container-fluid">
{{ $slot }}
</div><!--container-fluid-->
</body>
</html>
Finally, in head.blade.php:
<head>
<link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
#if ($uses_form === true)
<link type='text/css' rel='stylesheet' href='/css/form.css' />
#endif
</head>
This results in an:
Undefined variable $uses_form
at:
head.blade.php: line 3
How can I get the variable to be recognized in head.blade.php?
I'm open to other approaches, such as generated the conditional style include, at a higher level, but I rather keep this check in head.blade.php for maintainability.
Using Laravel version 9.48.0
Edit (Additional Notes)
If I var_dump $uses_form from the top of layout.blade.php, I get the following:
object(Illuminate\View\ComponentSlot)#301 (2) {
["attributes"]=> object(Illuminate\View\ComponentAttributeBag)#299 (1) {
["attributes":protected]=> array(0) { }
}
["contents":protected]=> string(1) "1"
}
So, it's already changed form.
You can try to pass the variable $uses_form from the parent component layout.blade.php to the child component head.blade.php using following changes and I hope it will helpful to you.
layout.blade.php look like:
<!DOCTYPE html>
<html lang="en">
<x-head :uses-form="$uses_form"/>
<body>
<div class="container-fluid">
{{ $slot }}
</div><!--container-fluid-->
</body>
</html>
head.blade.php look like:
<head>
<link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
#if ($usesForm === true)
<link type='text/css' rel='stylesheet' href='/css/form.css' />
#endif
</head>
I got it working. There were a few things needing adjusting, but, mainly, I needed to modify the component classes to accept the parameter data.
Another change that was needed, was to pass the data to the layout component, at the top of start.blade.php, like so:
<x-layout :hasForm="$hasForm">
Also, as indicated in another answer and in comments, I needed to place the variable in quotes.
Finally, I'm not sure if this was part of problem, but I changed the uses_form variable from snake_case to camelCase.
The changes, from the question are such:
Controller:
$data =
[
'total' => $total,
'hasForm' => true
];
return view('start', $data);
start.blade.php
<x-layout :hasForm="$hasForm">
<!-- additional html -->
</x-layout>
app/View/Components/Layout.php
class Layout extends Component
{
public $hasForm;
public function __construct($hasForm)
{
$this->hasForm = $hasForm;
}
}
layout.blade.php
<!DOCTYPE html>
<html lang="en">
<x-head :hasForm:"$hasForm" />
<body>
<div class="container-fluid">
{{ $slot }}
</div><!--container-fluid-->
</body>
</html>
app/Views/Components/Head.php
class Head extends Component
{
public $hasForm;
public function __construct($hasForm)
{
$this->hasForm = $hasForm;
}
}
head.blade.php
<head>
<link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
#if ($hasForm === true)
<link type='text/css' rel='stylesheet' href='/css/form.css' />
#endif
</head>
Hope this may help someone else, down the line.

include controller in view laravel 5

I'm new to laravel and I got stuck.
My problem is I want 2 sections (navigation, content) that has dynamic data
Here's some code
Main Blade
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Portfolio</title>
</head>
<body>
<div class="navigation">
#yield('menu')
</div>
<div class="content">
#yield('content')
</div>
</body>
</html>
portfolio blade
#extends('main')
#section('content')
#foreach($data as $portfolio)
<img src='{{ URL::asset("images/$portfolio->picture.jpg") }}'/>
#endforeach
#stop
and my navigation blade
#extends('main')
#section('menu')
#foreach($menuknoppen as $menuknop)
<a href='{{ URL::to("$menuknop->menu_url") }}'>{{$menuknop->menutitle}}</a>
#endforeach
#stop
the portfolio blade has a controller, but also the menu blade has a controller
Edit1:
the problem is the navigation isn't showing even if I add static text
Edit2:
My controllers
my portfolio controller
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
public function index(){
//here comes a whole list with what i've done
$results = DB::table('projects')->get();
//return $results;
$data = array();
foreach ($results as $key => $result) {
$data[] = $result;
}
return view('portfolio.portfolio')->with('data', $data);
}
public function getProject($portfolio_url){
//this gets the project thats clicked
$results = DB::select('select * from projects where portfolio_url = ?', array($portfolio_url));
return view('portfolio.single')->with('data', $results['0']);
}
}
my navigation controller
class menuController extends Controller {
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
// public function __construct($table){
// $results = DB::table($table)->get();
// return view('menu')->with('menuknoppen', $results);
// }
public function index(){
$results = DB::table('navigation')->get();
return view('menu')->with('menuknoppen', $results);
}
}
Your main blade should be:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Portfolio</title>
</head>
<body>
<div class="navigation">
#include('menu');
</div>
<div class="content">
#yield('content')
</div>
</body>
</html>
Your portfolio should be:
#extends('main')
#section('content')
#foreach($data as $portfolio)
<img src='{{ URL::asset("images/$portfolio->picture.jpg") }}'/>
#endforeach
#stop
Navigation field should be:
//Don't use extends here
#foreach($menuknoppen as $menuknop)
<a href='{{ URL::to("$menuknop->menu_url") }}'>{{$menuknop->menutitle}}</a>
#endforeach
Pass multiple data
public function index()
{
$data = //data code;
$results = // results code
return view(portfolio.portfolio, compact('data', 'results'));
}
You have mixed the concept of #yield , #include and #extend
#yield provides a place for you to replace, so when you call #extend in other view you can reuse the template in view which you extend and replace the part with #yield
#include means this part of code is always replaced by the view it defined
So when you are designing a webpage, you need to make sure what is "always called" (use #include) and what could be replaced (use #yield)
As an assisting explanation to aldrin27 working code, I hope this make your mind clearer on the blade template, it rocks! :D

Passing array from view(Blade) to another view(Blade) in laravel

I have master layout of laravel blade template main.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>#yield('title','My Site')</title>
</head>
<body>
#yield('container','Content area')
{{ HTML::script('assets/js/jquery-1.9.0.js') }}
</body>
</html>
I extended it for another view index.blade.php
#extend('main')
I want to add javascript links to master layout(main.blade.php) if exists in child layout(index.blade.php)
added code in index.blade.php
$extraJs = array('plugins1.js','plugins2.js');
#section('extraJs')
{{ $extraJs }}
#stop
So, How can I add javascript to master layout if exists in child blade?
In php:
<?php
if(isset($extraJs)):
foreach($extraJs as $js):
?>
<script src="assets/js/<?php echo $js ?>" type="text/javascript" />
<?php endforeach; endif; ?>
You can just add a yield in your main.blade.php, like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>#yield('title','My Site')</title>
</head>
<body>
#yield('container','Content area')
{{ HTML::script('assets/js/jquery-1.9.0.js') }}
#yield('javascripts')
</body>
</html>
Then, in your child layout, you add a section for it, like you did. For example:
#section('javascripts')
#foreach($scripts as $script)
{{ HTML::script('ets/js/' . $script) }}
#endforeach
#stop
If you add another child view which doesn't need to use extra javascripts, Laravel won't complain because the section is optional.
I wouldn't really encourage this method but since you asked. It is definitely possible to pass something "up" in the view tree. You can just define a PHP variable in your view and it will be available anywhere in the layout.
index.blade.php
<?php $extraJs = array('plugins1.js','plugins2.js'); ?>
main.blade.php
#if(isset($extraJs))
#foreach($extraJs as $js)
<script src="{{ asset('assets/js/'.$js) }}" type="text/javascript" />
#endforeach
#endif
As you can see I also converted your code in the layout to blade and made use of the asset() function to generate absolute URLs
Note Instead of doing it this way there are other methods. For example View composers or defining the plugins in the controller.

Can not view the rows of the authors table (Laravel)

Hello and thanks for the help! I'm new to laravel and i'm trying to learn it through a tutorial that i found in youtube! http://www.youtube.com/watch?v=lceNwQf-ufY
Everything has been worked correctly until now!
I'm trying to make a list of all the rows of my table authors
My Controller authors.php
<?php
class Authors extends BaseController{
public function get_index(){
return View::make('authors.index')
->with('title', 'Authors Title')
->with('authors', Author::all());
}
}
My Model author.php
<?php
class Author extends Eloquent{
protected $table = 'authors';
}
My View index.blade.php
#extends('authors.layout')
#section('content')
<h2>Authors Page</h2>
<h3>Welcome to the authors page</h3>
<ul>
#foreach($authors as $author)
<li>{{ $author->name }}</li>
#endforeach
</ul>
#stop
And my layout layout.blade.php
<!DOCTYPE html>
<html>
<head>
<title>{{ $title }}</title>
</head>
<body>
#yield('content')
</body>
</html>
Routes.php
<?php
Route::get('/', function()
{
return View::make('hello');
});
Route::get('users', function()
{
return View::make('users');
});
Route::get('authors', array('uses'=>'authors#index'));
You should change in your routes.php
Route::get('authors', array('uses'=>'authors#index'));
to
Route::get('authors', array('uses'=>'Authors#get_index'));
Using Authors#get_index the first part is the name of controller (in your case it's Authors and the second part is the name of method - in your case it's get_index and not index.

Laravel Blade Layouts

This is the problem, its not reading #layout()
Inside the folder View/authors/index.blade.php
#layout('layouts.default')
#section('content')
Authors Home Page
#endsection
In the folder Controllers/authors.php
class Authors_Controller extends Base_Controller{
public $restful = true;
public function get_index(){
return View::make('authors.index')->with('title', 'Autores e Livros');
}
}
and inside the folder View/layouts/default.blade.php
basic html
<html>
<head> <title> {{ $title }} </title> </head>
<body>
{{ $content }}
</body>
</html>
Where's my error? why is it not reading?
First: Inside View/layouts/default.blade.php
<html>
<head> <title> {{ $title }} </title> </head>
<body>
#yield('content')
</body>
</html>
And second: Update
I'm like 99% sure that '#layout('layouts.default')' in your View/authors/index.blade.php is not on the first line. It has to be at the top of the page.
It seems in Laravel 4 you should use #extends('layouts.default') instead of #layout('layouts.default')

Categories