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
,endwhile
instead 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_posts
filter (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
global
keyword 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
if
etc. - pass array to function instead of query-like
foo=foo_value&bar=bar_value
arguments. - 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.