Build a one-click Doc template library
Spin a new Doc from any approved template via a custom menu in the master sheet.
Published Dec 7, 2025
Northwind has a tidy set of approved Doc templates — proposals, statements of work, meeting notes — but starting a new one was a chore. People hunted through Drive for the right file, copied it, renamed the copy, and half the time grabbed an outdated version or edited the master by mistake.
This script turns the template folder into a menu. When the master Sheet opens, it lists every Doc in a designated Drive folder as a menu item. Click one and it copies the template, datestamps the name, and shows a link to the fresh Doc — no hunting, no accidental edits to the master.
What you’ll need
- A Drive folder holding your approved templates. Every Google Doc inside it becomes a menu item, so keep only real templates in there.
- A master Google Sheet with a bound Apps Script project.
- The template folder’s ID, pasted into the config block.
The script (bound to the Sheet)
// Drive folder whose Docs are offered as templates.
const TEMPLATES_FOLDER = '1abcTemplatesFolderId';
/**
* Builds the "Templates" menu when the spreadsheet opens, with one
* item per Google Doc in the templates folder. Each item is wired
* to a generated function that copies that specific template.
*/
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('Templates');
// 1. List every Google Doc in the templates folder.
const files = DriveApp.getFolderById(TEMPLATES_FOLDER)
.getFilesByType(MimeType.GOOGLE_DOCS);
let count = 0;
while (files.hasNext()) {
const file = files.next();
// 2. Give each template a unique handler name based on its file ID.
const fnName = `create_${file.getId()}`;
// 3. Define that handler on the global scope so the menu can call it.
this[fnName] = () => copyTemplate(file.getId());
// 4. Add the template to the menu under its file name.
menu.addItem(file.getName(), fnName);
count++;
}
if (count === 0) {
menu.addItem('(no templates found)', 'noop');
}
menu.addToUi();
}
/**
* Copies a template Doc, datestamps the copy's name, and shows the
* user a link to the new file.
*
* @param {string} fileId - The Drive ID of the template to copy.
*/
function copyTemplate(fileId) {
const file = DriveApp.getFileById(fileId);
const today = new Date().toISOString().slice(0, 10);
// Copy the template with today's date appended to the name.
const copy = file.makeCopy(`${file.getName()} — ${today}`);
SpreadsheetApp.getUi()
.alert('Created', `Doc: ${copy.getUrl()}`, SpreadsheetApp.getUi().ButtonSet.OK);
}
/** Placeholder handler used when the templates folder is empty. */
function noop() {}
How it works
onOpenruns each time the master Sheet is opened and starts a menu called Templates.- It lists every Google Doc in
TEMPLATES_FOLDERwithgetFilesByType, so the menu always reflects what is actually in the folder. - For each template it builds a handler name from the file’s ID — guaranteed
unique — and attaches a function to the global scope (
this[fnName]). Apps Script menus can only call a function by name, so the handler must exist globally. - Each generated handler calls
copyTemplatewith that file’s ID, and the template is added to the menu under its file name. - If the folder holds no Docs, a disabled-looking placeholder item is shown instead of an empty menu.
copyTemplatecopies the chosen file, appends today’s date inYYYY-MM-DDform to the name, and pops an alert with a clickable link to the new Doc.
Example run
With three Docs in the templates folder, opening the master Sheet shows:
Templates
├─ Project proposal
├─ Statement of work
└─ Meeting notes
Clicking Statement of work on 7 December 2025 creates a Drive file named:
Statement of work — 2025-12-07
and shows an alert with a link straight to it. The original template is untouched.
Run it
The library sets itself up:
- Reload the master Sheet so
onOpenbuilds the Templates menu. - Open the menu and click any template.
- Follow the link in the alert to your new Doc.
Add or remove a Doc in the folder and the menu updates on the next reload — no code change needed.
Watch out for
onOpenis a simple trigger and runs on every open. A folder with dozens of templates makes the menu slow to build; keep the folder lean.- The copy lands in the user’s Drive root, not the templates folder — which is
intentional, so the folder stays clean. Pass a folder to
makeCopyif you want copies collected somewhere specific. - Building handlers with
this[fnName]only works becauseonOpenruns in the global scope. Do not move that loop inside another function. - Only Google Docs are listed. Templates saved as Word
.docxfiles are skipped byMimeType.GOOGLE_DOCS— convert them to Docs first. - The menu is a snapshot from when the Sheet was opened. Add a template while the Sheet is open and it will not appear until the next reload.
Related
Generate personalized study guides from notes
Reformat raw notes into structured study guides — for Northwind's internal training programme.
Updated Feb 8, 2026
Build a contract-clause assembly system
Construct Northwind agreements from a library of approved clauses — drag-drop in code.
Updated Feb 1, 2026
Translate and resolve Doc comments
Localise reviewer feedback on a shared Doc so multilingual teams can collaborate.
Updated Jan 25, 2026
Auto-archive finalized Docs to dated folders
File completed Northwind Docs by month so the active folder stays focused on in-flight work.
Updated Jan 18, 2026
Build a fillable intake form inside a Doc
Create structured intake forms with placeholder fields readers can fill — for client briefs.
Updated Jan 11, 2026