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

Использование действий и фильтров
Если вы считаете, что пользователи могут захотеть добавить или изменить данные: предоставьте apply_filters() перед возвратом.
P.S. Одна вещь, которая меня немного расстраивает и на которую указывает ваш вопрос, — это процент плагинов, разработанных только для конечных пользователей, то есть не имеющих собственных хуков. Представьте, если бы WordPress был разработан как большинство плагинов? Он был бы негибким и очень нишевым решением.
Возможно, всё было бы иначе, если бы WordPress имел возможность автоматически устанавливать плагины, от которых зависят другие плагины? В текущей ситуации мне часто приходится писать большую часть необходимой функциональности с нуля, потому что клиенты хотят определённых вещей, а доступные плагины, хоть и покрывают 90% потребностей, не позволяют гибко доработать оставшиеся 10%.
Мне действительно хотелось бы, чтобы лидеры сообщества WordPress нашли способ поощрять плагины, следующие лучшим практикам (например, добавление хуков для других разработчиков), подобно тому, как поощряются хорошие ответы на StackExchange.
Рассмотрим пример из другого вопроса:
Пример: я хочу выполнить что-то в своём плагине, когда кто-то ретвитит статью. Если бы в популярном плагине для ретвитов был кастомный хук, к которому я мог бы подключиться, это было бы замечательно. Но его нет, поэтому я могу модифицировать их плагин, чтобы добавить его, но это будет работать только в моей копии, и я не хочу пытаться распространять это дальше.
Связанные материалы

Загрузка скриптов и CSS с помощью wp_enqueue_script
и wp_enqueue_style
Плагины не должны загружать или пытаться загружать дублирующиеся версии файлов JS/CSS, особенно jQuery и других JS-файлов, входящих в ядро WordPress.
Плагины всегда должны использовать wp_enqueue_script
и wp_enqueue_style
для подключения JS и CSS файлов, а не напрямую через теги <script>
.
Связанные темы

Рекомендация: Возможно, стоит добавить небольшую заметку об использовании зависимостей (поскольку это часть системы enqueue).

Да, но лучше сначала зарегистрировать стили и скрипты, а затем подключать их по ID. Это удобно для других разработчиков, чтобы изменять скрипты или использовать их в своих плагинах. Также проще изменить порядок или создать объединенный файл.

Плюс, загружайте скрипты и стили только на нужных страницах. http://scribu.net/wordpress/optimal-script-loading.html

Поддержка интернационализации (I18n)
Все выводимые строки должны быть привязаны к соответствующему текстовому домену, чтобы обеспечить возможность интернационализации заинтересованными сторонами, даже если разработчик не планирует переводить свой плагин самостоятельно.
Важно отметить, что загрузка языковых файлов должна происходить во время действия init
, чтобы пользователь мог подключиться к этому действию.
См. Codex: Интернационализация для разработчиков WordPress
А также эту статью: Правильная загрузка языковых файлов в WordPress.
Начиная с WordPress 4.6+
В WordPress 4.6 изменился порядок загрузки и места проверки, что значительно упростило жизнь разработчикам и пользователям.
Рассмотрим плагин с текстовым доменом 'my-plugin'. Теперь WordPress СНАЧАЛА будет искать файл перевода по пути:
/wp-content/languages/plugins/my-plugin-en_US.mo
Если файл не найден, WordPress проверит путь, указанный в плагине (обычно в папке 'language', если следовать рекомендациям Codex):
/wp-content/plugins/my-plugin/languages/my-plugin-en_US.mo
В крайнем случае, если языковой файл так и не найден, будет проверено стандартное расположение:
/wp-content/languages/my-plugin-en_US.mo
Первый вариант был добавлен в версии 4.6 и предоставляет пользователям определенное место для добавления языкового файла. Раньше пользователям нужно было знать, где разработчик разместил языковой файл, теперь же достаточно знать текстовый домен плагина: /wp-content/languages/plugins/ТЕКСТОВЫЙ_ДОМЕН-ЛОКАЛЬ.mo
Старый способ (Не актуально с версии WP 4.6+)
[...]
Наконец, хочу подчеркнуть, что важно загружать пользовательские языковые файлы из WP_LANG_DIR перед загрузкой языковых файлов, поставляемых с плагином. Когда для одного домена загружено несколько MO-файлов, будет использован первый найденный перевод. Таким образом, языковые файлы плагина будут служить резервным вариантом для строк, не переведенных пользователем.
public function load_plugin_textdomain()
{
$domain = 'my-plugin';
// Фильтр "plugin_locale" также используется в load_plugin_textdomain()
$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
load_textdomain(
$domain,
WP_LANG_DIR . '/my-plugin/' . $domain . '-' . $locale . '.mo'
);
load_plugin_textdomain(
$domain,
FALSE,
dirname( plugin_basename(__FILE__) ) . '/languages/'
);
}

