Recipe: Team / Staff Directory

TableCrafter table builder, connect Gravity Forms, Google Sheets, Airtable, CSV, or JSON data sources
TableCrafter table builder, connect Gravity Forms, Google Sheets, Airtable, CSV, or JSON data sources

Turn a single CSV file or Google Sheet into a live, searchable staff directory with circular avatar thumbnails. TableCrafter auto-detects image URLs in any cell and renders them as zoomable photos, so a directory needs no custom code, just one [tablecrafter] shortcode.

CSV / Google Sheets Image column Search & filters Column ordering No-code

What you'll build

A people directory rendered from a spreadsheet where one column holds a photo URL. The finished table shows an avatar thumbnail per person, a global search box, per-column filters (e.g. by Department or Status), and clickable email links, all from a few CSV columns. Because TableCrafter reads the sheet live, HR can update the directory by editing a Google Sheet, no WordPress login required.

ℹ️

TableCrafter does not have a dedicated "image column" attribute. Instead, the renderer inspects every cell value: anything that looks like an image URL is automatically converted to an <img> tag. This recipe is built entirely on that real auto-detection behavior, no extra column type to configure.

Step 1, Prepare the spreadsheet

Create a sheet (or CSV) with one row per person. Add a column whose cells contain full image URLs ending in a supported extension. The server-side renderer accepts .jpg, .jpeg, .png, .gif, .webp, and .bmp (SVG is intentionally rejected for security). A realistic layout:

# team.csv
Photo,Name,Role,Department,Email,Status,Join Date
https://cdn.example.com/staff/sconnor.jpg,Sarah Connor,Project Manager,Operations,sarah@example.com,Active,2023-01-15
https://cdn.example.com/staff/jsmith.png,John Smith,Lead Developer,Engineering,john@example.com,Active,2022-11-20
https://cdn.example.com/staff/echen.jpg,Emily Chen,UX Designer,Design,emily@example.com,On Leave,2023-03-10
https://cdn.example.com/staff/mbrown.webp,Michael Brown,DevOps Engineer,Engineering,mike@example.com,Active,2023-05-01

Several columns get smart formatting for free once TableCrafter recognizes their values:

Cell contentRendered as
URL ending in .jpg/.png/.webp etc.Avatar <img class="tc-cell-image"> (lazy-loaded)
A valid email addressmailto: link
An ISO date like 2023-01-15<time> formatted as "Jan 15, 2023"
true / falseA green "Yes" / "No" badge
Any other http(s) URLTruncated link opening in a new tab

Step 2, Publish the data source

TableCrafter fetches the data over HTTP, so the file needs a public URL. Two common options:

💡

Host the avatar images somewhere stable (the WordPress Media Library works well). Use the same height-to-width ratio for every photo so the thumbnails line up cleanly in the column.

Step 3, Add the directory shortcode

Drop this into any page or post. It is a complete, working example using only real attributes:

[tablecrafter source="https://cdn.example.com/team.csv"
             include="Photo,Name,Role,Department,Email,Status"
             search="true"
             filters="true"
             sort="Name:asc"
             per_page="25"]

What each attribute does here:

Attribute reference

These are the shortcode attributes most relevant to a directory. Names are case-sensitive and match the column headers in your sheet.

AttributeDefaultDescription
source(empty)Required URL of the CSV file or published Google Sheet.
include(all)Optional Comma-separated column names to show; also sets column order.
exclude(none)Optional Comma-separated columns to hide (e.g. an internal ID).
searchfalseOptional Show a global search box. Accepts true/false.
filterstrueOptional Auto-generate per-column filters (great for Department / Status).
sort(none)Optional Initial sort as column:direction, e.g. Name:asc.
per_page0Optional Rows per page; 0 disables pagination.
exportfalseOptional Show export controls (CSV / XLSX / PDF).
id(auto)Optional Custom container ID for targeting with CSS/JS.
root(empty)Optional Dot-path to the data array (JSON sources only; not needed for CSV).
ℹ️

For a flat CSV or Sheet you never need root, that attribute is for digging into nested JSON API responses. A directory built from a spreadsheet uses source plus include and is done.

Step 4, Style the avatars

Every auto-detected photo is wrapped in <img class="tc-cell-image">. The bundled stylesheet already gives these thumbnails a small footprint, rounded corners, and a hover-to-zoom effect, so a directory looks polished out of the box:

/* shipped defaults for .tc-cell-image */
.tc-cell-image {
  max-height: 50px;
  border-radius: 4px;
  cursor: zoom-in;        /* hover scales the avatar up */
}

To make the photos perfectly circular like classic profile avatars, add this to your theme's Additional CSS (target your own container id if you set one):

.tablecrafter-container .tc-cell-image {
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: 50%;
}
💡

Hovering an avatar enlarges it (a built-in transform: scale(2.5) with a soft shadow), giving visitors a quick close-up of each photo without a separate lightbox.

Variations

How the image detection works

Understanding the rule helps you avoid surprises. On first render TableCrafter builds the table server-side, and for each cell it checks, in order: is this a boolean, an image URL, an email, an ISO date, or a plain URL? A value passes the image test when it ends in a supported raster extension (or is a data:image/...;base64 string). Matching values become a lazy-loaded <img>; everything else falls through to the next check and is finally HTML-escaped. The frontend script applies the same logic during live updates, additionally requiring an http/https prefix before it will render a remote image.

⚠️

SVG avatars are rejected on purpose to prevent script injection, and so are javascript: / non-image data: URLs. If a photo cell shows the raw URL text instead of an image, confirm the link ends in .jpg/.png/.webp (etc.) and is reachable over HTTPS.

Troubleshooting

SymptomLikely cause & fix
Photo shows as a link, not an imageThe cell value doesn't end in a supported extension, or it's an SVG. Use a direct .jpg/.png/.webp URL.
Column missing from the tableThe name in include/exclude must match the sheet header exactly, including spaces and capitalization.
Edits to the sheet don't appearOutput is cached (stale-while-revalidate). It refreshes within a few minutes; clear site/page caches to force it sooner.
"Unable to load data" messageThe source URL isn't publicly reachable. Re-publish the Google Sheet to the web, or verify the CSV is served over HTTPS.

To experiment first, the bundled sample at WP Admin → TableCrafter ships an "Employee List (CSV)" demo you can point a shortcode at before wiring up your own sheet.

Next steps

Add download buttons to your roster with export-data.html, or learn the full source-URL rules for live spreadsheets in google-sheets-source.html.