Achieving this is definitely possible. All you need to do is send an ajax request to the corresponding action that will return the rendered collection for you. There are a couple of ways to go about this:
You can either create a new action (recommended), or you can add new parameters to the request that will inform twig about which part to render or not (easier but harder to maintain).
Edit
I am extending my answer at the request of the author.
For example, let's consider a News
controller in the YourNs\YourBundle
namespace. The contents might look something like this:
class NewsController extends Controller
{
/**
* @Route("/articles")
* @Template()
*/
public function listAction(){
$articles = $this->yourMethodToFindArticles();
return compact('articles');
}
}
The next step would be to render this action by creating a
YourNs/YourBundle/Resources/views/News/list.html.twig
file and populating it accordingly.
Once you have completed this step, you will need to implement the functionality to trigger an ajax request in order to retrieve a refreshed collection of articles. The FOSJsRouting bundle might come in handy for this purpose.
You can either add a new action to the controller:
/**
* @Route("/_api/articles-list")
* @Template()
*/
public function apiListAction(){
$articles = $this->yourMethodToFindArticles();
return compact('articles');
}
And then have its template render only the collection.
Alternatively, you can parameterize your initial action and adjust the template accordingly:
{% if app.request.query.get('partial') %}
Template elements
{% endif %}
{% for article in articles %}
<li
{% if article.new %}
class="new"
{% endif %}
>{{ article.name|e }}</li>
{% endfor %}
{% if app.request.query.get('partial') %}
Other template elements
{% endif %}
The second solution is less favorable compared to the first one, particularly when you start utilizing esi tags. In that case, your code would look like this:
class NewsController extends Controller
{
/**
* @Route("/articles")
* @Template()
*/
public function listAction(){
return [];
}
/**
* @Route("/_api/articles-list")
* @Template()
*/
public function apiListAction(){
$articles = $this->yourMethodToFindArticles();
return compact('articles');
}
}
And the template for listAction():
Template elements
{{ render_esi(url('yourns_yourbundle_news_apilist' }}
Other template elements
Please note that the snippets provided above are simplified solutions for explaining a straightforward issue.
Edit2
Here is an example of fetching using FOSJsRouting, including the js code with the api action:
var url = Routing.generate('yourns_yourbundle_news_apilist')
var fetchedCollection = $.get(url);
And an example with a parameterized template:
var url = Routing.generate('yourns_yourbundle_news_list', {'partial': 'true'})
var fetchedCollection = $.get(url);