Объективные лучшие практики разработки плагинов?
Создаю вики-сообщество для сбора объективных лучших практик разработки плагинов. Этот вопрос был вдохновлён комментариями @EAMann на wp-hackers.
Идея заключается в совместной работе над определением объективных лучших практик, чтобы впоследствии можно было использовать их в процессе совместного ревью сообщества.
ОБНОВЛЕНИЕ: После первых нескольких ответов стало ясно, что каждый ответ должен содержать только одну идею/предложение/лучшую практику, и перед публикацией нужно проверять список на отсутствие дубликатов.

Тестирование вашего плагина
В нашей среде разработки плагинов обязательно должны быть инструменты для тестирования.
Основываясь на этом ответе от Итана Зайферта на вопрос о тестировании, вот хорошие практики, которым стоит следовать:
- Модульные тесты должны проверять минимально возможное поведение, которое может выполнять класс.
- На уровне функционального тестирования вы можете тестировать ваш код с зависимостями WordPress.
- В зависимости от функционала вашего плагина — рассмотрите возможность использования тестов на основе Selenium, которые проверяют наличие данных в DOM с помощью ID.

Хотя тестирование важно, утверждение, что модульные тесты должны проверять наименьшие, а не наибольшие части, кажется неразумным. Если у вас возникают сложности с тестированием зависимых от WordPress проблем, просто погрузитесь в ядро WordPress — вы найдете множество внутренних глобальных переменных, которые можно использовать для проверки работоспособности элементов.

Но сначала покрыть наименьшие части — это основа, чтобы затем перейти к функциональному тестированию с WordPress, как указано в ответе, разве не так?

