good day dear folks
"Generating a Card in the FacetWP Listing Builder"
description: "A step-by-step guide on building a mini-catalog with WordPress, CPT-UI, ACF Pro, and FacetWP, focusing on card design, performance, and GDPR."
tags: "wordpress, facetwp, tutorial, webdev"
Hi there, good evening, dear friends,
How are you doing? Today, we're going to dive into generating a card in the FacetWP Listing Builder.
I currently want to build a mini-catalog website using:
- WordPress
- CPT-UI (for custom post types)
- ACF Pro (for custom fields)
- FacetWP (for filtering/search)
The Goal: I want to display ~300 catalog items as clean, professional cards, using ONLY public data (no personal info for GDPR safety).
Since I've been receiving lots of help on such WordPress postings, I want to ask here if somebody could help out!
So, here is the start... see below my current setup and the plan, with some ASCII images that I have created.
First Things First: Understanding FacetWP
First of all, as I am pretty new to FacetWP, here are some preliminary questions and assumptions:
a. FacetWP allows us to visually design how we search results (posts, products, etc.). That said:
b. All the data should appear on the WordPress site.
The core question is: how to generate a card using the FacetWP Listing Builder?
Which methods and techniques are used here? Which pitfalls are known and what approaches can you recommend?
Below, I have written down some thoughts, ideas, and some possible "approaches."
I look forward to hearing from you.
Greetings,
ps. See some of the things I already have, which are the conceptual basics. Now I have to find out how to operate all these things.
The Master Plan
A schematic view of the setup:
Week 1: Setup
├── Create CPT via CPT-UI
├── Add ACF fields
└── Import data (manually or via CSV)
Then: Design
├── Build basic card in FacetWP
├── Add grid layout
├── Style hover effects
└── Test on mobile
Then: Filters & Polish
├── Configure facets
├── Add facet labels
├── Test all combinations
└── GDPR/legal review
System Architecture & GDPR Safety
Here is a general overview of the card-creation process:
┌─────────────────────────────────────────────────────────┐
│ MINI-CATALOG SYSTEM ARCHITECTURE │
└─────────────────────────────────────────────────────────┘
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ DATA SOURCE │───▶│ STRUCTURE │───▶│ PRESENTATION │
│ (Source Data) │ │ (WordPress) │ │ (FacetWP) │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ Public Data │ │ Custom Post Type│ │ Listing Builder │
│ Source (e.g., │ │ "Catalog Items" │ │ Card Template │
│ EU Database) │ │ (via CPT-UI) │ ├─────────────────┤
├─────────────────┤ ├─────────────────┤ │ • Card Design │
│ SELECT ONLY: │ │ ACF Pro Fields: │ │ • Grid Layout │
│ ✓ Item Title │ │ • Title │ │ • Filters │
│ ✓ Country │ │ • Country │ │ • Search │
│ ✓ Category │ │ • Website │ └─────────────────┘
│ ✓ Technologies │ │ • Type │ │
│ ✓ Sector │ │ • Technologies │ ▼
│ ✓ Website │ │ • Sector │ ┌─────────────────┐
│ ✗ No Personal │ │ • Description │ │ FINAL OUTPUT │
│ Data │ └─────────────────┘ │ Mini-Catalog │
└─────────────────┘ │ │ Cards with: │
│ │ │ • Clean design │
▼ ▼ │ • Hover effects │
┌─────────────────────────────────────────────────────────┐ │ • 2-3 columns │
│ GDPR SAFE ZONE │ └─────────────────┘
│ ✓ No personal data stored │
│ ✓ Only institutional information │
│ ✓ Public data only │
│ ✓ Legal notice on website │
└─────────────────────────────────────────────────────────┘
Card Design Overview
Here are a few design options I'm considering:
| Option 1: Minimal | Option 2: With Icons | Option 3: Compact |
|---|---|---|
┌─────────────────┐ |
┌─────────────────┐ |
┌─────────────────┐ |
│ Item Name │ |
│ Item Name │ |
│ Item Name │ |
│ │ |
│ │ |
│ ┌─────────────┐ │ |
│ Type: Value │ |
│ Type: ● Value │ |
│ │ Type/Country│ │ |
│ Country: Value │ |
│ Country: DE │ |
│ └─────────────┘ │ |
│ │ |
│ Tech: Cloud │ |
│ │ |
│ [Details] │ |
│ [Details] │ |
│ [→] │ |
└─────────────────┘ |
└─────────────────┘ |
└─────────────────┘ |
Step-by-Step Card Building: My Approaches
Step 1: Outer Card
┌─────────────────────────────────┐
│ Padding: 20px │
│ Border: 1px solid #e5e5e5 │
│ Border-Radius: 8px │
│ Background: #ffffff │
└─────────────────────────────────┘
Step 2: Title
┌─────────────────────────────────┐
│ Title (clickable) │
│ Font: Large, Bold │
│ Margin-bottom: 10px │
└─────────────────────────────────┘
Step 3: Meta Area
┌─────────────────────────────────┐
│ Type: Example │
│ Technologies: Cloud, AI │ ← Font: Small
│ Sector: Health │ ← Color: #666
└─────────────────────────────────┘
Step 4: Button
┌─────────────────────────────────┐
│ [ View Item ] │ ← Border-Radius: 6px
└─────────────────────────────────┘
The Current Setup: A Summary
┌─────────────────────────────────────────────────────────┐
│ SYSTEM ARCHITECTURE │
├─────────────────────────────────────────────────────────┤
│ 1. Custom Post Type "Catalog Items" (CPT-UI) │
│ 2. ACF Fields: Title, Country, Type, │
│ Technologies, Sector, Website, Description │
│ 3. FacetWP Listing Builder for card design │
│ 4. Frontend: Filterable grid of cards │
└─────────────────────────────────────────────────────────┘
I've created the taxonomies in the Listing Builder. I think I can add lots of the above-mentioned data in these fields.
My To-Do List for the Card Design
I have to create the following things:
- Basic card with padding, border, border-radius
- Clickable title linked to single page
- Meta information in small gray text
- "View Item" button
- Grid layout with CSS
The Card Design I am aiming for:
┌─────────────────────────────────┐
│ [Item Title - clickable] │
├─────────────────────────────────┤
│ Type: Example Value │
│ Technologies: Cloud, AI, IoT │
│ Sector: Healthcare │
├─────────────────────────────────┤
│ [ View Item ] │
└─────────────────────────────────┘
The Game-Changing Advice I Received
The community provided some incredible insights. Here’s the corrected understanding and best practices.
The Core Concept: FacetWP's Role
My previous thinking was that FacetWP "builds" the card. The reality is that FacetWP delivers the data, and you tell it what to display.
My previous thinking: Corrected understanding:
┌─────────────────┐ ┌─────────────────┐
│ FacetWP │ │ FacetWP │
│ "builds" the │ │ delivers data │
│ card │ │ │
├─────────────────┤ ├─────────────────┤
│ That was too │ │ YOU tell it: │
│ optimistic │ │ "Show title, │
│ │ │ then ACF field X│
└─────────────────┘ │ then button" │
└─────────────────┘
│
▼
┌─────────────────┐
│ CSS formats │
│ everything into │
│ a proper card │
└─────────────────┘
The Golden Rule: Conditional Display
"Only show fields if they have values." This is GOLD for a clean design!
| Without condition check: | With condition check: |
|---|---|
┌─────────────────┐ |
┌─────────────────┐ |
│ Hub XYZ │ |
│ Hub XYZ │ |
│ Type: │ ← empty! |
│ Technologies: │ |
│ Technologies: │ |
│ Cloud, AI │ |
│ Cloud, AI │ |
│ Sector: Health │ |
│ Sector: Health │ |
└─────────────────┘ |
│ Website: │ ← empty! |
|
└─────────────────┘ |
In FacetWP Listing Builder: For each field, check "Show if not empty".
The Performance Tip Par Excellence: Pagination
Don't load all 300 at once!
| Bad practice: | Good practice: |
|---|---|
┌─────────────────┐ |
┌─────────────────┐ |
│ 300 Cards │ |
│ Page 1: 12 Cards│ |
│ → slow │ |
│ → fast │ |
│ → overwhelming │ |
│ → clear │ |
│ → mobile nightmare│ |
│ → "Load More" │ |
└─────────────────┘ |
│ or pager │ |
`└─────────────────┘`
FacetWP → Settings → Pager:
- [x] Enable pager
- Results per page: 12
- Pager style: (●) Numbers / ( ) Load more / ( ) Infinite scroll
Practical Implementation in FacetWP
Here’s how the logic translates into a card structure:
STEP 1: Base Structure (always visible)
┌─────────────────────────────────────┐
│ ⬛ TITLE (Post Title) │ ← always there
│ • Link: Post URL │
│ • Style: Large, Bold │
├─────────────────────────────────────┤
│ │
│ STEP 2: Conditional Fields │
│ ┌─────────────────────────────────┐ │
│ │ [SHOW ONLY IF NOT EMPTY] │ │
│ │ ⬛ Type ACF Field │ │
│ │ • Label: "Type: " │ │
│ │ • Condition: "Show if not empty"│
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ [SHOW ONLY IF NOT EMPTY] │ │
│ │ ⬛ Technologies ACF Field │ │
│ │ • Label: "Technologies: " │ │
│ │ • Condition: "Show if not empty"│
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ [SHOW ONLY IF NOT EMPTY] │ │
│ │ ⬛ Sector ACF Field │ │
│ │ • Label: "Sector: " │ │
│ │ • Condition: "Show if not empty"│
│ └─────────────────────────────────┘ │
├─────────────────────────────────────┤
│ ⬛ BUTTON │ ← always there
│ • Text: "View Details" │
│ • Link: Post URL │
└─────────────────────────────────────┘
The Result: From Cluttered to Clean
BEFORE (all fields, even empty ones):
┌─────────────────────────────────┐
│ Digital Hub Berlin │
│ Type: │ ← empty!
│ Technologies: Cloud, AI │
│ Sector: │ ← empty!
│ Website: │ ← empty!
│ [View Hub] │
└─────────────────────────────────┘
AFTER (only filled fields):
┌─────────────────────────────────┐
│ Digital Hub Berlin │
│ Technologies: Cloud, AI │
│ [View Hub] │
└─────────────────────────────────┘
→ MUCH cleaner!
The CSS: Making it a Real Grid
This CSS handles the grid, the card styling, and ensures equal heights (button always at the bottom).
/* Equal height cards with different content */
.facetwp-template {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
align-items: stretch; /* Critical for equal heights */
}
.catalog-card {
display: flex;
flex-direction: column;
height: 100%; /* Full height in grid */
padding: 20px;
border: 1px solid #e5e5e5;
border-radius: 8px;
background: #ffffff;
transition: all 0.3s ease;
}
.catalog-card:hover {
transform: translateY(-4px);
box-shadow: 0 10px 20px rgba(0,0,0,0.15);
}
.catalog-card .button {
margin-top: auto; /* Pushes button to the bottom */
align-self: flex-start;
padding: 8px 16px;
background: #0073aa;
color: white;
text-decoration: none;
border-radius: 4px;
border: none;
}
/* Meta information styling */
.card-meta {
font-size: 0.9em;
color: #666;
margin: 10px 0;
line-height: 1.6;
}
.card-meta p {
margin: 5px 0;
}
Responsive Behavior
The CSS handles this automatically with grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));.
| Desktop (3 cols): | Tablet (2 cols): | Mobile (1 col): |
|---|---|---|
┌───┬───┬───┐ |
┌───┬───┐ |
┌─────────┐ |
│ C │ C │ C │ |
│ C │ C │ |
│ C │ |
├───┼───┼───┤ |
├───┼───┤ |
├─────────┤ |
│ C │ C │ C │ |
│ C │ C │ |
│ C │ |
└───┴───┴───┘ |
└───┴───┘ |
└─────────┘ |
For fine-tuning on mobile:
@media (max-width: 768px) {
.facetwp-template {
gap: 16px; /* Smaller gap on mobile */
}
}
Accessibility Implementation
Ensure keyboard users can navigate your cards easily.
Keyboard Navigation:
[Tab] → [Hub Title] (focus)
↓
[Tab] → [View Button] (focus)
↓
[Enter] → Open link
Suggested HTML structure:
<a href="..." class="card-link" aria-label="View details for Hub Name">
Hub Name
</a>
... content ...
<a href="..." class="button" aria-label="View full details">
View Details
</a>
Implementation Checklist
- [ ] Listing Builder: Enable "Show if not empty" for all ACF fields.
- [ ] Pagination: Set to 12-24 items per page.
- [ ] CSS: Implement equal height cards (button always at bottom).
- [ ] Testing: Check cards with 1-2 fields vs. fully filled ones.
- [ ] Mobile: Test in Chrome DevTools for all screen sizes.
- [ ] Accessibility: Ensure keyboard navigation works.
- [ ] Performance: Monitor load time with 300+ items.
Bonus: Handling Empty States
What if ALL optional fields are empty?
┌─────────────────────────────────┐
│ Digital Hub Berlin │
│ [View Hub] │
└─────────────────────────────────┘
→ Still works! Clean and honest.
Summary & Key Takeaways
- FacetWP delivers data, you design the cards.
- Conditional display is crucial—only show what exists.
- Pagination is crucial—never overwhelm the user or the browser.
- CSS does the heavy lifting—grid, hover effects, and responsiveness.
Questions for the Community
I'm still looking for advice on:
- Grid Layout: 2 vs 3 columns on desktop? What's your experience?
- Hover Effects: Subtle vs noticeable? Any creative ideas?
- Empty Fields: How do you handle missing data elegantly?
- Performance: Best practices for ~300 items with filters?
- Accessibility: What should I consider for card interfaces?
- Responsive Design: How do your cards behave on mobile?
What's working well:
- FacetWP Listing Builder is intuitive for visual design.
- Clear separation (CPT for structure, ACF for data, FacetWP for display).
- No code needed for basic card layout.
Current challenges:
- Adding facet labels requires custom PHP.
- Ensuring consistent card heights.
- Mobile optimization.
- Performance with many filters.
I'd love to hear from you!
- How do you structure your ACF fields for catalog items?
- Any FacetWP tips/tricks you've discovered?
- What's your approach to card design in 2024?
- How do you handle GDPR when displaying third-party data?
Would love to see examples of your FacetWP projects and hear about what worked (or didn't)!
Thanks in advance!
Top comments (0)