A WordPress plugin that displays directory contents as a table using a shortcode. Supports recursive folder navigation, sub-documents, and markdown commentary.
- Display files from any server directory as a formatted table
- Recursive navigation - Browse subfolders with breadcrumb navigation
- Virtual "Current" folder - Show the latest documents across all subfolders
- Commentary.md - Display markdown content above file listings
- Annex folders - Automatically display related sub-documents inline
- Meta descriptions - Add descriptions to files via text files
- PDF files open in new tabs, all files have download buttons
- Copy the
docdisplayfolder to your WordPresswp-content/plugins/directory - Log in to WordPress admin
- Go to Plugins and activate Parish Document Display
- Go to Settings → Parish Document Display to configure the base directory path
Set the Base Directory Path to the absolute server path where your documents are stored.
Example: /var/www/html/wp-content/uploads/documents
The path must:
- Be an absolute server path (not a URL)
- Exist and be readable by the web server
- Be accessible via the web (within your site's document root)
[docdisplay path="subfolder"]
The path attribute is relative to the base directory configured in settings.
Enable folder navigation with breadcrumbs:
[docdisplay path="documents" recursive="true"]
When enabled:
- Subfolders appear as clickable buttons above the file table
- Breadcrumb navigation shows the current path
- Click any breadcrumb segment to navigate back
Show the latest documents from all subfolders in one view:
[docdisplay path="documents" recursive="true" show_current="true"]
When enabled:
- A "Current" button appears at the top of the subfolder list
- Clicking it shows the most recent documents across all subfolders
- Documents are sorted by modification date (newest first)
- Use
limitto control how many documents are shown (default: 10)
[docdisplay path="documents" recursive="true" show_current="true" limit="20"]
Direct embedding: Embed the "current" view directly by ending the path with /current:
[docdisplay path="documents/current" recursive="true" flatten="true" limit="20"]
This is useful for dedicated "latest documents" pages. The /current path requires flatten="true" to show a flat list of recent documents. An error is shown if a real folder named "current" exists at that location.
Show only files with a specific extension:
[docdisplay path="documents" include="pdf"]
Hide files with specific extensions (comma-separated):
[docdisplay path="documents" exclude="doc,docx,odt"]
Hide specific extensions from displayed filenames:
[docdisplay path="minutes" hide_extension="pdf,docx"]
This removes the extension from the displayed name while keeping the actual file intact.
Sort directories ascending or descending (default: desc):
[docdisplay path="documents" recursive="true" directory_sort="asc"]
Sort files by name or date, ascending or descending (default: name,desc):
[docdisplay path="documents" sort_by="name,asc"]
[docdisplay path="documents" sort_by="date,desc"]
Hide files matching a regex pattern (case-insensitive):
[docdisplay path="documents" exclude_pattern="compressed|draft"]
Display all files from all subdirectories in one flat table (requires recursive="true"):
[docdisplay path="documents" recursive="true" flatten="true"]
Enable pagination with a specified number of items per page:
[docdisplay path="documents" per_page="20"]
Show breadcrumb navigation:
[docdisplay path="documents" recursive="true" show_title="true"]
Show "No documents found" message when folder is empty:
[docdisplay path="documents" show_empty="true"]
Show empty directories in folder list (default: hidden):
[docdisplay path="documents" recursive="true" hide_empty_dirs="false"]
| Attribute | Values | Default | Description |
|---|---|---|---|
path |
string | "" |
Relative path from base directory |
recursive |
true/false | false | Enable subfolder navigation |
show_current |
true/false | false | Show "Current" button for latest docs |
limit |
number | 10 | Number of documents in Current view |
include |
extension | "" |
Only show files with this extension |
exclude |
ext,ext,... | "" |
Hide files with these extensions |
hide_extension |
ext,ext,... | "" |
Hide extensions from display names |
show_title |
true/false | false | Show breadcrumb navigation |
show_empty |
true/false | false | Show message when no files found |
directory_sort |
asc/desc | desc | Sort order for directories |
sort_by |
field,dir | name,desc | Sort files: "name,asc", "name,desc", "date,asc", "date,desc" |
hide_empty_dirs |
true/false | true | Hide empty directories |
exclude_pattern |
regex | "" |
Hide files matching regex pattern (case-insensitive) |
flatten |
true/false | false | Show all subdirectory files in one table (requires recursive) |
per_page |
number | 0 | Items per page; 0 = show all |
If your base path is /var/www/html/documents:
| Shortcode | Displays |
|---|---|
[docdisplay path=""] |
All files in base directory |
[docdisplay path="meetings"] |
Files in meetings folder |
[docdisplay path="policies" recursive="true"] |
Policies with subfolder navigation |
[docdisplay path="minutes" recursive="true" show_current="true"] |
Minutes with "Current" button |
[docdisplay path="minutes" hide_extension="pdf"] |
PDFs displayed without .pdf extension |
[docdisplay path="reports" exclude="doc,docx,odt"] |
All files except Word/ODT |
[docdisplay path="archive" recursive="true" flatten="true"] |
All files from all subfolders in one table |
[docdisplay path="reports" sort_by="date,desc" per_page="20"] |
Newest first, paginated |
[docdisplay path="docs" exclude_pattern="draft|compressed"] |
Hide files matching pattern |
The plugin displays a table with the following columns:
| Column | Description |
|---|---|
| File Name | The filename. PDFs are clickable links that open in a new browser tab |
| Document Date | The file's modification date |
| Download | A download button that forces the file to download |
| Description | Contents of the meta file (only shown if any meta files exist) |
If a folder contains a file named Commentary.md, its content is displayed above the file table. Supports basic markdown:
- Headers (
#,##,###) - Bold (
**text**) and italic (*text*) - Links (
[text](url)) - Unordered lists (
- item)
Create a folder named {filename}_annexes to add related documents that display inline below the main document.
Example:
documents/
annual-report.pdf
annual-report.pdf_annexes/ <- Annex folder (filename + _annexes)
appendix-a.pdf <- Displayed inline below annual-report.pdf
appendix-b.pdf
The annex files appear in a compact row with download icons, making it easy to access related documents. Annexes are also shown in the "Current" view.
To add a description for a file, create a text file named meta_{filename}.txt in the same directory.
Example:
For a file called annual-report.pdf, create meta_annual-report.pdf.txt containing:
Annual financial report for 2024
This text will appear in the Description column.
The plugin shows:
- PDF files (clickable links)
- Other document files (DOC, DOCX, XLS, etc.)
- Subfolders (when
recursive="true")
The plugin hides:
- Annex folders (
*_annexes) - displayed inline with their parent document - Files starting with
meta_ Commentary.mdfiles (rendered above the table)- Hidden files (starting with
.)
If your documents are stored outside the WordPress directory (e.g., mounted from another service like Nextcloud), you need to configure your reverse proxy to serve the files.
First, mount the document directory into the WordPress container (read-only):
# docker-compose.yml
services:
wordpress:
volumes:
- /path/to/documents:/var/www/html/wp-content/uploads/public-docs:roAdd a handle_path block to serve files from the external location:
example.com {
# Serve documents from external path
handle_path /wp-content/uploads/public-docs/* {
root * /path/to/documents
file_server
}
# ... rest of WordPress config
php_fastcgi localhost:9000 {
root /var/www/html
}
root * /path/to/wordpress
file_server
}
Caddy permissions: If your documents are outside the web root (e.g., Nextcloud data), Caddy needs read access:
# Add caddy to the file owner's group (e.g., www-data)
usermod -aG www-data caddy
# Ensure parent directories allow traversal (x permission)
chmod o+x /path/to/parent/directories
# Restart Caddy to pick up group membership
systemctl restart caddyAdd a location block:
server {
# Serve documents from external path
location /wp-content/uploads/public-docs/ {
alias /path/to/documents/;
autoindex off;
}
# ... rest of WordPress config
}After configuration changes:
- Caddy:
systemctl reload caddy - Nginx:
systemctl reload nginx
"Base path not configured" Go to Settings → Parish Document Display and set the base directory path.
"Directory not found or not readable"
- Check the path exists on the server
- Ensure the web server has read permissions for the directory
"Base directory not found or not readable"
- This appears when accessing
?docdisplay_path=current - Verify the shortcode path exists and is readable
Download links don't work
- Ensure the base directory is within your web root
- Check that files are accessible via the web server
Subfolders not appearing
- Ensure you're using
recursive="true"in the shortcode - Check that the folders are not named
{filename}_annexes(those are treated as annex folders) - Empty folders are hidden by default; use
hide_empty_dirs="false"to show them
"Current" button not showing
- Ensure you're using
show_current="true"in the shortcode - The button only appears at the root level, not in subfolders
- Path traversal attacks are blocked (no
..allowed in paths) - URL parameters are sanitized to prevent injection
- All output is escaped to prevent XSS
- Admin settings use WordPress nonces
The plugin checks GitHub for new releases and shows update notifications in the WordPress admin. Updates can be installed with one click from the Plugins page.
To create a new release:
- Update the version in
document-display.php(both the header andDOCDISPLAY_VERSIONconstant) - Commit and push changes
- Create a new release on GitHub with a tag (e.g.,
v1.8.0) - WordPress sites will detect the update within 12 hours (or immediately if they check for updates)
- WordPress 5.0 or higher
- PHP 7.0 or higher
- Updated README to match current plugin attributes and features
- See git log for full history since 1.8.0
Key additions since 1.8.0:
- Replaced
file_sortattribute withsort_by="field,direction"(supports name and date sorting) - Added
exclude_patternattribute for regex-based filename filtering - Added
flattenattribute to display all subdirectory files in one flat table - Added
per_pageattribute for pagination - Added direct
/currentpath embedding (e.g.path="documents/current") - Added REST API search handler for document link picker integration
- Added virtual "Current" folder showing latest documents across all subfolders
- Added
show_currentattribute to show/hide the Current button (default: false) - Added
limitattribute to control number of documents in Current view (default: 10) - Annexes now display in Current view
- Renamed "Published" column to "Document Date"
- Added
show_titleattribute for breadcrumb navigation - Added
show_emptyattribute to show message when no files found - Added
directory_sortattribute (asc/desc) - Added
hide_empty_dirsattribute to show/hide empty directories - Added
file_sortattribute (asc/desc) — later replaced bysort_by
- Changed
hide_extensionto accept comma-separated list of extensions to hide from display
- Support multiple extensions in exclude attribute (comma-separated)
- Display annex files one per line
- Added
exclude="ext"attribute to hide files with a specific extension
- Added
include="ext"attribute to filter files by extension - Added
hide_extension="true"attribute to hide extensions in display - Added automatic updates from GitHub releases
- Fixed Commentary.md rendering (replaced wpautop with custom parser)
- Subfolders now display as buttons above the file table (not inside it)
- Changed annex folder naming to
{filename}_annexesto avoid conflicts
- Added
recursive="true"attribute for subfolder navigation - Added breadcrumb navigation
- Added Commentary.md rendering (basic markdown support)
- Improved path sanitization for subpaths
- Added annex folder support (sub-documents displayed inline)
- Initial release with file table display and meta descriptions
Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
Free to use and modify for non-commercial purposes. See LICENSE for details.