Для меня это самый важный момент. Это не требует много дополнительной работы, но делает ваш плагин гораздо полезнее для миллионов пользователей, для которых английский не является родным языком. Вам даже не нужно самому переводить ни одного слова — достаточно просто подготовить всё для перевода.

Убедитесь, что плагины не вызывают ошибок при WP_DEBUG
Всегда тестируйте свои плагины с включённой опцией WP_DEBUG
и, в идеале, держите её включённой на протяжении всего процесса разработки. Плагин не должен вызывать НИКАКИХ ошибок при включённом WP_DEBUG
. Это включает в себя уведомления об устаревших функциях и непроверенных индексах.
Чтобы включить режим отладки, отредактируйте файл wp-config.php
, установив константу WP_DEBUG
в значение true
. Подробнее см. в Кодексе по отладке.

Пожалуйста, ознакомьтесь с ОБНОВЛЕНИЕM о том, что в каждом ответе должна быть только одна лучшая практика; можете ли вы разделить на несколько ответов?

Спасибо, и это не ваша оплошность, а моя. Я пересмотрел вопрос, чтобы попросить одну лучшую практику в каждом ответе, основываясь на вопросе @hakre о дубликатах и том, как это должно работать.

Сначала используйте существующие функции в ядре WordPress
По возможности: используйте встроенные функции WordPress вместо написания собственных. Разрабатывайте собственные PHP-функции только тогда, когда в ядре WordPress нет подходящей готовой функции.
Одним из преимуществ является возможность использовать "уведомления об устаревании" для простого отслеживания функций, которые следует заменить. Ещё одно преимущество — пользователи могут просмотреть документацию по функциям в Codex и лучше понять, что делает плагин, даже если они не являются опытными PHP-разработчиками.
Связанные материалы

Одна из самых больших проблем здесь - узнать, что существует подходящая готовая функция. Было бы полезно иметь место, где можно публиковать код и/или потребности в функциональности, чтобы сообщество могло подсказать, какую функцию лучше использовать. Может быть, для этого можно использовать StackExchange?

Фух. Это было бы довольно сложно и, я думаю, бесконечной задачей. Я считаю, что лучше всего расширять кодекс таким образом, поскольку он уже существует.

Думаю, расширение кодекса и, возможно, ссылки оттуда на соответствующие темы на StackExchange было бы вполне достаточно.

Проблема в том, что большая часть ядра не спроектирована структурно для повторного использования. Мне пришлось скопировать и немного модифицировать половину функций для работы с изображениями и метаданными, чтобы создать свой тип записи, который ведёт себя как вложение, просто потому что функция downsize() вызывает другую функцию, которая содержит жёстко заданную проверку post-type='attachment'. Таких примеров множество — например, негибкая функция wp_count_posts(). Прежде чем можно будет повторно использовать ядро, WordPress нуждается в полном рефакторинге.

Удаление плагина должно очищать все его данные
После удаления из системы WordPress плагин должен удалить все созданные им файлы, папки, записи и таблицы в базе данных, а также значения опций, которые он создал.
Плагины могут предоставлять возможность экспорта/импорта настроек, чтобы пользователи могли сохранить настройки вне WordPress перед удалением.
Связанные темы

Это должно быть поведением по умолчанию, да, но также должно быть предложение пользователю сохранить некоторые данные... как при удалении видеоигры, когда вас спрашивают, хотите ли вы удалить сохранения и загруженные материалы. Пользователь может деактивировать плагин только для тестирования и не захочет заново настраивать все параметры при повторной активации.

Я говорю только о случаях, когда плагин полностью удаляется, а не когда он деактивируется.

Я понимаю это... но иногда я удаляю плагины, чтобы вручную добавить их заново из резервной копии или бета-версии, которая ещё не размещена в репозитории...

