显示图像预览
这是一个完整的示例,展示了在 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
字段类型将 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 上更新此方法。同样,如果存在任何错误或错别字(或更好的方法来执行此操作),请参与并分享您的见解,以使每个人受益。