VichUploaderBundle使用twig渲染图像的问题

时间:2022-09-10 19:06:54

I have a problem with VichUploaderBundle, I followed all the instructions and I could make it upload an image, now I don't know how to render the images using twig. I have a Product entity which has a OneToOne relation with Photo (I use entity photo with VichUploaderBundle).

我有一个VichUploaderBundle的问题,我按照所有说明,我可以上传一个图像,现在我不知道如何使用树枝渲染图像。我有一个与Photo具有OneToOne关系的Product实体(我使用带VichUploaderBundle的实体照片)。

My html.twig file

我的html.twig文件

{% for product in products %}

 <img src="{{ vich_uploader_asset(product, 'image')   }}" alt="{{ product.nombre }}" />
{% endfor %}

This gives me the following error,

这给了我以下错误,

 An exception has been thrown during the rendering of a template ("Impossible to determine the class name. Either specify it explicitly or give an object") in products/list_all_products.html.twig at line 9.

So I added to the img tag the following

所以我在img标签中添加了以下内容

  <img src="{{ vich_uploader_asset(product, 'image','AppBundle\Entity\Product') }}" alt="{{ product.nombre }}" />

and throws me this error

并把这个错误扔给我

An exception has been thrown during the rendering of a template ("Class AppBundleEntityProduct does not exist") in products/list_all_products.html.twig at line 9.

My entities are stored in AppBundle\Entity\ * and also it removes the slashes.

我的实体存储在AppBundle \ Entity \ *中,并删除斜杠。

I also tried to add this with no success.

我也尝试添加这个没有成功。

<img src="{{ vich_uploader_asset(product.photo, 'image','AppBundle\Entity\Product') }}" alt="{{ product.nombre }}" />

My Photo entity (It's a copy & paste from the instructions of the bundle)

我的照片实体(它是从包的​​说明中复制和粘贴)

<?php 
 //src/AppBundle/Entity/Photo.php

 namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collection\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

 /**
  * @ORM\Entity
  * @ORM\Table(name="photo")
  * @Vich\Uploadable
  */

/*
This class represents the images 
*/


 class Photo 
 {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

/**
* @Vich\UploadableField(mapping="product_image", fileNameProperty="imageName") 
* 
* @var File $imageFile
*/
protected $imageFile;

/**
 * @ORM\Column(type="string", length=255, name="image_name")
 *
 * @var string $imageName
 */
protected $imageName;

/**
 * @ORM\Column(type="datetime")
 *
 * @var \DateTime $updatedAt
 */
protected $updatedAt;

/**
 * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
 * of 'UploadedFile' is injected into this setter to trigger the  update. If this
 * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
 * must be able to accept an instance of 'File' as the bundle will inject one here
 * during Doctrine hydration.
 *
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
 */
public function setImageFile(File $image = null)
{
    $this->imageFile = $image;

    if ($image) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime('now');
    }
}

/**
 * @return File
 */
public function getImageFile()
{
    return $this->imageFile;
}

/**
 * @param string $imageName
 */
public function setImageName($imageName)
{
    $this->imageName = $imageName;
}

/**
 * @return string
 */
public function getImageName()
{
    return $this->imageName;
}
}

And here's my Product entity

这是我的产品实体

<?php
 //src/AppBundle/Entity/Product.php

 /*
  This class represents a product, for instance, we'll be using
  only product.
 */

 namespace AppBundle\Entity;

 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\ArrayCollection;

/**
  * @ORM\Entity
  * @ORM\Table(name="product")
* ORM\Entity(repositoryClass="AppBundle\Repositories\ProductRepository")
*/

 //extends objComercio has been removed for simplicity.
