Weekend Project: WordPress Custom Theme and Plugin Development

Applying George Polya's 4-Step Problem-Solving Approach to WordPress Development

Project Overview

In this weekend project, you'll create a complete WordPress site with a custom theme and plugin that work together to solve a real-world problem. You'll apply George Polya's proven 4-step problem-solving methodology to guide your development process.

flowchart TB A[Project Goal] --> B[Understand the Problem] B --> C[Devise a Plan] C --> D[Execute the Plan] D --> E[Review and Extend] B --> F[Define Requirements] B --> G[Research Similar Solutions] C --> H[Theme Architecture] C --> I[Plugin Architecture] D --> J[Develop Theme] D --> K[Develop Plugin] D --> L[Integration] E --> M[Test & Debug] E --> N[Optimize] E --> O[Document]

George Polya's Problem-Solving Approach

George Polya was a Hungarian mathematician who developed a systematic approach to problem-solving in his book "How to Solve It" (1945). His 4-step process has been widely adopted across disciplines, including software development.

Step 1: Understand the Problem

Define exactly what you're trying to solve before writing any code.

  • What is the problem statement?
  • What are the constraints?
  • What are the desired outcomes?
  • Do you have all the necessary information?

Step 2: Devise a Plan

Strategize your approach before diving into implementation.

  • Break down the problem into smaller parts
  • Consider alternative approaches
  • Draw from similar problems you've solved
  • Create a step-by-step strategy

Step 3: Execute the Plan

Implement your solution according to your plan.

  • Follow your strategy step by step
  • Create incremental, testable components
  • Verify each step as you go
  • Persist through challenges

Step 4: Review and Extend

Evaluate your solution and identify improvements.

  • Test thoroughly against requirements
  • Review code for quality and optimization
  • Learn from the process
  • Identify extensions and refinements

This methodology aligns perfectly with the software development process. When applied to WordPress development, it helps create more thoughtful, robust solutions that truly solve user problems rather than just implementing features.

The Weekend Project Challenge

Your challenge is to create a "Portfolio Showcase" WordPress site for creative professionals with the following components:

flowchart LR A[WordPress Core] --> B[Portfolio Theme] A --> C[Portfolio Plugin] B <--> C B --> D[Display Layer] C --> E[Data Management] C --> F[Admin Interface] E --> G[Portfolio Custom Post Type] E --> H[Project Metadata] E --> I[Category Taxonomy] F --> J[Project Settings] D --> K[Portfolio Archive] D --> L[Single Project View] D --> M[Filtering Interface]

This project will test and solidify your understanding of WordPress theme development, plugin architecture, and the integration between the two, while solving a real-world need for creative professionals.

Step 1: Understand the Problem

Following Polya's first step, let's thoroughly understand what we're trying to build.

Problem Statement

Creative professionals (designers, photographers, artists, etc.) need a clean, customizable way to showcase their work online. They need:

Research Existing Solutions

Before building, examine existing portfolio themes and plugins to understand:

Define Requirements

Based on the problem statement and research, define specific requirements:

Theme Requirements:

Plugin Requirements:

Understanding Exercise

Before proceeding, answer these questions to ensure you fully understand the problem:

  1. Who is the primary user of your solution?
  2. What are their top three needs/pain points?
  3. What makes a portfolio showcase effective?
  4. How should the theme and plugin work together?
  5. What are potential technical challenges you might face?

Step 2: Devise a Plan

Now that we understand the problem, let's create a detailed plan for our development.

Theme Development Plan

  1. Theme Structure:
    • Create a standard WordPress theme directory structure
    • Implement template hierarchy with focus on portfolio templates
    • Set up style organization with SASS/SCSS
  2. Core Files:
    • style.css with theme information
    • functions.php for theme setup and customizations
    • index.php, header.php, footer.php as base templates
  3. Portfolio-Specific Templates:
    • archive-portfolio.php for the portfolio grid view
    • single-portfolio.php for individual project display
    • taxonomy-portfolio-category.php for filtered views
  4. Theme Features:
    • Customizer settings for colors, typography, and layout options
    • JavaScript for filtering and interactive elements
    • CSS Grid or Flexbox for responsive portfolio display

