WordPress / 8 MIN READ
Custom Posts Templating PHP
Templating custom posts with PHP
From the original Fervor library. Examples may use older package versions.
🌟 Building a Custom Post Type (CPT) in WordPress with PHP 🌟
WordPress allows you to go beyond posts and pages with Custom Post Types (CPTs)—perfect for adding unique content types like portfolios, events, recipes, or products. Let’s create one step by step! 🚀
📋 What is a Custom Post Type?
A Custom Post Type is a type of content different from standard WordPress posts or pages. Examples include:
- Portfolios for showcasing your work.
- Events for an event management website.
- Products for an online store.
🔧 Step 1: Register a Custom Post Type
- Open your child theme folder.
- Locate the
functions.phpfile. - Add the following code to register your Custom Post Type (CPT):
Example: Registering a “Portfolio” CPT
function create_portfolio_cpt() {
$labels = [
'name' => 'Portfolios',
'singular_name' => 'Portfolio',
'menu_name' => 'Portfolios',
'add_new_item' => 'Add New Portfolio',
'edit_item' => 'Edit Portfolio',
'new_item' => 'New Portfolio',
'view_item' => 'View Portfolio',
'all_items' => 'All Portfolios',
];
$args = [
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-portfolio', // Admin menu icon
'supports' => ['title', 'editor', 'thumbnail', 'custom-fields'],
'rewrite' => ['slug' => 'portfolio'], // URL slug
];
register_post_type('portfolio', $args);
}
add_action('init', 'create_portfolio_cpt');
🧩 Step 2: Customize Your CPT
Add Taxonomies (Optional)
Just like posts have categories and tags, you can add custom taxonomies to your CPT.
Example: Add “Project Type” Taxonomy to Portfolios
function create_portfolio_taxonomy() {
$args = [
'labels' => [
'name' => 'Project Types',
'singular_name' => 'Project Type',
'search_items' => 'Search Project Types',
],
'hierarchical' => true, // Works like categories
'public' => true,
'rewrite' => ['slug' => 'project-type'],
];
register_taxonomy('project-type', ['portfolio'], $args);
}
add_action('init', 'create_portfolio_taxonomy');
Why It’s Cool:
- Organize portfolios by type (e.g., “Web Design”, “Photography”).
- Enhance filtering and display options for users.
🎨 Step 3: Add a Custom Archive Template
WordPress uses the template hierarchy to display CPTs. Create an archive template to control how your CPT archive appears.
-
Create a File:
Inside your child theme, create a file calledarchive-portfolio.php. -
Add Custom Layout:
<?php
get_header(); // Load the site header
?>
<div class="portfolio-archive">
<h1>Our Portfolios</h1>
<?php
if (have_posts()) :
while (have_posts()) : the_post();
?>
<div class="portfolio-item">
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php the_post_thumbnail('medium'); ?>
<p><?php the_excerpt(); ?></p>
</div>
<?php
endwhile;
else :
echo '<p>No portfolios found.</p>';
endif;
?>
</div>
<?php
get_footer(); // Load the site footer
?>
🔗 Step 4: Create a Custom Single Template
Want a unique layout for single portfolio items? Let’s make one!
-
Create a File:
Inside your child theme, create a file calledsingle-portfolio.php. -
Add Custom Content:
<?php
get_header();
?>
<div class="portfolio-single">
<h1><?php the_title(); ?></h1>
<?php if (has_post_thumbnail()) : ?>
<div class="portfolio-thumbnail">
<?php the_post_thumbnail('large'); ?>
</div>
<?php endif; ?>
<div class="portfolio-content">
<?php the_content(); ?>
</div>
<div class="portfolio-meta">
<p><strong>Project Type:</strong> <?php echo get_the_term_list(get_the_ID(), 'project-type', '', ', '); ?></p>
</div>
</div>
<?php
get_footer();
?>
🎯 Step 5: Add CPT to Menus and Widgets
- Go to Appearance > Menus in the WordPress admin.
- Add your CPT archive (e.g., “Portfolios”) to the menu for easy navigation.
- Use the Custom HTML widget to highlight specific portfolio items in a sidebar.
💡 Pro Tips for CPTs
1️⃣ Use Dashicons for Admin Menus
Add a slick WordPress icon to your CPT menu with menu_icon.
'menu_icon' => 'dashicons-portfolio',
2️⃣ Custom Fields for Extra Data
Use the Advanced Custom Fields (ACF) plugin to add fields like:
- Client Name
- Completion Date
- Project URL
Display the fields in your template:
<div class="portfolio-details">
<p>Client: <?php the_field('client_name'); ?></p>
<p>Date: <?php the_field('completion_date'); ?></p>
<p>URL: <a href="<?php the_field('project_url'); ?>"><?php the_field('project_url'); ?></a></p>
</div>
3️⃣ Custom Rewrite Rules
Want cleaner URLs? Use rewrite in register_post_type():
'rewrite' => ['slug' => 'work'],
This changes URLs from /portfolio/project-name to /work/project-name.
4️⃣ Add CPTs to the WordPress Search
By default, WordPress searches only posts and pages. Add your CPTs like this:
function include_cpt_in_search($query) {
if ($query->is_search && !is_admin()) {
$query->set('post_type', ['post', 'page', 'portfolio']);
}
return $query;
}
add_filter('pre_get_posts', 'include_cpt_in_search');
5️⃣ CPT Pagination
For long archives, add pagination with paginate_links():
echo paginate_links([
'total' => $wp_query->max_num_pages,
'prev_text' => '« Previous',
'next_text' => 'Next »',
]);
6️⃣ Block Editor Compatibility
Make your CPT Gutenberg-friendly by adding show_in_rest:
'show_in_rest' => true,
🎉 You Did It!
You’ve created a fully functional Custom Post Type in WordPress! Here’s what you’ve learned:
- How to register a CPT with PHP.
- Adding taxonomies for better organization.
- Customizing archive and single templates.
- Pro tips for extending functionality.
🚀 Next Steps:
- Add custom taxonomies for more structure.
- Explore custom meta boxes or use ACF for advanced fields.
- Let me know if you want to learn about custom shortcodes, CPT filtering, or Gutenberg blocks next! 🛠️
Bonus Cool Stuff
🌟 Trendy Single Post Template for Your Custom Post Type (Portfolio) 🌟
Let’s design a modern and trendy template for a single portfolio post! This template will:
- Highlight the project details (e.g., client name, project date).
- Include a large hero section for the featured image.
- Use a clean, minimalist layout perfect for showcasing projects.
- Look great with mobile-friendly, responsive styles.
🎨 Step 1: Create the Template File
- In your child theme, create a file called
single-portfolio.php. - Add the following code as the base structure:
<?php
get_header(); // Load the site header
?>
<div class="portfolio-single trendy-template">
<?php if (has_post_thumbnail()) : ?>
<div class="portfolio-hero" style="background-image: url('<?php echo get_the_post_thumbnail_url(get_the_ID(), 'full'); ?>');">
<div class="portfolio-hero-overlay">
<h1 class="portfolio-title"><?php the_title(); ?></h1>
</div>
</div>
<?php endif; ?>
<div class="portfolio-content-wrapper">
<div class="portfolio-details">
<h2>Project Details</h2>
<ul>
<li><strong>Client:</strong> <?php the_field('client_name'); ?></li>
<li><strong>Date:</strong> <?php the_field('completion_date'); ?></li>
<li><strong>Category:</strong> <?php echo get_the_term_list(get_the_ID(), 'project-type', '', ', '); ?></li>
<li><strong>Website:</strong> <a href="<?php the_field('project_url'); ?>" target="_blank"><?php the_field('project_url'); ?></a></li>
</ul>
</div>
<div class="portfolio-description">
<h2>About the Project</h2>
<?php the_content(); ?>
</div>
</div>
</div>
<?php
get_footer(); // Load the site footer
?>
🎨 Step 2: Add Modern Styling
Add the following CSS to your child theme’s style.css file to give it a trendy and responsive design:
/* General Styles */
.trendy-template {
font-family: 'Arial', sans-serif;
color: #333;
}
/* Hero Section */
.portfolio-hero {
position: relative;
height: 400px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.portfolio-hero-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.portfolio-title {
color: #fff;
font-size: 2.5rem;
text-transform: uppercase;
text-align: center;
margin: 0;
}
/* Content Wrapper */
.portfolio-content-wrapper {
max-width: 900px;
margin: 30px auto;
padding: 20px;
background: #f9f9f9;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
/* Details Section */
.portfolio-details h2 {
font-size: 1.8rem;
margin-bottom: 10px;
color: #222;
}
.portfolio-details ul {
list-style: none;
padding: 0;
}
.portfolio-details li {
margin-bottom: 10px;
font-size: 1rem;
line-height: 1.5;
}
.portfolio-details li a {
color: #0073aa;
text-decoration: none;
}
.portfolio-details li a:hover {
text-decoration: underline;
}
/* Description Section */
.portfolio-description h2 {
font-size: 1.8rem;
margin-top: 30px;
margin-bottom: 15px;
color: #222;
}
.portfolio-description p {
font-size: 1rem;
line-height: 1.8;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-hero {
height: 250px;
}
.portfolio-title {
font-size: 1.8rem;
}
.portfolio-content-wrapper {
padding: 15px;
}
.portfolio-details h2,
.portfolio-description h2 {
font-size: 1.5rem;
}
}
🎯 Step 3: Add Extra Polish
Custom Fonts
Use Google Fonts for a modern look. For example:
-
Add this to your
functions.php:function enqueue_trendy_template_styles() { wp_enqueue_style('google-fonts', 'https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&display=swap', [], null); } add_action('wp_enqueue_scripts', 'enqueue_trendy_template_styles'); -
Update your CSS to use the new font:
font-family: 'Montserrat', sans-serif;
Icons for Project Details
Add icons next to each detail using Font Awesome or similar libraries.
-
Enqueue Font Awesome in
functions.php:function enqueue_fontawesome() { wp_enqueue_style('font-awesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css', [], null); } add_action('wp_enqueue_scripts', 'enqueue_fontawesome'); -
Add icons in your details section:
<li><i class="fas fa-user"></i> <strong>Client:</strong> <?php the_field('client_name'); ?></li> <li><i class="fas fa-calendar"></i> <strong>Date:</strong> <?php the_field('completion_date'); ?></li> <li><i class="fas fa-tags"></i> <strong>Category:</strong> <?php echo get_the_term_list(get_the_ID(), 'project-type', '', ', '); ?></li> <li><i class="fas fa-link"></i> <strong>Website:</strong> <a href="<?php the_field('project_url'); ?>" target="_blank"><?php the_field('project_url'); ?></a></li>
🎉 Features of This Template
1️⃣ Responsive Hero Section
- Uses the featured image as a stunning full-width background.
- Includes an overlay for better readability.
2️⃣ Highlight Project Details
- Clearly displays key project information in a modern card-like design.
3️⃣ Minimalist Content Section
- Keeps the focus on the content with clean typography and spacing.
4️⃣ Responsive Design
- Looks great on all devices, from desktops to smartphones.
🚀 Next Steps
- Custom Styling: Play with colors, spacing, and fonts to match your brand.
- Enhance with Animation: Add CSS transitions or animations for hover effects and smooth scrolling.
- Add Related Projects Section: Showcase similar projects at the bottom of the page.
<div class="related-projects"> <h2>Related Projects</h2> <?php $related = new WP_Query([ 'post_type' => 'portfolio', 'posts_per_page' => 3, 'post__not_in' => [get_the_ID()], 'tax_query' => [ [ 'taxonomy' => 'project-type', 'field' => 'slug', 'terms' => wp_get_post_terms(get_the_ID(), 'project-type', ['fields' => 'slugs']), ], ], ]); if ($related->have_posts()) : while ($related->have_posts()) : $related->the_post(); echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>'; endwhile; wp_reset_postdata(); endif; ?> </div>
🔥 Final Thoughts
This trendy template elevates your portfolio to a professional, modern level. It’s minimalist, mobile-friendly, and customizable. Pair it with the rest of your custom post type setup for a sleek, cohesive website.