Забота о будущих версиях WordPress и темы
Примечание: Перечитав этот совет, я теперь отступаю от этой практики, так как проверка каждого существующего функции может замедлить ваш сайт.
Проверяйте, устарели ли функции непосредственно в вашей теме.
Это пример, "как это может выглядеть".
if ( ! function_exists( 'wp_some_fn' ) )
{
$theme_data = wp_get_theme();
$error = new WP_Error( 'wp_some_fn', sprintf( __( 'Функция %1$s устарела. Пожалуйста, сообщите автору', TEXTDOMAIN ), "Тема: {$theme_data->Name}: Версия {$theme_data->Version}" );
// прерывание
if ( is_wp_error( $error ) )
return print $error->get_error_message();
}
// иначе, если нет ошибки - функция работает и существует
wp_some_fn();
Для правильной/лучшей практики обработки ошибок см. этот ответ: ссылка
Вы можете даже добавить $cause в функцию. Это поможет вам и вашим пользователям отслеживать функции или классы в вашей теме, которые могут измениться.

Используйте осмысленные имена
Давайте осмысленные имена хукам и фильтрам (классам, функциям и переменным), чтобы люди могли идентифицировать их даже через год, когда уже не помнят, откуда взялся этот кусочек кода. Не имеет значения, если имена хуков/фильтров получатся длинными. Например: youruniquename_hook/filter_whatitdoes.
- Если ваш файл содержит класс с именем "dbdbInit", то файл, содержащий этот класс, должен называться "
dbdbInit.class.php
". - Если внутри вашего класса
dbdbInit
есть функция, которая регистрирует, например, пользовательские типы записей, назовите еёregister_custom_post_types()
. - Если у вас есть массив, содержащий имена пользовательских типов записей, назовите переменную, в которой хранится этот массив,
$custom_post_type_names
. - Если у вас есть функция, обрабатывающая массив, назовите её
function array_handler( $array ) { // обработать массив}
. - Просто старайтесь называть вещи так, чтобы по имени было понятно, что они делают или к чему относятся.
Ещё один совет: если вам приходится отлаживать код, в 99% случаев вы получаете сообщения не только для своего кода, но и для WordPress. Поэтому старайтесь использовать один и тот же префикс, например "dbdb
", для своих классов, публичных функций и переменных/объектов. Так вы сможете легко найти их среди сотен файлов. (WordPress загружает 64 файла до вашей темы и около 1,550 функций, не говоря уже о хуках и фильтрах.)

У меня нет четкого понимания, что это означает. Первое предложение не является законченным. Это нужно переписать и уточнить.

Следование стандартам WP при именовании файлов и функций — это тоже хорошая практика, например, "class-db-init.php" http://codex.wordpress.org/WordPress_Coding_Standards

Отделение от основного кода WordPress
Плагин должен сводить использование WordPress API к необходимому минимуму, чтобы отделить код плагина от кода WordPress. Это уменьшает влияние изменений в базовом коде WordPress на плагин. Кроме того, это улучшает кросс-версионную совместимость кода вашего плагина.
Это не означает, что не следует использовать функции WordPress (используйте их, как предлагается в Повторное использование существующих функций), но не следует слишком тесно переплетать ваш код с функциями WordPress, а нужно отделять бизнес-логику плагина от функциональности WordPress.

У меня возникли сложности с формулировкой. Вы имеете в виду, что плагин должен использовать API WordPress везде, где это возможно, вместо прямого доступа к SQL-таблицам и/или глобальным переменным?

Ну вот пример. В одном проекте нам нужно было работать с данными формы, поэтому мы обращались к $_REQUEST. Потом в WordPress изменили механизм экранирования. Вместо использования $_REQUEST напрямую, лучше создать функцию, которая делает единичный вызов $_REQUEST для всего плагина. Если правила экранирования снова изменятся, потребуется правка только в этой функции. Это не против использования API WordPress, а способ сделать плагин менее зависимым от него, чтобы легче реагировать на изменения в ядре WP. Это помогает в долгосрочном сопровождении плагинов. Для простых гаджетов такой подход не обязателен.

Будучи разработчиком с 23-летним стажем (с перерывами), я видел множество циклов и множество "лучших практик", которые появлялись и исчезали. Я наблюдал, как маятник качается в обе стороны. Теперь я верю в умеренность. В начале карьеры я абстрагировал всё подряд, но понял, что абстракция добавляет сложности, которая часто перевешивает ожидаемую пользу. Когда мы сталкиваемся с проблемой, мы сразу ищем способы защититься от неё в будущем, но часто "лекарство хуже болезни". В США закон Сарбейнса-Оксли — яркий пример этого.

Раньше я считал, что глобальные переменные — это просто плохо. Потом я поработал с WordPress и, знаете что, у них есть свои преимущества, если использовать их в меру. Я мог бы написать книгу на эту тему (хотя и не планирую — слишком много работы за слишком маленькое вознаграждение). Где сейчас находится маятник моих взглядов? Простота имеет наивысшую ценность. Возможно, лучше не абстрагироваться заранее, а просто решать проблемы по мере их возникновения, вместо того чтобы тратить кучу времени на страх перед потенциальными проблемами. Поэтому я склонен проголосовать против.

Из короткого вопроса, который я задал на wp-hackers: они вас возненавидят, если вы используете глобальные переменные вроде $wp_taxonomies
, потому что они "внутренние" (хотя я знаю, что есть такие, которые можно использовать, например $wp_query
или $post
)...

@kaiser — Либо что-то является внутренним, либо его изменение нарушит обратную совместимость. Вот вам и глобальное пространство имен в WordPress.

@hakre: Кто говорил о замене? Я говорю о получении и использовании данных из этого. Не всегда есть функция, которая делает то, что вам нужно, и прежде чем я начну писать собственные SQL-запросы, я просто использую их.

@kaiser: Под "изменением" я имел в виду, что данные в этих переменных могут измениться. Или даже ты хотел изменить данные в глобальных массивах? ;) Это огромная экономия времени. Даже если что-то сломается в новой версии, это быстро исправить.

@hakre: Нет, я не играюсь и не изменяю данные, которые предоставляются глобальными переменными. И да: лучше пойти этим путем и сломаться в будущей версии, чем возиться с 5 функциями, которые также могут устареть (и не быть помеченными как устаревшие), а потом исправить это за 5 минут. Экономия времени: +1.

Использование wp options для строк вывода плагина
Для того чтобы сделать плагин простым в использовании и настройке, все строки вывода должны быть изменяемыми. Лучший способ реализовать это - использовать wp-options для хранения строк вывода и предоставить интерфейс для изменения значений по умолчанию. Плагин не должен использовать отображаемые строки, которые нельзя легко изменить через бэкенд плагина.
Пример: Sociable - предоставляет возможность изменить фразу, которая появляется перед иконками "поделиться и насладиться:"

Что именно означает "строка плагина"? Можете привести примеры использования? Также, пожалуйста, пишите полными предложениями, чтобы это могло стать более ценным ресурсом.

Я не согласен. Это упрощает работу конечным пользователям, но усложняет разработчикам. Как сказал Рафаэль, вместо этого следует использовать i18n.

Используйте хуки удаления, активации и деактивации
Для этого существуют три разных хука:
- Удаление
register_uninstall_hook();
- Деактивация
register_deactivation_hook();
- Активация
register_activation_hook();