class Product
{

public function __construct()
{

    $this->photos = new ArrayCollection();
}

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\Column(type="string",length=255, nullable=false)
*/
protected $nombre;

/**
* @ORM\Column(type="string",length=255, nullable=false)
*/
protected $descripcion;

/**
* @ORM\Column(type="integer",nullable=false)
*/
protected $precio;

/**
* @ORM\Column(type="string",length=255, nullable=false)
*/
protected $empresa;

/**
* @ORM\OneToOne(targetEntity="Photo", cascade={"persist"})
*/
protected $photo; 

/**
* @ORM\ManyToOne(targetEntity="Store",inversedBy="products")
*/
protected $store_product;


public function getPhoto()
{
    return $this->photo;
}
public function setPhoto(\AppBundle\Entity\Photo $photo)
{
    $this->photo = $photo;
}
public function getPrecio()
{
    return $this->precio;
}
public function setPrecio($aPrice)
{
    $this->precio = $aPrice;
}
public function getEmpresa()
{
    return $this->empresa;
}
public function setEmpresa($anEnterprise)
{
    $this->empresa = $anEnterprise;
}




/**
 * Set store_product
 *
 * @param \AppBundle\Entity\Store $storeProduct
 * @return Product
 */
public function setStoreProduct(\AppBundle\Entity\Store $storeProduct = null)
{
    $this->store_product = $storeProduct;

    return $this;
}

/**
 * Get store_product
 *
 * @return \AppBundle\Entity\Store 
 */
public function getStoreProduct()
{
    return $this->store_product;
}

/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set nombre
 *
 * @param string $nombre
 * @return Product
 */
public function setNombre($nombre)
{
    $this->nombre = $nombre;

    return $this;
}

/**
 * Get nombre
 *
 * @return string 
 */
public function getNombre()
{
    return $this->nombre;
}

/**
 * Set descripcion
 *
 * @param string $descripcion
 * @return Product
 */
public function setDescripcion($descripcion)
{
    $this->descripcion = $descripcion;

    return $this;
}

/**
 * Get descripcion
 *
 * @return string 
 */
public function getDescripcion()
{
    return $this->descripcion;
}
}

I printed everything using {{}}, and it's all working fine.

我使用{{}}打印了所有内容,并且一切正常。

I don't what else to do.

我不知道还有什么可做的。

Thanks in advance!

提前致谢!

5 个解决方案

#1


1  

I know this is really old, but for Google is still pretty relevant. I think this should work:

我知道这真的很古老,但对谷歌而言仍然非常重要。我认为这应该有效:

  • put 'imageFile' instead of 'image';
  • 把'imageFile'代替'image';

  • double the slashes for the className;

    加倍className的斜杠;

    {{ vich_uploader_asset(product, 'imageFile', 'AppBundle\\Entity\\Product') }}

    {{vich_uploader_asset(product,'imageFile','AppBundle \\ Entity \\ Product')}}

#2


0  

I think you have to display your photo depending of your photo entity config:

我想你必须根据你的照片实体配置显示你的照片:

<img src="{{ vich_uploader_asset(product.photo, 'image') }}" alt="{{ product.nombre }}" />

or

<img src="{{ vich_uploader_asset(product.photo, 'file') }}" alt="{{ product.nombre }}" />

#3


0  

I finally managed to make it work. I've written some angularjs code (I'm also using that on my site). Here's what I've done

我终于成功了。我写了一些angularjs代码(我也在我的网站上使用它)。这就是我所做的

My main.js

 $http.get('/get-products-by-user').success(function(data){
    $scope.products = data;
})

routing.yml

get_products_by_user:
  path: /get-products-by-user
  defaults: { _controller: AppBundle:Product:getAllProductsByUser}

productController:getAllProductsByUser

 public function getAllProductsByUserAction()
{
    $products = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->findAllProductsByUser($this->getUser()->getId());

    return new Response(json_encode($products),200);
}

My list-all-products.html.twig line where I render the image

我的list-all-products.html.twig行我渲染图片的地方

<div ng-repeat="product in products | filter: query" >
   <img ng-src="/images/products/{[{product.photo.imageName }]}" class="img-responsive img-thumbnail size-img" alt="{[{ product.nombre }]}"/></div>

My config.yml, vich uploader section

我的config.yml,vich上传部分

 mappings:
    product_image:
        uri_prefix: /images/products
        upload_destination: %kernel.root_dir%/../web/images/products

