This module is a great improvement on the core media module in terms of logically splitting up all the uploaded media into manageable and user-friendly groups. This makes finding files much easier for users. However, an issue for some sites is that by default all the files get saved in the root files directory of the site, and whilst this isn't an issue for the users of the site - who don't see where the files are actually stored - it can be an issue for the site creators/maintainer/s for the following reasons :-

  1. there is a potential for a performance degradation as the number of files increases. Generally the more files in the same directory the slower the file system will be to retrieve them.
  2. there is an increasing chance of filename duplicates - with the resulting numerical suffixes being appended - e.g. image.jpg, image_0.jpg, image_1.jpg
  3. from a file-management perspective most people would prefer to organise files into a physical directory structure.

The good news is there is a very simple way to implement a physical file directory structure that mirrors the logical directory structure this module provides - described below...

What you need

  1. Drupal 8.7 recommended
  2. Media (core)
  3. Media library (core)
  4. this module - Media directories
  5. File (Field) Paths (https://www.drupal.org/project/filefield_paths)

Steps :-

  1. Obviously make sure all above modules are enabled.
  2. Create a taxonomy vocabulary - e.g. "Media Directories".
  3. Add terms relating to directory names - e.g. "Product Images", "Customre Logos", etc. N.B. The terms can be hierarchical
  4. Goto admin/config/media/media_directories to configure the taxonomy to use as the directories
  5. Assign taxonomy to module_directory

  6. Goto admin/structure/media/manage/image/fields/media.image.field_media_image to configure File Field Path settings for the Image media type (you can configure the other media types as required)
  7. Settings for file field paths for media image
    The key here is to use the following Media tokens for the File Path : [media:directory:entity:parents]/[media:directory:entity:name]
    It is advisable to :-

  • Not Remove slashes (/) from tokens
  • Cleanup using Pathauto
  • Transliterate

Now, when image is uploaded via the Media upload form the user gets to choose the logical directory to use (as is standard for this module). The difference now is that the logical directory maps directly to the (cleaned & transliterated) physical directory.

Other uses

There may be times when you don't want the user to be able to choose which logical and physical directory to place certain images in - because, as a site builder, you want to group certain types of images in specific specific directories - e.g. user profile images in the "user-profile-pictures" directory. You may well still want to use the media upload functionality. No problem: you can write a piece of custom code and utilise hook_form_FORM_ID_alter() to pre-select the required taxonomy term for the relevant form - and either hide or disable the Directory selection form widget.

Comments

mautumn created an issue. See original summary.

mautumn’s picture

Issue summary: View changes
StatusFileSize
new50.75 KB
mautumn’s picture

Issue summary: View changes
StatusFileSize
new158.09 KB
mautumn’s picture

mautumn’s picture

Issue summary: View changes
mautumn’s picture

Issue summary: View changes
ytsurk’s picture

Maybe this used to work .. right now the upload directory is not respected, see #3092728: Respect the file storage definitions upload directory.

Actually, it would be quite easy to add this as a feature, having a setting allowing to turn of the physical directory mapping.

letrollpoilu’s picture

That's a brilliant idea.

I just made it worked now.

The issue is when the user is then editing the image and chooses another directory through the jsTree view for example. The file is not moved to the new physical directory.

Any idea how to make that work ?

rang501’s picture

Hi!
Maybe the module filefield_paths could help here when using an active updating feature?

dom.’s picture

This issue is an excellent documentation on how to map media directories with physical path.
However, the jsTree part of media directories UI does not allow physical field to be moved for some operations (directory rename / move).
I have created a sub-issue for handling that and provide integration of filefield_paths in this module.
#3178219: Support file field paths module (filefield_paths)

ytsurk’s picture

Assigned: mautumn » Unassigned
Category: Plan » Task
Lyhtande’s picture

[media:directory:entity:parents]/[media:directory:entity:name] works for the image media type but not for an image field inside a content type.
I get the error: Invalid token.
How can I use this module for content type image fields?

ytsurk’s picture

Make sure to use media entity references instead of (file) image fields.

ebo1958’s picture

Hi, I hope it's OK for me to post my question here.
I've set up media directories as listed above.
I'm pretty sure I found the module through a post (which I sadly can't find anymore) where it was asked how to add media to a directory other than xxx.com/sites/default/files. When media directories was set up the folder name would replace the default directory. I was expecting xxx.com/new-directory/file-name.
What I get is xxx.com/sites/default/files/new-directory/file-name.
Would you please tell me if I have made a mistake in setting up the directories? Possibly there is another token I could use. Unfortunately, I'm not experienced enough to know what it could be.
Any help would be appreciated.

nixar’s picture

I have good luck using filefield_paths with this module.

I can even drag and drop documents from the browser and the path gets updated automatically.

Configuration for the file field of the Document media type:
Enable Filefield_paths?: checked
then under Field (Field) Path Settings:
File path: media-library/[media:directory:entity:parents]/[media:directory:entity:name]
File path options: check all
File name: leave unchanged
File name options: check all
Active Updating: checked

The only caveat is that my folders can only be nested with a depth of 2 since the token [media:directory:entity:parents] can turn multiple nested terms into a flat one but I can leave with that.

Edit: the workaround to this limitation is to use this string for the File path:
[media:directory:entity:parents:join-path]/[media:directory:entity:name]

The join-path formatter joins all the parents with a '/' hence removing the initial limitation. Note that you need the Pathauto module to use this formatter.

hope this helps!

ebo1958’s picture

Hello Nixar,
Thanks for your post. I tried the steps you laid out and now just wonder if I have misunderstood how the module works.

The entity:name is displayed as you say but it is the path to the PDF that is still in the sites/default/files folder.
So the path I was expecting was xxx.com/media-library/new-directory/entity-name/xyz.pdf but I'm getting xxx.com/sites/default/files/media-library/new-directory/entity-name/xyz.pdf.

Would you please let me know if it's possible to change the PDF path with this module. :-)

ytsurk’s picture

Drupal will always serve it's files from the sites/default/files folder!

You could change that by messing with .htaccess (if you're running on apache).

tonytheferg’s picture

Found this issue to be very helpful. If the related issue gets incorporated, I think it's good not to make it dependent upon directories UI, as I don't use it, and still want the mapping to real directories.

nixar’s picture

edited my comment for an updated File Path setting that leverages the join-path formatter however it introduces a dependency with Pathauto

[media:directory:entity:parents:join-path]/[media:directory:entity:name]