I have reviewed several wordpress themes submitted to wordpress.org. I have seen that most theme developers who code the theme, repeat the same common mistakes again and again. Back in the wordpress team, we follow strict guidelines and best coding practices, which is why we go through every bit of code and every file in the them, to see everything is properly implemented, and only best ones qualify for approval.
First, before uploading your wordpress theme, take your time carefully review these guidelines here: http://codex.wordpress.org/Theme_Review
Have you tested your theme with the test data? https://codex.wordpress.org/Theme_Unit_Test
I am putting together the most common mistakes committed by theme developers, causing the submitted theme not approved!
1. Watch out for errors or warnings in your theme.
If we see any error, notices or warnings, generated by your theme, we are certainly not going to approve your theme and it will come back to you. Sometimes these warnings are invisible, which is why you have to enable WP_DEBUG to true in wp-config.php
- Test using one of the following methods:
- Via wp-config.php:
define(WP_DEBUG, true);
- Via Plugin: Log Deprecated Notices and/or Debogger
- Via wp-config.php:
- Themes must not generate any notices, warnings or other errors!
Note: Some themes throw notices, upon deactivation. Make sure you test this on the last part.
2. Do not use Bloginfo() to get paths
Do not use bloginfo(‘template_url’) / bloginfo (‘stylesheet_directory’) or TEMPLATEPATH / STYLESHEETPATH to get the template directory or stylesheet path. Use get_feed_link( 'feed' ) instead of bloginfo('feed_url')
We do not approve themes using bloginfo to get the path of directory or stylesheet, instead replace them with these.
Template/Stylesheet Path:
- Themes are required to use
get_template_directory()
rather thanTEMPLATEPATH
to return the template path. - Themes are required to use
get_stylesheet_directory()
rather thanSTYLESHEETPATH
to return the stylesheet path.
3. No Hardcoding scripts in document head of header.php
We reject themes which hardcoded javascripts or any other resources (except styles.css) in the document <head> in header.php.
The proper way to add scripts and stylesheets is using wp_enqueue_style() and wp_enqueue_scripts() in functions.php
Themes are required to enqueue all stylesheets and scripts, using wp_enqueue_style()
/wp_enqueue_script()
, and hooked into an appropriate hook via callback function, rather than hard-coding stylesheet/script links or tags in the template.
4. Social sharing in themes
We generally do not approve themes containing social icons in theme, for these reasons.
- Social sharing fall into plugin territory (implement as a separate plugin)
- All third party images and icons used must be 100% GPL. You must document the license information in readme.txt
So dont implement social sharing in your theme.
5. License Issues
You have to be very careful with licensing terms, when including third party resources in your theme. We require all theme bundled resources (images, scripts etc..) to be 100% GPL. You must document each license in readme.txt so that we can check it. Further, to make it easy for you, we have compiled a list of GPL compatible licenses here: https://make.wordpress.org/docs/theme-developer-handbook/releasing-your-theme/theme-review-guidelines/#bundled-resources
6. Theme Name Selection
When chosing a theme name, you have to make sure that you cannot have “WordPress” or “Theme” in your theme name. It must be unique and distinct.
- Themes are not to use WordPress in their name. For example My WordPress Theme, WordPress AwesomeSauce, and AwesomeSauce for WordPress would not be accepted. After all, this is the WordPress Theme repository.
- Themes are not to use the term Theme in their name, such as: AwesomeSauce Theme. Same reason as above … it’s a Theme repository.
- Themes may use the WP acronym in the Theme name, such as WP AwesomeSauce.
- Themes are not to use version-specific, markup-related terms (e.g. HTML5, CSS3, etc.) in their name.
- Themes are not to use related terms (e.g. Blog, Web Log, Template, Skin, etc.) in their name.
- Themes are not to use Theme author/developer credit text in their name.
- Themes are not to use related Theme names (e.g. WP Twenty Eleven, Twenty Eleven WP, The Twenty Eleven, etc.) in their name.
7. Footer Credit Links
We only allow one hard coded footer link, with credit to author website. It cannot be spammy and be sure that you escape the hard coded URL using esc_url. An example is below
<span>Theme by <a href="<?php echo esc_url('https://corpocrat.com'); ?>">Corpocrat</a></span>
8. Readme.txt
Dont be lazy to document about your theme in readme.txt. We at the review team, are definitely going to look at this file, to understand how your theme works. You must document everything including install instructions, all the licenses here. Any page templates you have coded for your theme, must be documented here, describing what exactly they do.
9. Do not use function_exists()
Themes must not provide backward compatibility for out-of-date WordPress versions, including using function_exists()
conditional wrappers for current WordPress functions.
10. Unique Theme Slug in Functions.php
Functions.php is a the heart of a wordpress theme. We carefully go through every function, hooks and actions written in this file and nothing can escape our eyes. All template tags and function hooks must be implemented properly wrapped with a unique theme slug.
An example of the very well written tidy code, wrapped inside a function:
/************************ Theme Initial setup ***********************************/ add_action ('after_setup_theme','thinlines_theme_setup'); function thinlines_theme_setup () { add_theme_support('post-thumbnails'); set_post_thumbnail_size(150, 150, true); add_theme_support( 'automatic-feed-links' ); if ( ! isset( $content_width ) ) $content_width = 1115; $thinlines_settings = get_option('thinlines-options'); update_option('thinlines-options', $thinlines_settings); }
11. Do not forget 404.php and search.php
When reviewing a theme, We check these files to find out whether they work or not. So do not forget to include these files in your theme.
12. Including theme Files
At the minimum, wordpress themes are required to have the following files to work properly.
Theme are recommended to include these files:
- 404.php
- archive.php
- page.php
- search.php
- single.php
- header.php (via
get_header()
) - footer.php (via
get_footer()
) - sidebar.php (via
get_sidebar()
)- Note: header.php, footer.php, and sidebar.php include variations such as: sidebar-left.php, sidebar-right.php, sidebar-footer.php, etc.
All the files must be called via these functions, rather than using includes…
- All headers are included via
get_header()
- All footers are included via
get_footer()
- All comments templates are included via
comments_template()
- All sidebars are included using
get_sidebar()
- All template part files are included via
get_template_part()
- Any search form markup is included via
get_search_form()
- Any login form markup is included via
wp_login_form()
13. Screenshot size
Many wordpress theme developers completely overlook the screenshot size.
screenshot.png
- Recommended 4:3 W:H ratio, size 600x450px (2x the previous 300x225px, to account for Retina displays).
- Maximum size: 600x450px but 880×660 is recommended.
14. Admin Theme Options Page
When you implement theme options page, in the admin area, you must make sure you follow these guidelines. If not we are certainly not going to approve your theme.
- Themes are required to use the add_theme_page() function to add the Theme Settings Page to the Appearance menu, rather than using add_menu_page() to add a top-level menu.
- Themes are required to use the edit_theme_options capability for add_theme_page(), rather than rely on a role (e.g. “administrator”), or a different capability (e.g. “edit_themes”, “manage_options”) for the capability to add the settings page.
- Themes are recommended to use
do_settings_sections()
to output settings sections/fields, rather than hard-coding markup
15. Theme Security
We take security built into wordpress themes very seriously and we reject themes which implement poor form of security in theme. Imagine your theme used by hundreds of thousands of users and iamgine, if hacked or compromised?
We expect all input data to be properly validated and escaped when outputting in the theme.
- Themes are required to validate and sanitize all untrusted data before entering data into the database, and to escape all untrusted data before being output in the Settings form fields or in the Theme template files (see: Data Validation)
- Themes are required to use esc_attr() for text inputs and esc_html() (or esc_textarea() in WP 3.1) for textareas.
- Themes are recommended to use the Settings API to get and save form input data rather than rely on $_POST and $_REQUEST data directly.
- Themes are required to provide explicit Settings-page nonce checking, if not using the Settings API (see: WordPress Nonces)
16. Saving Theme Options in Database
When you implement saving theme options data in admin area, simply using get_option() and set_option() will not work. Lets say, If you have 100 theme settings to store, then set_option() will end up creating 100 fields in the wordpress options database, which isnt the way to do. The correct way is store all the values in a single options array and store that array as a single value in database.
As a theme reviewer, i am certainly not gonna approve themes which endup creating too many options, all over the database.
17. Use Core Built in WordPress Scripts
Always try to call and use core built in wordpress scripts, like jquery. You dont need to include separate jquery files in the theme. For example jquery can be enqueued and added to the theme using just one line.
wp_enqueue_script('jquery');
18. Favicons
Try to avoid implementing favicons, but if implemented If implemented, favicon functionality is required to be opt-in by user with user defined favicon, and disabled by default.
19. Checkboxes and Radioboxes
For checkboxes and select options, Themes are required to use the checked() and selected() functions for outputting checked=”checked” and selected=”selected”, respectively.
20. Theme Required Hooks
Themes are required to use the following hooks in their themes.
The following template tags and hooks are required to be included where appropriate:
wp_title()
wp_head()
– (immediately before </head>)body_class()
– (inside <body> tag)$content_width (use it in functions.php and set its width properly)
post_class() (used with posts)
wp_link_pages() (page navigation)
paginate_comments_links()
, orprevious_comments_link()
/next_comments_link()
posts_nav_link()
, orprevious_posts_link()
/next_posts_link()
, orpaginate_links()
wp_footer()
– (immediately before </body>)
21. More and Next Tags
More tag: It allows the user to specify user defined excerpt in the latest blog posts, without the auto trimmed excerpt. You can insert the more tag in the tinymce editor. We anticipate that themes properly implement more tags: http://en.support.wordpress.com/splitting-content/more-tag/
Next tags: break the post/page into sections:
page – <!–nextpage–> WordPress tag similar to the more
tag, except it can be used any number of times in a post, and each insert will “break” and paginate the post at that location. Hyperlinks to the paginated sections of the post are then generated in combination with the wp_link_pages() or link_pages() template tag.
22. Styling Issues
We look for any issues with styles in the theme including margins or content bleeding. You might want to fix any of these issues when uploading the theme.
23. Plugin Territory
This is very important. Many theme developers, dont realize which functions fall into plugin territory. Themes must not incorporate the following, Plugin-territory functionality
- Analytics scripts
- SEO options (meta tags, page title, post titles, robots.txt, etc.)
- Social Sharing buttons/links
- Custom post-content shortcodes
- Custom Post Types
- Custom Taxonomies
- Removing or modifying non-presentational core hooks
- Disabling the admin toolbar
- Resource compression/caching
Note for deciding when to add functions to functions.php or to a specific plugin: You may find that you need the same function to be available to more than one parent theme. If that is the case, the function should be created in a plugin instead of a functions.php for the specific theme. This can include template tags and other specific functions. Functions contained in plugins will be seen by all themes.
24. Widgets and Sidebars
These are the guidelines for implementing widgets in themes.
(i) Custom Widgets
- Themes may OPTIONALLY unregister core Widgets. If unregistered, Themes are REQUIRED to replace these Widgets with their own (extended) version.
(ii) All widget and sidebars must be registered properly using the following functions..
register_sidebar()
dynamic_sidebar()
add_action(widgets_init)
,register_widget()
(see Widgets API) – (if Theme uses custom widgets)
25. Google Fonts and Libraries
The proper way to include google fonts is not to hardcode in the document head. The correct way is to enqueue using wp_enqueue_style() function. Don’t use http or https in the link.
wp_register_style('thinlines-fonts','//fonts.googleapis.com/css?family=Fjalla+One|Open+Sans:300');
26. Stylesheets
We allow only one styles.css to be hardcoded in header.php. This is still not recommended, but again the correct way to add one or more stylesheets is through wp_enqueue_style() in functions.php
Lets take a look on an example below.
wp_enqueue_style( 'thinlines-css', get_stylesheet_uri() ); // include default stylesheet styles.css
27. Sidebars
All sidebars implemented must have a separate file sidebar.php or sidebar-left.php or sidebar-right.php and can be called using get_sidebar() function.
<?php get_sidebar(); ?> // calls sidebar.php <?php get_sidebar('left'); ?> // calls sidebar-left.php