Description
OmniDirectory is one flexible directory engine for searchable WordPress directories: staff, members, professionals, businesses, organizations and more. Every entry has a name, a photo, relabelable directory fields, Phone, Email, Bio, Website, a Directory Category and a profile page, shown in your choice of search and profile layouts. You adapt it to your use case by relabeling fields — no code required.
Use it as a staff, employee, team, member, professional, medical, business, school, church, nonprofit, multilingual or Arabic/RTL directory. These are uses of the same engine, not separate modes with industry-specific fields.
Search
Add the [omnidirectory_search] shortcode to any page for live AJAX search as visitors type. Search matches the entry’s name and Directory Category (developers can extend it with filters). Results are cached briefly, refreshed as soon as an entry changes, capped to a configurable limit, and protected by basic rate limiting.
Arabic, multilingual and RTL
Search normalizes common Arabic letter variants (forms of Alef, ta marbuta / ha, and similar), and every layout uses the correct dir="rtl" or dir="ltr". Directory entries and categories are registered as translatable for Polylang and WPML (wpml-config.xml included).
Layouts and fields
- Eight search-result layouts: Modern Grid Cards (default), Horizontal List Row, Avatar Badge Compact, Structured Table View, Masonry Grid, Horizontal Directory List, Compact Table Matrix, Interactive Hover Flip Cards.
- Eight profile layouts: Modern Centered Card (default), Two-Column Sidebar, Hero Banner Top, Tabbed Profile View, Minimalist Clean, Split Screen Cover, Interactive Dashboard, Floating Card Overlay.
- Field labels are relabeled from Settings (e.g. Specialty / Location / Phone, or Department / Office / Phone). Relabeling does not add new fields.
- Documents (PDF, DOC, DOCX, XLS, XLSX, TXT) can be attached to profiles with custom labels; the real file type is checked on upload. A gallery field stores and renders a shortcode you provide.
- Optional Click-to-Reveal masks a profile’s phone and email until clicked (the profile markup holds them only base64-encoded). A light deterrent against simple bots, not privacy or access control: a published entry’s contact details stay public, and its JSON-LD still lists them.
- Profiles include Schema.org
PersonJSON-LD (name, URL, photo, phone, email, website, bio, job title). Theomnidirectory_structured_datafilter ($schema, $post_id) can unsettelephone/email, or return an empty array for none.
CSV import and export
Export downloads every entry as CSV (Excel-friendly, with formula-injection protection). Import replaces the whole directory with the file’s content; it doesn’t edit entries in place.
- The whole file is validated first (header, every row, at most 1,000 rows); an invalid file changes nothing. Headers are matched automatically, including variants such as “Title” or “Phone Number”; unknown columns are ignored and new categories are created.
- New entries are staged privately in the background, then swapped in only when all are ready. Previous published entries go to Trash (restorable); unpublished entries that are not in the file, and scheduled entries, are kept. If a new entry cannot be given its status, it stays private and the entry it replaces is kept unchanged, together with all of that entry’s Polylang translations; this is listed with a warning. “Resume Import” continues a stalled import.
- Draft, pending and private entries keep their status, and password-protected entries keep their protection (passwords are never exported). A row whose status or protection cannot be kept safely is not imported and is listed with the reason. Files from 4.3.32 or earlier have no Status column: their rows keep the status of the existing entry with the same name, so re-export from this version before moving a directory to another site.
- Featured images are downloaded afterwards in the background (WordPress safe HTTP, limited retries); a failed image never fails the import.
- The uploaded file is kept in
uploads/omnidirectory-imports/only until the import ends. Apache blocks it via.htaccess; on Nginx, deny that path.
Polylang: each entry is imported in the language from its Language Code column, and entries sharing a Translation Group value (last export column) are linked again as translations — only when the whole group was imported, one entry per language; otherwise a warning is shown. A file with a Language Code that is not a language of the site is refused before anything changes. Files without a Translation Group column are never linked automatically, not even by name. Translation Group values change after each import (entries are new posts).
Without Polylang (including WPML): a file with any Language Code or Translation Group value is refused before anything changes; empty columns import as before. WPML is not supported for these two columns.
Screenshots



