considbrs-webdev / modularity-folder-browser
An accessible file and folder browser module for Modularity.
Package info
github.com/Considbrs-Webdev/modularity-folder-browser
Type:wordpress-plugin
pkg:composer/considbrs-webdev/modularity-folder-browser
Suggests
- helsingborg-stad/municipio: ^6.0.0
README
An accessible Modularity module for exposing selected server folders as a public document browser. Editors choose one or more folders from configured safe filesystem sources, visitors can browse nested folders, and allowed files can be downloaded without exposing real filesystem paths.
Features
- Select one or more start folders from configured filesystem sources
- Optional top folder name to group selected folders on the frontend
- Modal folder picker with lazy-loaded expandable folder trees and checkbox selection
- Accessible disclosure/list interface using real buttons and links
- Lazy-loaded subfolders through WordPress REST endpoints
- Public download endpoint with server-side path and extension validation
- Optional file type, file description, file size, and modified date display
- Natural sorting by name, date, or file type
- Hidden files, traversal attempts, and unsafe file extensions are blocked
- Source paths stay in code and are never rendered in HTML or JSON
- Default file support includes common office documents, text files, images, archives, video, and audio
Configuration
Sources must be configured by code. Use either the MODULARITY_FILE_BROWSER_SOURCES constant or the Modularity/Module/FolderBrowser/Sources filter.
define('MODULARITY_FILE_BROWSER_SOURCES', [ 'public-documents' => [ 'label' => 'Public documents', 'path' => '/srv/shared/public-documents', ], ]);
Each source path must be absolute, readable by the web server user, and resolvable with realpath(). Invalid sources are ignored.
Module Fields
- Top folder name
- Start folders
- Source
- Selected folders
- Initially expanded
- Show file type
- Show file description
- Show file size
- Show modified date
- Download display
- Sort order
- Allowed file types override
Selected folders are stored only as relative paths inside the selected source. The admin folder picker uses an authenticated REST endpoint and never shows absolute paths.
The allowed file types override field can only narrow the globally allowed extensions. Use the Modularity/Module/FolderBrowser/AllowedFileTypes filter to change the global list.
REST Endpoints
GET /wp-json/modularity-file-browser/v1/admin/folders?source=public-documents&path=policiesGET /wp-json/modularity-file-browser/v1/modules/{module_id}/roots/{root_index}/tree?path=optional/subfolderGET /wp-json/modularity-file-browser/v1/download?module_id=123&root=0&path=file.pdf
The admin endpoint requires edit_posts. Public tree and download endpoints revalidate the stored module configuration, selected root, requested relative path, and file extension on every request.
Inline Gutenberg module instances do not have a persisted module ID. Those rendered instances use module_id=0 with an opaque instance_token query parameter. The token resolves to server-side transient configuration and does not expose absolute source paths in the DOM or REST payload.
Filters
Modularity/Module/FolderBrowser/Sources
Add or change available filesystem sources.
add_filter('Modularity/Module/FolderBrowser/Sources', function (array $sources): array { $sources['meeting-documents'] = [ 'label' => 'Meeting documents', 'path' => '/srv/shared/meeting-documents', ]; return $sources; });
Modularity/Module/FolderBrowser/AllowedFileTypes
Restrict or extend the global file extension allowlist. The filter receives the plugin defaults and the current module ID, so it can be used to add file types, remove file types, or replace the whole list. Server-side executable extensions remain blocked even if they are added here.
add_filter('Modularity/Module/FolderBrowser/AllowedFileTypes', function (array $extensions): array { $extensions[] = 'heic'; return array_values(array_unique($extensions)); });
add_filter('Modularity/Module/FolderBrowser/AllowedFileTypes', function (array $extensions): array { return array_values(array_diff($extensions, ['zip', 'rar', '7z', 'tar', 'gz'])); });
add_filter('Modularity/Module/FolderBrowser/AllowedFileTypes', function (array $extensions, ?int $moduleId): array { if ($moduleId === 123) { return ['pdf', 'docx', 'xlsx']; } return $extensions; }, 10, 2);
Default allowed extensions:
pdf, doc, docx, odt, rtf, xls, xlsx, ods, ppt, pptx, odp, txt, md, csv, jpg, jpeg, png, gif, webp, zip, rar, gz, 7z, tar, mp4, m4v, mov, avi, webm, mkv, wmv, mpeg, mpg, 3gp, ogv, mp3, wav, ogg, oga, m4a, aac, flac, wma, aiff, aif, opus
Modularity/Module/FolderBrowser/FileIcon
Override the icon URL for a file extension or icon category.
add_filter('Modularity/Module/FolderBrowser/FileIcon', function (string $url, string $extension, string $category): string { if ($category === 'archive') { return get_stylesheet_directory_uri() . '/assets/icons/archive.svg'; } return $url; }, 10, 3);
Modularity/Module/FolderBrowser/FolderIcon
Override the folder icon URL.
add_filter('Modularity/Module/FolderBrowser/FolderIcon', function (string $url): string { return get_stylesheet_directory_uri() . '/assets/icons/folder.svg'; });
Modularity/Module/FolderBrowser/DownloadIcon
Override the download icon URL.
add_filter('Modularity/Module/FolderBrowser/DownloadIcon', function (string $url): string { return get_stylesheet_directory_uri() . '/assets/icons/download.svg'; });
Modularity/Module/FolderBrowser/CacheTTL
Change directory listing cache duration.
add_filter('Modularity/Module/FolderBrowser/CacheTTL', function (): int { return 5 * MINUTE_IN_SECONDS; });
Modularity/Module/FolderBrowser/InstanceToken/CacheTTL
Change how long inline Gutenberg instance tokens remain valid. Defaults to one day.
add_filter('Modularity/Module/FolderBrowser/InstanceToken/CacheTTL', function (): int { return DAY_IN_SECONDS; });
Development
composer install npm install npm run build
Requirements
- WordPress
- Modularity
- Advanced Custom Fields Pro
- Municipio/component library for Blade rendering
License
MIT