OmniDirectory – Directory & Listings
OmniDirectory – Directory & Listings

OmniDirectory – Directory & Listings

5/5 (2 ratings) — active installs Updated Nov 8, 2026
Live search results in the default Modern Grid Cards layout.

Live search results in the default Modern Grid Cards layout.

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.

Add a directory to any page with the [omnidirectory_search] shortcode or with four Gutenberg blocks: Directory Search, Directory Category List, Directory Listings and Member Card.

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, or the Directory Search block, 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). Only published entries that are not password-protected are listed. Results are cached briefly, refreshed as soon as an entry changes, capped to a configurable limit, and protected by basic rate limiting.

Gutenberg blocks

Four blocks in the “OmniDirectory” block category. They need WordPress 6.0 or later.

  • Directory Search — the live search of [omnidirectory_search], with the same search box and results.
  • Directory Category List — your directory categories as links to each category’s page, as a list or a grid.
  • Directory Listings — a paginated list of published members in your result layouts.
  • Member Card — one published member’s photo, name, first two profile fields, categories and a link to the full profile. Phone and email are never shown on the card.

Live search (the shortcode and the Directory Search block), Directory Listings and Member Card show only published members that are not password-protected. Search filters added by other plugins use their own queries and are not covered. Each block’s settings are described under “Using the blocks” below.

Each Directory Listings block pages on its own: moving one list to page 2 keeps every other list on the page where it is. This also applies to lists inside synced patterns in your posts and pages, and to lists in template parts and block widgets. Page links are plain links (they work without JavaScript), and each combination of pages has its own URL, so it can be bookmarked. See the FAQ for bookmarks, synced patterns and page caching.

The shortcode is still supported

The [omnidirectory_search] shortcode keeps working as before, with the same output and attributes, so existing pages need no change. You can keep using it, use the blocks, or use both on the same site.

On a single page, the combination that has been tested is several Directory Search blocks together with an [omnidirectory_search] shortcode: each of them searches on its own. Other blocks on the same page as the shortcode have not been specifically tested.

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).

With Polylang, the Directory Category List, Directory Listings and Member Card blocks show the categories and members of the page’s language; Directory Search searches exactly as the shortcode does. The blocks have not been tested with WPML.

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 Person JSON-LD (name, URL, photo, phone, email, website, bio, job title). The omnidirectory_structured_data filter ($schema, $post_id) can unset telephone/email, or return an empty array for none.

CSV import and export

Export downloads every entry as CSV. A cell that a spreadsheet could read as a formula (starting with = + – @, a tab, carriage return or line feed, or their full-width forms = + - @, also after spaces) gets a leading apostrophe, which import removes again. Phone numbers such as +46 70 123 45 67 and plain numbers are left as they are. Spreadsheets may show the apostrophe, and a file edited and saved again in a spreadsheet may lose it. 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, and draft, pending or private entries whose name matches a row, go to Trash, where they can be restored until WordPress empties it. If Trash is turned off on the site (EMPTY_TRASH_DAYS is 0), they are permanently deleted and cannot be restored. The upload must be confirmed. The confirmation states that up to a given number of published entries, and every draft, pending or private entry whose name matches a row, will be replaced, and, when Trash is turned off, that they will be permanently deleted. With Trash turned off, the import then stops before it changes the directory and lists the entries it would delete permanently, in parts of at most 10,000; it deletes only entries on a list an administrator approved, unchanged since then, contents included, and stops to ask again before any other. If Trash is turned off after the upload, the import pauses before it deletes any previous entry permanently, and continues only after an administrator confirms the permanent deletion or Trash is turned on again. Before it finishes, it checks again and goes back if entries were published, renamed or changed while it was finishing, up to three times; then it stops and asks whether to continue or to finish, and lists the entries it did not replace. Entries added or changed after its final check are kept; 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 stored in uploads/omnidirectory-imports/ under a random name. It is deleted as soon as its rows are staged, or when the import fails or is cancelled (“Cancel Import”). An import still staging that has made no progress for 24 hours is ended, and its file deleted, the next time WP-Cron runs or an administrator opens the Import page or uploads a file. On a site with little traffic or without WP-Cron, this can be later. While the file exists, the web server must block that folder. PHP cannot do this on Nginx, and the plugin cannot stop Nginx from listing or serving the folder without a deny rule. The file’s name is kept out of error messages and logs. Tested: Apache 2.4 with AllowOverride All, which honours the plugin’s .htaccess; Nginx 1.24 with location ^~ /wp-content/uploads/omnidirectory-imports/ { deny all; return 404; }. Other servers were not tested.

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.