This is my best practices for WordPress but it is also the one FOR MOST OF THE WORDPRESSS DESIGNERS/DEVELOPERS. Some of these practices are useful to check code quality of themes/plugins.
You may/should break away from WordPress Coding Standards and follow PSR if you are not a core/core-plugin developer (If you haven't followed either of WordPress Conding Standards or PSR, it is a bad habit) .
- The filename convention of WordPress Coding Standards doesn't support namespace/abstract class/interface/trait.
- It has bad practices such as Yoda Conditions.
- use spaces instead of real tabs.
- You may use
<?= $var; ?>in your template on PHP 5.4+ (You should not use PHP 5.2, 5.3).
- follow PSR
- files only for WordPress may follow WordPress Coding Standard. e.g. you may place your template tags in
includes/template-tags.php.
- do not use Yoda conditions.
- use the latest version of PHP, at least 5.5+. You should not use PHP 5.2, 5.3 and 5.4. If some plugins you are using cause error(s), stop using the plugins.
- use WordPress only for blog, content publishing and consider other CMSs/CMFs/Frameworks if you want to build SNS/Comminity site/Membership site/EC etc. Customized WordPress breaks easily and the maintenance becomes difficult soon. Finally, your site get stuck in the spell of WordPress.
- read Codex, API documentation at first. You should not copy & paste code snippet someone wrote. Besides, reading WordPress code is better.
- use UTF-8 and LF. You should not use Notepad on Windows and you should remove .DS_Store, _MACOSX if you works on OSX.
- Template: use
endif,endforeach,endwhileinstead of}. - Template: write single template tag per single line/single php tag. e.g.
<?php if (...) : ?><?php // do_something ?><?php endif; ?>instead of<?php if (...) : /* do_something */ endif; ?>. - Template: use WP_Query or
pre_get_postsfilter (or the wrapper function/method of WP_Query) instead ofget_posts(),query_posts()etc. However, using action/filter isn't a good idea because we cannot handle the dependencies and we cannot stop propagation either. - always add prefix to your template function.
- always check whether the function you declare hasn't already existed by
function_exists()whenever you declare your template function. - create your own template function if the code includes any logics.
- create function/method for
add_action(),add_filter()etc. instead of calling them in your constructor. Such side-effect in the constructor makes it difficult to extend/re-use class(es) and it causes conflict between other themes/plugins. In addition, consider create event listener class(es) for them. - wrap your object with your template functions.
- always check whether the function exists before you use non-standard functions.
- consider using
get_*()andapply_filters()thenesc_*()instead ofthe_*().the_*()can be injected malicious output by filters. - use instance method in your class instead of
do_shortcode(). - use closure instead of
create_function(). - create the plugin for your theme. Theme should not include any features that are not related to theme-specific things such as the appearance.
- manage dependencies with container etc. instead of using Child theme feature. Extending by inheritance is a bad practice. Child theme breaks easily.
- pass WordPress global variable(s) or only the argument(s) that is/are used to function/method, instead of using
globalkeyword in your function/method. - use WP_Scripts/WP_Styles (
register_*(),enqueue_*()can be OK) instead you directly place styles/scripts in head element (or before closing body tag). - use Composer for dependency management and autoload. You can dynamically map namespace to your class by using
Composer\Autoload\ClassLoader::addPsr4()etc. anytime, anywhere. - use guard clauses instead of teribble nest of
ifetc. - pass array to function instead of query-like
foo=foo_value&bar=bar_valuearguments. - use
$arr['key']instead ofextract($arr, EXTR_SKIP);or consider other solutions to resolve options, for example, by using OptionResolver. - Plugin: use global variable(s) only for exporting object(s). Otherwise, wrap all variables with Class/Closure. Using DI/IoC/AOP container is a better idea.
- manage dependencies by using WP_Scripts/WP_Styles and concanate/minify them on your build process instead of using plugins such as Head Clear. Such plugins cannot correctly handle dependencies and it breaks dependencies if there are a few styles/scripts that aren't properly registered.