@EAMann: Для этого, а также для переноса плагинов на другой сервер, плагин должен предоставлять механизм экспорта и импорта настроек.

@MikeSchinkel: Готово: http://wordpress.stackexchange.com/questions/715/objective-best-practices-for-plugin-development/925#925

Это так часто игнорируется. Только вчера я обнаружил настройки и целые таблицы, которые раздувают мою базу данных. Это так раздражает!

Я не совсем уверен, что согласен. Если плагин создает свои собственные таблицы в базе данных — да, но с новыми пользовательскими типами записей, которые используются для всего, мы (надеюсь) скоро увидим плагины, использующие общие типы записей и так далее. Это может сделать тему "удаления данных" довольно сложной.

Я видел несколько плагинов, которые предлагают кнопку "Удалить" в их настройках с большими красными предупреждениями о том, что это удалит все данные. Это отдельно от деактивации, и, я думаю, отличный способ решить эту проблему. Не все используют кнопку "Удалить" для удаления плагина.

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

Предотвращение SQL-инъекций при работе с входными данными
Плагин должен санировать все пользовательские данные, полученные напрямую или косвенно (например через $_POST
или $_GET
) перед использованием этих значений в запросах к базе данных MySQL.
Смотрите: Форматирование SQL-запросов.

Также следует санировать данные, выходящие из базы данных. В общем, никогда не доверяйте данным, которые не захардкожены. http://codex.wordpress.org/Data_Validation — тоже хороший справочник.

Используйте классы и объектно-ориентированный PHP-код
Нет причин не писать чистый, объектно-ориентированный PHP-код. Поддержка PHP4 прекращена ещё в 2008 году. Конечно, вы можете добавлять префиксы ко всем именам функций и получать что-то вроде бесконечно_длинные_имена_функций_с_кучей_подчёркиваний
, но гораздо проще создать простой класс и собрать всё внутри него. Также поместите ваш класс в отдельный файл и назовите его соответствующим образом, чтобы его можно было легко расширять и поддерживать:
// в functions.php
require 'inc/class-my-cool-plugin.php';
new MyCoolPlugin();
// в inc/class-my-cool-plugin.php
class MyCoolPlugin {
function __construct() {
// добавляем хуки фильтров, wp_enqueue_script и т.д.
// Чтобы назначить метод из вашего класса для функции WP,
// сделайте что-то подобное
add_action('admin_menu', [$this, "admin"]);
}
public function admin() {
// публичные методы для использования вне класса
// Обратите внимание, что методы, используемые в других функциях WP
// (например, add_action), должны быть public
}
private function somethingelse() {
// методы, которые используются только внутри этого класса
}
}

не используйте new MyCoolPlugin(); я считаю, что лучше подключиться к WP через хук: plugins_loaded

Не уверен насчет этого. Согласно кодексу, plugins_loaded загружается одним из самых первых, поэтому думаю, что нет большой разницы между таким конструктором и добавлением его как экшена.

это просто одно из лучших практик, которое делает работу удобнее для всех.

Насколько я могу судить, добавление хука в plugins_loaded не дает никаких улучшений и не может считаться лучшей практикой, так как нет никаких преимуществ. Наоборот, это может привести к увеличению использования памяти и снижению скорости, поскольку код должен проходить через действие, вместо того чтобы просто добавлять действия напрямую. Кроме того, использование ООП не всегда следует считать лучшей практикой.

Есть ли согласие по поводу того, как создавать объект – через хук или без него?

Это отличная идея, но нужно быть осторожным и убедиться, что файл класса подключается только если сервер использует PHP5. Пример можно посмотреть здесь: https://github.com/iandunn/WordPress-Plugin-Skeleton/blob/master/bootstrap.php.

Префикс для всех элементов глобального пространства имён
Плагин должен правильно добавлять префикс ко ВСЕМ элементам глобального пространства имён (константам, функциям, классам, переменным, а также пользовательским таксономиям, типам записей, виджетам и т.д.). Например, не создавайте функцию с именем init()
; вместо этого назовите её, например, jpb_init()
.
Обычно рекомендуется использовать трёх- или четырёхбуквенный префикс перед именами или воспользоваться возможностями пространств имён в PHP. Сравните: Однобуквенные префиксы для констант классов в PHP?
Связанные материалы