Plugin Development Plan

  1. Plugin Structure:
    • Create object-oriented plugin architecture
    • Set up activation, deactivation, and uninstall hooks
    • Implement autoloading for classes
  2. Custom Post Type:
    • Register 'portfolio' post type with appropriate supports
    • Register 'portfolio-category' and 'portfolio-tag' taxonomies
    • Add project metadata fields (client, date, URL, etc.)
  3. Admin Interface:
    • Create settings page for plugin configuration
    • Implement meta boxes for project details
    • Add media management for project galleries
  4. Frontend Features:
    • Create shortcode for portfolio display
    • Implement AJAX filtering functionality
    • Add template functions for theme integration

Integration Plan

  1. Theme Support for Plugin:
    • Check if plugin is active and provide graceful fallback
    • Add specific styling for plugin elements
    • Implement plugin template functions in theme templates
  2. Plugin Support for Theme:
    • Provide template functions for theme developers
    • Add theme-specific hooks for customization
    • Ensure plugin outputs are semantically structured for styling

Development Schedule

Break down the weekend into manageable time blocks:

gantt title Weekend Project Schedule dateFormat YYYY-MM-DD axisFormat %a %H:%M section Planning Understand Problem :done, p1, 2025-05-24 09:00, 1h Create Plan :done, p2, after p1, 1h section Setup WordPress Installation :s1, after p2, 30m Theme Scaffolding :s2, after s1, 30m Plugin Scaffolding :s3, after s2, 30m section Theme Dev Core Theme Files :t1, after s3, 2h Portfolio Templates :t2, after t1, 2h Theme Styling :t3, after t2, 2h section Plugin Dev Custom Post Types :pl1, 2025-05-24 16:00, 2h Admin Interface :pl2, 2025-05-25 09:00, 2h Frontend Functionality :pl3, after pl2, 2h section Integration Theme-Plugin Integration :i1, after pl3, 2h Testing & Debugging :i2, after i1, 2h Documentation :i3, after i2, 1h

Planning Exercise

Before moving to implementation, complete these planning tasks:

  1. Sketch the portfolio grid layout and single project view
  2. Create a more detailed file structure for both the theme and plugin
  3. List all the hooks your plugin will use and provide
  4. Define the database schema for your custom post type and meta fields
  5. Identify potential reusable components or functions

Step 3: Execute the Plan

Now it's time to implement your solution according to the plan. Below are key implementation details for both the theme and plugin.

Theme Implementation

Initial Theme Setup


// functions.php
<?php
/**
 * Portfolio Theme functions and definitions
 */

// Theme setup function
function portfolio_theme_setup() {
    // Add theme support
    add_theme_support('title-tag');
    add_theme_support('post-thumbnails');
    add_theme_support('html5', array(
        'search-form',
        'comment-form',
        'comment-list',
        'gallery',
        'caption',
    ));
    add_theme_support('customize-selective-refresh-widgets');
    add_theme_support('responsive-embeds');
    
    // Register menus
    register_nav_menus(array(
        'primary' => esc_html__('Primary Menu', 'portfolio-theme'),
        'footer' => esc_html__('Footer Menu', 'portfolio-theme'),
    ));
    
    // Add image sizes for portfolio
    add_image_size('portfolio-thumbnail', 450, 450, true);
    add_image_size('portfolio-large', 1200, 800, false);
}
add_action('after_setup_theme', 'portfolio_theme_setup');

// Enqueue scripts and styles
function portfolio_theme_scripts() {
    wp_enqueue_style('portfolio-theme-style', get_stylesheet_uri(), array(), '1.0.0');
    wp_enqueue_script('portfolio-theme-navigation', get_template_directory_uri() . '/js/navigation.js', array(), '1.0.0', true);
    
    // Portfolio-specific scripts
    if (is_post_type_archive('portfolio') || is_singular('portfolio') || is_tax('portfolio-category')) {
        wp_enqueue_script('portfolio-theme-isotope', get_template_directory_uri() . '/js/isotope.pkgd.min.js', array('jquery'), '3.0.6', true);
        wp_enqueue_script('portfolio-theme-portfolio', get_template_directory_uri() . '/js/portfolio.js', array('jquery', 'portfolio-theme-isotope'), '1.0.0', true);
    }
}
add_action('wp_enqueue_scripts', 'portfolio_theme_scripts');

