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.