Simfony2-Twig: Render only a single part of a template - php

I have a homepage wich dynamically loads a bunch of "posts" (similar to facebook wall).
There is the option to follow a post, but when someone clicks on the follow button, which has a counter on following people, I need to reload all the homepage to update this value. How can I update just the part corresponding to the post? Actually the post is in an extern hmtl.twig file which I render from the homepage code:
<div class="row">
<div class="col-md-6">
{% for sueno in suenos %}
{% if loop.index0 is even %}
{{ render(controller('SuenoBundle:Default:suenoFrontend', { 'sueno': sueno } )) }}
{% endif %}
{% endfor %}
</div><!--/col-md-6-->
This is the controller:
public function suenoFrontendAction($sueno)
{
return $this->render('SuenoBundle:Default:suenoFrontend.html.twig', array(
'sueno' => $sueno));
}
This the post html file:
<h4 class="text-center nombre-usuario">{{ sueno.usuario.nombre ~ ' ' ~ sueno.usuario.apellido }}</h4>
{% if sueno.necesitaAyuda == 1 %}
<p class="text-center texto-sueno"><img src="{{ asset('bundles/estructura/images/SOS.png') }}" width="25" height="25" alt="SOS" /></p>
{% endif %}
{% if sueno.rol == 'foto' %}
<img src="{{ asset('upload/images/' ~ sueno.fotoLink) }}" class="img-responsive img-thumbnail" alt="Responsive image">
{% elseif sueno.rol == 'video' %}
<div class="video-container"><iframe src="{{ sueno.linkVideo }}" frameborder="0" allowfullscreen=""></iframe></div>
{% endif %}
<h4 class="text-center titulo-sueno">{{ sueno.titulo }}</h4>
<h4 class="text-center quepido-sueno">{{ sueno.quePido }}</h4>
<p class="text-center texto-sueno info">{{ sueno.texto }}</p>
<br>
<div>
{% set size = sueno.usuariosColaboradores | length %}
{% set size2 = sueno.usuariosSeguidores | length %}
<p class="text-center opciones-sueno">
<img src="{{ asset('bundles/estructura/images/colaboradores.png') }}" width="20" height="20" alt="Colaboradores" /> {{ size }}
<img src="{{ asset('bundles/estructura/images/punto.png') }}" width="5" height="5" alt="punto" />
<img src="{{ asset('bundles/estructura/images/seguidores.png') }}" width="20" height="20" alt="Seguidores" /> {{ size2 }}
<img src="{{ asset('bundles/estructura/images/punto.png') }}" width="5" height="5" alt="punto" />
<img src="{{ asset('bundles/estructura/images/compartir.png') }}" width="20" height="20" alt="Compartir" />
</p>
</div>
<hr>
Here you can see the action correpsonding to follow a post(its in the previous code, I remark the line):
<img src="{{ asset('bundles/estructura/images/seguidores.png') }}" width="20" height="20" alt="Seguidores" /> {{ size2 }}
size2 value is the one to update. the controller called when clicking here is this(and where I suppose the failure is):
public function seguirAction($suenoid)
{
$em = $this->getDoctrine()->getManager();
$usuario = $this->getUser();
$sueno = $em->getRepository('SuenoBundle:Sueno')->findOneBy(array('id' => $suenoid));
$usuario->getSuenosSigue()->add($sueno);
$em->persist($usuario);
$em->flush();
// $suenos = $em->getRepository('SuenoBundle:Sueno')->findBy(array('usuario' => $usuario->getId()));
//esto hay que cambiarlo entero para conseguir los sueños apropiados
//return $this->render('EstructuraBundle:Home:home.html.twig', array('suenos'=> $suenos , 'usuario' => $usuario));
return $this->render('SuenoBundle:Default:suenoFrontend.html.twig', array(
'sueno' => $sueno));
}
The thing is that when this render happens, the post fills the full page.
What I want is just to re-render this post in the homepage

Related

foreach loop : I can't see my added input

