我从buildForm函数创建了一个自定义表单。在这种形式中,我想添加一个图像字段。
我可以通过以下代码执行此操作:
$form['main']['image'] = array(
'#type' => 'text_format',
'#title' => t('image'),
'#default_value' => array(10),
);
我可以上传和删除表单中的图片。但是,当我上传图片时,我没有预览。 我的意思是,当我通过Drupal UI创建内容时。我可以添加一个预配置的“图像”字段。当我通过此“图像”字段上传图像时,我会预览图像。
在这里,当我以编程方式创建field元素时,我上传她时没有预览图像。 当我通过“图像”字段上传她时,如何使用api Drupal进行图像预览?
答案 0 :(得分:8)
所以这是我如何让表单显示缩略图。我基本上做的是获取ImageWidget :: process中的代码,将其放在主题预处理器中,并将元素的#theme属性设置为image_widget。
表单类中的图像元素应如下所示:
$form['profile_image'] = [
'#type' => 'managed_file',
'#title' => t('Profile Picture'),
'#upload_validators' => array(
'file_validate_extensions' => array('gif png jpg jpeg'),
'file_validate_size' => array(25600000),
),
**'#theme' => 'image_widget',**
**'#preview_image_style' => 'medium',**
'#upload_location' => 'public://profile-pictures',
'#required' => TRUE,
];
在name_of_default_theme.theme文件中,您需要以下内容:
function name_of_default_theme_preprocess_image_widget(&$variables) {
$element = $variables['element'];
$variables['attributes'] = array('class' => array('image-widget', 'js-form-managed-file', 'form-managed-file', 'clearfix'));
if (!empty($element['fids']['#value'])) {
$file = reset($element['#files']);
$element['file_' . $file->id()]['filename']['#suffix'] = ' <span class="file-size">(' . format_size($file->getSize()) . ')</span> ';
$file_variables = array(
'style_name' => $element['#preview_image_style'],
'uri' => $file->getFileUri(),
);
// Determine image dimensions.
if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
$file_variables['width'] = $element['#value']['width'];
$file_variables['height'] = $element['#value']['height'];
} else {
$image = \Drupal::service('image.factory')->get($file->getFileUri());
if ($image->isValid()) {
$file_variables['width'] = $image->getWidth();
$file_variables['height'] = $image->getHeight();
}
else {
$file_variables['width'] = $file_variables['height'] = NULL;
}
}
$element['preview'] = array(
'#weight' => -10,
'#theme' => 'image_style',
'#width' => $file_variables['width'],
'#height' => $file_variables['height'],
'#style_name' => $file_variables['style_name'],
'#uri' => $file_variables['uri'],
);
// Store the dimensions in the form so the file doesn't have to be
// accessed again. This is important for remote files.
$element['width'] = array(
'#type' => 'hidden',
'#value' => $file_variables['width'],
);
$element['height'] = array(
'#type' => 'hidden',
'#value' => $file_variables['height'],
);
}
$variables['data'] = array();
foreach (Element::children($element) as $child) {
$variables['data'][$child] = $element[$child];
}
}
解决方案效果很好,但图像模块缺少带有@FormElement注释的类。这就是元素没有正确呈现的原因。
答案 1 :(得分:2)
您可以尝试使用managed_file类型吗?
'#type' => 'managed_file'
答案 2 :(得分:0)
很好的回答,我唯一要做的更改是使用令牌作为上载位置,使用字节作为文件上载大小,尽管我猜这取决于用例。类似于以下内容(为了简单起见,将大部分代码删除了。
namespace Drupal\my_module\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Component\Utility\Bytes;
use Drupal\Core\Utility\Token;
class SampleForm extends FormBase
{
protected $currentUser;
protected $token;
public function __construct(AccountProxyInterface $current_user, Token $token) {
$this->currentUser = $current_user;
$this->token = $token;
}
public static function create(ContainerInterface $container)
{
return new static(
$container->get('current_user'),
$container->get('token')
);
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['sample_image'] = [
'#type' => 'managed_file',
'#title' => t('Profile Picture'),
'#upload_validators' => array(
'file_validate_extensions' => array('gif png jpg jpeg'),
'file_validate_size' => file_upload_max_size() / pow(Bytes::KILOBYTE, 2) . 'M',
),
'#theme' => 'image_widget',
'#preview_image_style' => 'medium',
'#upload_location' => $this->token->replace('private://[date:custom:Y]-[date:custom:m]'),
'#required' => TRUE,
];
return $form;
}
}
答案 3 :(得分:0)
将其主题化以处理多个文件上传。来自上面@Je Suis Alrick 的回答。
function themename_preprocess_image_widget(&$variables) {
$element = $variables['element'];
$variables['attributes'] = array('class' => array('image-widget', 'js-form-managed-file', 'form-managed-file', 'clearfix'));
if (!empty($element['fids']['#value'])) {
foreach ($element['#files'] as $file) {
$element['file_' . $file->id()]['filename']['#suffix'] = ' <span class="file-size">(' . format_size($file->getSize()) . ')</span> ';
$file_variables = array(
'style_name' => $element['#preview_image_style'],
'uri' => $file->getFileUri(),
);
// Determine image dimensions.
if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
$file_variables['width'] = $element['#value']['width'];
$file_variables['height'] = $element['#value']['height'];
} else {
$image = \Drupal::service('image.factory')->get($file->getFileUri());
if ($image->isValid()) {
$file_variables['width'] = $image->getWidth();
$file_variables['height'] = $image->getHeight();
}
else {
$file_variables['width'] = $file_variables['height'] = NULL;
}
}
$element['preview'][] = array(
'#weight' => -10,
'#theme' => 'image_style',
'#width' => $file_variables['width'],
'#height' => $file_variables['height'],
'#style_name' => $file_variables['style_name'],
'#uri' => $file_variables['uri'],
);
// Store the dimensions in the form so the file doesn't have to be
// accessed again. This is important for remote files.
$element['width'] = array(
'#type' => 'hidden',
'#value' => $file_variables['width'],
);
$element['height'] = array(
'#type' => 'hidden',
'#value' => $file_variables['height'],
);
}
}
$variables['data'] = array();
foreach (\Drupal\Core\Render\Element::children($element) as $child) {
$variables['data'][$child] = $element[$child];
}
}