Files and downloads

Hand a client a file library, not an FTP login

A depot field holds as many files as a record needs — organised into subfolders, checked against the upload rules you wrote into the schema, and served through download or streaming URLs you drop straight into a template.

Total CMS has two upload fields. A file field holds one upload — a spec sheet, a signed contract, a single PDF. A depot field holds as many as the record needs, and it is where a site keeps the things it hands out: manuals, price lists, session recordings, a year of invoices.

Both are fields on a schema, so the files belong to a record rather than to a shared drop box somewhere on the server. The upload rules live in the schema next to the field, and they are enforced before anything reaches disk:

  • size — minimum and maximum in kilobytes
  • count — how many files a depot may hold
  • filetype — an allow-list of MIME types
  • filename — an allow-list of exact names, for a record that expects one specific document

Access is decided by the collection, not by where a file happens to sit on disk. New uploads are protected by default, which means they inherit the collection's File Access Groups: leave that list empty and the file is effectively public; set it to default and any signed-in user can download it; name groups and only members of those groups can. Set protectedByCollection to false on a field whose files are meant to be open — a downloads page, marketing assets — and new uploads land unprotected instead. Existing files keep whatever setting they already had.

In a template you never build a path. cms.media.depot() lists the files on a property, cms.media.depotDownload() returns a URL that sends one as an attachment, and cms.media.depotStream() returns one that plays inline and answers HTTP range requests — which is what a video scrubber needs to work. Both accept a subfolder path and an optional password.

The shape this takes in practice: a consultancy keeps one record per client with a depot of deliverables filed by year. The client signs in and sees their own record's files and nobody else's, and the consultant adds next quarter's report by dropping it into the right subfolder in the admin.

What you get

Many files, one record

A file field takes a single upload. A depot takes as many as you allow, filed into subfolders, all attached to the record they belong to.

Rules before the upload

Size, count, MIME type and exact filename rules live in the schema. Anything outside them is rejected rather than quietly stored.

Subfolders you can rearrange

Depots organise into subfolders, and the admin's depot field moves files between them by drag and drop.

Protected by default

New uploads inherit the collection's File Access Groups. Empty means public, default means any signed-in user, and named groups mean only those groups.

Download or stream

One URL sends the file as an attachment; the other serves it inline with range-request support for video and audio.

In practice

One snippet

{% set files = cms.media.depot('documents') %}
{% for file in files %}
	<a href="{{ cms.media.depotDownload('documents', file.name) }}">{{ file.name }}</a>
{% endfor %}

List every file in a depot property and link each one to its download URL.

FAQ

Common questions

What is the difference between a file field and a depot field?

A file field holds a single upload. A depot field holds many, organises them into subfolders, and adds a count rule that caps how many files may be attached.

Can I control who downloads a file?

Yes. Protected files are gated by the collection's File Access Groups. An empty list means anyone, including anonymous visitors; the reserved default group means any logged-in user; named groups restrict access to their members. Super admins always have access.

Can I limit which file types get uploaded?

The field's rules accept an allow-list of MIME types, a size range in kilobytes, a maximum file count, and even a list of exact filenames when a record expects one specific document.

Do depot files travel in a JumpStart export?

No. JumpStart references image, file, gallery and depot values but does not embed the binaries. Use a collection's Export to Zip when you need the actual files.