I don't know if this is a good way of using the bundle (It just works), I'm just using vichUploader for uploading the image, then I do a query in order to get all my products including the file name, Once I got that I use the uri_prefix/{[{product.imageName}]} to render the image.

我不知道这是不是一个使用捆绑的好方法(它只是工作),我只是使用vichUploader上传图像,然后我做一个查询,以获得我的所有产品,包括文件名,一次我知道我使用uri_prefix / {[{product.imageName}]}来渲染图像。

({[{}]}, I'm using both angularjs and twig template engine, that's why I use that syntax )

({[{}}},我正在使用angularjs和twig模板引擎,这就是我使用该语法的原因)

#4


0  

This is an old question but this confused me as well as someone new to Symfony, Doctrine and VichUploaderBundle, and this question is most relevant in Google. A common Twig error if you get this all wrong is Mapping not found for field which I'm including for Google reasons!

这是一个古老的问题,但这让我和Symfony,Doctrine和VichUploaderBundle的新手混淆了,这个问题在Google中最为相关。一个常见的Twig错误,如果你弄错了,那就是找不到我为Google包含的字段的映射!

Doctrine returns an array of Product objects, with one Photo object as a subobject of each Product. It's this Photo subobject that vich_uploader_asset needs to render an image. So use dot to access the photo subobject of each product object: product.photo, not just product

Doctrine返回一个Product对象数组,其中一个Photo对象作为每个Product的子对象。这是照片子对象,vich_uploader_asset需要渲染图像。因此,使用点访问每个产品对象的照片子对象:product.photo,而不仅仅是产品

The second paramter of vich_uploader_asset is the field name used in your Photo entity where you added the UploadableField annotation/configuration. In your example above, that's imageFile, not image. In the vich_uploader_asset documentation, image is the field name, so that's probably where you just copied that code from.

vich_uploader_asset的第二个参数是您在Photo实体中使用的字段名称,您在其中添加了UploadableField注释/配置。在上面的示例中,这是imageFile,而不是图像。在vich_uploader_asset文档中,image是字段名称,因此可能就是您从中复制该代码的位置。

And the 3rd parameter to vich_uploader_asset is to specify the class name of the uploadable entity, which again, is not Product but Photo. But you actually don't need it as vich will figure it out as long as you specify product.photo. But if you DID need it, you need to include 2 backslashes as @StefanNch points out.

vich_uploader_asset的第3个参数是指定可上载实体的类名,它同样不是Product而是Photo。但实际上你并不需要它,因为只要你指定product.photo,vich就会知道它。但是如果你需要它,你需要包含2个反斜杠,如@StefanNch指出的那样。

So here's the line you need:

所以这就是你需要的产品线:

<img src="{{ vich_uploader_asset(product.photo, 'imageFile') }}" alt="{{ product.nombre }}" />

#5


0  

try this where date is your object

试试这个日期是你的对象

<img src="{{ path ~ vich_uploader_asset(data, 'imageFile', 'App\\Entity\\Crente') }}" style="margin-top: -20px" />

#1


1  

I know this is really old, but for Google is still pretty relevant. I think this should work:

我知道这真的很古老,但对谷歌而言仍然非常重要。我认为这应该有效:

  • put 'imageFile' instead of 'image';
  • 把'imageFile'代替'image';

  • double the slashes for the className;

    加倍className的斜杠;

    {{ vich_uploader_asset(product, 'imageFile', 'AppBundle\\Entity\\Product') }}

    {{vich_uploader_asset(product,'imageFile','AppBundle \\ Entity \\ Product')}}

#2


0  

I think you have to display your photo depending of your photo entity config:

我想你必须根据你的照片实体配置显示你的照片:

<img src="{{ vich_uploader_asset(product.photo, 'image') }}" alt="{{ product.nombre }}" />

or

<img src="{{ vich_uploader_asset(product.photo, 'file') }}" alt="{{ product.nombre }}" />

#3


0  

I finally managed to make it work. I've written some angularjs code (I'm also using that on my site). Here's what I've done