Деактивация не должна приводить к потере данных
Плагин не должен удалять свои данные при деактивации.
Связанные темы

Предупреждение о потере данных при удалении плагина
При удалении плагин должен предупредить пользователя о том, что его данные будут удалены, получить подтверждение от пользователя перед удалением данных, а также предоставить возможность сохранить данные при удалении. (Эта идея принадлежит @EAMann.)
Связанные темы

Сам WordPress отображает предупреждающее сообщение в админке о том, что это происходит (по крайней мере, в текущей версии trunk).

Помимо предупреждающего сообщения от WordPress, плагин не может запросить подтверждение у пользователя, так как на момент удаления он уже деактивирован. Но см. тикет #20578.

Разрешить изменение имени папки плагина
/plugins/pluginname/{разные файлы}
Имя "pluginname", используемое для папки, всегда должно быть изменяемым.
Обычно это реализуется путем определения констант и их последовательного использования во всем плагине.
Не секрет, что многие популярные плагины грешат несоблюдением этого правила.
Связанные темы:
plugins_url()
- для простого создания ссылок на ресурсы, включенные в плагин.

Переименование папки плагина приведет к сбою автоматических обновлений, поэтому я не уверен, что это лучший вариант.

В любом случае, вам придется повторно включить плагин после внесения изменений (переименование, скорее всего, приведет к деактивации плагина), после чего WordPress заново создаст или обновит соответствующие записи в базе данных, связанные с плагинами (так что обновления не сломаются).

Минимизация имен, добавляемых в глобальное пространство имен
Плагин должен максимально снижать свое влияние, минимизируя количество имен, которые он добавляет в глобальное пространство имен.
Этого можно добиться, инкапсулировав функции плагина в класс или используя функционал пространств имен в PHP. Префиксирование всех элементов также может помочь, но оно менее гибкое.
Помимо функций и классов, плагин не должен вводить глобальные переменные. Использование классов обычно делает их ненужными и упрощает поддержку плагина.
Связанные темы

Можете, пожалуйста, перенести пункт "не следует вводить глобальные переменные" в отдельный ответ? Это связано, но отделено от данного вопроса, и на самом деле я хотел бы обсудить этот момент (как потому что, возможно, не согласен в особых случаях, так и потому что хочу узнать мнение других.)

Используйте встроенную в WordPress обработку ошибок
Не просто используйте return;
, если какие-то пользовательские данные были неверны. Предоставьте им информацию о том, что было сделано неправильно.
function some_example_fn( $args = array() )
{
// Если значение не было установлено, создаем сообщение об ошибке
if ( ! isset( $args['some_value'] ) )
$error = new WP_Error( 'some_value', sprintf( __( 'Вы забыли указать %1$s для вашей функции. %2$s Ошибка вызвана в %3$s на строке %4$s.', TEXTDOMAIN ), '$args[\'some_value\']', "\n", __FILE__, __LINE__ ) );
// Завершаем выполнение и выводим сообщение об ошибке и код - только для администраторов!
if ( isset( $error ) && is_wp_error( $error ) && current_user_can( 'manage_options' ) )
wp_die( $error->get_error_code(), 'Ошибка темы: Отсутствует аргумент' );
// Если ошибка не была вызвана, продолжаем...
}
Один объект ошибки для всех
Вы можете создать глобальный объект ошибки для вашей темы или плагина во время загрузки:
function bootstrap_the_theme()
{
global $prefix_error, $prefix_theme_name;
// Используем название темы как ID ошибки:
$theme_data = wp_get_theme();
$prefix_theme_name = $theme_data->Name;
$prefix_error = new WP_Error( $theme_data->Name );
include // что угодно и т.д...
}
add_action( 'after_setup_theme', 'bootstrap_the_theme' );
Позже вы можете добавлять неограниченное количество ошибок по требованию:
function some_theme_fn( $args )
{
global $prefix_error, $prefix_theme_name;
$theme_data = wp_get_theme();
if ( ! $args['whatever'] && current_user_can( 'manage_options' ) ) // какое-то обязательное значение не установлено
$prefix_error->add( $prefix_theme_name, sprintf( 'Функции %1$s требуется установленный аргумент %2$s.', __FUNCTION__, '$args[\'whatever\']' ) );
// продолжаем выполнение функции...
}
Затем вы можете собрать все ошибки в конце работы вашей темы. Таким образом, вы не прерываете отображение страницы, но все равно можете вывести все ошибки для разработки.
function dump_theme_errors()
{
global $prefix_error, $prefix_theme_name;
// Не администратор? ИЛИ: Нет ошибок?
if ( ! current_user_can( 'manage_options' ) ! is_wp_error( $prefix_error ) )
return;
$theme_errors = $prefix_error->get_error_messages( $prefix_theme_name );
echo '<h3>Ошибки темы</h3>';
foreach ( $theme_errors as $error )
echo "{$error}\n";
}
add_action( 'shutdown', 'dump_theme_errors' );
Дополнительную информацию вы можете найти в этом вопросе. Связанный тикет для исправления "совместной работы" WP_Error
и wp_die()
доступен по ссылке, и еще один тикет появится позже. Комментарии, критика и подобное приветствуются.

