symfony 4 - Custom error page & custom error message - php

I want to create my custom error page (404, 403, etc.) in Symfony 4 so I have exception, e.g.
if (!$thisVarIsNull) {
throw $this->createNotFoundException(
'This is my custom message'
);
}
and I have created basic template in location templates/bundles/TwigBundle/Exception/error.html.twig:
{% extends "base.html.twig" %}
{% block title %}
We got a problem
{% endblock %}
{% block body %}
<div>
<p>
{{ status_code }} :: {{ exception.message }}
</p>
</div>
{% endblock %}
but the exception.message does not return anything. Where is the problem?

What you are looking for is {{ status_message }} instead of {{ exception.message }}.

Well, I checked over docs. There is no variable exception.
You can only get 2 things
CODE - {{ status_code }}
STATUS_TEXT - {{ status_text }}
Additionally
error.html.twig will be rendered when you get all erros except 404/403
Please also create templates for 404/403 (in same folder), otherwise the default ones will be rendered.
error404.html.twig
error403.html.twig
You can easily test everything in development by using /_error/{statusCode}...
For example: yoursite.com/_error/404

Related

Symfony 4 EasyAdmin - Property does not render when overriding bundle template

Using Symfony 4.1 with EasyAdmin bundle.
I am trying to override a template for the User (one of my entites) show view. I have set up the override and it is working.
Created a user_show.html.twig and registered it in the easy_admin config file.
I then copy the twig blocks from corresponding bundle template for show.html.twig.
Then tried to render a User property from my user entity, called profile height.
Here are twig blocks I'm overriding:
{# templates/admin/user_show.html.twig #}
{% extends '#EasyAdmin/default/show.html.twig' %}
{% block content_title %}
Test Title {{ dump() }}
{% endblock %}
{% block main %}
{{ profileHeight }}
{% endblock %}
Error
Twig_Error_Runtime: Variable "profileHeight" does not exist
Debug
I did a dump and found the property is present on page:
Why can twig not see these variables appearing in the dump? How can I render the properties I want in the template?
As you can see in your dumped data, there is entity array key which hold the User object. So instead of:
{% block main %}
{{ profileHeight }}
{% endblock %}
Use:
{% block main %}
{{ entity.profileHeight }}
{% endblock %}

How can I pass variable from parent template to child template in Twig?

I'm working with Symfony and Twig and I can't find solution for the next problem:
in my parent template (index.html.twig) I have such code:
<noscript>
{% block noscript %}
<div class="alert alert-warning">
<strong>{% block notice %}{{ notice_js_disabled }}{% endblock %} </strong>
{% block message %}{{ js_disabled }}{% endblock %}
</div>
{% endblock %}
</noscript>
I have child template (category.html.twig) which extends index.html.twig template.
Can I pass value of {{ notice_js_disabled }} var from index template to category template?
notice_js_disabled is returned from my Symfony indexAction controller.
UPD:
The solution for my problem I founded, next:
I have made base templae, called main.html.twig, where I'm rendering element from the controller:
{% block header %}
{{ render(controller('StoreBundle:Header:index')) }}
{% endblock %}
Then, on my index.html.twig file, I made next things:
{% extends 'Store/tpl/main.html.twig' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<p class="currentPage" hidden>home</p>
{{ parent() }}
{% endblock %}
I'm not sure is it correct solution, but it's work:)
The only way in Twig you can pass some variable to a child template is by the include tag.
{# template.html will have access to the variables from the current context and the additional ones provided #}
{% include 'template.html' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
{% include 'template.html' with vars %}
However in this way you are not extending some parent template from the child, but you are doing the other way around: you are placing a submodule into the current template.
There are only a couple of variables which are global in symfony
You can set some custom global variables in configuration like described here
Otherwise you can use some predefined global variables, the app variable. (check it out here)
My personal advice is that you should review your application template logic.
Hope it helps!
What you have to do is the following:
-Create A variable in the parent template
{% set notice_js_disabled = value_received_from_indexAction %}
After the template that you need that value
{{ notice_js_disabled }}
I hope it helps you

Twig Inheritance: get raw resulting template

I'm developing Symfony2 + Twig project. I need to get raw not interpeted template (variables shouldn't be replaced) string in Symfony2 Controller after merging with its parent template.
For example:
parent.html.twig
{% block title %}
Parent Content
{% endblock %}
child.html.twig
{% extends "parent.html.twig" %}
{% block title %}
{{ parent() }}
{{ CHILD_CONTENT }}
{% endblock %}
Desirable result is a string:
Parent Content
{{ CHILD_CONTENT }}
I've heard about source function in 1.15 version, but it doesn't handle inheritance.
Is there any way to get around?
already tried "verbatim"? http://twig.sensiolabs.org/doc/tags/verbatim.html
Your code should look like this:
{% block title %}
{{ parent() }}
{% verbatim %}
{{ CHILD_CONTENT }}
{% endverbatim %}
{% endblock %}
This should solve your problem.

Symfony2+Twig, variable in translation return "A message must be a simple text"

When I was doing plain PHP, I was simply doing this:
printf(_("Hello %s !"), $name);
Now with Twig, I must use the trans tag. So I've copy/paste the documentation example, and here's my full template:
{% extends 'MyAppBundle::layout.html.twig' %}
{% block content %}
<h1>
{% trans %}
Hello {{ name }}!
{% endtrans %}
</h1>
{% endblock %}
Why Symfony return the following exeption ?
A message must be a simple text in "MyAppBundle::home.html.twig"
500 Internal Server Error - Twig_Error_Syntax
One missing bit with the previous answer is the "with" portion that is needed to do the replacement of the variable part of the message.
{% trans with {'%name%':name} %}Hello %name%!{% endtrans %}
The precise syntax for translations is a little different in Symfony2 than it is in standalone Twig. You'll want to check out the Symfony2 documentation for translations in twig templates, found here. The correct syntax would look something like this:
{% trans %}Hello %name%!{% endtrans %}
I have a similar issue: to pass my translation path to trans filter, I need to concatenate a string and a variable, then transform into lowercase.
Here {% trans %} and {% endtrans %} are not used, but trans filter instead:
<span>{{ ('statuses.' ~ status | lower) | trans }}</span>
Assuming in the translation there is:
- status:
- failed: The task has failed
and in the template you pass the variable name with value FAILED.

How to get a Doctrine2 Entity method from a Symfony2 Form in Twig

I'm in a Twig template, and I have a "form" variable that represents a Doctrine2 Entity Form.
This Entity has properties that are mapped into the form, but the Entity has also some methods that I would like to access from my Twig template.
I would love to do something like this:
{{ form.myMethod }}
or maybe something like this:
{{ form.getEntity.myMethod }}
but unfortunately it doesn't work.
How could I achieve what I need?
To access your entity from your FormView in a twig template you can use the following code
{{ form.get('value') }}
Where form is your FormView object. This will return your entity and from there you can call any methods on it. If you embed a collection of entities or a single entity in your form you can access it the same way
{{ form.someembedform.get('value') }}
or
{% for obj in form.mycollection %}
{{ obj.get('value').someMethod }}
{% endif %}
An even more convenient syntax to get the underlying entity instead of:
{{ form.get('value') }}
is this:
{{ form.vars.value }}
Then you can call any entity method like this:
{{ form.vars.value.someMethod }}
See also the Form chapter in the Symfony documentation.
Just in order to update the subject:
form.get('value')
is deprecated since symfony 2.1. Copy from Symfony\Component\Form\FormView :
/*
* #deprecated Deprecated since version 2.1, to be removed in 2.3. Access
* the public property {#link vars} instead.
*/
public function get($name, $default = null) ....
so, I guess
form.vars.value.youMethod()
should be the way to go. It has worked form me.
... and there it goes my first post here. hope it helps!
Lost few hours trying to figure out what's going on and why
{{ form.vars.value }}
is NULL.
If you have form.element (not the form object itself) object, for example if you are overriding a form_row template that has passed the form.row object, you can get the Entity like this:
{{ form.getParent().vars.value.MyEntityMethod }}
hope that helps someone!
EDIT: Year and so later - another useful tip:
{% block sonata_type_collection_widget %}
{% for child in form %}
{{ child.vars.form.vars.value.name }}
{% endfor %}
{% endblock %}
object methods should work in twig, I know I used them in some project.
try to use ()
like {{ form.myMethod() }}
It seems that at some point the value is actually null. So you can use
{{ (form.vars.value != null) ? form.vars.value.yourEntityMethod():'' }}
tested in SF v3.0.6.
None of the above worked for me in version 2.6.7. I used customised form widgets to achieve this:
{# src/AppBundle/Resources/views/Form/fields.html.twig #}
{% extends 'form_div_layout.html.twig' %}
{%- block entity_widget -%}
<div {{ block('widget_container_attributes') }}>
{%- for n, child in form %}
{{- form_widget(child, {
'entity': form.vars.choices[n].data
}) -}}
{{- form_label(child) -}}
{% endfor -%}
</div>
{%- endblock %-}
{%- block radio_widget -%}
{# You now have access to entity #}
{%- endblock %-}
use {{ form.getData.myMethod }}.

Categories