我终于成功了。我写了一些angularjs代码(我也在我的网站上使用它)。这就是我所做的

My main.js

 $http.get('/get-products-by-user').success(function(data){
    $scope.products = data;
})

routing.yml

get_products_by_user:
  path: /get-products-by-user
  defaults: { _controller: AppBundle:Product:getAllProductsByUser}

productController:getAllProductsByUser

 public function getAllProductsByUserAction()
{
    $products = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->findAllProductsByUser($this->getUser()->getId());

    return new Response(json_encode($products),200);
}

My list-all-products.html.twig line where I render the image

我的list-all-products.html.twig行我渲染图片的地方

<div ng-repeat="product in products | filter: query" >
   <img ng-src="/images/products/{[{product.photo.imageName }]}" class="img-responsive img-thumbnail size-img" alt="{[{ product.nombre }]}"/></div>

My config.yml, vich uploader section

我的config.yml,vich上传部分

 mappings:
    product_image:
        uri_prefix: /images/products
        upload_destination: %kernel.root_dir%/../web/images/products

I don't know if this is a good way of using the bundle (It just works), I'm just using vichUploader for uploading the image, then I do a query in order to get all my products including the file name, Once I got that I use the uri_prefix/{[{product.imageName}]} to render the image.

我不知道这是不是一个使用捆绑的好方法(它只是工作),我只是使用vichUploader上传图像,然后我做一个查询,以获得我的所有产品,包括文件名,一次我知道我使用uri_prefix / {[{product.imageName}]}来渲染图像。

({[{}]}, I'm using both angularjs and twig template engine, that's why I use that syntax )

({[{}}},我正在使用angularjs和twig模板引擎,这就是我使用该语法的原因)

#4


0  

This is an old question but this confused me as well as someone new to Symfony, Doctrine and VichUploaderBundle, and this question is most relevant in Google. A common Twig error if you get this all wrong is Mapping not found for field which I'm including for Google reasons!

这是一个古老的问题,但这让我和Symfony,Doctrine和VichUploaderBundle的新手混淆了,这个问题在Google中最为相关。一个常见的Twig错误,如果你弄错了,那就是找不到我为Google包含的字段的映射!

Doctrine returns an array of Product objects, with one Photo object as a subobject of each Product. It's this Photo subobject that vich_uploader_asset needs to render an image. So use dot to access the photo subobject of each product object: product.photo, not just product

Doctrine返回一个Product对象数组,其中一个Photo对象作为每个Product的子对象。这是照片子对象,vich_uploader_asset需要渲染图像。因此,使用点访问每个产品对象的照片子对象:product.photo,而不仅仅是产品

The second paramter of vich_uploader_asset is the field name used in your Photo entity where you added the UploadableField annotation/configuration. In your example above, that's imageFile, not image. In the vich_uploader_asset documentation, image is the field name, so that's probably where you just copied that code from.

vich_uploader_asset的第二个参数是您在Photo实体中使用的字段名称,您在其中添加了UploadableField注释/配置。在上面的示例中,这是imageFile,而不是图像。在vich_uploader_asset文档中,image是字段名称,因此可能就是您从中复制该代码的位置。

And the 3rd parameter to vich_uploader_asset is to specify the class name of the uploadable entity, which again, is not Product but Photo. But you actually don't need it as vich will figure it out as long as you specify product.photo. But if you DID need it, you need to include 2 backslashes as @StefanNch points out.

vich_uploader_asset的第3个参数是指定可上载实体的类名,它同样不是Product而是Photo。但实际上你并不需要它,因为只要你指定product.photo,vich就会知道它。但是如果你需要它,你需要包含2个反斜杠,如@StefanNch指出的那样。

So here's the line you need:

所以这就是你需要的产品线:

<img src="{{ vich_uploader_asset(product.photo, 'imageFile') }}" alt="{{ product.nombre }}" />

#5


0  

try this where date is your object

试试这个日期是你的对象

<img src="{{ path ~ vich_uploader_asset(data, 'imageFile', 'App\\Entity\\Crente') }}" style="margin-top: -20px" />