Зачем создавать объект WP_Error, если вы только обращаетесь к его свойствам и никогда не передаёте экземпляр как объект?

@ProfK Я переработал код, чтобы сделать его короче, и заголовок/содержание для wp_die();
были неправильными (перепутаны местами). По поводу вашего вопроса) Я не совсем понял. Когда вы создаёте экземпляр класса WP_Error, у вас есть полный доступ к его данным через такие функции, как get_error_code();
, get_error_message();
, get_error_data();
и их множественные версии. Вы также можете создать экземпляр только один раз при загрузке темы или плагина и просто использовать $error->add();
для добавления других ошибок, а затем вывести их все в подвале с помощью $error->get_error_messages();
.

@ProfK Я буду публиковать будущие обновления в этом вопросе. Сейчас я изучаю поведение класса wp error и хочу написать тикет о публичном API для ошибок темы (черновик уже готов). Внизу вопроса вы найдёте ссылку на другой тикет, который сближает WP_Error
и wp_die()
(уже есть патч). Любые комментарии, предложения, критика и прочее очень приветствуются.

Используйте Settings API вместо add_option
Вместо добавления опций в базу данных через функцию add_option, вы должны сохранять их в виде массива, используя Settings API, который позаботится обо всём за вас.
Используйте Theme Modifications API вместо add_option
Modifications API — это довольно простой и безопасный способ, позволяющий добавлять и извлекать настройки. Всё сохраняется в базе данных как сериализованное значение. Просто, безопасно и удобно.

Кроме того, используйте update_option
и никогда не используйте add_option
, так как функция update создаст опцию, если она не существует.. :)

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

Комментирование с использованием PhpDoc
Лучшей практикой считается стиль, близкий к PhpDoc. Если вы не используете IDE, такую как "Eclipse", вы можете просто ознакомиться с руководством по PhpDoc.
Вам не нужно точно знать, как это работает. Профессиональные разработчики в любом случае могут прочитать код и им нужна лишь краткая сводка. Любители и пользователи могут оценить то, как вы объясняете это на понятном им уровне.

Защита конфиденциальности пользователей плагинов
(Ранее: Анонимное API-взаимодействие)
Если плагин взаимодействует с внешней системой или API (например, с каким-либо веб-сервисом), он должен делать это анонимно или предоставлять пользователю анонимную опцию, гарантирующую, что никакие данные, связанные с пользователем плагина, не попадут к третьей стороне без контроля.

Размещение плагинов на WordPress.org
Используйте SVN-репозиторий, предоставляемый WordPress.org, для хостинга плагинов. Это обеспечивает более удобный процесс обновления для пользователей. Если вы никогда раньше не работали с SVN, этот опыт поможет вам понять его в контексте, который оправдывает его использование.

Контроль доступа с использованием разрешений
Во многих случаях пользователи могут не хотеть, чтобы все имели доступ к областям, созданным вашим плагином, особенно с плагинами, выполняющими множество сложных операций — одной проверки прав с жестко заданными параметрами может быть недостаточно.
Как минимум, необходимо реализовать соответствующие проверки прав для всех видов операций, которые может выполнять ваш плагин.

