Howto get attribute from related entity in template - php

I want to get the id attribute from an entity using "lazy loading".
This is my controller:
public function indexAction() {
$em = $this->getDoctrine()->getManager();
$topics = $em->getRepository('BackendBundle:Topic')->findAll();
$posts = $em->getRepository('BackendBundle:Post')->findAll();
return $this->render('BackendBundle:Home:home.html.twig',
['topics' => $topics, 'posts' => $posts]
);
}
And here is my template block:
{% block article %}
{% for post in posts %}
<h3>
<a href="{{ path('backend_posts_post',
{ 'topic_id': post.topic.id, 'post_id': post.id }) }}">
{{ post.title }}
</a>
</h3>
<br>
<p>{{ post.text }}</p>
<hr>
{% endfor %}
{% endblock %}
I'm trying to get the topic id. Every post depends on a topic and should be possible to get his identifier.

Solved. I was trying to access a post whitout topic.

Related

Adding a global action in EasyAdmin, place my button underneath the table instead of above

I created a global Action :
public function export(
Admin $user,
StructureRepository $structureRepository,
ExportCsvEntity $exportCsvEntity,
string $entityClass
): HttpFoundationResponse {
$zipcodes = $structureRepository->getZipcodesByStructureFromAdmin($user->getId());
$exportCsvEntity->export(
$zipcodes,
$entityClass
);
return $exportCsvEntity->download($entityClass);
}
public function exportButton(): Action
{
return Action::new('export', 'admin.crud.user.field.activities_tracking.button.export')
->linkToCrudAction('export')
->displayAsLink()
->setCssClass('btn btn-primary')
->createAsGlobalAction()
;
}
Then in my Crud Controller I call it :
if ($this->getUser() instanceof Admin) {
$export = $this->exportAction->exportButton();
$actions->add(Crud::PAGE_INDEX, $export);
}
In the doc its written => Global actions are displayed above the listed entries.
But in my case the button is underneath the table
Have a look here
My template is extending '#!EasyAdmin/crud/index.html.twig'then I override the global_actions block :
{% block global_actions %}
{{ parent() }}
{% endblock global_actions %}
Now my button is above the table but also underneath :
Have a look here
What do I do wrong ?
You are correct when trying to do this by overriding the index template.
An easy way to do this considering how the template is organized is to modify the global_actions block by filtering actions you do not want to show above the list. For example by using a css class to not show a global action above the list.
{% block global_actions %}
<div class="global-actions">
{% for action in global_actions|filter(a => 'under-list' not in a.cssClass) %}
{{ include(action.templatePath, { action: action }, with_context = false) }}
{% endfor %}
</div>
{% endblock global_actions %}
And in your crud controller:
Action::new('customAction', $label, $icon)
->addCssClass('under-list')
->createAsGlobalAction()
->linkToCrudAction('customAction');
And you need to add your new list of actions under your list by overriding the main block.
{% block main %}
{{ parent() }}
{% block under_list_global_actions %}
<div class="under-list-global-actions">
{% for action in global_actions|filter(a => 'under-list' in a.cssClass) %}
{{ include(action.templatePath, { action: action }, with_context = false) }}
{% endfor %}
</div>
{% endblock under_list_global_actions %}
{% endblock main %}
And you should get your custom global action (with the css class under-list) under your list.

symfony 3 - url image from database

I wanted to display the url of an image from bdd in my file twig I receive an error of the image like the:
this is my bdd :
and my view from twig :
{% extends '#App/layout.html.twig' %}
{% block title %} Illustration {% endblock %}
{% block body %}
<div class="col-md-4 col-md-offset-4 text-center">
<h2> {{ imageFormation.image.nom }}</h2>
<hr>
<img src=" {{ imageFormation.image.url |raw }} "/><br><br>
</div>
{% endblock %}
Can you help me solve my problem please?
i dont know why i cant get the real image.
edit :
/**
* #Route("/formation/{formation}" , name="image")
* #param $image
* #return \Symfony\Component\HttpFoundation\Response
*/
public function imageFormationAction($formation){
$doctrine = $this->container->get('doctrine');
$em = $doctrine->getManager();
$imageRepository = $em->getRepository('AppBundle:Formation');
$imageFormation = $imageRepository->findOneByid($formation);
return $this->render('#App/formation/formationImage.html.twig', array(
'imageFormation' => $imageFormation
));
}
Your image url must be relative to web directory, like this fichier\Mention.jpg, not the image's path in your file system C:\xampp\htdocs\Symfony\MonProjetCv\web\fichier\Mention.jpg.
Save a relative path to your image file in the database (url equal fichier\Mention.jpg), and use asset function in your twig file:
{% extends '#App/layout.html.twig' %}
{% block title %} Illustration {% endblock %}
{% block body %}
<div class="col-md-4 col-md-offset-4 text-center">
<h2> {{ imageFormation.image.nom }}</h2>
<hr>
<img src=" {{ asset(imageFormation.image.url); }} "/><br><br>
</div>
{% endblock %}
Can you please try this way?
<img src='{{ asset("IMAGE_DIRECTORY_PATH/"~ image.url)}}' />

