Folderline documentation1.x
Developers

Hooks and REST API

The PHP filters and actions, the JavaScript hooks for the folder tree, and the folderline/v1 REST API.

Folderline stores folders as terms of a private, hierarchical taxonomy, folderline_folder, on attachments. A file is in at most one folder. A folder's position among its siblings is the folderline_order term meta. Everything below is how add-ons (Folderline Pro is built on these) and your own code work with that.

Which post types get folders

Hook What it's for
folderline_post_types (filter) The post types that get folders, each with its own tree. Default [ 'attachment' ]; attachment is always kept. Folderline itself only brings screens for the Media Library: an add-on that adds a post type brings its screen too.
folderline_taxonomy_args (filter) register_taxonomy() arguments for a post type's folders ($args, $post_type). The taxonomy is folderline_folder for attachments and folderline_{post_type} for others.
folderline_registered_taxonomy (action) After a post type's folder taxonomy is registered ($taxonomy, $post_type), on init.

Extendiment\Folderline\Taxonomy::name( $post_type ) gives a post type's taxonomy, and Taxonomy::supports( $post_type ) whether it has folders.

Folders and permissions

Hook What it's for
folderline_can_manage (filter) Whether the current user may see and use a post type's folders ($can, $post_type). Default: upload_files for the Media Library, the post type's edit_posts capability for others.
folderline_can_edit_folder (filter) Whether the current user may rename, move or delete a folder, create subfolders in it or put files in it ($can, $folder_id, $post_type).
folderline_hold_back_private_folders (filter) Whether Folderline hides, and keeps unchanged, the folders that Folderline Pro's per-user folders keep private to another person (term meta folderline_pro_owner), while Folderline Pro isn't active. Default true; Folderline Pro returns false and applies per-user folders itself.
folderline_folder_query_args (filter) The get_terms() arguments for the folders shown in a tree ($args, $post_type), e.g. to show each person only some folders.
folderline_folder_data (filter) One folder's data for the panel ($data, $term, $post_type): id, parent, name, count, editable. Add keys of your own; the panel's JavaScript gets them.
folderline_tree (filter) The whole tree sent to the panel and the folder filters ($tree, $post_type): postType, folders, total, unsorted.

Changes

Actions after each change: folderline_folder_created ($id, $post_type, $parent), folderline_folder_renamed ($id, $post_type, $name), folderline_folder_moved ($id, $post_type, $parent, $old_parent), folderline_before_delete_folders and folderline_folders_deleted ($ids, $post_type), and folderline_assigned ($ids, $folder, $post_type; folder 0 is Unsorted).

To make changes from code, use Extendiment\Folderline\Folders: create( $post_type, $name, $parent ), rename(), delete( $post_type, $id, 'delete' | 'lift' ), move( $post_type, $id, $parent, $index ), assign( $post_type, $ids, $folder ), folder_of( $id, $post_type ) and tree( $post_type ). They run the same checks as the screens and return a WP_Error when something isn't allowed. delete() checks everything before it changes anything: a WP_Error means the folder is still there, and deleted lists only the folders actually deleted.

// Put every PDF uploaded by a form plugin into a "Documents" folder.
add_filter( 'folderline_upload_folder', function ( $folder, $attachment_id ) {
	if ( 'application/pdf' === get_post_mime_type( $attachment_id ) ) {
		$term = get_term_by( 'name', 'Documents', 'folderline_folder' );
		return $term ? $term->term_id : $folder;
	}
	return $folder;
}, 10, 2 );

Media Library

Hook What it's for
folderline_upload_folder (filter) The folder a new upload goes into ($folder, $attachment_id, $requested; 0 for none).
folderline_media_query_args (filter) The media grid's and media pickers' WP_Query arguments after the folder filter is applied ($args, $props).
folderline_screen_config (filter) The folder panel's configuration on a screen (window.folderlineScreen).
folderline_script_config (filter) Settings every Folderline script gets (window.folderlineConfig).
folderline_enqueue_panel (action) The panel was put on a screen ($post_type, $mode): enqueue your script here with folderline-screen as a dependency.
folderline_settings (action) Media → Folder Settings is being set up: add Settings API sections and fields to the folderline page.
folderline_settings_after (action) Prints after the settings form.
folderline_loaded (action) Fires on plugins_loaded once Folderline has loaded. Add-ons start here; FOLDERLINE_VERSION is defined.

The folder tree's JavaScript

window.folderline has the API client (api( path, options )), the per-post-type folder store( postType ) with create(), rename(), remove(), move(), assign() and refresh(), the Tree, a dialog() and a menu(). On a screen with the panel, folderline.screen has the store, the tree, select( value ) and moveItems( ids, folder ).

Add your hooks with wp.hooks, in a script that depends on folderline-screen, and namespace them:

Hook Arguments What it's for
folderline.menuItems (filter) items, folder, tree A folder's menu: add { id, label, icon, action } items.
folderline.folderRow (action) row, folder, tree After a folder's row is drawn, e.g. to colour its icon from your own folder data.
folderline.treeDrawn (action) tree After the tree is drawn.
folderline.selected (action) value, tree A folder ('all', 'none' or an ID) was opened.
folderline.panelHead / folderline.panelFoot (filter) nodes, screen Controls in the panel's header and footer.
folderline.gridProps (filter) props, screen The media grid's query props for the open folder.
folderline.listArgs (filter) args, screen The URL arguments for the open folder on a list screen.
folderline.ready (action) screen The panel is up.
// A "Copy folder ID" item in every folder's menu.
wp.hooks.addFilter( 'folderline.menuItems', 'my-plugin', ( items, folder ) => items.concat( {
	id: 'copy-id',
	label: 'Copy folder ID',
	icon: 'clipboard',
	action: () => navigator.clipboard.writeText( String( folder.id ) ),
} ) );

REST API

folderline/v1, for logged-in users with folderline_can_manage for the post type (every route takes post_type, default attachment). Changes answer with the new tree as tree.

Route What it does
GET /folders The tree.
POST /folders Create (name, parent).
POST /folders/{id} Rename (name).
DELETE /folders/{id} Delete (children: delete or lift).
POST /folders/{id}/move Move (parent, index).
POST /assign Put files in a folder (ids, folder; 0 for Unsorted). Answers with moved and skipped.
POST /state Save the panel's state for the current user.

folderline_rest_routes (action, $namespace, $controller) is the place to add routes to the same namespace.