Recipe: Team / Staff Directory

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.