跳到内容

显示图像预览

编辑此页

这是一个完整的示例,展示了在 SonataAdmin 中向创建和编辑视图添加图像预览的一种方法。

前提条件

  • 您已在服务器上的某个位置获取了图像文件,并有一个辅助方法来检索该图像的公开可见 URL,在本例中,该方法名为 Image::getWebPath()
  • 您已经设置了一个 Admin 来编辑包含图像的对象,现在您想添加预览。在本例中,该类名为 ImageAdmin

注意

有一个单独的 Cookbook 方法演示如何使用 SonataAdmin 上传图像(和其他文件)。

方法

您可以使用 Symfony 的 'help' 和 'help_html' 选项将原始 HTML 放入任何给定的表单字段。我们将使用此功能在图像存在时嵌入图像标签。

为此,我们需要

  • ImageAdmin 中获取对 Image 实例的访问权限
  • 基于 Image 的 URL 创建一个图像标签
  • 向 Image 表单上的字段添加 'help' 和 'help_html' 选项以显示图像标签

为了本示例,我们将使用一些基本的 CSS 来限制预览图像的大小(我们不会生成和保存特殊的缩略图)。

基本示例 - 适用于单层管理员

如果我们直接使用 ImageAdmin 类,那么可以通过调用 $this->getSubject() 来获取 Image 实例。由于我们正在操作表单字段,因此我们从 ImageAdmin::configureFormFields() 中执行此操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
final class ImageAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $form): void
    {
        // get the current Image instance
        $image = $this->getSubject();

        // use $fileFormOptions so we can add other options to the field
        $fileFormOptions = ['required' => false];
        if ($image && ($webPath = $image->getWebPath())) {
            // get the request so the full path to the image can be set
            $request = $this->getRequest();
            $fullPath = $request->getBasePath().'/'.$webPath;

            // add a 'help' option containing the preview's img tag
            $fileFormOptions['help'] = '<img src="'.$fullPath.'" class="admin-preview"/>';
            $fileFormOptions['help_html'] = true;
        }

        $form
            ->add('file', 'file', $fileFormOptions)
        ;
    }
}

然后我们使用 CSS 来限制图像的最大尺寸

1
2
3
4
img.admin-preview {
    max-height: 200px;
    max-width: 200px;
}

这就是全部内容!

但是,当可以使用 Sonata\\AdminBundle\\Form\\Type\\AdminType 字段类型将 ImageAdmin 嵌入到其他 Admin 中时,此方法不起作用。为此,我们需要...

高级示例 - 适用于嵌入式管理员

当一个 Admin 嵌入到另一个 Admin 中时,$this->getSubject() 不会返回嵌入式 Admin 管理的实例。相反,我们需要检测到我们的 Admin 类是嵌入式的并使用不同的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
final class ImageAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $form): void
    {
        if($this->hasParentFieldDescription()) { // this Admin is embedded
            // $getter will be something like 'getlogoImage'
            $getter = 'get' . $this->getParentFieldDescription()->getFieldName();

            // get hold of the parent object
            $parent = $this->getParentFieldDescription()->getAdmin()->getSubject();
            if ($parent) {
                $image = $parent->$getter();
            } else {
                $image = null;
            }
        } else {
            $image = $this->getSubject();
        }

        // use $fileFormOptions so we can add other options to the field
        $fileFormOptions = ['required' => false];
        if ($image && ($webPath = $image->getWebPath())) {
            // add a 'help' option containing the preview's img tag
            $fileFormOptions['help'] = '<img src="'.$webPath.'" class="admin-preview"/>';
            $fileFormOptions['help_html'] = true;
        }

        $form
            ->add('file', 'file', $fileFormOptions)
        ;
    }
}

如您所见,唯一的更改是我们如何检索设置 $image 到相关的 Image 实例。当我们的 ImageAdmin 是嵌入式时,我们需要首先获取父对象,然后使用 getter 来检索 Image。从那时起,其他一切都相同。

注意

如果您有多个级别的嵌入式 Admin,这(可能)不起作用。如果您知道更通用的解决方案,请 fork 并在 GitHub 上更新此方法。同样,如果存在任何错误或错别字(或更好的方法来执行此操作),请参与并分享您的见解,以使每个人受益。

这项工作,包括代码示例,均根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本