> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Templates Collection

`templates` holds one document per template in the template gallery. The files of a template (the project zip and the PDF) are not here: they are kept in filestore under `template/<_id>/v/<version>/`. The collection belongs to the `template-gallery` web module (`services/web/modules/template-gallery`). The schema is the Mongoose model `Template` in `services/web/modules/template-gallery/app/src/models/Template.mjs`; the logic is in `services/web/modules/template-gallery/app/src/TemplateGalleryManager.mjs` and `TemplateGalleryHelper.mjs` next to it.

#### Fields

| Field | Type | Meaning | Source |
| - | - | - | - |
| `_id` | ObjectId | Set by Mongoose. It is also the folder of the template's files in filestore. | `TemplateGalleryHelper.mjs:148-150` |
| `name` | String | The title. Required, at most 150 characters. Publishing looks a template up by name, and editing refuses a name that another template has, so names stay unique without an index. | `Template.mjs:7`, `TemplateGalleryHelper.mjs:50-52`, `TemplateGalleryManager.mjs:30-38,55` |
| `category` | String | The category link, `/templates/<key>`, where `<key>` is one of `OVERLEAF_TEMPLATE_CATEGORIES` or `all`. Required. | `Template.mjs:8`, `services/web/modules/template-gallery/index.mjs:17-31`, `TemplateGalleryManager.mjs:206` |
| `descriptionMD` | String | The description as typed, in Markdown. At most 4096 characters. Searched by the gallery. | `Template.mjs:10`, `TemplateGalleryHelper.mjs:53-55`, `TemplateGalleryManager.mjs:207-212` |
| `description` | String | HTML rendered from `descriptionMD` and cleaned. Set whenever `descriptionMD` is set. | `Template.mjs:9`, `TemplateGalleryHelper.mjs:224-228` |
| `authorMD` | String | The author as typed, in Markdown. At most 512 characters. Searched by the gallery. | `Template.mjs:12`, `TemplateGalleryHelper.mjs:56-58` |
| `author` | String | HTML rendered from `authorMD`, links only. Set whenever `authorMD` is set. | `Template.mjs:11`, `TemplateGalleryHelper.mjs:229-232` |
| `license` | String | The license text chosen in the form. Required, at most 512 characters. | `Template.mjs:13`, `TemplateGalleryHelper.mjs:59-61` |
| `mainFile` | String | The path of the source project's root doc, without the leading slash. Required: a project without a root doc cannot be published. | `Template.mjs:14`, `TemplateGalleryHelper.mjs:112-114` |
| `compiler` | String | The source project's compiler. Required. | `Template.mjs:15`, `TemplateGalleryHelper.mjs:122` |
| `imageName` | String | The source project's TeX Live image. The template page shows only the last part of it. | `Template.mjs:16`, `TemplateGalleryHelper.mjs:123`, `TemplateGalleryManager.mjs:249-253` |
| `language` | String | The source project's spell check language. Can be changed in the edit form. | `Template.mjs:17`, `TemplateGalleryHelper.mjs:124` |
| `version` | Number | Starts at 1 and goes up by one each time the template is published again under the same name. The files of each version are under `v/<version>/`. Required. | `Template.mjs:18`, `TemplateGalleryManager.mjs:74-79` |
| `owner` | ObjectId | The user who first published the template. Publishing again over it keeps the owner. | `Template.mjs:19`, `TemplateGalleryManager.mjs:70-79` |
| `project_id` | ObjectId | The project it was last published from. Updated on every publish. | `Template.mjs:20`, `TemplateGalleryManager.mjs:81-84` |
| `lastUpdated` | Date | When it was last published or edited. Required, default now. | `Template.mjs:21-27`, `TemplateGalleryHelper.mjs:125`, `TemplateGalleryManager.mjs:41` |
| `__v` | Number | The Mongoose version key. The schema does not turn it off. | Mongoose default |

#### Who Writes It

| Code | What it does |
| - | - |
| `TemplateGalleryManager.mjs:53-97` (`createTemplateFromProject`) | `POST /template/new/:Project_id`. It copies the project's settings (`TemplateGalleryHelper.mjs:94-134`), uploads the zip and the PDF to filestore, and saves. If the name is taken it answers with a conflict, unless the client asked to override: then it updates that template and raises its `version`, then deletes the files of the previous version. |
| `TemplateGalleryManager.mjs:21-47` (`editTemplate`) | `POST /template/:template_id/edit`. It assigns the posted fields to the document, renders `description` and `author` again, and sets `lastUpdated`. The edit form posts the changed fields among `name`, `license`, `category`, `language`, `authorMD` and `descriptionMD` (`services/web/modules/template-gallery/frontend/js/pages/template/util/api.ts:22-29`). |
| `TemplateGalleryHelper.mjs:186-222` (`deleteTemplateAssets`) | `DELETE /template/:template_id/delete` deletes the document and the files of the given version (`TemplateGalleryManager.mjs:49-51`). |

Only site admins and the user in `OVERLEAF_TEMPLATES_USER_ID` may call these three routes (`services/web/modules/template-gallery/app/src/Router.mjs:55-62,70-84`, `PermissionsMiddleware.mjs:8-19`).

#### Who Reads It

| Code | What it does |
| - | - |
| `TemplateGalleryManager.mjs:158-183` (`getTemplate`) | Finds one template by `_id` or `name` for the template page and for `GET /api/template` (`services/web/modules/template-gallery/app/src/TemplateGalleryController.mjs:210-232`). If `project_id` points to a project that no longer exists, the answer leaves it out; the document is not changed. |
| `TemplateGalleryManager.mjs:190-236` (`getCategoryTemplates`) | `GET /api/templates`: one page of a category, searched in `name`, `authorMD` and `descriptionMD`, sorted by `lastUpdated` or by `name` (case-insensitive). |
| `TemplateGalleryHelper.mjs:64-80` (`canUserOverrideTemplate`) | Reads `owner` to name the owner in the conflict message. |

#### Indexes

| Name | Keys | Options | Migration |
| - | - | - | - |
| `_id_` | `_id: 1` | | default |

Mongoose `autoIndex` is off (`services/web/app/src/infrastructure/Mongoose.mjs:7`). `tools/migrations/20190912145030_create_templates_indexes.mjs` (unique `project_id`, `user_id`, `name`) is tagged `server-pro` and `saas`, so it does not run in CE, which runs only the `server-ce` migrations (`server-ce/init_scripts/900_run_web_migrations.sh`).

#### Notes

* Upstream treats `templates` as a stale collection and drops it on its own site (`tools/migrations/20241002180623_drop_unused_collections.mjs`, tagged `saas`). In Ayakaleaf Pro the template gallery module uses it.
* Sorting by name uses a case-insensitive collation, and the comment at `TemplateGalleryManager.mjs:186-188` notes that a `name` index would need the same one. CE has no `name` index, so Mongo sorts in memory.
* Deleting the source project or the owner does not delete the template.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.