ThemeForest WordPress Theme Approval Checklist

repository·master·Indexed 41 days ago

https://github.com/hasinhayder/themeforest-wp-theme-approval-checklist

A comprehensive checklist and best-practices guide for developers creating WordPress themes for ThemeForest submission. Covers technical requirements including coding standards, security, split licensing, prefixing functions, and architectural boundaries such as avoiding 'Plugin Territory' and using TGMPA for helper plugins.

Tokens
2.5K
Snippets
8
Records
15
Agent score
50%

What's inside ThemeForest WP Theme Approval Checklist

  1. Avoid 'Plugin Territory' in themes

    master

    Themes should not change the default behavior or look-and-feel of WordPress core panels or components. Such functionality belongs in a plugin, not a theme.

    Move the following to a helper plugin:

    • Any call to wp_mail().
    • Registering custom taxonomies.
    • Registering custom post types (CPTs).
    • Adding new columns or checkboxes to core admin tables (e.g., the 'All Posts' table).
  2. Rename script and CSS handles

    master

    When enqueueing external CSS or JavaScript files, do not use generic or default handles. Use meaningful, readable, and unique handler names within the wp_enqueue_script() and wp_enqueue_style() functions to avoid conflicts with other plugins or themes.

    function mythemename_enqueue_js_and_css() {
        // Use unique handles like 'mythemename' instead of generic ones
        wp_enqueue_script( "mythemename", mythemename_get_js_assets_dir()."/scripts.js", array("jquery"), "1.0.1", true);
        wp_enqueue_style( "mythemename", mythemename_get_css_assets_dir()."/styles.css", null, "1.0.1" );
    }
    add_action( 'wp_enqueue_scripts', 'mythemename_enqueue_js_and_css' );
  3. Prefix functions, image sizes, and global variables

    master

    To avoid naming collisions, all theme-specific identifiers must be prefixed with a consistent string (e.g., themename_, authorname_, or frameworkname_). You cannot use multiple different prefixes.

    Ensure the following are prefixed:

    • All function names.
    • All image sizes registered via add_image_size().
    • All global variable names declared outside of function scopes.
    $mythemename_variable = "whatever";
    
    function mythemename_setup() {
        add_image_size("mythemename_single_hero", 1140, 9999);
    }
    add_action( 'after_setup_theme', 'mythemename_setup' );
  4. Bundle helper plugins using TGMPA

    master

    If your theme requires a helper plugin (to handle CPTs, taxonomies, etc.), you must bundle the plugin as a .zip file inside your theme directory (e.g., in a /plugin/ folder). Use the TGMPA (TGM Plugin Activation) library to declare it as a required asset.

    Note: Do not host the plugin in a remote location for installation; it must be included within the theme zip.

    add_action( 'tgmpa_register', 'mythemename_register_required_plugins' );
    
    function mythemename_register_required_plugins() {
        $plugins = array(
            array(
                'name'               => 'ThemeName Plugin Name',
                'slug'               => 'themename-helper-plugin',
                'source'             => get_template_directory() . '/plugin/themename-helper-plugin.zip',
                'required'           => true,
                'force_activation'   => false,
                'force_deactivation' => false,
            ),
        );
    
        $config = array(
            'id'           => 'themename',
            'default_path' => '',
            'menu'         => 'tgmpa-install-plugins',
            'has_notices'  => true,
            'dismissable'  => true,
            'dismiss_msg'  => '',
            'is_automatic' => false,
            'message'      => '',
        );
    
        tgmpa( $plugins, $config );
    }
  5. Add Google Fonts following best practices

    master

    When adding Google Fonts, use a method that allows for character set support checks. This prevents issues where certain fonts might not support specific languages. Use wp_enqueue_style with a dynamically constructed URL that includes the desired font families and subsets.

    wp_enqueue_style( 'prefix-google-font', prefix_get_google_font_url() );
    
    function prefix_get_google_font_url() {
        $font_url = '';
        $arizonia = _x( 'on', 'Arizonia font: on or off', 'massive' );
        $source_sans_pro = _x( 'on', 'Source Sans Pro font: on or off', 'massive' );
    
        if ( 'off' !== $arizonia || 'off' !== $source_sans_pro ) {
            $font_families = array();
            if ( 'off' !== $arizonia ) { $font_families[] = 'Arizonia'; }
            if ( 'off' !== $source_sans_pro ) { $font_families[] = 'Source Sans Pro:400,300,400italic,600'; }
    
            $query_args = array(
                'family' => urlencode( implode( '|', $font_families ) ),
                'subset' => urlencode( 'latin,latin-ext' ),
            );
            $font_url = add_query_arg( $query_args, '//fonts.googleapis.com/css' );
        }
        return esc_url_raw( $font_url );
    }
  6. Enqueue jQuery as a dependency

    master

    Do not enqueue jQuery directly using wp_enqueue_script('jquery');. Instead, list jquery in the dependency array of the script that requires it. This ensures WordPress uses its bundled version of jQuery correctly.

    // CORRECT: Define jquery as a dependency
    wp_enqueue_script( "bootstrap-js", mythemename_get_js_assets_dir()."/bootstrap.js", array("jquery"), null, true );
    
    // INCORRECT: Do not do this
    // wp_enqueue_script('jquery'); 
  7. How to customize the search form using the get_search_form filter

    master

    To avoid rejection, do not hardcode search form markup directly into your theme templates. Instead, use the WordPress function get_search_form(). If you need to use custom markup, hook into the get_search_form filter to return your custom HTML.

    add_filter("get_search_form", "mythemename_get_search_form");
    
    function mythemename_get_search_form($form) {
        return "<your own search form code>";
    }