I have read somewhere on the web that in the blade template engine, the {{ }} automatically sanitize output.
But, what if I want to echo a sanitized Input::get from the controller. What is the best way to do it (e() which is just an htmlentities or HTML::entities or something else)?
I have read somewhere on the web that in the blade template engine, the {{ }} automatically sanitize output.
That is incorrect. You need to use three (3) curly braces to sanitize output {{{ }}}
But, what if I want to echo a sanitized Input::get from the controller.
You should not output from your controllers - you should do it from a view
What is the best way to do it (e() which is just an htmlentities or HTML::entities or something else)?
Yes - e() is the best way to do it in Laravel 4.
On the backend, all that {{{ }}} is doing is actually changing to the equilivant of {{ e() }} anyway
Edit: in Laravel 5 both {{ }} and {{{ }}} now sanitize output. If you need to have unsantized output in Laravel 5 - you can use {!! !!}
Related
I have a master view and depending on the URL and controller, it will load in another subview to a variable called $content, that's the idea.
Currently I am trying with:
return view("master")->with(["content" => view("pages.group")]);
So for example, if the URL is https://example.com/group/1 I am trying to get the subview included on my master template. Currently, it just gets escaped for XSS but I feel like this isn't the right way to do this?
I assume you are trying to display the sub-view content in the follwing way:
{{ $content }}
Change your syntax from {{ }} (Escaped output) to {!! !!} (Non escaped output).
{!! $content !!}
In the end after #lagbox mentioned it, using Laravel sections enabled me to use a master view and extend it when needed. https://laravel.com/docs/6.x/blade#extending-a-layout
I have defined a Twig function like this:
new Twig_SimpleFunction('link', 'html_link', ['is_safe' => ['html']]);
so every {{ link(...) }} isn't auto-escaped by Twig. That works.
But html_link() returns a Link object that can be tweaked in the template, to add a URL #fragment or link [attribute]:
{{ link('url', 'label').withFragment('foo') }}
{{ link('url', 'label').withClass('special') }}
But Twig detects that it's not a pure link() anymore, so it's not html-safe anymore, and I have to add |raw to make it work:
{{ link('url', 'label').withFragment('foo')|raw }}
{{ link('url', 'label').withClass('special')|raw }}
Which works. But. Not very pretty.
Can I tell Twig that link().withFragment() and link().withClass() are still html-safe?
Custom filters have an option preserves_safety that kinda works kinda like that:
{{ someFunction(someVar)|someFilter }}
If someFunfction is html-safe, and someFilter was defined with preserves_safety, the output is still safe. I don't want to make filters for ever Link method, so that's not quite good enough.
I can't use Twig_Markup, because:
It has to remain an object as long as possible (withFragment, withClass etc return $this), so you can do multiple things to it, e.g. add a class AND a fragment.
It must be usable outside of Twig. E-mails and flash messages can include links. Only Twig knows (and should know) what a Twig_Markup is. Since it's not an interface, I can't add it to the Link class.
I have this weird problem with my Laravel 5.5 version... I created the auth views using
php artisan make:auth
This command created the views controllers and everything I need to lets get stared to work. But I'm having this visualization problem
As you can see on the register view I have this problem.
The real thing is that "{{ any_command }}" is printing the code that its supose to generate instead of interprating like part of the code. But if I use {!! any_command !!} instead it seems to work propertly. What can happend to my laravel is screwed up. It has nothing to be with the artisan auth method, because I tried to create a new form (using laravel collective form helper) and get the same result.
{{ }} will escape all data before printing. So, if you write any HTML tag inside, it will be escaped and printed as is. Just like your example.
{!! !!} will print unescaped data. This will print the tags correctly, but you have to take care where you use it, because someone could inject unwanted data there.
So, in your case, you should use {!! !!}.
Please, refer to this question: What is the difference between {{ }} and {!! !!} in laravel blade files?
Laravel 5.4 Blade introduced the concept of components & slots - but I can't see what they add over the traditional #include. As I understand, with component/slots, you do:
In template component-tpl.blade.php:
<div class='container'>
<h1>{{$slot1}}</h1>
<h2>{{$slot2}}</h2>
</div>
Using slots in page template, you do:
#component('component-tpl')
#slot('slot1')
The content of Slot 1
#endslot
#slot('slot2')
The content of Slot 2
#endslot
#endcomponent
What functionality does that provide over the older:
#include('component-tpl',['slot1'=>'The content of Slot 1',
'slot2'=>"The content of Slot 2"])
using the exact same 'component-tpl.blade.php' Blade template?
What am I missing? Thanks for any insights.
Chris
As stated, there's no functional difference I was incorrect - see benjaminhull's answer for details on variable scoping and passing blade syntax code. The following still holds for basic usage, though.
If a slot could contain HTML, then using a component will give a cleaner syntax in your blade files.
#component('test')
<strong>This text has html</strong>
#endcomponent
versus
#include('test', ['slot' => '<strong>This text has HTML</strong>'])
Equally, if a component has no slots, then an include may be preferred:
#include('test')
versus
#component('test')
#endcomponent
There are two key differences.
1. Variable scope
As described in #DavidHyogo's answer, a component only sees variables explicitly passed to it. So you have to give it all variables like so...
#component('my-component', ['foo' => 'bar', 'etc' => 'etc'])
Whereas an include will adopt all variables from the global/current scope by default - unless you define an explicit set of variables to pass it, which then becomes local scope again.
{{-- This include will see all variables from the global/current scope --}}
#include('my-component')
{{-- This include will only see the variables explicitly passed in --}}
#include('my-component', ['foo' => 'bar', 'etc' => 'etc'])
2. Component's {{ $slot }} vs include's {{ $var }}
When using a {{ $slot }} in a component, you can give it blade syntax code e.g...
{{-- alert.blade.php --}}
<div class="alert">{{ $slot }}</div>
#component('alert')
<div>Hello {{ $name }} #include('welcome-message')</div>
#endcomponent
Note how the slot will receive html AND blade syntax code and just deal with it.
This is not possible with includes because you can only pass variables into includes...
{{-- alert.blade.php --}}
<div class="alert">{{ $slot }}</div>
#include('alert', ['slot' => "I CAN'T PASS IN BLADE SYNTAX HERE!"])
It could be done in a more hacky way by grabbing a fresh view() helper and passing it some variables to compile the output we want to pass into the slot, but this is what components are for.
I think I've tracked down another crucial difference. For instance, from the documentation for 5.4:
Blade's #include directive allows you to include a Blade view from within another view. All variables that are available to the parent view will be made available to the included view:
As far as I can tell, components have a different scope from a containing view and so the variables available to the parent view are not available within the component. You need to pass a variable to a component like this:
#component('alert', ['foo' => 'bar'])
#endcomponent
This discussion is related to this problem:
Use variables inside the Markdown Mailables
As the documentation says:
Components and slots provide similar benefits to sections and
layouts; however, some may find the mental model of components and
slots easier to understand.
For me most important thing is component needs a class. So when I need just a simplest reusable part of html (blade) there is no need to create blade file + php file, just simple #include with subview is enough ;)
I want to use view helper like {{ render_part("user_profile"); }} in laravel layout, and render_profile will return and html,
Right now it prints as plain string and not rendering as HTML, Also I need some good guide to understand laravel blade/view compilation architecture so that i can write custom classes overriding core methods.
I've upvoted Gerard Reches answer. But if you want to render views from your controller and display the HTML in your views:
By default, Blade {{ }} statements are automatically sent through PHP's htmlentities function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:
{!! $myHTML !!}
Hope this helps.