Preface
Welcome back to the cutting edge of web development! In our first two guides, we explored the philosophy of Vibe Coding and assembled our AI-powered arsenal of tools. You understand the ‘what,’ the ‘why,’ and the ‘with what.’ Now, it’s time for the most exciting part: doing. Theory is essential, but true understanding is forged in the fires of creation. This guide is where the rubber meets the road.
Introduction
This isn’t another abstract discussion. This is a step-by-step, practical walkthrough where you and I will build a real-world feature for a WordPress website entirely through vibe coding. We will go from a simple idea to a fully functional, styled, and interactive component. You will see firsthand how the workflow we’ve discussedāthe fluid dance between a conversational AI and an in-editor assistantācomes to life.
Our project will be to create a “Meet Our Team” showcase. This is a common requirement for business websites, making it the perfect practical example. We will touch on PHP for the backend logic, HTML for the structure, CSS for the styling, and a sprinkle of JavaScript for interactivity. Don’t worry if you’re not an expert in these languages! That’s the beauty of vibe coding. Your primary skill will be directing the AI.
By the end of this tutorial, you will have not only built a tangible feature but also gained the confidence and the core workflow to tackle your own AI-assisted projects. Let’s roll up our sleeves and start making something amazing.
Chapter 1: The Project & Our Setup
Before we write our first prompt, let’s define our goals and prepare our digital workshop.
The Project Goal: A “Team Showcase” Section
Our objective is to build a showcase for a company’s team members. It needs to be professional, dynamic, and easy for a client to update. Here’s the plan:
- Create a “Team Members” Custom Post Type (CPT) in WordPress. This will give us a dedicated section in the WordPress admin for adding team members, complete with their name, photo, title, and biography. This is far better than using standard pages or posts.
- Build a Front-End Display Grid. We will create a page template that fetches all the team members and displays them in a clean, responsive grid of profile cards.
- Style the Profile Cards. We’ll use CSS to make the cards look professional, with hover effects to make them engaging.
- Add Interactivity. We’ll add a simple JavaScript feature: when a user clicks a card, a modal window (a popup) will appear with the team member’s full biography.
Our Vibe Coding Toolkit for This Project
We’ll use the ‘WordPress Freelancer’ workflow we defined in our previous article.
- Code Editor: Visual Studio Code (VS Code).
- AI Assistant: GitHub Copilot. We’ll have this installed and running in VS Code.
- Conversational AI: ChatGPT or Claude. We’ll have this open in a browser tab for our high-level planning and scaffolding.
- Environment: A local or live WordPress installation. If you’re starting fresh, setting up on a host like Hostgator is a quick process.
- Theme: A simple, flexible theme like Astra will work perfectly.
Important: For this tutorial, we will be adding code directly to our theme’s functions.php and style.css files. In a real-world production site, it is best practice to use a Child Theme for these modifications. This prevents your custom code from being erased when you update the parent theme.
Chapter 2: The Foundation – Prompting a Custom Post Type
Our first step is to create the backend structure. We need to tell WordPress about our new “Team Members” content type. This is a perfect task for a high-level conversational AI because it involves generating a significant, self-contained block of boilerplate code.
Let’s open ChatGPT or your conversational AI of choice and craft our first prompt.
Your Prompt:
Act as a senior WordPress developer who strictly follows the WordPress Coding Standards. Generate the PHP code to register a new Custom Post Type called 'Team Member'.
The post type should:
– Be named ‘team_member’ internally.
– Have public-facing labels like ‘Team Members’ (plural) and ‘Team Member’ (singular).
– Support a title (for the name), editor (for the bio), and featured image (for the photo).
– Have a custom icon in the admin menu. Use the ‘dashicons-groups’ icon.
– Be public and have an archive page.
Wrap this all in a function called ‘smw_register_team_member_cpt’ and hook it to ‘init’.
AI-Generated Code:
The AI will process this and give you a beautiful, complete block of code. It should look very similar to this:
/**
* Register a custom post type for Team Members.
*/
function smw_register_team_member_cpt() {
code
Code
$labels = array(
'name' => _x( 'Team Members', 'Post Type General Name', 'text_domain' ),
'singular_name' => _x( 'Team Member', 'Post Type Singular Name', 'text_domain' ),
'menu_name' => __( 'Team Members', 'text_domain' ),
'name_admin_bar' => __( 'Team Member', 'text_domain' ),
'archives' => __( 'Team Member Archives', 'text_domain' ),
'attributes' => __( 'Team Member Attributes', 'text_domain' ),
'parent_item_colon' => __( 'Parent Team Member:', 'text_domain' ),
'all_items' => __( 'All Team Members', 'text_domain' ),
'add_new_item' => __( 'Add New Team Member', 'text_domain' ),
'add_new' => __( 'Add New', 'text_domain' ),
'new_item' => __( 'New Team Member', 'text_domain' ),
'edit_item' => __( 'Edit Team Member', 'text_domain' ),
'update_item' => __( 'Update Team Member', 'text_domain' ),
'view_item' => __( 'View Team Member', 'text_domain' ),
'view_items' => __( 'View Team Members', 'text_domain' ),
'search_items' => __( 'Search Team Member', 'text_domain' ),
'not_found' => __( 'Not found', 'text_domain' ),
'not_found_in_trash' => __( 'Not found in Trash', 'text_domain' ),
'featured_image' => __( 'Profile Photo', 'text_domain' ),
'set_featured_image' => __( 'Set profile photo', 'text_domain' ),
'remove_featured_image' => __( 'Remove profile photo', 'text_domain' ),
'use_featured_image' => __( 'Use as profile photo', 'text_domain' ),
'insert_into_item' => __( 'Insert into team member', 'text_domain' ),
'uploaded_to_this_item' => __( 'Uploaded to this team member', 'text_domain' ),
'items_list' => __( 'Team Members list', 'text_domain' ),
'items_list_navigation' => __( 'Team Members list navigation', 'text_domain' ),
'filter_items_list' => __( 'Filter team members list', 'text_domain' ),
);
$args = array(
'label' => __( 'Team Member', 'text_domain' ),
'description' => __( 'Post type for team members', 'text_domain' ),
'labels' => $labels,
'supports' => array( 'title', 'editor', 'thumbnail' ),
'taxonomies' => array(),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-groups',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => true,
);
register_post_type( 'team_member', $args );
}
add_action( 'init', 'smw_register_team_member_cpt', 0 );
Action: Copy this code and paste it at the end of your theme’s functions.php file. You can learn more about this crucial file in our guide: WordPress functions.php: What it is and Where to find it.
Save the file, and then refresh your WordPress admin dashboard. You should now see a new “Team Members” section in the menu! Go ahead and add 3-4 sample team members with names, bios, and featured images.
Chapter 3: The Display – Vibe Coding with an AI Assistant
Now that we have data, we need to display it. We’ll create a new page template and use our in-editor AI assistant, GitHub Copilot, to write the code that fetches and displays our team members.
Step 1: Create a Page Template File
In your theme’s folder, create a new file named `template-team.php`. Add the following PHP comment at the top. This tells WordPress that this is a page template.
<?php /** * Template Name: Team Showcase * Template Post Type: page */ get_header(); ?>
Step 2: Vibe Code The WordPress Loop
Now, inside this file, we’ll direct Copilot to build The Loopāthe standard WordPress mechanism for displaying posts. We do this with a series of descriptive comments.
In your `template-team.php` file, after `get_header();`, start typing the following comment and watch Copilot work its magic.
Your Comment Prompt:
// Set up a new WP_Query to get all posts from the 'team_member' post type. // Order them by title in ascending order.
Copilot will suggest the code for the query arguments and the new `WP_Query` object. Accept the suggestion. It will look like this:
$args = array( 'post_type' => 'team_member', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', ); $team_query = new WP_Query( $args );
Now, let’s prompt for the loop itself.
Your Comment Prompt:
// Start the WordPress loop. If there are posts, loop through them.
Copilot will generate the `if` statement and `while` loop. Inside the loop, we’ll add more comments to get the specific data we need.
Here is the fully “vibe-coded” file, with comments showing how we directed the AI at each step:
<?php
/**
* Template Name: Team Showcase
* Template Post Type: page
*/
get_header();
?>
<div class='team-showcase-container'>
<h1>Meet Our Team</h1>
<?php
// Vibe Prompt: Set up a new WP_Query to get all posts from the 'team_member' post type.
// Order them by title in ascending order.
$args = array(
'post_type' => 'team_member',
'posts_per_page' => -1, // -1 gets all of them
'orderby' => 'title',
'order' => 'ASC',
);
$team_query = new WP_Query( $args );
// Vibe Prompt: Start the WordPress loop. If there are posts, loop through them.
if ( $team_query->have_posts() ) :
?>
<div class='team-grid'>
<?php
while ( $team_query->have_posts() ) : $team_query->the_post();
?>
<!-- Vibe Prompt: Create a card for each team member -->
<div class='team-member-card'>
<?php
// Vibe Prompt: Display the featured image (profile photo)
if ( has_post_thumbnail() ) {
the_post_thumbnail('medium_large', ['class' => 'team-member-photo']);
}
?>
<!-- Vibe Prompt: Display the team member's name -->
<h3 class='team-member-name'><?php the_title(); ?></h3>
<!-- We will add the Job Title with a custom field later -->
<!-- Vibe Prompt: Display a short excerpt of the bio -->
<div class='team-member-excerpt'>
<?php the_excerpt(); ?>
</div>
</div> <!-- .team-member-card -->
<?php
endwhile;
?>
</div> <!-- .team-grid -->
<?php
// Vibe Prompt: Reset post data after the loop
wp_reset_postdata();
else :
// Vibe Prompt: If no team members are found, display a message
echo '<p>No team members found.</p>';
endif;
?>
</div> <!-- .team-showcase-container -->
<?php get_footer(); ?>
Action: Create a new page in WordPress called “Our Team,” and in the “Page Attributes” panel on the right, select “Team Showcase” from the Template dropdown. Publish the page. When you view it, you should see your team members’ names, photos, and bios in a basic, unstyled list.
Chapter 4: Styling the Showcase with AI-Generated CSS
Our showcase is functional but ugly. Let’s fix that. This is a great task to start with a conversational AI to get a foundational block of CSS, then refine it.
Let’s go back to ChatGPT.
Your Prompt:
Act as a senior front-end designer. I have an HTML structure with a main container `.team-grid` that holds several `.team-member-card` divs. I need CSS to:
1. Turn `.team-grid` into a responsive CSS Grid. It should show 1 column on small screens, 2 on medium screens, and 3 on large screens.
2. Style the `.team-member-card` with a light gray border, a subtle box-shadow, rounded corners, and center the text inside.
3. Make the `.team-member-photo` circular and ensure it fits its container without stretching.
4. Add a hover effect to the card: when a user hovers, the box-shadow should become more prominent and the card should lift up slightly using a transform. Add a smooth transition for this effect.
AI-Generated CSS:
/* Main Grid Container */
.team-grid {
display: grid;
grid-template-columns: 1fr; /* 1 column by default on small screens */
gap: 2rem;
padding: 2rem;
}
/* Team Member Card Styling /
.team-member-card {
border: 1px solid #e0e0e0;
border-radius: 15px;
padding: 1.5rem;
text-align: center;
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
transition: transform 0.3s ease, box-shadow 0.3s ease;
overflow: hidden; / Important for the rounded corners on the image */
}
/* Hover Effect */
.team-member-card:hover {
transform: translateY(-10px);
box-shadow: 0 12px 24px rgba(0,0,0,0.1);
}
/* Profile Photo /
.team-member-photo {
width: 150px;
height: 150px;
border-radius: 50%; / Makes the image circular /
object-fit: cover; / Prevents stretching */
margin: 0 auto 1rem;
border: 4px solid #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* Name and Excerpt */
.team-member-name {
margin: 0;
font-size: 1.5rem;
}
.team-member-excerpt {
font-size: 0.9rem;
color: #666;
margin-top: 0.5rem;
}
/* Responsive Grid - Media Queries /
@media (min-width: 768px) {
.team-grid {
grid-template-columns: repeat(2, 1fr); / 2 columns on medium screens */
}
}
@media (min-width: 1024px) {
.team-grid {
grid-template-columns: repeat(3, 1fr); /* 3 columns on large screens */
}
}
Action: Copy this CSS and paste it into your theme’s `style.css` file or the “Additional CSS” section of the WordPress Customizer. Now, refresh your “Our Team” page. It should look dramatically better!
Chapter 5: Final Polish – Vibe Coding JavaScript for Interactivity
We’re in the home stretch! For the final touch, let’s add a modal popup. We’ll skip building a complex modal from scratch and use the browser’s native `alert()` function for simplicity, to show the concept.
Back in your `template-team.php` file, let’s prompt Copilot to add the JavaScript.
Your Comment Prompt (inside a `<script>` tag before `get_footer()`):
// Add a click event listener to all elements with the class 'team-member-card'. // When a card is clicked, get the full bio from a data attribute. // Show the bio in a simple browser alert.
First, we need to add the data attribute to our card in the PHP loop. Modify the `team-member-card` div line:
<div class='team-member-card' data-bio='<?php echo esc_attr(get_the_content()); ?>'>
Now, add the script tag and the comment at the bottom of the file.
<script>
document.addEventListener('DOMContentLoaded', function() {
// Add a click event listener to all elements with the class 'team-member-card'.
const cards = document.querySelectorAll('.team-member-card');
cards.forEach(card => {
card.addEventListener('click', function() {
// When a card is clicked, get the full bio from a data attribute.
const bio = this.getAttribute('data-bio');
// Show the bio in a simple browser alert.
alert(bio);
});
});
});
</script>
Action: Save `template-team.php` and refresh the page. Now, when you click on a team member’s card, their full biography will pop up in an alert box!
Conclusion
Take a step back and look at what you just accomplished. You went from a simple idea to a fully functional, styled, and interactive WordPress component in a fraction of the time it would have taken with traditional coding. You directed the process, and the AI handled the heavy lifting of syntax and boilerplate.
You have now successfully completed your first vibe coding project. You’ve seen how to:
- Use a conversational AI for high-level scaffolding (the CPT).
- Use an in-editor AI assistant for iterative, line-by-line coding (The Loop).
- Generate complex CSS based on a descriptive prompt.
- Add JavaScript interactivity by describing the desired behavior.
This workflow is the core of modern, AI-assisted development. You are now equipped to start tackling your own ideas. In our next guide, we’ll take this a step further. Get ready for “Vibe Coding Workflows: Integrating AI into Your Development Process,” where we will explore more advanced techniques, debugging strategies, and how to use AI to manage the entire lifecycle of a project.






