2

I'm trying to override the file-link.html.twig to display the size next to the file link (also the file MIME type, but I think I can figure that out once I figure out how to display the size) but so far I've been failing spectacularly. I assume this must be super simple and I'm missing something obvious.

Using kint($variables) in the function themename_preprocess_file_link(&$variables) I see the filesize:

$args array (1)
array (15
'file' => Drupal\file\Entity\File(27) 
"contents" tab:
    protected values -> array(13)
    'filesize' => array(1)
    'x-default' => string(7) "2245389"

But I can't figure out how to turn this into a variable I can use in a template file.

I tried following How can I override template_preprocess_file_link function? but then I couldn't figure out what was suppose to be the variable to use in the template file. Also, his "code" just seems to be same as what is on https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/template_preprocess_file_link/8.6.x.

  • I know this isn't exactly what you are asking for, but you can use tokens to display the file size and mime type (handy if you are using display suite, for example). [file:size] & [file:mime] - or you can access them in the twig if you install Twig Tweak drupal_token([file:size]) -- drupal.org/project/twig_tweak – 100pic Feb 26 at 5:58
  • How do I use token in a node template? I tried this for a referenced media file but it doesn't work? {{ drupal_token('node.myfield.entity|file:size') }} – paulcap1 Nov 1 at 11:24
2

Using HOOK_preprocess_field(&$variables):

/**
 * Implements HOOK_preprocess_field().
 *
 * @inheritdoc
 */
function HOOK_preprocess_field(&$variables) {
  $element = $variables['element'];
  // Check that field_name is set.
  if (isset($element['#field_name'])) {
    // Checking for field_name, but could check for field_type.
    if ($element['#field_name'] == 'field_name') {
      // Set our file size to a variable.
      $fileSize = $element[0]['#file']->filesize->value;
      // Edit our title for the field display.
      $element[0]['#file']->filename->value = $element[0]['#file']->filename->value . ' ' . $fileSize;
    }
  }
}

Using HOOK_preprocess_file_link(&$variables):

/**
 * Add the "file-link.html.twig" template to your theme and adjust as needed.
 * 
 * Twig variables:
 * - {{ fileLinkDisplay.fileBundle }}
 * - {{ fileLinkDisplay.fileCreatedTime }}
 * - {{ fileLinkDisplay.fileChangedTime }}
 * - {{ fileLinkDisplay.fileFid }}
 * - {{ fileLinkDisplay.fileLangcode }}
 * - {{ fileLinkDisplay.fileMime }}
 * - {{ fileLinkDisplay.fileName }}
 * - {{ fileLinkDisplay.fileOwnerId }}
 * - {{ fileLinkDisplay.fileOwnerName }}
 * - {{ fileLinkDisplay.fileOwnerUserPictureUrl }}
 * - {{ fileLinkDisplay.fileSize }}
 * - {{ fileLinkDisplay.fileSizeFormatted }}
 * - {{ fileLinkDisplay.fileStatus }}
 * - {{ fileLinkDisplay.fileUrl }}
 * - {{ fileLinkDisplay.fileUuid }}
 */

function HOOK_preprocess_file_link(&$variables) {
  if (isset($variables['file'])) {
    $variables['fileLinkDisplay'] = [
      'fileBundle' => $variables['file']
        ->bundle(),
      'fileCreatedTime' => $variables['file']
        ->getCreatedTime(),
      'fileChangedTime' => $variables['file']
        ->getChangedTime(),
      'fileFid' => $variables['file']
        ->fid->value,
      'fileLangcode' => $variables['file']
        ->langcode->value,
      'fileMime' => $variables['file']
        ->getMimeType(),
      'fileName' => $variables['file']
        ->getFilename(),
      'fileOwnerId' => $variables['file']
        ->getOwnerId(),
      'fileOwnerName' => $variables['file']
        ->getOwner()->name->value,
      'fileOwnerUserPictureUrl' => file_create_url($variables['file']
        ->getOwner()->user_picture->entity->uri->value),
      'fileSize' => $variables['file']
        ->getSize(),
      'fileSizeFormatted' => format_size($variables['file']
        ->getSize()),
      'fileStatus' => $variables['file']
        ->status->value,
      'fileUrl' => file_create_url($variables['file']
        ->getFileUri()),
      'fileUuid' => $variables['file']
        ->uuid->value,
    ];
  }
}

See https://gitlab.com/prestosaurus/file-link-display/blob/master/file_link_display.module

Then your file-link.html.twig might look like:

{#
/**
 * @file
 * Theme override for a link to a file.
 *
 * @see template_preprocess_file_link()
 */
#}
{{ attach_library('classy/file') }}
<span{{ attributes }}>{{ icon }} {{ link }} {{ fileLinkDisplay.fileSize }} {{ fileLinkDisplay.fileMime }}</span>
  • 1
    In a preprocess function, you never use echo, not even for debugging purposes. – kiamlaluno Feb 26 at 7:37
  • True, the echo I have is just so the user can see the result of $element['#title'] and that it is not quantified or altered in other processes. Do not leave this in your function. – Prestosaurus Feb 26 at 7:46
  • What would you hope to achieve with this code? Currently you're just altering some variables within a function, you're not changing anything that would be altered in the template – Clive Feb 26 at 8:37
  • I updated my answer a bit. The #title was just what I was working with. The first function will rewrite the label of the field and append the filesize value. – Prestosaurus Feb 26 at 15:44
  • Thank you for the detailed response. I'm not sure its all clicking in my head. Why "HOOK_preprocess_field" and not "HOOK_preprocess_file_link"? – fallenturtle Feb 26 at 20:51

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.