Skip to the document
DocsThe media library

Folders and the tree

The tree sits beside Media → Library in both list and grid view, in the editor's insert-media panel, and in the media modal of every page builder whose integration you switch on.

What you can do with it #

  • Drag files onto a folder to file them.
  • Drag folders into each other to rearrange the tree.
  • Rename in place — double-click the name.
  • Colour a folder — stored as the vergeml_color term meta.
  • Order folders by hand — stored as vergeml_order term meta, so the order is yours and not alphabetical-or-nothing.
  • Counts roll up through descendants, so a parent shows what is underneath it.
  • Download a folder as a ZIP, sub-folders included as directories.

The expanded/collapsed state of the tree is remembered per user, in the vergeml_tree_state user meta.

A file can be in more than one folder #

This is the thing single-folder plugins cannot do without a schema change, and it falls out of folders being terms.

  • Drag moves the file, exactly as on your desktop.
  • Ctrl + drop adds it to the target folder without removing it from where it was.

So the same photo can be in Products and in Autumn Campaign with only one file on disk.

If you would rather have the strict one-folder promise kept — which is what somebody arriving from FileBird expects — switch on One folder per file under VergeLabs Library → Settings → Folders and categories. Every drop then moves. It is off by default, because multi-filing is the capability worth having.

More than one filing system over the same files #

Folders are terms, and terms are plural. You can run a Clients tree, a Projects tree and a Usage rights tree over the same library and switch between them from the tree header.

Alongside them you can register flat (non-hierarchical) taxonomies — needs approval, hero image, client supplied — so folders carry structure and tags carry what cuts across it.

Which taxonomies exist, which are hierarchical, and which of them behave as folders is set on VergeLabs Library → Settings → Folders and categories. Third-party taxonomies registered by another plugin can be assigned to the media library from the same screen.

Filing without effort #

Uploads land where you are. Upload with a folder open and the files arrive already filed into it. With All files open, uploads arrive unfiled, exactly as before.

Auto-assign on upload. Files uploaded while editing a post inherit that post's terms. Developers can adjust what gets assigned with the vergeml_auto_assign_terms filter.

Keyboard filing. Everything the mouse can do has a keyboard path:

KeyWhat it does
MWith files selected, open the Move dialog
Arrow keysMove through the folder list
TypeJump to a folder by name
Shift + F10Open a folder's context menu (the other spelling of the menu key)

Full right-to-left stylesheets ship for every screen; WordPress swaps them in automatically on an RTL locale.

Private folders #

On a site where ten people upload, ten people's filing in one sidebar is nobody's filing. So a folder can belong to the person who made it and stay out of everyone else's tree.

This is organisation, not access control, and the screen says so.

A folder is a label stuck on a file. Hiding the label does not hide the file: anyone who can open the media library can still reach that picture by searching, by its URL, or through the REST API, exactly as they could before. The label reads "only you see this folder" and never "only you can see these files" — because a folder that looked like a locked drawer would eventually be trusted with something that needed one.

Administrators see other people's private folders, marked with whose they are. Without that, a folder belonging to a deleted user would be invisible to everyone and impossible to tidy up.

Ownership is kept in a single autoloaded option (vergeml_private_folders), term id to owner id, so no folder query anywhere needs an extra join. See Data model.

Two languages #

With Polylang or WPML:

  • A translated copy of an image lands in the original's folders.
  • One set of folders shows in every language. Polylang's language filter on get_terms() does not apply on the admin side, and that is the outcome worth having — the alternative is half the tree silently missing, which looks exactly like working software.
  • A file can sit in folders of different languages at once, and both count it correctly.
  • The CSV export writes both languages out.

If you want per-language folders instead, return false from vergeml_multilingual_shared_folders.

No compatibility shim was needed for either plugin. Folders are terms, and both Polylang and WPML already translate terms — which is the taxonomy decision paying for itself. FileBird needs a dedicated Support/WPML.php for the same job.

Polylang costs one extra query on every request, measured on an endpoint that never touches folders, so it is Polylang's and not ours. Nothing to fix; worth knowing.

The library screen itself #

Beyond the tree, the plugin reworks the media library screen:

  • Filters for type, date, author and every taxonomy you assign — configurable per taxonomy and per filter, with include/exclude child categories.
  • Taxonomy columns in list view, sortable.
  • Search widened past core's title/caption/description to filenames, uploader, and every term a file is filed under. Which columns are searched is a setting.
  • Bulk select with no special mode, plus a bulk term picker and bulk action.
  • Drag-and-drop reordering in the library.
  • Grid captions — title, filename or caption.
  • Infinite scroll and a configurable loads-per-page.
  • Full MIME type management — add, remove, rename, allow or disallow uploading, and fold a type into the filters.

Every one of those is documented field by field in the Settings reference.

How it stays out of core's way #

WordPress core's media JavaScript exposes no hook API — wp-includes/js/media-views.js contains zero wp.hooks calls and one doAction. There is no supported way to add a filter dropdown to the media grid, so patching core views is the only route, and the question is how rather than whether.

The rule this plugin follows is wrap or add, never replace: register a new view, or call core's method and then adjust what it produced. A replacement silently falls behind every time WordPress changes, which is exactly how the WordPress 7.0 toolbar break happened in the first place.

Seven replacements remain in the codebase and are being converted one at a time. That is the honest number and it is published rather than implied.

Written from version 3.15.0 of the plugin. Last updated 2026-10-02. All documentation · Legal · Support