12

The generated markup for displaying a file field is (PDF in this example):

<img src="/modules/file/icons/application-pdf.png" title="application/pdf" alt="" class="file-icon">

I'd like to use a different icon image. How could I do this without changing the content of /modules/file/icons?

I guess I could hide the default image and display a different one with CSS, but seems a bit messy.

5 Answers 5

11

You can override theme_file_icon in your theme, and specify different icon images. See file_icon_path for reference regarding how core determines which icons to use.

You can also set the "file_icon_directory" variable to the path to your icons, as the file_icon_path function looks for the path in that variable.

1
  • Following on from what jhedstrom says I've written a novice blog on how to use the two functions above to achieve this solution here. Hope that's helpful to someone!
    – Alison
    Commented Aug 9, 2012 at 22:10
4

Two additional notes on this:

  1. It is not necessary to copy all of the default icon files to your theme directory.
  2. If you are using a custom icon, it must be appropriately named in order for it to be found.

As an example, I had a need to use a custom icon for a .bib (bibtex) file. This type is mapped in file_default_mimetype_mapping(), but it defaults to the default text icon since there isn't an icon specifically defined for that mime type (text/x-bibtex).

I overrode theme_file_icon() in my theme's template.php, but I did it so that the icon path is only modified as needed, and I didn't have to copy the default icons directory to my theme directory:

function mytheme_file_icon($variables) {
  $file = $variables['file'];
  $icon_directory = $variables['icon_directory'];

  $mime = check_plain($file->filemime);

  if ($mime == 'text/x-bibtex') {
    $icon_directory = drupal_get_path('theme', 'mytheme') . '/images';
  }

  $icon_url = file_icon_url($file, $icon_directory);
  return '<img class="file-icon" alt="" title="' . $mime . '" src="' . $icon_url . '" />';
}

The second thing is that you have to name the icon appropriately. If you just keep the use of file_icon_url(), this code from that function will determine the file name for the icon:

// For a few mimetypes, we can "manually" map to a generic icon.
$generic_mime = (string) file_icon_map($file);
$icon_path = $icon_directory . '/' . $generic_mime . '.png';
if ($generic_mime && file_exists($icon_path)) {
  return $icon_path;
}

So in my case, I needed to name my file text-x-bibtex.png. Of course, if you want to just name it whatever you want (bibtex.png in this case), you could just set the file name manually:

$icon_url = $icon_directory . '/bibtex.png';

Either one will work, but this method allows you to keep the default icons where they are and only tweak things as needed.

1

Me and tregis got this File Field Icons module done a while ago. Hope this helps

This modules adds the ability to change default file field icons. You can use core icon packages (included in this module), or you can define a custom icon package.

0

You can (usually) preprocess theme functions. So if you:

  1. Are okay with copying all the icons into your theme to override one or more icons.
  2. Don't care to override theme_file_icon() in your theme.

Copy the entire modules/file/icons directory to your theme (I used file_icons) and add this preprocess function to your theme's template.php:

/**
 * Implements hook_preprocess_HOOK() for theme_file_icon().
 *
 * Change the icon directory to use icons from this theme.
 */
function MYTHEME_preprocess_file_icon(&$variables) {
  $variables['icon_directory'] = drupal_get_path('theme', 'MYTHEME') . '/file_icons';
}

You could also do conditional overrides this way ala @wonder95 but I wanted to keep things simple.

0

While not being as clean as some of the solutions given, a really simple way of dealing with this is to make use of the CSS3 'type' attribute selector. You can use this to quickly add your custom icon as background image to your link. The result that both are linked to the target file. You can then hide the original image. I did this to get the following appearance:

Screenshot of result

This is the CSS I used to achieve the results above:

.views-field-field-image-files img.file-icon {display:none;}
.views-field-field-image-files a {padding-left: 100px; height: 80px; display: block; margin-bottom: 20px;}
.views-field-field-image-files a[type*="application/pdf"] {background: url(../img/icons/file-icon-pdf.gif) no-repeat; }
.views-field-field-image-files a[type*="application/zip"] {background: url(../img/icons/file-icon-zip.gif) no-repeat; }
.views-field-field-image-files a[type*="application/ppt"] {background: url(../img/icons/file-icon-ppt.gif) no-repeat; }
.views-field-field-image-files a[type*="application/pptx"] {background: url(../img/icons/file-icon-ppt.gif) no-repeat; }

In my example I was showing the file fields using views.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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