I want to show some fields of an object with SonataAdmin. One of these fields is an integer (status) in the database, but I don't want to show the integer, else a specific string depending on the value of this field.
public function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('notice')
->add('start')
->add('end')
->add('status')
;
}
Is it possible?
And a second question:
in the same example, I want to add a field which is not mapped in the database (people) because this is calculated with data related with other objects.
public function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('notice')
->add('start')
->add('end')
->add('status')
->add('people')
;
}
Can I do this with Sonata Admin?
Thanks in advance.
I guess your best way to do this is to make custom setters and getters in your entity.
For example you have the entity user:
private $customState; // NOTE -> NO ORM MAPPING because you don't want an actual column
public function setCustomState() {
if($this->state){
$this->customState = 'yup!';
return $this;
}
$this->customState = 'nope!';
return $this;
}
public function getCustomState() {
return $this->customState;
}
Thanks for the answer. However, I've been looking for information on Internet and I've found other way to do this. You can render a specific template for your field. In your Admin class, in the configureListFields function you could do this:
public function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('notice')
->add('start')
->add('end')
->add('status', 'string', array('template' => 'YourBundle:YourController:status_field.html.twig'))
->add('Resources', 'string', array('template' => 'YourBundle:YourController:resources_field.html.twig'))
}
For the "status" field, the status_field.html.twig template will be rendered as below:
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
<div>
{% if object.status == 0 %}
<strong>Inactivo</strong>
{% elseif object.status == 1 %}
<strong>Activo</strong>
{% endif %}
</div>
{% endblock %}
And for my second question, the same solution is valid. The template rendered for the "resources" field would be as below:
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
<div>
<strong>{{ object.getResources|length }}</strong>
</div>
{% endblock %}
In this way, the object is passed to the template, and you can use its methods to get the information that you need. In this case, the method getResources() is used to display its length.
Related
I'm trying to add a custom field to the list view in Sonata Admin where it will concat a fixed string (http://www.example.com) and the field slug as seen below, so that I can access that specific product url. The column shows in the table and the link is created, but I can't figure out how to pass the slug variable to the template so that it works.
I have the following configuration:
#ProductAdmin.php
protected function configureListFields(ListMapper $listMapper)
{
$listMapper->addIdentifier('id')
->addIdentifier('name')
->add('date')
->add('slug', 'text', [
'editable' => true
])
->add('link', 'string', [
'template' => 'default/admin-link.html.twig',
])
#default/admin-link.html.twig
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
Product link
{% endblock %}
In template you can access object which holds data of current iteration from loop just call {{object.slug}} in template to access slug for particular row like
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
Product link
{% endblock %}
Or it would be better if you generate your URLs using route/path method
I am trying to show/edit postgis point type. I am using creof/doctrine2-spatial package which provides some neat functions to get X and Y values for a point. The following works fine in edit/new form so the point is listed as 'Y X' (in this case "latitude longitude").
I am not sure if this is the correct way to accomplish what I need, but it works.
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name', 'text')
->add('coords', 'text', array(
'data'=>
$this->getSubject()->getCoords()->getLatitude() . ' ' .
$this->getSubject()->getCoords()->getLongitude()
));
}
However the problem is the list views. Because point is converted to string as "X Y" it prints the latitude and longitude in wrong order in list view. It prints as "longitude latitude" I am very new to sonata so I am not exactly sure how to solve the issue in list view.
Any ideas?
Update: Thanks to #kunicmarko20 I have resolved the issue:
So the file goes to app/Resources/views/SonataAdmin/CRUD/geography_point_list.html.twig
I decided to put the file to a reasonable folder.
The contents of the template is:
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
<div>
{{ object.coords.getLatitude }} {{ object.coords.getLongitude }}
</div>
{% endblock %}
The code for using the template was:
->add('coords', null, ['template' => 'SonataAdmin/CRUD/geography_point_list.html.twig']);
For some reason I couldn't get the : type path to work?
For your list view field, you can create custom template as explained here.
Example:
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('yourfiled', null, ['template' => 'AppBundle:Admin:your_field_list.html.twig'])
;
}
And your template would look like:
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
<div>
{{ object.longitude }} {{ object.latitude }}
</div>
{% endblock %}
The object here is your entity with all values.
Im trying my first project using symfony2 + twig. I created basic twig template with defined blocks. It basically looks like this
{% block content %}
some content...
{% endblock %}
{% block footer %}
{{ footer.content}}
{% endblock %}
I want footer to be same for all pages. Footer is loaded from DB and its set in controller. I wanted inherit from template described above to other pages but I have to always set footer in controller otherwise variable is not defined.
My questions is if exists any 'nice' way how to set footer variable for multiple templates inherited from parent template?
The solution : Embedding Controllers
In some cases, you need to do more than include a simple template.
Suppose you have a sidebar in your layout that contains the three most
recent articles. Retrieving the three articles may include querying
the database or performing other heavy logic that can't be done from
within a template.
The solution is to simply embed the result of an entire controller
from your template. First, create a controller that renders a certain
number of recent articles:
Controller
// src/AppBundle/Controller/ArticleController.php
namespace AppBundle\Controller;
// ...
class ArticleController extends Controller
{
public function recentArticlesAction($max = 3)
{
// make a database call or other logic
// to get the "$max" most recent articles
$articles = ...;
return $this->render(
'article/recent_list.html.twig',
array('articles' => $articles)
);
}
}
View
{# app/Resources/views/article/recent_list.html.twig #}
{% for article in articles %}
<a href="/article/{{ article.slug }}">
{{ article.title }}
</a>
{% endfor %}
Layout
{# app/Resources/views/base.html.twig #}
{# ... #}
<div id="sidebar">
{{ render(controller(
'AppBundle:Article:recentArticles',
{ 'max': 3 }
)) }}
</div>
you can do with one of the following, 'write a custom Twig Extension'
<?php
namespace AppBundle\Extension;
class MyTwigExtension extends \Twig_Extension
{
private $em;
private $conn;
public function __construct(\Doctrine\ORM\EntityManager $em) {
$this->em = $em;
$this->conn = $em->getConnection();
}
public function getFunctions()
{
return array(
'users' => new \Twig_Function_Method($this, 'getUsers'),
);
}
public function getUsers()
{
$sql = "SELECT * FROM users ORDER BY accountname";
return $this->conn->fetchAll($sql);
}
public function getName()
{
return 'smproc4_twig_extension';
}
}
Register an Extension as a Service
services:
my.twig.extension:
class: AppBundle\Extension\MyTwigExtension
tags:
- { name: twig.extension }
arguments:
em: "#doctrine.orm.entity_manager"
Using the custom Extension
Hello {{ name }}!
<ul>
{% for user in users() %}
<li>{{ user.accountname }}</li>
{% endfor %}
</ul>
have a look at the
How to Write a custom Twig Extension
Creating an Extension
I was wondering how should i approach this problem. In sonata admin dashboard i have users and i would like to preview users profile pictures in thumbnails of a ListMapper. I'm new to symfony and still a bit confused trying to wrap my head around these concepts.
You need to create a custom template where you display the image of your user, i will assume that your Entity User as a Picture Entity which has a path method that gives the image URL :
picture.html.twig
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
<div>
{% if object.picture != null %}
<img src="{{ object.picture.path }}">
{% else %}
<span>No picture</span>
{% endif %}
</div>
{% endblock %}
You know have to use this template in your list
class UserAdmin extends Admin
{
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('picture', null, array(
'template' => 'ApplicationSonataAdminBundle:User:picture.html.twig'
));
}
}
Documentation is available here : http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/list_field_definition.html#custom-template
one separated entity, -no user-, where I have added one media, this for me worked
in admin configureListFields
->add('media', 'string', array('template' => 'SonataMediaBundle:MediaAdmin:list_image.html.twig'))
I'm doing a project with Symfony2 and Sonata Admin Bundle.
How I can apply the filter raw of twig (to display formated text) in action configureShowFields?
I would not override Sonata templates...
The code of my configureShowFields:
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('active')
->add('title')
->add('subtitle') // I need this field with twig RAW filter
->add('description') //I need this field with twig RAW filter
->add('url')
->add('date')
->add('tags')
->add('file');
}
You can use the "safe" sonata field option as follow:
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('subtitle', null, array('safe' => true))
;
}
It will add the "raw" twig filter to your entity field.
From the base_show_field.html.twig:
{% block field %}
{% if field_description.options.safe %}
{{ value|raw }}
{% else %}
{{ value|nl2br }}
{% endif %}
{% endblock %}
You need to make a custom template.
Under:
sonata_doctrine_orm_admin:
templates:
types:
list:
array: SonataAdminBundle:CRUD:list_array.html.twig
*** other existing declarations ***
raw: MyBundle:CRUD:raw.html.twig
Then make the template that the declaration maps to, and give 'raw' as the second argument to add field. It'll then call your new template to render that field.