// Check if Portfolio plugin is active
function portfolio_theme_has_plugin() {
    return class_exists('Portfolio_Plugin');
}

// Include theme files
require get_template_directory() . '/inc/customizer.php';
        

Portfolio Archive Template


// archive-portfolio.php
<?php
/**
 * The template for displaying portfolio archives
 */

get_header();
?>

<main id="primary" class="site-main">
    
    <header class="page-header">
        <h1 class="page-title">
            <?php esc_html_e('Portfolio', 'portfolio-theme'); ?>
        </h1>
        
        <?php if (portfolio_theme_has_plugin()) : ?>
        <div class="portfolio-filters">
            <button class="filter-button active" data-filter="*"><?php esc_html_e('All', 'portfolio-theme'); ?></button>
            
            <?php
            $categories = get_terms(array(
                'taxonomy' => 'portfolio-category',
                'hide_empty' => true,
            ));
            
            foreach ($categories as $category) {
                printf(
                    '<button class="filter-button" data-filter=".%s">%s</button>',
                    esc_attr($category->slug),
                    esc_html($category->name)
                );
            }
            ?>
        </div>
        <?php endif; ?>
    </header>

    <div class="portfolio-grid">
        <?php
        if (have_posts()) :
            while (have_posts()) :
                the_post();
                
                // Get categories for filtering
                $categories = '';
                $terms = get_the_terms(get_the_ID(), 'portfolio-category');
                if ($terms && !is_wp_error($terms)) {
                    $category_slugs = array();
                    foreach ($terms as $term) {
                        $category_slugs[] = $term->slug;
                    }
                    $categories = join(' ', $category_slugs);
                }
                ?>
                
                <article id="post-<?php the_ID(); ?>" <?php post_class('portfolio-item ' . $categories); ?>>
                    <a href="<?php the_permalink(); ?>" class="portfolio-link">
                        <div class="portfolio-thumbnail">
                            <?php 
                            if (has_post_thumbnail()) {
                                the_post_thumbnail('portfolio-thumbnail');
                            } else {
                                echo '<img src="' . esc_url(get_template_directory_uri()) . '/images/placeholder.png" alt="Placeholder" />';
                            }
                            ?>
                        </div>
                        <h2 class="portfolio-title"><?php the_title(); ?></h2>
                        
                        <?php if (portfolio_theme_has_plugin() && function_exists('portfolio_get_client')) : ?>
                            <div class="portfolio-meta">
                                <span class="portfolio-client"><?php echo esc_html(portfolio_get_client(get_the_ID())); ?></span>
                            </div>
                        <?php endif; ?>
                    </a>
                </article>
                
                <?php
            endwhile;
        else :
            get_template_part('template-parts/content', 'none');
        endif;
        ?>
    </div>
    
    <?php the_posts_navigation(); ?>

</main>

<?php
get_footer();
        

Plugin Implementation

Main Plugin File


<?php
/**
 * Plugin Name: Portfolio Plugin
 * Plugin URI: https://example.com/portfolio-plugin
 * Description: A portfolio management plugin for creative professionals.
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://example.com
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: portfolio-plugin
 * Domain Path: /languages
 */

// If this file is called directly, abort.
if (!defined('WPINC')) {
    die;
}

