I am implementing a custom field-widget for the file-field in Drupal 8.

I extended the FileWidget class as my widget uses most of the file-field-widget functionality.

There is just a small part I want to theme/customize from the file upload form, the part I marked in the following screenshot:

enter image description here

What is the best way to alter the output from a field-widget?

I want to add some surrounding container elements and similar things you do in a theme function.

  • What do you want to change, just the styling? File fields are different from others when it comes to styling, most of it is done by the browser. There are a few possblities though, but it isn't as straight forward as you'd think, here's an example: css-tricks.com/snippets/css/… – pjcarly Jan 20 '16 at 9:13
  • Thank you, but this is not about css. I want to theme the file field marked in the screenshot. I want to add some surrounding containers and so on. The usual things you do in a theme function. – Linus Jan 20 '16 at 9:20
  • I updated the question to make it more clear – Linus Jan 20 '16 at 9:40

The file field for uploading is defined in the render callback of ManagedFile:

public static function processManagedFile(&$element, FormStateInterface $form_state, &$complete_form) {

  // The file upload field itself.
  $element['upload'] = [
    '#name' => 'files[' . $parents_prefix . ']',
    '#type' => 'file',
    '#title' => t('Choose a file'),
    '#title_display' => 'invisible',
    '#size' => $element['#size'],
    '#multiple' => $element['#multiple'],
    '#theme_wrappers' => [],
    '#weight' => -10,
    '#error_no_message' => TRUE,

So one way to change the output of the field is to define a custom form element which extends File. The element can be themed as wanted.

And in the process callback of the custom widget the type of the upload element can be overwritten to use the newly defined element:

public static function process($element, FormStateInterface $form_state, $form) {
  $element = parent::process($element, $form_state, $form);
  $element['upload']['#type'] = 'myCustomFileElement';
  return $element;

To add custom html wrapper around, you should use drupal form API #prefix and #suffix attribute to form element.

For example:

function HOOK_form_FORM_ID_alter(&$form, &$form_state, $form_id){
  $form['field_my_field']['#prefix'] = '<div class="the-custom-class">';
  $form['field_my_field']['#suffix'] = '<img width="32" height="32" src="http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons/matte-blue-and-white-square-icons-alphanumeric/116590-matte-blue-and-white-square-icon-alphanumeric-plus-sign.png"></div>';

Here you need to replace HOOK with your custom module name,and FORM_ID with id of form.

Hope it will help.

  • You're right, that would be working. I could also override a theme function, but I want to do this as a field widget. – Linus Jan 20 '16 at 11:21
  • What do you mean by "What is the best way to alter the output from a field-widget?" in your Original Post? Do you mean the field-widget will alter the output? Or are you trying to customize the look of the field-widget? Or...? – longboardnode Jan 20 '16 at 13:30
  • I want to provide my own file field widget. This widget is based on the file field widget but has some modifications and also has a different look. Therefore I need to alter the markup of the upload form. So yeah, I want to customize the look of my widget. – Linus Jan 20 '16 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.