Twig loop for nested comment in a Symfony-Doctrine blog

I am trying to implement a comment section on a blog with Symfony and Doctrine, using Twig templates.
I am having some trouble trying to implement a response system for my comments. I would like to have something like this:
<div class="comment">
<p>This is comment number 1</p>
<div class="response">
<p>This is a response to comment number 1</p>
<div class="response">
<p>This is a response to response just above</p>
</div>
</div>
</div>
So I would like to have sort of a nested comment system.
I have a Comment entity with a $response property having a OneToOne Relation with another Comment entity:
/**
* #ORM\OneToOne(targetEntity="Comment")
*/
protected $response;
In my controller, I just get my comments like this:
$comments = $this->getDoctrine()
->getManager()
->getRepository('AppBundle:Comment')
->findByArticle($article);
Now I am trying to create the HTML (Twig) but I don't know how to loop throught all comment and associated response so I can create the HTML as I wrote just above...
Anyone who can help me with that?
Thanks.
All you need is recurrence. You have a few options to choose from, one of them is using a macro.
Create twig file with your macro:
{# src/AppBundle/Resources/views/Default/_macro.html.twig #}
{% macro print_comments_recursively(comment) %}
<div class="response">
<p>{{ comment }}</p> {# implement __toString on your Comment class or print appropriate property #}
{% if comment.response is not null %}
{{ _self.print_comments_recursively(comment.response) }}
{% endif %}
</div>
{% endmacro %}
Import macro in your view and use it:
{% import 'AppBundle:Default:_macro.html.twig' as macros %}
<div class="comment">
<p>{{ comment }}</p>
{% if comment.response %}
{{ macros.print_comments_recursively(comment.response) }}
{% endif %}
</div>
Here you have similar problem, already solved, with other solutions: How to render a tree in Twig

Why can't I pass this object correctly in Symfony2?

I am following the tutorial from here: https://www.digitalocean.com/community/tutorials/how-to-use-symfony2-to-perform-crud-operations-on-a-vps-part-1
Here is my controller:
public function indexAction()
{
$news = $this->getDoctrine()
->getRepository('FooNewsBundle:News')
->findAll();
if (!$news) {
throw $this->createNotFoundException('No news found');
}
$build['news'] = $news;
return $this->render('FooNewsBundle:Default:news_show_all.html.twig',$build);
}
Here is my view for news_show_all.html.twig
{% block body %}
<table>
{% for new in news %}
<h3>{{ new.Title }}</h3>
{% endfor %}
</table>
{% endblock %}
What I get is a blank page but when viewing source I get this:
<h3></h3>
<h3></h3>
Which is amazing since I have 3 items in my table and it only shows 2 and they are blank. Any ideas?

Symfony2 internal route in Twig render function

My layout.html.twig:
{{ render(controller('AcmeDemoBundle:Page:mainmenu')) }}
The Page controller retrieves all pages from the Doctrine and renders mainmenu.html.twig with a set of pages.
My mainmenu.html.twig:
{% if menu_pages is defined %}
{% for page in menu_pages %}
<li class="{% if app.request.attributes.get('_internal') == '_page_show' and app.request.get('id') == page.id %}active{% endif %}">{{ page.title|e }}</li>
{% endfor %}
{% endif %}
But no active class is displayed. As far as I understand the problem is in internal routing. How to fix that?
Better do not use {{ render(controller('AcmeDemoBundle:Page:mainmenu')) }}. It work more fast and comfortable when you use services instead. You can create a service which will show menu on any page where you include them. And in service you can easy get access to current _route for add active class.
But if you really need to use {{ render(controller('AcmeDemoBundle:Page:mainmenu')) }}, so you need pass to them a current request like:
{{ render(controller('AcmeDemoBundle:Page:mainmenu', {'request': app.request})) }}
and then in action pass request to twig:
public function mainmenuAction($request) {
return $this->render('AcmeDemoBundle:Page:mainmenu.html.twig', array('request' => $request));
}
and in twig use this request:
{% if menu_pages is defined %}
{% for page in menu_pages %}
<li class="{% if request.get('_route') == '_page_show' and request.get('id') == page.id %}active{% endif %}">{{ page.title|e }}</li>
{% endfor %}
{% endif %}

Categories