// Define plugin constants
define('PORTFOLIO_PLUGIN_VERSION', '1.0.0');
define('PORTFOLIO_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('PORTFOLIO_PLUGIN_URL', plugin_dir_url(__FILE__));

/**
 * Main plugin class
 */
class Portfolio_Plugin {
    
    /**
     * Instance of this class
     */
    private static $instance = null;
    
    /**
     * Get singleton instance
     */
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        // Initialize plugin
        add_action('plugins_loaded', array($this, 'load_textdomain'));
        add_action('init', array($this, 'register_post_types'));
        add_action('init', array($this, 'register_taxonomies'));
        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('admin_init', array($this, 'register_settings'));
        add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
        add_action('save_post_portfolio', array($this, 'save_meta_boxes'));
        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
        add_shortcode('portfolio', array($this, 'portfolio_shortcode'));
        
        // Register activation/deactivation hooks
        register_activation_hook(__FILE__, array($this, 'activate'));
        register_deactivation_hook(__FILE__, array($this, 'deactivate'));
    }
    
    /**
     * Load plugin text domain
     */
    public function load_textdomain() {
        load_plugin_textdomain('portfolio-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
    }
    
    /**
     * Register portfolio post type
     */
    public function register_post_types() {
        $labels = array(
            'name'                  => _x('Portfolio Items', 'Post type general name', 'portfolio-plugin'),
            'singular_name'         => _x('Portfolio Item', 'Post type singular name', 'portfolio-plugin'),
            'menu_name'             => _x('Portfolio', 'Admin Menu text', 'portfolio-plugin'),
            'add_new'               => __('Add New', 'portfolio-plugin'),
            'add_new_item'          => __('Add New Portfolio Item', 'portfolio-plugin'),
            'edit_item'             => __('Edit Portfolio Item', 'portfolio-plugin'),
            'new_item'              => __('New Portfolio Item', 'portfolio-plugin'),
            'view_item'             => __('View Portfolio Item', 'portfolio-plugin'),
            'search_items'          => __('Search Portfolio Items', 'portfolio-plugin'),
            'not_found'             => __('No portfolio items found', 'portfolio-plugin'),
            'not_found_in_trash'    => __('No portfolio items found in Trash', 'portfolio-plugin'),
            'all_items'             => __('All Portfolio Items', 'portfolio-plugin'),
            'featured_image'        => __('Portfolio Image', 'portfolio-plugin'),
            'set_featured_image'    => __('Set portfolio image', 'portfolio-plugin'),
            'remove_featured_image' => __('Remove portfolio image', 'portfolio-plugin'),
        );
        
        $args = array(
            'labels'                => $labels,
            'public'                => true,
            'publicly_queryable'    => true,
            'show_ui'               => true,
            'show_in_menu'          => true,
            'query_var'             => true,
            'rewrite'               => array('slug' => 'portfolio'),
            'capability_type'       => 'post',
            'has_archive'           => true,
            'hierarchical'          => false,
            'menu_position'         => 20,
            'menu_icon'             => 'dashicons-portfolio',
            'supports'              => array('title', 'editor', 'thumbnail', 'excerpt'),
            'show_in_rest'          => true,
        );
        
        register_post_type('portfolio', $args);
    }
    
    /**
     * Register portfolio taxonomies
     */
    public function register_taxonomies() {
        // Register category taxonomy
        $labels = array(
            'name'                       => _x('Portfolio Categories', 'taxonomy general name', 'portfolio-plugin'),
            'singular_name'              => _x('Portfolio Category', 'taxonomy singular name', 'portfolio-plugin'),
            'search_items'               => __('Search Portfolio Categories', 'portfolio-plugin'),
            'popular_items'              => __('Popular Portfolio Categories', 'portfolio-plugin'),
            'all_items'                  => __('All Portfolio Categories', 'portfolio-plugin'),
            'edit_item'                  => __('Edit Portfolio Category', 'portfolio-plugin'),
            'update_item'                => __('Update Portfolio Category', 'portfolio-plugin'),
            'add_new_item'               => __('Add New Portfolio Category', 'portfolio-plugin'),
            'new_item_name'              => __('New Portfolio Category Name', 'portfolio-plugin'),
            'separate_items_with_commas' => __('Separate categories with commas', 'portfolio-plugin'),
            'add_or_remove_items'        => __('Add or remove categories', 'portfolio-plugin'),
            'choose_from_most_used'      => __('Choose from the most used categories', 'portfolio-plugin'),
            'menu_name'                  => __('Categories', 'portfolio-plugin'),
        );
        
        $args = array(
            'hierarchical'      => true,
            'labels'            => $labels,
            'show_ui'           => true,
            'show_admin_column' => true,
            'query_var'         => true,
            'rewrite'           => array('slug' => 'portfolio-category'),
            'show_in_rest'      => true,
        );
        
        register_taxonomy('portfolio-category', array('portfolio'), $args);
        
        // Register tags taxonomy (similar implementation)
    }
    
    /**
     * Add meta boxes for portfolio items
     */
    public function add_meta_boxes() {
        add_meta_box(
            'portfolio_details',
            __('Portfolio Details', 'portfolio-plugin'),
            array($this, 'render_details_meta_box'),
            'portfolio',
            'normal',
            'high'
        );
        
        add_meta_box(
            'portfolio_gallery',
            __('Portfolio Gallery', 'portfolio-plugin'),
            array($this, 'render_gallery_meta_box'),
            'portfolio',
            'normal',
            'high'
        );
    }
    
    /**
     * Render details meta box
     */
    public function render_details_meta_box($post) {
        // Add nonce for security
        wp_nonce_field('portfolio_details_save', 'portfolio_details_nonce');
        
        // Get saved values
        $client = get_post_meta($post->ID, '_portfolio_client', true);
        $date = get_post_meta($post->ID, '_portfolio_date', true);
        $url = get_post_meta($post->ID, '_portfolio_url', true);
        
        // Output fields
        echo '<p>';
        echo '<label for="portfolio_client">' . esc_html__('Client:', 'portfolio-plugin') . '</label> ';
        echo '<input type="text" id="portfolio_client" name="portfolio_client" value="' . esc_attr($client) . '" class="widefat" />';
        echo '</p>';
        
        echo '<p>';
        echo '<label for="portfolio_date">' . esc_html__('Project Date:', 'portfolio-plugin') . '</label> ';
        echo '<input type="date" id="portfolio_date" name="portfolio_date" value="' . esc_attr($date) . '" class="widefat" />';
        echo '</p>';
        
        echo '<p>';
        echo '<label for="portfolio_url">' . esc_html__('Project URL:', 'portfolio-plugin') . '</label> ';
        echo '<input type="url" id="portfolio_url" name="portfolio_url" value="' . esc_attr($url) . '" class="widefat" />';
        echo '</p>';
    }
    
    /**
     * Save meta box data
     */
    public function save_meta_boxes($post_id) {
        // Security checks
        if (!isset($_POST['portfolio_details_nonce']) || 
            !wp_verify_nonce($_POST['portfolio_details_nonce'], 'portfolio_details_save')) {
            return;
        }
        
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }
        
        if (!current_user_can('edit_post', $post_id)) {
            return;
        }
        
        // Save meta values
        if (isset($_POST['portfolio_client'])) {
            update_post_meta($post_id, '_portfolio_client', sanitize_text_field($_POST['portfolio_client']));
        }
        
        if (isset($_POST['portfolio_date'])) {
            update_post_meta($post_id, '_portfolio_date', sanitize_text_field($_POST['portfolio_date']));
        }
        
        if (isset($_POST['portfolio_url'])) {
            update_post_meta($post_id, '_portfolio_url', esc_url_raw($_POST['portfolio_url']));
        }
        
        // Gallery saving code would go here
    }
    
    /**
     * Portfolio shortcode implementation
     */
    public function portfolio_shortcode($atts) {
        $atts = shortcode_atts(array(
            'category' => '',
            'count' => 6,
            'columns' => 3,
        ), $atts, 'portfolio');
        
        // Query parameters
        $args = array(
            'post_type' => 'portfolio',
            'posts_per_page' => intval($atts['count']),
        );
        
        // Add category filter if specified
        if (!empty($atts['category'])) {
            $args['tax_query'] = array(
                array(
                    'taxonomy' => 'portfolio-category',
                    'field'    => 'slug',
                    'terms'    => explode(',', $atts['category']),
                ),
            );
        }
        
        $query = new WP_Query($args);
        
        // Start output buffer
        ob_start();
        
        if ($query->have_posts()) {
            echo '<div class="portfolio-grid columns-' . esc_attr($atts['columns']) . '">';
            
            while ($query->have_posts()) {
                $query->the_post();
                
                echo '<div class="portfolio-item">';
                echo '<a href="' . esc_url(get_the_permalink()) . '">';
                
                if (has_post_thumbnail()) {
                    echo get_the_post_thumbnail(null, 'portfolio-thumbnail');
                }
                
                echo '<h3>' . esc_html(get_the_title()) . '</h3>';
                echo '</a>';
                echo '</div>';
            }
            
            echo '</div>';
        }
        
        wp_reset_postdata();
        
        return ob_get_clean();
    }
    
    // Other plugin methods would go here
}