Installation
- Install from Plugins Add New (search “OmniDirectory”), or upload the zip under Plugins Add New Upload Plugin, then activate.
- Go to Directory Members Directory Settings to set field labels, layouts and colors.
- Add entries under Directory Members Add New, or import them under Directory Members Import / Export.
- Place
[omnidirectory_search]on any page.
FAQ
-
Which kinds of directory can I build?
-
Staff, member, employee, professional, medical, business, school or other directories of people or listings, by relabeling the built-in fields and choosing layouts. There are no industry-specific fields (for example for courses or departments).
-
Does it support Polylang and WPML?
-
Both can translate entries and categories. CSV import keeps languages and translation links with Polylang only; see “CSV import and export” for WPML.
-
Can I add unlimited custom fields?
-
No. You can relabel the existing fields, but this plugin does not add new ones.
-
Does CSV import update existing entries?
-
No. It replaces the directory with the file’s content; previous published entries go to Trash (unpublished entries not in the file and scheduled entries are kept).
-
Is there a Gutenberg block?
-
No. Use the
[omnidirectory_search]shortcode (also in the Shortcode block). -
What is it not designed for?
-
Membership management (registration, logins, gated content), marketplaces or e-commerce, bookings, reviews/ratings and affiliate features.
-
My site is behind a reverse proxy or CDN. Does rate limiting still work?
-
Limits use
REMOTE_ADDR. Behind a proxy, return the real visitor IP with theomnidirectory_client_ipfilter (only from a header your proxy sets). Limits can be changed withomnidirectory_rate_limits. -
Can other plugins add CSV export columns?
-
Yes, with the
omnidirectory_csv_export_columnsandomnidirectory_csv_export_valuefilters. Extra columns come after this plugin’s columns and cannot change them.
Reviews
Contributors & Developers
“OmniDirectory – Directory & Listings” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “OmniDirectory – Directory & Listings” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
4.3.33
- Fix: live search and the profile language switcher recover from expired nonces on cached pages (new
omni_refresh_noncesaction). - Fix: search rate limit no longer blocks steady searching below the limit, cannot be exceeded in parallel or bypassed by changing the User-Agent; the language-switcher action is rate limited too.
- Fix: CSV import keeps draft, pending, private and password-protected members unpublished/protected, and no longer duplicates them on re-import. Exports add Status and Password Protected columns. A previous member that cannot be moved to Trash, or a new member whose status cannot be set, no longer stalls the import; it is listed with a warning, and the member it would replace is kept.
- Fix (Polylang): CSV import applies each Language Code and links translations again (new Translation Group column). Files with unknown languages, or with language data on sites without Polylang, are refused before anything changes.
- Fix (Polylang): Directory Members list counts (All, Published, Trash and others) now match the members listed for the selected admin language.
- Fix: names are exported exactly as stored; Security: CSV cells are protected against formula injection.
- Security: password-protected members and unpublished translations are no longer shown on profiles, in structured data or through AJAX; click-to-reveal only opens phone and email links; CSV files use standard quoting, so a value with a backslash can no longer break out of its cell or merge rows on re-import. A failed row keeps the member it would replace. Documents only accept media the editor may view. A field label can’t hide Status or another fixed CSV column. Uploaded import files are deleted when the import ends.
- Added
omnidirectory_csv_export_columns,omnidirectory_csv_export_value,omnidirectory_rate_limitsandomnidirectory_client_ipfilters. - Full details: see
changelog.txt.
4.3.32
- Broader plugin name and description (adaptable directory and listings). No functional changes.
- Added extension points for companion plugins:
omnidirectory_single_profile_extra_fields,omnidirectory_csv_import_aliases,omnidirectory_csv_row_meta_input,omnidirectory_profile_data_fields.
Older versions and full details: see changelog.txt.