I work with Symfony and Twig. I currently have a twig page containing a list of products, I display them with a foreach loop and I put pagination to limit the display of products.
I'm trying to put a form in this page with a checkbox as input and my problem is the following:
the checkboxes appear on all the products on the first page but when I go to the second page, I don't see the checkboxes, I need to reload the page to see them.
there is some code :
view of my loop :
<form>
<div class="row" >
{% for annonce in annonces %}
<div class="col-12 col-md-6 col-lg-4">
<p class="text text--blue text--bold m-0 text--medium mt-2">
{{ annonce._source.titre }}
</p>
<p class="m-0">{{ 'Réf' }}: {{ annonce._source.reference }}</p>
<div class="d-flex mt-2 text--bold">
<div class="d-flex me-2">
{{ annonce._source.ville }}
</div>
</div>
<div>
<input type="checkbox" name="checkbox[]" id="checkbox_pdf" value="{{annonce._id}}" multiple/>
</div>
</div>
{% endfor %}
</div>
<input type="submit" id="pdf_submit" value="Create PDF" name="submit_pdf" class="btn btn-primary">
</form>
view of the pagination :
<div class="col d-flex justify-content-between align-items-center">
<div class="d-flex">
{% if page > 0 %}
<a href="#" data-action="pagination" data-uri="{{ path('ajax_annonce_pagination',{'page':0, 'type':'frontoffice'}) }}" data-target="pagination-target">
«
</a>
<a href="#" data-action="pagination" data-uri="{{ path('ajax_annonce_pagination',{'page':page-1, 'type':'frontoffice'}) }}" data-target="pagination-target">
{{ 'Précédent' }}
</a>
{% else %}
<a href="#" disabled="disabled" >
{{ 'Précédent' }}
</a>
{% endif %}
</div>
<div>
<ul class="list-unstyled pagination m-0">
{% for i in (page+1)..(page+4) %}
{% if i <= numberOfMaxPage %}
{% if i == (page+1) %}
<li>
<a href="#" data-action="pagination" data-uri="{{ path('ajax_annonce_pagination',{'page':(i-1), 'type':'frontoffice'}) }}" data-target="pagination-target">
{{ i }}
</a>
</li>
{% else %}
<li>
<a href="#" data-action="pagination" data-uri="{{ path('ajax_annonce_pagination',{'page':(i-1), 'type':'frontoffice'}) }}" data-target="pagination-target">
{{ i }}
</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
</div>
<div class="d-flex">
{% if page < (numberOfMaxPage-1) %}
<a href="#" data-action="pagination" data-uri="{{ path('ajax_annonce_pagination',{'page':page+1, 'type':'frontoffice'}) }}" data-target="pagination-target">
{{ 'Suivant' }}
</a>
<a href="#" data-action="pagination" data-uri="{{ path('ajax_annonce_pagination',{'page':numberOfMaxPage-1, 'type':'frontoffice'}) }}" data-target="pagination-target">
»
</a>
{% endif %}
</div>
</div>
JS of the pagination :
$( document ).ready(function() {
$(document).on('click', 'a.pagination',function(e) {
e.preventDefault();
$.ajax({
url: $(this).data('uri'),
}).done(function(html) {
$('#pagination-target').html(html);
$('html,body').animate({scrollTop: $('#pagination-target').offset().top - 80}, 200);
var $scrollable = document.getElementById('pagination-target');
$scrollable.scrollIntoView();
});
});
});
In my controller I render my view like this :
return $this->render('front/annonce/list.html.twig', array(
'annonces' => $results['hits']['hits'],
'total' => $results['hits']['total']['value'],
'website' => $website,
'page' => $request->query->getInt('page')
));
What is this problem related to? is this due to the fact that it is not possible to add inputs in a looped element?
Is it related to pagination?
thanks you in advance

Use Twig loop to output WordPress/ACF image gallery in nested structure