// Initialize the plugin
function portfolio_plugin() {
    return Portfolio_Plugin::get_instance();
}
portfolio_plugin();

/**
 * Helper function to get portfolio client
 */
function portfolio_get_client($post_id = null) {
    if (!$post_id) {
        $post_id = get_the_ID();
    }
    return get_post_meta($post_id, '_portfolio_client', true);
}

/**
 * Helper function to get portfolio date
 */
function portfolio_get_date($post_id = null) {
    if (!$post_id) {
        $post_id = get_the_ID();
    }
    return get_post_meta($post_id, '_portfolio_date', true);
}

/**
 * Helper function to get portfolio URL
 */
function portfolio_get_url($post_id = null) {
    if (!$post_id) {
        $post_id = get_the_ID();
    }
    return get_post_meta($post_id, '_portfolio_url', true);
}
        

Implementation Exercise

As you work through implementation, tackle these key tasks:

  1. Complete the theme's single-portfolio.php template
  2. Implement the gallery meta box in the plugin
  3. Create the portfolio.js file for handling filtering
  4. Develop the plugin's admin settings page
  5. Add appropriate styles for both the frontend and admin interfaces

Implementation Tips:

  • Work incrementally, testing each component before moving to the next
  • Use version control (Git) to track changes and enable rollback if needed
  • Comment your code thoroughly for future maintenance
  • Use WordPress coding standards for consistent, maintainable code
  • Keep security in mind, validating and sanitizing all inputs

