Folders

Folders provide a convenient mechanism for organizing your projects. Each folder may contain other folders and projects, and you copy and move their contents between folders.

Class Functions

Using the byIdentifier() method to locate a folder using the value of its primaryKey property (object ID):

Locating Folder by ID


Folder.byIdentifier('a0UDF6AROY8') //--> [object Folder: Home Renovation]

Using the flattenedFolders property of the Database class and the byName(…) function of the SectionArray class to return an object reference to the first folder identified by name:

Locating 1st Instance of Folder by Name


fldr = flattenedFolders.byName('Home Renovation') if(fldr){ console.log(fldr.id.primaryKey) //--> "a0UDF6AROY8" }

Instance Properties

Here are the properties of an instance of the Folder class:

Using the flattenedProjects property of the Folder class to iterate all projects within a specified folder:

Iterating All Projects in a Folder


folderName = 'Home Renovation' fldr = flattenedFolders.byName(folderName) if(fldr){ fldr.flattenedProjects.forEach(project => { // process project }) }

Folder.Status Class

The value for the status property of the Folder class:

Dropping a Folder


folder = folderNamed("Folder A") if(folder){folder.status = Folder.Status.Dropped}

Creating Folders

New folders are created using the standard Javascript new item constructor, passing in values for the name and optinal insertion position parameters:

omnifocus://localhost/omnijs-run?script=try%7Bfldr%20%3D%20new%20Folder%28%22AAPL%22%2C%20library%2Ebeginning%29%0Atitles%20%3D%20%5B%221st%20Q%22%2C%222nd%20Q%22%2C%223rd%20Q%22%2C%224th%20Q%22%5D%0Atitles%2EforEach%28title%20%3D%3E%20new%20Folder%28title%2C%20fldr%29%29%7Dcatch%28err%29%7Bconsole%2Elog%28err%29%7D
Creating Folders within a Folder
 

fldr = new Folder("AAPL", library.beginning) titles = ["1st Q","2nd Q","3rd Q","4th Q"] titles.forEach(title => new Folder(title, fldr.ending))
New Folder on iPad
omnifocus://localhost/omnijs-run?script=var%20fldr%20%3D%20new%20Folder%28%22Top%20Level%20Folder%22%2C%20library%2Ebeginning%29%0Avar%20titles%20%3D%20%5B%221st%20Level%22%2C%222nd%20Level%22%2C%223rd%20Level%22%2C%224th%20Level%22%5D%0Atitles%2EforEach%28title%20%3D%3E%20fldr%20%3D%20new%20Folder%28title%2C%20fldr%2Ebeginning%29%29
Creating a Folder Hierarchy
 

fldr = new Folder("Top Level Folder", library.beginning) titles = ["1st Level","2nd Level","3rd Level","4th Level"] titles.forEach(title => fldr = new Folder(title, fldr.beginning))
folder-hierarchy

An example script for creating a new top-level folder for each month of the year:

omnifocus://localhost/omnijs-run?script=try%7Bvar%20locale%20%3D%20%22en%2Dus%22%0Avar%20monthNames%20%3D%20%5B%5D%0Afor%20%28i%20%3D%200%3B%20i%20%3C%2012%3B%20i%2B%2B%29%20%7B%0A%09var%20objDate%20%3D%20new%20Date%28%29%0A%09objDate%2EsetDate%281%29%0A%09objDate%2EsetMonth%28i%29%0A%09monthName%20%3D%20objDate%2EtoLocaleString%28locale%2C%7Bmonth%3A%22long%22%7D%29%0A%09monthNames%2Epush%28monthName%29%0A%7D%0AfolderNames%20%3D%20folders%2Emap%28fldr%20%3D%3E%20%7Breturn%20fldr%2Ename%7D%29%0AmonthNames%2EforEach%28%28month%29%3D%3E%7B%0A%09if%28%21folderNames%2Eincludes%28month%29%29%7Bnew%20Folder%28month%29%7D%0A%7D%29%7Dcatch%28err%29%7Bconsole%2Elog%28err%29%7D
Folder for Each Month
 

locale = "en-us" monthNames = new Array() for (i = 0; i < 12; i++) { objDate = new Date() objDate.setDate(1) objDate.setMonth(i) monthName = objDate.toLocaleString(locale, {month:"long"}) monthNames.push(monthName) } folderNames = folders.map(fldr => fldr.name) monthNames.forEach(month => { if(!folderNames.includes(month)){new Folder(month)} })

Folder Instance Functions

Here are the functions that can be applied to instances of the Folder class:

For referencing specific folders within a folder hierarchy, use chained folderNamed() functions:

Folder Reference within a Folder Hierarchy


targetFolder = folderNamed("Top-Level").folderNamed("Secondary-Level").folderNamed("Third-Level")

Here’s a script that processes the net task of a specified project located within a specified top-level directory:

Next Task for Specified Folder Project


project = folderNamed("Fall Festival").projectNamed("Setup To-Do List") if(project){ task = project.nextTask // processing statements }

NOTE: The Finding Items section contains examples of using global search functions like foldersMatching(…) to locate items specified by the values of their properties.

Folder Hierarchy

Folders may contain projects and other folders. Contained folders may also contain folders and projects, and so on.

Here's a macOS-only function that will return the path string to the selected library item (folder or project), for example:

Top-Level Folder > Secondary-Level Folder > Third-Level Folder > Selected Project

Hierarchy Path for Selected Folder or Project


function pathToSelectedLibraryItem(){ if ( document.windows[0].perspective === Perspective.BuiltIn.Projects && document.windows[0].sidebar.selectedNodes.length === 1 ) { item = document.windows[0].sidebar.selectedNodes[0].object pathItems = [item.name] lvl = item.level if(lvl > 1){ do { item = item.parent lvl = item.level pathItems.unshift(item.object.name) } while (lvl > 1) } itemHeirarchy = pathItems.join(" > ") return itemHeirarchy } return null }

Sorting Folder Contents by Status

An example by Matt Johnson from the Omni Slack Channels demonstrating how to sort the projects of active folders by their status:

Sort Folder Projects by Status


activeFolders = flattenedFolders.filter( folder => folder.status == Folder.Status.Active ) activeFolders.forEach(fldr => { projs = fldr.projects.sort().sort((a, b) => { if (a.status < b.status) return 1; if (a.status > b.status) return -1; }) projs.forEach(project => { moveSections([project], fldr.beginning) }) })