How to var_dump variables in twig templates? - debugging

View layer pattern where you only present what you have been given is fine and all, but how do you know what is available? Is there a "list all defined variables" functionality in TWIG? Is there a way to dump a variable?
The solution I found by searching for it was to define a function where I can use my existing php debug tools by injecting a function, but all references I have found to that includes these nice two lines of code, but nowhere is it specified where to place them. Going by the fact that they need a $loader variable defined, I tried /app/config/autoload.php but the $loader there was the wrong kind. Where do I place the php code for adding a twig function?

As of Twig 1.5, the correct answer is to use the dump function. It is fully documented in the Twig documentation. Here is the documentation to enable this inside Symfony.
{{ dump(user) }}

If you are in an environment where you can't use the dump function (ex: opencart), you can try:
{{ my_variable | json_encode(constant('JSON_PRETTY_PRINT')) }}

You can use the debug tag, which is documented here.
{% debug expression.varname %}
Edit: As of Twig 1.5, this has been deprecated and replaced with the new dump function (note, it's now a function and no longer a tag). See also: The accepted answer above.

So I got it working, partly a bit hackish:
Set twig: debug: 1 in app/config/config.yml
Add this to config_dev.yml
services:
debug.twig.extension:
class: Twig_Extensions_Extension_Debug
tags: [{ name: 'twig.extension' }]
sudo rm -fr app/cache/dev
To use my own debug function instead of print_r(), I opened vendor/twig-extensions/lib/Twig/Extensions/Node/Debug.php and changed print_r( to d(
PS. I would still like to know how/where to grab the $twig environment to add filters and extensions.

If you are using Twig in your application as a component you can do this:
$twig = new Twig_Environment($loader, array(
'autoescape' => false
));
$twig->addFilter('var_dump', new Twig_Filter_Function('var_dump'));
Then in your templates:
{{ my_variable | var_dump }}

Dump all custom variables:
<h1>Variables passed to the view:</h1>
{% for key, value in _context %}
{% if key starts with '_' %}
{% else %}
<pre style="background: #eee">{{ key }}</pre>
{{ dump(value) }}
{% endif %}
{% endfor %}
You can use my plugin which will do that for you (an will nicely format the output):
Twig Dump Bar

If you are using Twig as a standalone component here's some example of how to enable debugging as it's unlikely the dump(variable) function will work straight out of the box
Standalone
This was found on the link provided by icode4food
$twig = new Twig_Environment($loader, array(
'debug' => true,
// ...
));
$twig->addExtension(new Twig_Extension_Debug());
Silex
$app->register(new \Silex\Provider\TwigServiceProvider(), array(
'debug' => true,
'twig.path' => __DIR__.'/views'
));

The complete recipe here for quicker reference (note that all the steps are mandatory):
1) when instantiating Twig, pass the debug option
$twig = new Twig_Environment(
$loader, ['debug'=>true, 'cache'=>false, /*other options */]
);
2) add the debug extension
$twig->addExtension(new \Twig_Extension_Debug());
3) Use it like #Hazarapet Tunanyan pointed out
{{ dump(MyVar) }}
or
{{ dump() }}
or
{{ dump(MyObject.MyPropertyName) }}

{{ dump() }} doesn't work for me. PHP chokes. Nesting level too deep I guess.
All you really need to debug Twig templates if you're using a debugger is an extension like this.
Then it's just a matter of setting a breakpoint and calling {{ inspect() }} wherever you need it. You get the same info as with {{ dump() }} but in your debugger.

Since Symfony >= 2.6, there is a nice VarDumper component, but it is not used by Twig's dump() function.
To overwrite it, we can create an extension:
In the following implementation, do not forget to replace namespaces.
Fuz/AppBundle/Resources/config/services.yml
parameters:
# ...
app.twig.debug_extension.class: Fuz\AppBundle\Twig\Extension\DebugExtension
services:
# ...
app.twig.debug_extension:
class: %app.twig.debug_extension.class%
arguments: []
tags:
- { name: twig.extension }
Fuz/AppBundle/Twig/Extension/DebugExtension.php
<?php
namespace Fuz\AppBundle\Twig\Extension;
class DebugExtension extends \Twig_Extension
{
public function getFunctions()
{
return array (
new \Twig_SimpleFunction('dump', array('Symfony\Component\VarDumper\VarDumper', 'dump')),
);
}
public function getName()
{
return 'FuzAppBundle:Debug';
}
}

For debugging Twig templates you can use the debug statement.
There you can set the debug setting explicitely.

You can edit
/vendor/twig/twig/lib/Twig/Extension/Debug.php
and change the var_dump() functions to \Doctrine\Common\Util\Debug::dump()