I am using the following code to output an image gallery from WordPress and Advanced Custom Fields using the Timber plugin.
{% if story.meta( 'gallery' ) %}
<div class="story__gallery">
<div class="gallery__row">
{% for image in story.meta( 'gallery' ) %}
{% if Image(image).width > Image(image).height %}
{% set dimension = 'gallery__item--horizontal' %}
{% else %}
{% set dimension = 'gallery__item--vertical' %}
{% endif %}
<figure class="gallery__item gallery__item--{{ Image(image).id }} {{ dimension }}">
<img src="{{ Image(image) }}" width="{{ Image(image).width }}" height="{{ Image(image).height }}" alt="{{ Image(image).alt }}" />
</figure>
{% if loop.index is divisible by(3) and not loop.last %}
</div><div class="gallery__row">
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
This version of the code is working, but now I am needing to implement some logic to output the gallery using the following HTML structure.
<div class="story__gallery">
<div class="gallery__row">
<figure class="gallery__item gallery__item--large"></figure>
<div class="gallery__cluster">
<figure class="gallery__item gallery__item--small"></figure>
<figure class="gallery__item gallery__item--small"></figure>
</div>
</div>
</div>
How would I go about working with the loop.index to wrap the two small figures in the gallery__cluster div and have it properly outputted in the gallery__row container?
I would set a variable outside of the loop and increment it by 1 each time, since you need to do different things each increment of the loop. Reset it every 3 loops. It's a lot of if statements, but it gets the job done. Note I have not tested the below since I don't have a component that matches yours to test but I think you can make it work.
{% set rowIndex = 0 %}
{% if story.meta( 'gallery' ) %}
<div class="story__gallery">
{% for image in story.meta( 'gallery' ) %}
{% set rowIndex = rowIndex + 1 %}
{% if rowIndex == 1 %}
<div class="gallery__row">
<figure class="gallery__item gallery__item--large">
<img src="{{ Image(image) }}" width="{{ Image(image).width }}" height="{{ Image(image).height }}" alt="{{ Image(image).alt }}" />
</figure>
{% if loop.last %}
</div>
{% endif %}
{% endif %}
{% if rowIndex == 2 %}
<div class="gallery__cluster">
<figure class="gallery__item gallery__item--small">
<img src="{{ Image(image) }}" width="{{ Image(image).width }}" height="{{ Image(image).height }}" alt="{{ Image(image).alt }}" />
</figure>
{% if loop.last %}
</div>
</div>
{% endif %}
{% endif %}
{% if rowIndex == 3 %}
<figure class="gallery__item gallery__item--small">
<img src="{{ Image(image) }}" width="{{ Image(image).width }}" height="{{ Image(image).height }}" alt="{{ Image(image).alt }}" />
</figure>
</div>
</div>
{% set rowIndex = 0 %}
{% endif %}
{% endfor %}
</div>
{% endif %}

Display something only once in a loop in twig

I have some pics that I want to display by months.
But I my code I get the month on top of every pics.
How to avoid this ?
{% for media in medias %}
{% if media.date|date("m") == 10 and media.assetpath is not null %}
<h2>Photos october</h2>
<div class="col-xs-2">
<img class="img-responsive" src="{{ asset(media.assetpath) }}"/>
</div>
{% elseif media.date|date("m") == 11 and media.assetpath is not null %}
<h2>Photos november</h2>
<div class="col-xs-2">
<img class="img-responsive" src="{{ asset(media.assetpath) }}"/>
</div>
{% else %}
<h2>other month</h2>
<div class="col-xs-2">
<img class="img-responsive" src="{{ asset(media.assetpath) }}"/>
</div>
{% endif %}
{% endfor %}
Assuming that medias is an array sorted by date, the problem can be solved using a temporary variable:
{% set last_month = '' %}
{% for media in medias %}
{% set month = media.date('F')|lower %}
{% if last_month and month != last_month %}
<h2>Photos {{ month }}</h2>
{% endif %}
{% set last_month = month %}
<div class="col-xs-2">
<img class="img-responsive" src="{{ asset(media.assetpath) }}"/>
</div>
{% endfor %}
However, I would rather generate a more appropriate structure, e.g.:
$media = [
'November' => [
[ /* media 1 */],
[ /* media 2 */],
// ...
],
// ...
];
With this structure, the template code will look much cleaner:
{% for month, media in medias %}
<h2>Photos {{ month }}</h2>
{% for m in media %}
<div class="col-xs-2">
<img class="img-responsive" src="{{ asset(m.assetpath) }}"/>
</div>
{% endfor %}
{% endfor %}

Dynamic limit per page Knp Pagination