Организуйте свой код
Всегда трудно читать код, который написан не в порядке его выполнения. Сначала подключайте файлы через include/require, определения (define), wp_enqueue_style и _script и т.д., затем функции, которые нужны плагину/теме, и в конце — код, который строит функционал (например, админ-панель, интеграции с темой и т.п.).
Попробуйте разделять такие вещи, как CSS и JS, в отдельные папки. То же самое сделайте с функциями-помощниками, например, для работы с массивами. Поддержание "главного" файла максимально чистым и читаемым поможет пользователям, разработчикам и вам самим, когда через год вам понадобится обновить код, который вы давно не видели.
Также хорошо иметь структуру, которую вы часто повторяете, чтобы всегда легко ориентироваться в коде. Разработка в знакомой структуре на разных проектах даст вам время сделать её лучше, и даже если клиент переключится на другого разработчика, вы никогда не услышите "он оставил хаос". Это укрепляет вашу репутацию и должно быть долгосрочной целью.

Я опасаюсь, что это слишком касается стиля, о котором люди будут спорить, а не объективных лучших практик, с которыми согласились бы все уважаемые специалисты. Очень важно, чтобы мы рассматривали только объективные лучшие практики, чтобы люди были готовы согласиться "одобрить" список, а не включать спорные моменты, какими бы благими намерениями они ни были продиктованы.

Импорт / Экспорт настроек плагина
Это не так распространено среди плагинов, но если ваш плагин имеет (некоторые) настройки, он должен предоставлять возможность Импорта / Экспорта данных, таких как конфигурация и пользовательский ввод.
Импорт/Экспорт улучшает удобство использования плагина.
Примером плагина, который имеет такую функциональность импорта и экспорта (а также механизм отмены), является Breadcrumb NavXT (Плагин для WordPress) (полное раскрытие: небольшой вклад моего кода там присутствует, основная работа сделана mtekk).
Связанные темы

Завершаем с стилем
Корректное завершение работы
Все функции плагинов (и даже тем) должны использовать wp_die()
в критических местах, чтобы предоставить пользователю немного информации о том, что произошло. Ошибки PHP раздражают, а wp_die
может вывести пользователю стильное сообщение о том, что плагин (или сам пользователь) сделал не так. Кроме того, если у пользователя отключена отладка, плагин просто сломается.
Использование wp_die()
также помогает обеспечить совместимость ваших плагинов/тем с тестовым набором WordPress.

Предоставление справочных экранов для пользователей
Лучше сказать "RTFM" (нажмите на справку) в качестве ответа, чем отвечать на один и тот же вопрос снова и снова.
/**
* Добавление контекстной справки для этого экрана
*
* @param $rtfm
* @uses get_current_screen
*/
function ContextualHelp( /*string*/ $rtfm)
{
$current_screen = get_current_screen();
if ($current_screen->id == $this->_pageid)
{
$rtfm .= '<h3>Плагин WordPress - Экран A</h3>';
$rtfm .= '<p>Вот несколько советов: пожертвуйте мне ' .
}
return $rtfm;
}
add_action('contextual_help', array($this,'ContextualHelp'),1,1);
обновление / примечание: (см. комментарии от kaiser): приведенный выше пример предназначен для использования в классе

Должен быть в арсенале каждого (если нужно объяснить конкретный экран интерфейса админки). +1

Предоставляйте расширяемые формы
Когда плагин предлагает возможность ввода данных, он всегда должен иметь хук в конце, прямо перед кнопкой "Отправить" и/или "Сбросить", чтобы разработчики могли легко расширять форму не только полями, но и кнопками.
См.: Settings API
Связанные темы

Всегда подключайте функции через хуки, а не напрямую.
Пример:
Не используйте прямое подключение класса плагина через new без хука
Используйте хук plugins_loaded
// добавляем класс в WordPress function my_plugin_start() { new my_plugin(); } add_action( 'plugins_loaded', 'my_plugin_start' );
Обновление: небольшой живой пример: Plugin-svn-trunk-page и псевдо-пример
// избегаем прямых вызовов этого файла, если файлы ядра WP отсутствуют
if (!function_exists ('add_action')) {
header('Status: 403 Forbidden');
header('HTTP/1.1 403 Forbidden');
exit();
}
if ( !class_exists( 'plugin_class' ) ) {
class plugin_class {
function __construct() {
}
} // конец класса
function plugin_start() {
new plugin_class();
}
add_action( 'plugins_loaded', 'plugin_start' );
} // конец class_exists
Вы также можете загружать через mu_plugins_loaded на мультисайт-установках, см. справочник по действиям в codex: http://codex.wordpress.org/Plugin_API/Action_Reference Также здесь вы можете увидеть, как подключить WP с этим хуком: http://adambrown.info/p/wp_hooks/hook/plugins_loaded?version=2.1&file=wp-settings.php Я использую это очень часто, и это не так сложно и рано, лучше чем жесткий вызов new class();

