- Theme name must not use keyword like `WordPress`, `Theme`.
- Text domain must be mentioned. Example: Text Domain: my-nepal
- Theme URI and Author URI are optional. If used Theme URI link with the page of theme information and Author URI link with the author personal site or project development site. Avoid using ‘wordpress.org’ as Theme or Author URI.
- License and License URI must be included.
- Version of theme should be mentioned.
- Theme Tags should be written.
- Only three subject tags are allowed.(Example: Blog, Portfolio, Corporate)
- Always pay extra attention and make sure that the entire theme is GPL, or GPL-Compatible. This will include, fonts, scripts, images etc.
- Check all given links for GPL license and sure all mentioned URL’s are GPL compatible.
- External components without GPL license are not allowed.
# Security and Privacy
- Don’t phone home without informed user consent.
- Make any collection of user data “opt-in” only and have a theme option that is set to disabled by default.
# Sanitization and Validation
- Sanitize every theme options used in the theme. You should always escape theme options while output.
- Escaping URL for ensuring no additional texts & characters are there. Example: <a href=”<?php echo esc_url( home_url( ‘/’ ) ); ?>”>Home</a>
- Escaping HTML for ensuring no additional texts & characters are there. Example: $html = esc_html( ‘<a href=”http://www.example.com/”>A link</a>’ );
- Escaping text area & attribute for ensuring no additional texts & characters are there. Example: <?php esc_textarea( $text ); ?>
- Escaping URL for image source. Example: <img src=”<?php echo esc_url( $image ); ?>
- Content Creation like Text area are not allowed on Customizer or Widgets.
# Theme Options
- Settings API is not allowed on theme for Theme Options. Use Customizer API to implement theme options.
- Only one subpage is allowed under Appearance menu. And that should contain relevant information about theme like documentation, user guide, etc.
- Can use any language for text, but only use the same one for all text.
- Themes are required to use as string as the text domain in translation functions.
- Theme must be translation ready. All string need to be translate able. Example: ‘Category:’ it’s translation ready is <?php _e( ‘Category: ‘, ‘textdomain’ ); ?>
- Text domain must be mentioned on ‘style.css’. It must match with the theme name. If theme name is “My Nepal” its text domain is ‘my-nepal’.
- ‘.pot’ must be inside the languages folder and name must be ‘textdomain.pot’.
- Languages must be load on theme file by ‘load_theme_textdomain(‘textdomain’, get_template_directory() . ‘/languages’);’
- Make sure ‘readme.txt’ in is theme root directory.
- If other file like ‘readme.md’,’theme-info.txt’ found on theme directory, recommended to use ‘readme.txt’ request to remove other files.
- ‘readme.txt’ must contain theme info, license info, changelog , short theme description etc. Reference: https://make.wordpress.org/themes/2015/04/29/a-revised-readme/
- No logo or mock up, should be of actual theme it appears.
- Size no bigger than 1200*900px. Any 4:3 image size is accepted.
- If changelog is not maintained on ‘readme.txt’ it must maintained under the ‘changelog.txt’.
- This is now core functionality, new theme should not add this feature.
# Site Logo
- If logo feature is implemented, Logo must be changeable and be disabled by default.
- No plugins are not allowed to bundle in the theme, but theme can recommend plugins and those plugins must be in dot org repository. Theme should work good without any plugin.
# Post Type
- Custom Post types and taxonomies are not allowed.
- No shortcodes are allowed on theme.
# Style and Scripts
- Theme must have ‘style.css’.
- No hard coding of style and scripts are allowed. Style and Scripts need to be enqueued.
- Use ‘get_template_directory_uri()’ instead of ‘get_stylesheet_directory_uri()’.
- No minification of style or scripts files are allowed unless original files are provided.
- If Google font is used, it should be enqueued. No other CDN urls are allowed.
- Default Scripts Included and Registered by WordPress itself. No need to enqueue, like ‘jquery.js, masonry.js’ etc
- Use dependencies on scripts to reduce conflicts.
- Proper DOCTYPE is needed.
- The opening ‘<html>’ tag should include ‘language_attribute’.
- Use ‘bloginfo()’ to set the ‘<meta>’ charset and description element.
- Add a call to ‘wp_head()’ before the closing ‘</head>’ tag. Plugins use this action hook to add their own scripts, stylesheets, and other functionality.
- ‘body_class()’must be inside the opening body tag.
Example: <body <?php body_class(); ?> >
- Do not link the theme stylesheets in the Header template. Use the ‘wp_enqueue_scripts’ action hook in a theme function instead.
- Use the ‘wp_footer()’ call, to appear just before closing body tag.
# Customizer API
- ‘capability’ should be ‘edit_theme_options’ while using Customizer API for theme options.
- ‘sanitize_callback’ is necessary for sanitizing customizer fields. For example: Sanitizing URL ‘sanitize_callback’ => ‘esc_url_raw’
- Sanitizing Email ‘sanitize_callback’ => ‘sanitize_email’ etc.
- add_theme_support( ‘title-tag’ ); must be included on functions.php. Title tag is not allowed in ‘header.php’. If <title><?php wp_title(‘|’); ?></title> found, it is not allowed because title tag already defined.
- Prefix theme functions, classes, global variables, image size name, script and style handles, etc with the theme slug.
//code goes here
- Functions like ‘the_archive_title’ and ‘the_archive_description’ are now available in WordPress core. And thus, we don’t have to keep the backward compatibility for more than last two major versions. They must not be defined. Mostly they are defined in ‘template-tags.php’.
- W and P of WordPress always in uppercase.
- Remove out unnecessary commented code. If any file or folder is not being used, it should be removed.
- It is not necessary to provide backward compatibility more the two major versions.
- No customization in WordPress admin.
- Redirection is not allowed after theme activated.
- Custom CSS field is not allowed. It’s now core functionality. (Since WordPress 4.7)
- It’s not allowed to remove the default functionality of core.