I need straightforward solution for dynamically set number of records per page with Knp Pagination Bundle.
I read the this page records per page allow user to choose - codeigniter pagination about dynamically set per page limits and I know I need a drop down with hyperlink inside each item that send a request to server and server use parameter on this request to set limit per page on knp pagination bundle. But I don't know exactly how to handle this actions on server and also and more harder to me how to create items on drop down related to the total number on my query.
my controller:
public function indexAction()
{
$page_title = Util::getFormattedPageTitle("Customers");
$em = $this->get('doctrine.orm.entity_manager');
$dql = "SELECT a FROM CustomersBundle:Customer a WHERE a.enable = 1 ORDER BY a.id";
//$query = $em->createQuery($dql);
//$customers = $query->execute();
$query = $em->createQuery($dql);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$this->get('request')->query->get('page', 1)/*page number*/,
3/*limit per page*/
);
// parameters to template
return $this->render('CustomersBundle:Default:index.html.twig', array(
'page_title' => $page_title,
'pagination' => $pagination,
'image_path' => CustomersConstants::$customers_image_thumb_path
));
}
And my view code is:
{% extends '::base.html.twig' %}
{% block title %}
{{ page_title }}
{% endblock %}
{% block body %}
<h1>
{{ "customers" }}
</h1>
<br />
{% for customer in pagination %}
<a href="{{ customer.url }}" target="_blank">
<div dir="rtl" class="st_simple_box" id="customer{{customer.id}}" >
<table cellpadding="0" cellspacing="0" width="100%">
<tr>
<td style="vertical-align: top; width: 115px;">
{% if customer.imageName is not empty %}
<img class="newsimage" src="{{asset(image_path) ~ customer.imageName}}" alt="No Image/>
{% else %}
<img class="newsimage" src="{{asset('images/vakil_default_small.png') ~ customer.imageName}}" alt="No Image"/>
{% endif %}
</td>
<td style="text-align: center;">
<p><span style="font-family: Tahoma;">{{customer.titleFa}}</span></p>
</td>
<td style="text-align: justify;">
<p><span style="font-family: Tahoma;">{{customer.descriptionFa}}</span></p>
</td>
</tr>
</table>
</div>
</a>
{% endfor %}
<div class="navigation">
<span>
{{ knp_pagination_render(pagination) }}
</span>
<!--Here is my drop down html code-->
</div>
<br />
{% endblock %}
**
Edited on 12 March 2014
||||
||||
||||
\\\///
\\//
\/
Is there any way to set MaxItemPerPage on cookie to have a integrated variable and use this variable or change it while Knp Pagination is showed up on twig file.
the answer was correct but because of I used pagination in many bundles to paginate between my entities so I need an integrate variable to change all of them. I use your answer and customize sliding.html.twig on Knp Pagination to reach this code for "customized_sliding.html.twig"
<div class="ui small pagination menu">
<div style="clear: both;">
{% if pageCount > 1 %}
<div class="pagination" style="float: right;">
{% if first is defined and current != first %}
<a href="{{ path(route, query|merge({(pageParameterName): first})) }}" class="small icon item">
<i class="small double angle right icon"></i>
</a>
{% endif %}
{% if previous is defined %}
<a href="{{ path(route, query|merge({(pageParameterName): previous})) }}" class="small icon item">
<i class="small angle right icon"></i>
</a>
{% endif %}
{% for page in pagesInRange %}
{% if page != current %}
<a href="{{ path(route, query|merge({(pageParameterName): page})) }}" class="small item">
{{ page }}
</a>
{% else %}
<a class="small active item">
{{ page }}
</a>
{% endif %}
{% endfor %}
{% if next is defined %}
<a href="{{ path(route, query|merge({(pageParameterName): next})) }}" class="small icon item">
<i class="small angle left icon"></i>
</a>
{% endif %}
{% if last is defined and current != last %}
<a href="{{ path(route, query|merge({(pageParameterName): last})) }}" class="small icon item">
<i class="small double angle left icon"></i>
</a>
{% endif %}
</div>
{% endif %}
<div style="float: left;">
<select name="maxItemPerPage" id="maxItemPerPage">
<option selected="true" style="display:none;">Number Per Page</option>
<option id="10">5</option>
<option id="20">10</option>
<option id="30">20</option>
</select>
</div>
</div>
<script type="text/javascript">
//on select change, you navigate to indexAction and send the parameter maxItemPerPage
$('#maxItemPerPage').change(function(){
{% set currentPath = path(app.request.attributes.get('_route')) %}
var url = "{{path(app.request.attributes.get('_route'),{'maxItemPerPage': '_itemNum'})}}";
var item = $('#maxItemPerPage').find(":selected").text();
jQuery(location).attr('href', url.replace('_itemNum',item ));
});
</script>
</div>
I want to fetch and store MaxItemPerPage from cookie so there is no need to change all bundles code.
For example in my controller I don't know have to fetch the $maxItemPerPage from cookie
$pagination = $paginator->paginate(
$query,
$this->get('request')->query->get('page', 1)/*page number*/,
$maxItemPerPage/*limit per page*/
);
And I need change the value of maxItemPerPage on cookie by changing the value of html tag by javascript and redirect the page to same controller and no need to send maxItemPerPage to controller.
This can be done easily (if i understood well)
public function indexAction($maxItemPerPage=20)
{
$page_title = Util::getFormattedPageTitle("Customers");
$em = $this->get('doctrine.orm.entity_manager');
$dql = "SELECT a FROM CustomersBundle:Customer a WHERE a.enable = 1 ORDER BY a.id";
//$query = $em->createQuery($dql);
//$customers = $query->execute();
$query = $em->createQuery($dql);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$this->get('request')->query->get('page', 1)/*page number*/,
$maxItemPerPage /*limit per page*/
);
// parameters to template
return $this->render('CustomersBundle:Default:index.html.twig', array(
'page_title' => $page_title,
'pagination' => $pagination,
'image_path' => CustomersConstants::$customers_image_thumb_path
));
}
in the view
{% extends '::base.html.twig' %}
{% block title %}
{{ page_title }}
{% endblock %}
{% block javascript%}
<script type="text/javascript">
//on select change, you navigate to indexAction and send the parameter maxItemPerPage
$('#maxItemPerPage').change(function(){
var url = '{{path('controller_index_route','maxItemPerPage':_itemNum)}}';
var item = $('#maxItemPerPage').find(":selected").text();
window.location.href = url.replace('_itemNum',item );
})
</script>
{% endblock %}
{% block body %}
<h1>
{{ "customers" }}
</h1>
<br />
{% for customer in pagination %}
<a href="{{ customer.url }}" target="_blank">
<div dir="rtl" class="st_simple_box" id="customer{{customer.id}}" >
<table cellpadding="0" cellspacing="0" width="100%">
<tr>
<td style="vertical-align: top; width: 115px;">
{% if customer.imageName is not empty %}
<img class="newsimage" src="{{asset(image_path) ~ customer.imageName}}" alt="No Image/>
{% else %}
<img class="newsimage" src="{{asset('images/vakil_default_small.png') ~ customer.imageName}}" alt="No Image"/>
{% endif %}
</td>
<td style="text-align: center;">
<p><span style="font-family: Tahoma;">{{customer.titleFa}}</span></p>
</td>
<td style="text-align: justify;">
<p><span style="font-family: Tahoma;">{{customer.descriptionFa}}</span></p>
</td>
</tr>
</table>
</div>
</a>
{% endfor %}
<div class="navigation">
<span>
{{ knp_pagination_render(pagination) }}
</span>
<!--Here is my drop down html code-->
</div>
<br />
<select name="maxItemPerPage" id="maxItemPerPage">
<option id="10">10</option>
<option id="20">20</option>
<option id="30">30</option>
</select>
{% endblock %}

Symfony 2 AvalancheImagineBundle image filter

input:
{% for car in closet %}
<img src="{{ asset('images/') }}{{ car.photo1 }}" />
{% endfor %}
html output:
<img src="/images/1bb8cee7cd58403ba84daee67d82fa869ec6052d.jpeg" />
How can I apply this from AvalancheImagineBundle:
<img src="{{ '/relative/path/to/image.jpg' | apply_filter('my_thumb') }}" />
I can't get this working because the path and filename are separated
Simply:
<img src="{{ (asset('images/') ~ car.photo1) | apply_filter('my_thumb') }}" />

Categories