@bueltige --- не мог бы ты объяснить это немного подробнее

небольшой живой пример: [Plugin-svn-trunk-page]http://svn.wp-plugins.org/filter-rewrite-rules/trunk/filter-rewrite-rules.php и псевдо пример
`//избегаем прямых вызовов этого файла, когда файлы ядра wp отсутствуют if (!function_exists ('add_action')) { header('Status: 403 Forbidden'); header('HTTP/1.1 403 Forbidden'); exit(); }
if ( !class_exists( 'plugin_class' ) ) { class plugin_class {
function __construct() { }
} // конец класса
function plugin_start() {
new plugin_class(); }
add_action( 'plugins_loaded', 'plugin_start' ); } // конец class_exists`

Описание вашего плагина должно точно отражать его функциональность. Существует 10 плагинов для избранных записей. Все они отображают избранные записи, но многие имеют разные функции. Читая описание, должно быть легко сравнить ваш плагин с аналогичными.
Следует избегать хвастовства о простоте вашего плагина, если он действительно не является очень базовым. В описание стоит включить полезные ссылки, например, ссылку на настройки.

Плагины, лицензированные под GPL-совместимой лицензией
Плагины и темы должны быть лицензированы под лицензией, совместимой с WordPress. Это позволяет распространять их вместе с WordPress как "программу". Рекомендуемая лицензия — GPL. Убедитесь, что все библиотеки кода, включённые в плагин, совместимы с этой же лицензией.
(Это вызывало проблемы и становилось серьёзным предметом споров как в прошлом, так и в настоящем.)

Давайте пока оставим вопрос совместимости с GPL: http://core.trac.wordpress.org/ticket/14685

Минимизация побочных эффектов удаленных источников данных и веб-сервисов
Плагин должен кэшировать/защищать веб-сервисы и/или запросы XMLRPC/SOAP через слой кэширования/поставщика данных, если вы их используете, чтобы не заставлять фронтальные запросы ждать (медленного) ответа веб-сервиса.
Это включает загрузку RSS-лент и других страниц. Проектируйте свои плагины так, чтобы они запрашивали данные в фоновом режиме.
Один из возможных ШАГОВ (на примере публикации в ping.fm): Создаем буферную таблицу, например: ping_fm_buffer_post( date, time, message, submitted_time, status )
- Каждый раз, когда вы хотите отправить обновление в ping.fm, добавляйте его в эту таблицу.
- Теперь нам нужно создать плагин для обработки этих данных. Этот плагин будет запускаться через crontab, чтобы проверять каждое еще не отправленное обновление
- Поскольку у нас есть эта таблица, мы также можем вывести список всех сообщений, отправленных в ping.fm, и проверить статус каждой публикации. В случае проблем на стороне ping.fm мы можем повторно отправить сообщение.

Я не совсем понимаю, к чему именно вы ведёте. Не могли бы вы предоставить ссылки на вспомогательные материалы?

Также я не совсем уверен, что означает "Net Overhead". Разве нет более подходящего термина? Если он будет понятнее, это сделает правило более объективным. И "Prevent" невозможно; может, заменить на "Minimize"?

Используйте стандарты кодинга WordPress
http://codex.wordpress.org/WordPress_Coding_Standards
Вы знаете, насколько проще обновлять код, над которым работали вы, по сравнению с кодом, написанным кем-то другим? Стандарты кодирования облегчают любому разработчику понимание происходящего в проекте.
Мы понимаем, что ваш плагин или тема — это ваше творение, и то, как вы разбиваете строки и расставляете фигурные скобки, выражает вашу индивидуальность. Каждый отступ — это тщательно продуманное высказывание. Но даже если ваш код не входит в ядро WordPress, вы вносите вклад в его экосистему. Стандарты кодирования помогают разработчикам быстрее разбираться в вашем коде.
