Skip to main content

Course Progress

Loading...

📚 Homework: Build a Complete Blog Listing

Apply everything you've learned about The Loop, template tags, custom queries, and pagination

Create a professional blog listing page with advanced features

Intermediate Advanced Options

Assignment Overview

In this homework assignment, you'll create a comprehensive blog listing page that demonstrates your mastery of WordPress content display techniques. You'll implement custom loops, template tags, pagination, and create a professional, user-friendly design.

Estimated Time: 4-6 hours

Due Date: End of Module 5

Points: 100 points (+ 20 bonus points available)

📋 Core Requirements

1 Create a Custom Home Page Template

Build a custom page template (template-blog-home.php) with the following sections:

  • Hero section with site title and description
  • Featured post section (1 large featured post)
  • Recent posts grid (6 posts in 2x3 or 3x2 layout)
  • Category-specific sections (posts from 2 different categories)

2 Implement Multiple Custom Queries

Use WP_Query to create at least 4 different custom queries:

  • Featured post query (meta field or sticky post)
  • Recent posts query (excluding featured)
  • Category-specific queries
  • Popular posts query (by comment count or views)

3 Display Complete Post Information

For each post, display using appropriate template tags:

  • Post title with permalink
  • Featured image (with fallback)
  • Author name with link to author archive
  • Publication date (formatted)
  • Categories and tags
  • Excerpt or trimmed content
  • Read more link
  • Comment count

4 Create an Archive Template

Build an archive.php template with:

  • Standard WordPress Loop
  • Archive title and description
  • Post cards in a grid layout
  • Sidebar with widgets

5 Implement Pagination

Add pagination to your archive template:

  • Numbered pagination using paginate_links()
  • Proper styling for pagination
  • Mobile-responsive pagination
  • Previous/Next links on single posts

6 Add a Single Post Template

Create or enhance single.php with:

  • Full post content display
  • Author bio section
  • Related posts section
  • Post navigation (previous/next)
  • Comments template

📦 Deliverables

template-blog-home.php
archive.php
single.php
category.php (optional)
author.php (optional)
style.css (with all styles)
functions.php (with support functions)
screenshot.png (theme screenshot)

Starter Code Templates

template-blog-home.php Structure

<?php
/**
 * Template Name: Blog Home
 * Description: Custom blog homepage with multiple sections
 */

get_header();
?>

<main id="primary" class="site-main">
    
    <!-- Hero Section -->
    <section class="hero-section">
        <div class="container">
            <h1><?php bloginfo('name'); ?></h1>
            <p><?php bloginfo('description'); ?></p>
        </div>
    </section>
    
    <!-- Featured Post Section -->
    <section class="featured-post">
        <div class="container">
            <h2>Featured Post</h2>
            <?php
            // Query for featured post
            $featured_args = array(
                'posts_per_page' => 1,
                'meta_key'       => 'featured',
                'meta_value'     => 'yes',
                // OR use sticky posts
                // 'post__in'       => get_option('sticky_posts'),
                // 'ignore_sticky_posts' => 1
            );
            
            $featured_query = new WP_Query($featured_args);
            
            if ($featured_query->have_posts()) :
                while ($featured_query->have_posts()) : $featured_query->the_post();
                    // Display featured post
                    get_template_part('template-parts/content', 'featured');
                endwhile;
                wp_reset_postdata();
            endif;
            ?>
        </div>
    </section>
    
    <!-- Recent Posts Grid -->
    <section class="recent-posts">
        <div class="container">
            <h2>Recent Posts</h2>
            <div class="posts-grid">
                <?php
                // Query for recent posts
                $recent_args = array(
                    'posts_per_page' => 6,
                    'post__not_in'   => get_option('sticky_posts'),
                );
                
                $recent_query = new WP_Query($recent_args);
                
                if ($recent_query->have_posts()) :
                    while ($recent_query->have_posts()) : $recent_query->the_post();
                        // Display post card
                        get_template_part('template-parts/content', 'card');
                    endwhile;
                    wp_reset_postdata();
                endif;
                ?>
            </div>
        </div>
    </section>
    
    <!-- Category Sections -->
    <?php
    // Add more sections for different categories
    $categories = array('news', 'tutorials'); // Your category slugs
    
    foreach ($categories as $cat_slug) :
        $category = get_category_by_slug($cat_slug);
        if ($category) :
    ?>
        <section class="category-section">
            <div class="container">
                <h2><?php echo esc_html($category->name); ?></h2>
                <div class="posts-list">
                    <?php
                    $cat_args = array(
                        'category_name'  => $cat_slug,
                        'posts_per_page' => 4,
                    );
                    
                    $cat_query = new WP_Query($cat_args);
                    
                    if ($cat_query->have_posts()) :
                        while ($cat_query->have_posts()) : $cat_query->the_post();
                            get_template_part('template-parts/content', 'list');
                        endwhile;
                        wp_reset_postdata();
                    endif;
                    ?>
                </div>
                <a href="<?php echo get_category_link($category->term_id); ?>" class="view-all">
                    View all in <?php echo esc_html($category->name); ?> →
                </a>
            </div>
        </section>
    <?php
        endif;
    endforeach;
    ?>
    
</main>

<?php
get_footer();
?>