Step 4: Review and Extend

After implementing your solution, it's time to review your work and consider extensions.

Testing Checklist

Thoroughly test your portfolio theme and plugin:

Documentation

Create necessary documentation for your project:

Potential Extensions

Consider ways to enhance your portfolio solution:

mindmap root((Portfolio Extensions)) Theme Enhancements Multiple Layout Options Dark/Light Mode Toggle Portfolio Color Schemes Animation Effects Plugin Features Project Testimonials Related Projects Video Support PDF Portfolio Export Integration Social Sharing SEO Optimization Lightbox Integration Analytics Tracking Advanced Features Portfolio Import/Export Client Access Portal Custom Fields Builder Multilingual Support

Reflection Questions

To fully embrace Polya's fourth step, reflect on your development process:

  1. How well did your solution address the original problem?
  2. What parts of the implementation were most challenging?
  3. What would you do differently if starting from scratch?
  4. Which parts of your solution are you most proud of?
  5. How could you apply this approach to other WordPress development problems?

Applying Polya's Method Beyond This Project

The 4-step problem-solving approach can be applied to all WordPress development challenges:

flowchart LR A[WordPress Development Challenge] --> B[1. Understand] B --> C[2. Plan] C --> D[3. Implement] D --> E[4. Review] E --> B B -->|Requirements Gathering| B1[User Needs] B -->|Research| B2[Existing Solutions] C -->|Architecture| C1[Component Structure] C -->|Dependencies| C2[APIs & Integrations] D -->|Development| D1[Code Implementation] D -->|Testing| D2[Validation] E -->|Evaluation| E1[Performance Analysis] E -->|Improvement| E2[Refactoring]

WordPress-Specific Applications

Apply Polya's method to different WordPress development scenarios:

Development Scenario Understanding Phase Planning Phase Implementation Phase Review Phase
E-commerce Site Product needs, customer journey, payment requirements WooCommerce integration, theme compatibility, checkout flow Product templates, payment gateways, shipping methods Conversion rate analysis, checkout optimization
Member Portal Access levels, content restrictions, user experience Membership plugin selection, role management, content strategy Registration process, restricted content, member dashboard User engagement metrics, retention optimization
Content Migration Content structure, metadata, relationships Migration tools, data mapping, testing strategy Data extraction, transformation, loading, verification Content integrity check, performance impact analysis

Final Project Submission

Your weekend project submission should include:

  1. Project Files:
    • Complete theme folder
    • Complete plugin folder
    • SQL export of sample data (optional)
  2. Documentation:
    • README files for both theme and plugin
    • Implementation notes following Polya's 4 steps
    • Screenshots of key features
  3. Reflection Paper:
    • Brief description of your solution
    • Challenges encountered and how you overcame them
    • What you learned from applying Polya's method
    • Future improvements you'd like to make

Submit all files as a compressed ZIP archive through the course submission portal by Sunday at 11:59 PM.

Resources and References

Estimated Time to Complete

Based on the project scope and complexity, here's an estimated timeline:

Day 1 (Saturday)

Day 2 (Sunday)

Total Estimated Time: 20-26 hours

Experience level adjustments: