Variable does not exist twig symfony - php

I have a controller that does this
/**
* #Route("/AjaxAddQuestionForm/{section}")
* #ParamConverter("section", class="AppBundle:Section")
*/
public function ajaxAddQuestionFormAction(Request $request, $section)
{
$question = new Question();
$addQuestionForm = $this->createForm(new AddQuestionType(), $question);
return $this->render('AppBundle:Form:ajaxAddQuestionForm.html.twig', array(
'section' => $section,
'addAjaxQuestionForm' => $addQuestionForm->createView(),
));
}
The ajaxAddQuestionForm.html.twig file looks like this
{% embed 'modal.html.twig' %}
{% block labelledby %}addnewquestion{% endblock %}
{% block modalId %}addnewquestion{% endblock %}
{% block modalHead %}
{{ 'client.modal.head'| trans }}
{% endblock %}
{% block modalBody %}
{{form_start(addAjaxQuestionForm)}}
<div>
{{form_widget(addAjaxQuestionForm.section, {value: section.id})}}
</div>
<div class="form-group">
{{form_label(addAjaxQuestionForm.name, null, {'label_attr': {'class': 'form-label'}}) }}
<span class="help"></span>
<div class="controls">
{{form_widget(addAjaxQuestionForm.name, {'attr':{'class':'form-control'}})}}
</div>
</div>
<div class="form-group">
{{form_label(addAjaxQuestionForm.category, null, {'label_attr': {'class': 'form-label'}}) }}
<span class="help"></span>
<div class="controls">
{{form_widget(addAjaxQuestionForm.category, {'attr':{'width':'100%'}})}}
</div>
</div>
{% endblock %}
{% block modalFooter %}
<button class="btn btn-default" data-dismiss="modal" type="button">{{'client.form.cancel'| trans}}</button>
<input class="btn btn-primary create" type="submit" value="{{'client.form.add.client'| trans}}">
{{form_end(addAjaxQuestionForm)}}
{% endblock %}
{% endembed %}
And finally I have an edit.html.twig that looks like this
<div aria-hidden="true" aria-labelledby="{% block labelledby %}{% endblock %}" class="modal fade" id="{% block modalId %}{% endblock %}" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button aria-hidden="true" class="close" data-dismiss="modal" type="button">×</button>
<h4 class="modal-title" id="myModalLabel">{% block modalHead %}{% endblock %}</h4>
</div>
<div class="modal-body">
{% block modalBody %}
{% endblock %}
</div>
<div class="modal-footer">
{% block modalFooter %}
{% endblock %}
</div>
</div>
</div>
</div>
{% include 'AppBundle:Form:ajaxAddQuestionForm.html.twig' %}
Now I get the following error:
Variable "addAjaxQuestionForm" does not exist in src/AppBundle/Resources/views/Form/ajaxAddQuestionForm.html.twig at line 9
Any idea what is wrong with my code?

In your edit.html.twig (assuming your addAjaxQuestionForm variable exists in it), you need to pass it on to the included twig.
{% include 'AppBundle:Form:ajaxAddQuestionForm.html.twig' with {'addAjaxQuestionForm': addAjaxQuestionForm} %}

Try to use
{{ render(controller('AppBundle:Section:ajaxAddQuestionFormAction',{'section':section})) }}
Instead of Include and you must add "section" parameter to ajaxAddQuestionFormAction.
We can help you more than that if you don't publish us all the code that concern the part of your problem.
I hope that helps

You should use render controller method instead of include
{{ render(controller(
'AppBundle:Form:ajaxAddQuestionForm',
{ 'section': section }
)) }}
read more about it here: http://symfony.com/doc/current/book/templating.html#embedding-controllers

Related

I want to avoid button repetition

I display the content of the category and I display the button "displays more" if I have other content but the button has been marked according to the number of ads in the category, and when I paste the button outside "for" I get always this button even when the category content is empty
<div class="pedagogical pedagogical--category js-pedagogical-items" data-type="category" data-nbdisplayed="4">
{% for categoryId in questionCategories %}
<div class="row pedagogical__items" data-type="category" data-value="{{ categoryId }}">
{% for tool in tools if tool.questionCategory == categoryId %}
<div class="col-12 col-md-6 pedagogical__item__wrapper">
{% include 'components/tool-preview-item.html.twig' with {'tool' : tool} %}
</div>
<div class="col-12 text-center">
<button class="btn btn-outline-secondary js-show-more" data-type="category" data-value="{{ categoryId }}">{{ 'show-more'|trans({}, 'action') }}</button>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
I think you just need to add a check before rendering your button:
<div class="pedagogical pedagogical--category js-pedagogical-items" data-type="category" data-nbdisplayed="4">
{% for categoryId in questionCategories %}
<div class="row pedagogical__items" data-type="category" data-value="{{ categoryId }}">
{% set has_items = 'false' %}
{% for tool in tools if tool.questionCategory == categoryId %}
{% set has_items = 'true' %}
<div class="col-12 col-md-6 pedagogical__item__wrapper">
{% include 'components/tool-preview-item.html.twig' with {'tool' : tool} %}
</div>
{% endfor %}
{% if has_items == 'true' %}
<div class="col-12 text-center">
<button class="btn btn-outline-secondary js-show-more" data-type="category" data-value="{{ categoryId }}">{{ 'show-more'|trans({}, 'action') }}</button>
</div>
{% endif %}
</div>
{% endfor %}
</div>

Twig how to check which template is geting rendered

I have
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include '/layouts/navbar.html.twig' %}
</div>
{% block body %}{% endblock %}
</div>
</div>
Now in this /layouts/navbar.html.twig theres an anchor tag, who's href attribute heavily depends on which template is rendered below, for example if its the Posts template, the href should be /posts/new, if its the announcements template, the href should be /announcements/newand so on, is that even possible?
You could make use of the global variable _self to solve this e.g.
main.twig
{% include "foo.twig" %}
{% include "bar.twig" %}
foo.twig and bar.twig
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include "nav.twig" with { 'template': _self, } %}
</div>
{% block body %}{% endblock %}
</div>
</div>
nav.twig
{% set path = '' %}
{% if template == 'foo.twig' %}
{% set path = 'path/to/foo' %}
{% elseif template == 'bar.twig' %}
{% set path = 'path/to/bar' %}
{% endif %}
{% for i in 0..3 %}
{{ i }}
{% endfor %}
demo
If the path is the only thing that depends on the current template, I'd modify DarkBee's example to just simply pass the path from the parent template. That way you don't need the if/else structure:
posts.twig:
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include "nav.twig" with { 'path': '/posts/new' } %}
</div>
{% block body %}{% endblock %}
</div>
</div>
announcements.twig:
<div>
<div id="page-wrapper" class="sidebar-content white-bg">
<div class="row border-bottom">
{% include "nav.twig" with { 'path': '/announcements/new' } %}
</div>
{% block body %}{% endblock %}
</div>
</div>
nav.twig:
{% for i in 0..3 %}
{{ i }}
{% endfor %}

Group by object field

Now i hav this. How do I group by the field hotel.name?
And yes, I saw this post, but it does not work.
Twig Loop Grouping
{% for item in pagination.items %} <!-- Вывод результатов по отелям -->
<div class="row">
<div class="col-lg-1">{{ loop.index }}</div>
<div class="col-lg-6">
<span class="text-capitalize">{{ item.hotel.name }}</span>
<span class="text-primary">{{ item.roomName }}</span>
{% if(item.mealName) %}
<span class="text-muted">({{ item.mealName }})</span>
{% endif %}
</div>
<div class="col-lg-2">{{ item.price }} {{ item.currency }}</div>
</div>
{% endfor %}
I need get this:
We were advised to use the groop_by, but I do not understand how.
{% for item,
group in pagination|group_by(=>_.hotel.name)
%} <!-- Вывод результатов по отелям -->
<div class="row">
<div class="col-lg-1">{{ loop.index }}</div>
<div class="col-lg-6">
<span class="text-capitalize">{{ item.hotel.name }}</span>
<span class="text-primary">{{ item.roomName }}</span>
{% if(item.mealName) %}
<span class="text-muted">({{ item.mealName }})</span>
{% endif %}
</div>
<div class="col-lg-2">{{ item.price }} {{ item.currency }}</div>
</div>
{% endfor %}
Controller:
public function resultsAction($searchId, $page)
{
$em = $this->getDoctrine()->getManager();
$objSearchRequest = $em->find('UtsHotelBundle:SearchRequest', $searchId);
if(!$objSearchRequest){
$this->createNotFoundException();
}
$objSearchForm = $this->createForm('uts_hotel_search_request', $objSearchRequest);
$templateVars = array(
'searchForm' => $objSearchForm->createView(),
'request' => $objSearchRequest
);
if($objSearchRequest->isComplete() || $objSearchRequest->isOld()){
$repository = $em->getRepository('UtsHotelBundle:SearchResult');
$query = $repository->createQueryForPagination($searchId);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($query, $page, 50);
$templateVars['pagination'] = $pagination;
}
return $this->render('UtsHotelBundle:Default:results.html.twig', $templateVars);
}
Answer:
{% set date = null %}
{% set otelindex=0 %}
{% for item in pagination.items %} <!-- Вывод результатов по отелям -->
{% if date != item.hotel.name %}
{% set date = item.hotel.name %}
{% set otelindex=otelindex+1 %}
<div class="row">
<div class="col-lg-6">
<h4>{{ otelindex }}{{ ". " }}{{item.hotel.name}}</h4>
</div>
<div class="col-lg-2">
<h4> {{ item.mealName }}{{ item.price }} {{ item.currency }}</h4>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-lg-6">
<span class="text-primary">{{ item.roomName }}</span>
{% if(item.mealName) %}
<span class="text-muted">({{ item.mealName }})</span>
{% endif %}
</div>
<div class="col-lg-2">{{ item.price }} {{ item.currency }}</div>
</div>
{% endfor %}

display error collapse accordion bootstrap

I do a file explorer with symfony2 and Php 5.3 :)
I wanna display {{ Twig error }} when a directory is empty . Here my twig view :
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" href=".mycollapse3">
<i class="fa fa-caret-square-o-right"></i> Tableaux de bord mensuels
</a>
</div>
{% for tab in tableauxliste %}
<div class="accordion-group">
{% if tableauxliste is empty %}
<div class="mycollapse3 collapse alert alert-info">
{{ erreur }}
</div>
<div class="accordion-heading mycollapse3 collapse">
<ul>
<a data-toggle="collapse" href="#collapse3{{ tab[0] }}">
{{ tab[0] }}
</a>
</ul>
{% endif %}
</div>
<div id="collapse3{{ tab[0] }}" class="accordion-body collapse">
<div class="accordion-inner">
{% if tab[0] is empty %}
<div class="alert alert-info">
{{ erreur }}
</div>
{% endif %}
{% for file in tab[1] %}
{% set repertoire = dir_tableaudebord ~ '/' ~ tab[0] %}
<ul><a target="_blank" href="{{ path('affiche', { 'repertoire':repertoire, 'file':file }) }}"><i class="fa fa-file-text-o"></i> {{ file | convert_encoding('UTF-8', 'Windows-1252') }}</a></ul>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
In this case, the error isn't hidden and I don't know why.
I just wanna hide the error and display it after click on it.
Any ideas ? Thanks !
Add to you action some condition and return response (render this data's in template).
return $this->render(
'FolderBundle:To/you:template.html.twig',
[
'erreur' => $erreur
'tableauxliste' => $tableauxliste,
]
);
And use this variable in you template.

Symfony Twig override specific form row

I have the a form twig template, where I want to parse a specific fields help text with the raw filter (it contains html). The field is called postcode in a form called Clinic
According to here http://symfony.com/doc/current/cookbook/form/form_customization.html#how-to-customize-an-individual-field
Form template:
{% extends 'AgriHealthAhpBundle::admin.html.twig' %}
{% form_theme form 'AgriHealthAhpBundle:Form:fields.html.twig' %}
{% block _clinic_postcode_row %}
<div class="row">
test<div class="small-12 medium-3 columns label">{{ form_label(form) }}</div>
<div class="small-12 medium-6 columns widget">
{{ form_widget(form) }}
<div class="error">
{{ form_errors(form) }}
</div>
</div>
<div class="small-12 medium-3 columns help">
{% if help is defined %}
{{ help|raw }}
{% endif %}
</div>
</div>
{% endblock %}
{% block admin -%}
<h1>New Clinic</h1>
{{ form(form) }}
<div class="row form_actions">
<div class="small-12 medium-offset-3 medium-2 columns submit">
<button type="submit" id="agrihealth_ahpbundle_clinic_submit_visible" name="agrihealth_ahpbundle_clinic[submit]">Create</button>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('#agrihealth_ahpbundle_clinic_submit_visible').click(function(){
jQuery('form[name="agrihealth_ahpbundle_clinic"]').submit();
});
});
</script>
<div class="small-12 medium-2 columns cancel">
<a href="{{ path('clinic') }}">
Cancel
</a>
</div>
<div class="small-12 medium-2 end columns cancel">
<a href="{{ path('clinic') }}">
Back to List
</a>
</div>
</div>
{% endblock %}
AhpBundle/Resources/views/Form/fields.html.twig
{% block form_row %}
{% spaceless %}
<div class="row">
<div class="small-12 medium-3 columns label">{{ form_label(form) }}</div>
<div class="small-12 medium-6 columns widget">
{{ form_widget(form) }}
<div class="error">
{{ form_errors(form) }}
</div>
</div>
<div class="small-12 medium-3 columns help">
{% if help is defined %}
{{ help }}
{% endif %}
</div>
</div>
{% endspaceless %}
{% endblock form_row %}
Anyone can see what I have overlooked, I tried
{% block _clinic_postcode_row %}
and
{% block _Clinic_postcode_row %}
Solution
As per accepted answer, the form row block needs to fully idetified with shorthand bundle name. The easiest way is to view the source code of the form and identify the text used in each input field and the form name="":
Replace
{% form_theme form 'AgriHealthAhpBundle:Form:fields.html.twig' %}
with
{% form_theme form with ['AgriHealthAhpBundle:Form:fields.html.twig', _self] %}
Since you are decorating the row inside action template, while applying separate form template you need to specify multiple templates
You also need to specify a fully qualified path name to your row block such as
{% block _agrihealth_ahpbundle_clinic_postcode_row %}

Categories