Is it possible to check into a blade view if #yield have content or not?
I am trying to assign the page titles in the views:
#section("title", "hi world")
So I would like to check in the main layout view... something like:
<title> Sitename.com {{ #yield('title') ? ' - '.#yield('title') : '' }} </title>
For those looking on it now (2018+), you can use :
#hasSection('name')
#yield('name')
#endif
See : https://laravel.com/docs/5.6/blade#control-structures
In Laravel 5 we now have a hasSection method we can call on a View facade.
You can use View::hasSection to check if #yeild is empty or not:
<title>
#if(View::hasSection('title'))
#yield('title')
#else
Static Website Title Here
#endif
</title>
This conditional is checking if a section with the name of title was set in our view.
Tip: I see a lot of new artisans set up their title sections like this:
#section('title')
Your Title Here
#stop
but you can simplify this by just passing in a default value as the second argument:
#section('title', 'Your Title Here')
The hasSectionmethod was added April 15, 2015.
There is probably a prettier way to do this. But this does the trick.
#if (trim($__env->yieldContent('title')))
<h1>#yield('title')</h1>
#endif
Given from the docs:
#yield('section', 'Default Content');
Type in your main layout e.g. "app.blade.php", "main.blade.php", or "master.blade.php"
<title>{{ config('app.name') }} - #yield('title', 'Otherwise, DEFAULT here')</title>
And in the specific view page (blade file) type as follows:
#section('title')
My custom title for a specific page
#endsection
#hasSection('content')
#yield('content')
#else
\\Something else
#endif
see "Section Directives" in If Statements - Laravel docs
You can simply check if the section exists:
if (isset($__env->getSections()['title'])) {
#yield('title');
}
And you can even go a step further and pack this little piece of code into a Blade extension: http://laravel.com/docs/templates#extending-blade
Complete simple answer
<title> Sitename.com #hasSection('title') - #yield('title') #endif </title>
I have a similar problem with the solution:
#section('bar', '')
#hasSection('bar')
<div>#yield('bar')</div>
#endif
//Output
<div></div>
The result will be the empty <div></div>
Now, my suggestion, to fix this, is
#if (View::hasSection('bar') && !empty(View::yieldContent('bar')))
<div>#yield('bar')</div>
#endif
New in Laravel 7.x -- sectionMissing():
#hasSection('name')
#yield('name')
#else
#yield('alternative')
#endif
Check if section is missing:
#sectionMissing('name')
#yield('alternative')
#endif
#if (View::hasSection('my_section'))
<!--Do something-->
#endif
Use View::hasSection to check if a section is defined and View::getSection to get the section contents without using the #yield Blade directive.
<title>{{ View::hasSection('title') ? View::getSection('title') . ' - App Name' : 'App Name' }}</title>
I don't think you can, but you have options, like using a view composer to always provide a $title to your views:
View::composer('*', function($view)
{
$title = Config::get('app.title');
$view->with('title', $title ? " - $title" : '');
});
why not pass the title as a variable View::make('home')->with('title', 'Your Title') this will make your title available in $title
Can you not do:
layout.blade.php
<title> Sitename.com #section("title") Default #show </title>
And in subtemplate.blade.php:
#extends("layout")
#section("title") My new title #stop
The way to check is to not use the shortcut '#' but to use the long form: Section.
<?php
$title = Section::yield('title');
if(empty($title))
{
$title = 'EMPTY';
}
echo '<h1>' . $title . '</h1>';
?>
Building on Collin Jame's answer, if it is not obvious, I would recommend something like this:
<title>
{{ Config::get('site.title') }}
#if (trim($__env->yieldContent('title')))
- #yield('title')
#endif
</title>
Sometimes you have an enclosing code, which you only want to have included in that section is not empty. For this problem I just found this solution:
#if (filled(View::yieldContent('sub-title')))
<h2>#yield('sub-title')</h2>
#endif
The title H2 gets only displayed it the section really contains any value. Otherwise it won't be printed...
Related
I'm aware that Laravel-blade allows us to define sections of code, but I'm wondering if it's possible to clear, or redefine a section within the same file as where it's been defined.
For example, something like:
#section('scripts')
<script src="/example.js"></script>
#endsection
//something like
#section('scripts')
// nothing
#endsection
// now the 'scripts' stack is an empty block of code.
//print
{{ #yield('scripts') }}
I've figured out a way to do it, by simply using ob_start() in regular php instead.
#php
ob_start();
#endphp
// write blade code here
#php
$scripts = ob_get_contents();
ob_end_clean();
#endphp
//print
{!! $scripts !!}
I have a simple controller function that fetch all records from db. but when i am trying to show all these records it show nothing. In fact it shows me hard coded foreach loop like this.
#foreach ($compactData as $value) {{ $value->Name }} #endforeach
this is my contoller function.
public function showallProducts()
{
$productstock = Product::all()->stocks;
$productoldprice = Product::all()->OldPrices;
$productcurrentprice = Product::all()->CurrentPrice;
$compactData=array('productstock', 'productoldprice', 'productcurrentprice');
return view('welcome', compact($compactData));
}
this is my view
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
</head>
<body>
<div class="flex-center position-ref full-height">
<div class="content">
<div class="title m-b-md">
Laravel
</div>
<div class="title m-b-md">
All products
</div>
<table>
<tbody>
#foreach ($compactData as $value)
{{ $value->Name }}
#endforeach
</tbody>
</table>
</div>
</div>
</body>
why it is behaving like this. any solution?? I am using phpstorm version 17. Is their any setting issue to run project because what ever project I ran it gives me the only page which i ran with only html?
My route is.
Route::get('/', function () {
$action = 'showallProducts';
return App::make('ProductController')->$action();
});
Have you checked your $compactData variable? Please dd($compactData) to see what it contains.
Problem 1
You are accessing a relational property as a property of Eloquent collection, like this:
Product::all()->stocks
which is not correct. Because the Collection object doesn't have the property stocks but yes the Product object might have a stocks property. Please read the Laravel documentation about Collection.
Problem 2
$compactData = array('productstock', 'productoldprice', 'productcurrentprice');
This line creating an array of 4 string, plain string not variable. So, your $compactData is containing an array of 4 string. If you want to have a variable with associative array then you need to do the following:
$compactData = compact('productstock', 'productoldprice', 'productcurrentprice');
Problem 3
return view('welcome', compact($compactData));
Here you are trying to pass the $compactDate to the welcome view but unfortunately compact() function doesn't accept variable but the string name of that variable as I have written in Problem 2. So, it should be:
return view('welcome', compact('compactData'));
Problem 4
Finally, in the blade you are accessing each element of the $compactData data variable and print them as string which might be an object.
You most likely have a problem with your web server.
Try to use Laravel Valet as development environnement.
Edit : I found this : Valet for Windows
I think you didn't mention the blade in the name of the view file by which it is saved. So change the name of the file by which it is save to something like:
filename.blade.php
and try again.
Explanation:
#foreach ($compactData as $value) this is the syntax of blade template engine, and to parse and excute it, you have to mention the blade extension in the name.
I'm building a small CMS in Laravel and I tried to show the content (which is stored in the DB). It is showing the HTML tags instead of executing them. Its like there is an auto html_entity_decode for all printed data.
<?php
class CmsController extends BaseController
{
public function Content($name)
{
$data = Pages::where('CID', '=', Config::get('company.CID'))
->where('page_name', '=', $name)
->first();
return View::make('cms.page')->with('content', $data);
}
}
I tried to print the content using the curly brace.
{{ $content->page_desc }}
and triple curly brace.
{{{ $content->page_desc }}}
And they give the same result. I need to execute those HTML tags instead of escaping them.
Change your syntax from {{ }} to {!! !!}.
As The Alpha said in a comment above (not an answer so I thought I'd post), in Laravel 5, the {{ }} (previously non-escaped output syntax) has changed to {!! !!}. Replace {{ }} with {!! !!} and it should work.
use this tag {!! description text !!}
I had the same issue. Thanks for the answers above, I solved my issue. If there are people facing the same problem, here is two way to solve it:
You can use {!! $news->body !!}
You can use traditional php openning (It is not recommended) like: <?php echo $string ?>
I hope it helps.
Include the content in {! <content> !} .
There is no problem with displaying HTML code in blade templates.
For test, you can add to routes.php only one route:
Route::get('/', function () {
$data = new stdClass();
$data->page_desc
= '<strong>aaa</strong><em>bbb</em>
<p>New paragaph</p><script>alert("Hello");</script>';
return View::make('hello')->with('content', $data);
}
);
and in hello.blade.php file:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
{{ $content->page_desc }}
</body>
</html>
For the following code you will get output as on image
So probably page_desc in your case is not what you expect. But as you see it can be potential dangerous if someone uses for example '` tag so you should probably in your route before assigning to blade template filter some tags
EDIT
I've also tested it with putting the same code into database:
Route::get('/', function () {
$data = User::where('id','=',1)->first();
return View::make('hello')->with('content', $data);
}
);
Output is exactly the same in this case
Edit2
I also don't know if Pages is your model or it's a vendor model. For example it can have accessor inside:
public function getPageDescAttribute($value)
{
return htmlspecialchars($value);
}
and then when you get page_desc attribute you will get modified page_desc with htmlspecialchars. So if you are sure that data in database is with raw html (not escaped) you should look at this Pages class
{{html_entity_decode ($post->content())}} saved the issue for me with Laravel 4.0. Now My HTML content is interpreted as it should.
I have an application without controllers and read about controller layouts in laravel 4 documentation and this other article too, but I don't know where to start for implement it within routes (version 4), how can I do that?
Error received: InvalidArgumentException, View [master] not found.
app/routes.php
<?php
View::name('layouts.master', 'layout');
$layout = View::of('layout');
Route::get('users/create', array('as' => 'users.create', function() use($layout) {
//#TODO: load view using 'layouts.master',
// desirable: append 'users.create' and 'users.menu' views to sidebar and content sections.
//return View::make('users.create');
return $layout->nest('content', 'master');
}));
?>
app/views/layouts/master.blade.php
<html>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
</body>
</html>
app/views/users/create.blade.php
{{ Form::open() }}
{{ Form::text('name') }}
{{ Form::submit('submit') }}
{{ Form::close() }}
app/views/users/menu.blade.php
<!-- This is appended to the master sidebar -->
<p>Create user</p>
Update: I modified example code to clarify what I want to do. Check app/routes.php and its comments
The code in your routes file is trying to nest the master layout within itself, which isn't really what you want. You're getting the error because 'master' would look for app/views/master.blade.php. That's easily fixed by changing it to 'layouts.master', but I wouldn't like to think what might happen...
The root cause of the issue you're having is the difference between "yielding" views from a Blade template, and nesting them from a route. When you nest a route, you need to echo it rather than using the #yield tag.
// File: app/routes.php
View::name('layouts.master', 'layout');
$layout = View::of('layout');
Route::get('users/create', array('as' => 'users.create', function() use ($layout)
{
return $layout
->nest('content', 'users.create')
->nest('sidebar', 'users.menu');
}));
/*
|--------------------------------------------------------------------------
| View Composer
|--------------------------------------------------------------------------
|
| Code in this method will be applied to all views that use the master
| layout. We use that to our advantage by injecting an "empty" sidebar
| when none is set when returning the view. It will error otherwise.
|
*/
View::composer('layouts.master', function($view)
{
if (!array_key_exists('sidebar', $view->getData()))
{
$view->with('sidebar', '');
}
});
// File: app/views/layouts/master.blade.php
<html>
<body>
#section('sidebar')
This is the master sidebar
{{ $sidebar }}
#show
<div class="container">
{{ $content }}
</div>
</body>
</html>
Laravel's View composers are a powerful tool. If you have any data (eg logged-in user info) used by all views that share the same template(s), you can use the composers to save injecting the data every time you load the view.
You could also use the #parent tag to append content, assuming you;re using blade for templating. E.g. (in the view)
#section('sidebar')
#parent
<p>This is appended to the master sidebar.</p>
#stop
You don't need to use nesting views if you're using blade.
app/views/users/create.blade.php
You need to extend the master.blade
#extends('layouts.master')
#section('content')
// form stuff here
#stop
Now, all you need to do is call create.blade
return View::make('users.create')
Just throwing this out there as a possible solution using controller routing (whereas you can set the template from within the controller).
app/routes.php
Route::controller('something', 'SomethingController');
app/controllers/SomethingController.php
class SomethingController extends BaseController {
protected $layout = "templates.main"; // denotes views/templates/main.blade.php
public function getIndex() { // the "landing" page for "/something" or "/something/index"
$this->layout->content = View::make('something.index')->with("myVar", "Hello, world!"); // load in views/something/index.blade.php INTO main.blade.php
}
public function getTest() { // for "/something/test"
$this->layout->content = View::make('something.index')->nest("widget", "something.widget", array("myVar" => "Hello, World!"));
}
}
app/views/templates/main.blade.php
#include('templates.partials.header')
#yield('something')
#yield('content')
#include('templates.partials.footer')
app/views/something/widget.blade.php
I'm a widget. {{ $myVar }}
app/views/something/index.blade.php
#section('something')
I will go in the 'something' yield in main.blade.php
#stop
#section('content')
I will go in the 'content' yield in main.blade.php.
{{ $myVar }}
{{ $widget }}
#stop
?>
Now you can test http://myserver/something and http://myserver/something/test to see the differences. Note: not tested but as a rough example.
How can i use something like {{#something}} and it will run a controller that checks for "something" so i can return it to translteable text?
My current blade template looks like following:
#layout("layouts.default")
#section("inner")
<h1>Velkommen til pornobiksen</h1>
#foreach($videos as $thumb)
{{$thumb}}
#endforeach
#endsection
I mean, how can i change the "Velkommen til pornobiksen" tekst? I know i can make something like
View::make("template")->with("h1_text","Velkommen til pornobiksen");
But is there not a module/plugin to make it easier? By making like {{#h1_text}} and it will takes from my database or something?
What is the easists way to make this?
You need to use {{ $h1_text }} to put the variable into your blade template.
#layout("layouts.default")
#section("inner")
<h1>{{ $h1_text }}</h1>
#foreach($videos as $thumb)
{{$thumb}}
#endforeach
#endsection
EDIT
I think I misunderstood you, it seems you are looking for localization
#layout("layouts.default")
#section("inner")
<h1>{{ Lang::get('messages.welcome') }}</h1>
#foreach($videos as $thumb)
{{$thumb}}
#endforeach
#endsection
For localization , you can use helper function : trans
home.php
return [
'welcome' => 'Velkommen til pornobiksen'
];
View
#layout("layouts.default")
#section("inner")
<h1>{{trans('home.welcome')}}</h1>
#foreach($videos as $thumb)
{{$thumb}}
#endforeach
#endsection