template-parts/content-card.php

<article id="post-<?php the_ID(); ?>" <?php post_class('post-card'); ?>>
    
    <?php if (has_post_thumbnail()) : ?>
        <div class="post-thumbnail">
            <a href="<?php the_permalink(); ?>">
                <?php the_post_thumbnail('medium'); ?>
            </a>
        </div>
    <?php else : ?>
        <div class="post-thumbnail placeholder">
            <a href="<?php the_permalink(); ?>">
                <img src="<?php echo get_template_directory_uri(); ?>/images/placeholder.jpg" alt="<?php the_title_attribute(); ?>">
            </a>
        </div>
    <?php endif; ?>
    
    <div class="post-content">
        <header class="entry-header">
            <?php the_title('<h3 class="entry-title"><a href="' . esc_url(get_permalink()) . '">', '</a></h3>'); ?>
            
            <div class="entry-meta">
                <span class="author">
                    By <?php the_author_posts_link(); ?>
                </span>
                <span class="date">
                    <?php echo get_the_date(); ?>
                </span>
                <span class="comments">
                    <?php comments_number('0', '1', '%'); ?> Comments
                </span>
            </div>
        </header>
        
        <div class="entry-excerpt">
            <?php 
            if (has_excerpt()) {
                the_excerpt();
            } else {
                echo wp_trim_words(get_the_content(), 20);
            }
            ?>
        </div>
        
        <footer class="entry-footer">
            <div class="categories">
                <?php the_category(', '); ?>
            </div>
            <a href="<?php the_permalink(); ?>" class="read-more">
                Read More →
            </a>
        </footer>
    </div>
    
</article>

CSS Grid Layout Starter

/* Posts Grid Layout */
.posts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 2rem;
    margin: 2rem 0;
}

.post-card {
    background: #fff;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.post-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}

.post-thumbnail {
    aspect-ratio: 16/9;
    overflow: hidden;
}

.post-thumbnail img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.3s ease;
}

.post-card:hover .post-thumbnail img {
    transform: scale(1.05);
}

.post-content {
    padding: 1.5rem;
}

.entry-title {
    margin: 0 0 0.5rem;
    font-size: 1.25rem;
}

.entry-title a {
    color: #333;
    text-decoration: none;
}

.entry-title a:hover {
    color: #007cba;
}

.entry-meta {
    display: flex;
    gap: 1rem;
    font-size: 0.875rem;
    color: #666;
    margin-bottom: 1rem;
}

.entry-excerpt {
    color: #555;
    line-height: 1.6;
    margin-bottom: 1rem;
}

.entry-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.categories a {
    background: #f0f0f0;
    padding: 0.25rem 0.75rem;
    border-radius: 4px;
    text-decoration: none;
    font-size: 0.875rem;
    color: #555;
}

.read-more {
    color: #007cba;
    text-decoration: none;
    font-weight: 600;
}

/* Responsive Design */
@media (max-width: 768px) {
    .posts-grid {
        grid-template-columns: 1fr;
    }
}

@media (min-width: 769px) and (max-width: 1024px) {
    .posts-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

🌟 Bonus Challenges (20 extra points)

AJAX Load More (+10 points)

Implement AJAX "Load More" functionality instead of traditional pagination:

  • Load more button that fetches additional posts
  • Smooth animation when new posts appear
  • Loading indicator
  • Disable button when no more posts

Advanced Filtering (+10 points)

Add filtering capabilities to your archive page:

  • Filter by category dropdown
  • Filter by tag
  • Sort options (date, title, popularity)
  • Search within results

Grading Rubric

Component Description Points
Custom Home Template Complete template with all required sections 20
Custom Queries Proper use of WP_Query with wp_reset_postdata() 20
Template Tags Correct usage of all required template tags 15
Archive Template Functional archive with proper Loop 15
Pagination Working pagination with proper styling 10
Single Post Template Complete single post display with navigation 10
Code Quality Clean, commented, properly formatted code 5
Design & UX Professional appearance and user experience 5
Total 100

📤 Submission Guidelines

  1. Create a ZIP file containing your entire theme folder
  2. Name your file: firstname_lastname_blog_listing.zip
  3. Include a README.md with:
    • Your name and date
    • Any special features you implemented
    • Known issues or incomplete features
    • Bonus challenges attempted
  4. Test your theme with Theme Check plugin before submission
  5. Submit via the course management system

💡 Tips for Success

Start with Structure

Create all your template files first with basic structure, then add functionality incrementally.

Use Template Parts

Create reusable template parts for post cards, headers, and other repeated elements to maintain DRY principles.

Test with Different Content

Test your templates with posts that have different lengths, with and without featured images, and various numbers of categories/tags.

Mobile-First Design

Ensure your blog listing looks great on mobile devices. Test responsive breakpoints thoroughly.

Performance Matters

Optimize your queries and consider using transients for expensive operations like popular posts.

✅ Pre-Submission Checklist

Helpful Resources

🚀
Ready to Build!

You now have all the knowledge needed to create an impressive blog listing page. Remember to:

  • Plan your layout before coding
  • Test frequently as you build
  • Focus on functionality first, then polish the design
  • Ask for help if you get stuck

Good luck with your assignment!