As most good PHP programmers like to use XDebug to actually step through running code and watch variables change in real-time, using dump() feels like a step back to the bad old days.
That's why I made a Twig Debug extension and put it on Github.
https://github.com/delboy1978uk/twig-debug
composer require delboy1978uk/twig-debug
Then add the extension. If you aren't using Symfony, like this:
<?php
use Del\Twig\DebugExtension;
/** #var $twig Twig_Environment */
$twig->addExtension(new DebugExtension());
If you are, like this in your services YAML config:
twig_debugger:
class: Del\Twig\DebugExtension
tags:
- { name: twig.extension }
Once registered, you can now do this anywhere in a twig template:
{{ breakpoint() }}
Now, you can use XDebug, execution will pause, and you can see all the properties of both the Context and the Environment.
Have fun! :-D

you can use dump function and print it like this
{{ dump(MyVar) }}
but there is one nice thing too, if you don't set any argument to dump function, it will print all variables are available, like
{{ dump() }}

Related

How to use #{{ }} without escaping the braces in blade?

I have my routes for user profiles like so example.com/#username. So now I want to say something like this:
Go to {{ $user->name }} profile
But this actually escapes the {{ $user->name }} in href attribute (as said in the documentation), so this will literally redirect me to example.com/{{ $user->name }}.
Of course, I can use the pure php way like #<?= $user->name; ?> or any other way. But I want to use laravel's curly braces {{ }}.
Is it possible?
Try this
Go to {{ $user->name }} profile
The only way to work this problem around is to use the above answer. It will make use of blade's {{ }}.
However, I recommend another (semi) approach. You can create a method for the User model (in my case) like so:
class User {
public function handle()
{
return '#' . $this->username;
}
}
Then you can use:
Go to {{ $user->name }} profile
As I said, this is not a general solution. But it works for my case. If you want more general solution, refer to the above answer.

October CMS and navigation on current page

I am trying to get the basically the active class applied to the current page. As it goes, the builder plugin is setting the URL through:
<a href="{{ detailsPage|page({ (detailsUrlParameter): attribute(record, detailsKeyColumn) }) }}">
However I am new to October so I am not sure how to reference this.page.id in comparison to the url set above.
Basically I want this:
{ set UrlParam = detailsPage|page({ (detailsUrlParameter): attribute(record, detailsKeyColumn) }
{% if this.page.id == UrlParam %} class="active" {% endif %}
Any ideas?
One of the best debugging plugins out there for OctoberCMS is this: https://octobercms.com/plugin/davask-dump
That plugin makes connecting your twig templates to your database / php rendering a breeze.
After installing that plugin you can use {{ d(variable) }} instead of {{ dd(variable) }} and get more information on the array nests etc.
So I would do {{ d(UrlParam) }} and {{ d(this.page.id) }} in your twig template. See what the dump has to say about each of those variables. For clarity I do believe you need the % here {**%** set 'variable' **%**}.
I am also not a fan of the builder component and I use the PHP section on the page / partial pages. And establishing a class with the use function and access the data with $this['variable']. Maybe worth looking into here is a quick example:
Pluginauthor\Plugin\Models\Plugin;
function onStart() {
$plugin = Pluggin::all();
$this['plugin'] = $plugin;
}

How to add helper class function in twig template with laravel

in blade template I have used like:
{{ Helper::getName() }}
But how it is used with twig template?
If you are using laravel-twigbridge you can use helpers from default Extensions, e.g:
{{ form_open(...) }}
instead of
{{ Form::open(...) }}
See docs

Get image name from database in laravel

I have database, with columns image and alttag. I want to use them in laravel blade view. I try something like this:
{{ HTML::image('images/{{ $item->image }}', $alt="{{ $item->alttag }}") }}
But syntax isn't correct. If i just echo image and alttag like this:
<h1>{{ $item->alttag }}</h1>
then they are correct. I wonder what is wrong in my code.
You used blade syntax in a PHP string. Watch the compiled blade templates to see where you did go wrong.
In short. Try this:
{{ HTML::image('images/'. $item->image, $alt = $item->alttag) }}
or equally short:
{{ HTML::image("images/{$item->image}", $alt = $item->alttag) }}

Laravel, variable output work with View::share but not with VIew::composer

I need the same menu in all my views.
So I get data I need for output the menu in a constructor defined in my BaseController.
To got the data I've first tried to use View::composer but dunno why I doesn't get any error, it looks like View::composer isn't executed at all...
If I use View::share, its work
//BaseController.php
//function called in the constructor
public function init()
{
$envs = $this->game->environments()->get();
View::share('test', $envs);
View::composer('layouts.base', function($view)
{
$view->with('envs', $envs);
});
}
//base.twig
//nothing output here, no error
{% for env in envs %}
{{ env.name }}
{% endfor %}
//its work
{% for env in test %}
{{ env.name }}
{% endfor %}
I'm new to laravel so maybe I miss something ?
I think the reason that this isn't working is because of where you put the View Composer in your code. View Composers in Laravel are essentially callbacks that are executed as soon as the view is rendered. Where is this init() function defined? My guess is that the view is being created before your view composer is defined - meaning that the view composer callback will never be executed.
Try moving the whole view composer block from the init() function and append it to the bottom of your routes.php file and see if it works. That's not a bad spot to place your view composers if you do not have too many, if you do you could create a new class to store them in and add that path to your autoload path.
Read more about view composers here

Resources