Объективные рекомендации по разработке плагинов?[закрыто]

wordpress.stackexchange https://wordpress.stackexchange.com/questions/715

Вопрос

Запускаю вики-сообщество, чтобы собрать цель рекомендации по разработке плагинов.Этот вопрос был навеян Комментарии @EAMann о wp-хакерах.

Идея состоит в том, чтобы совместно определить, какими могут быть объективные наилучшие практики, чтобы мы потенциально могли в конечном итоге использовать их в каком-нибудь процессе проверки совместной работы сообщества.

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

Это было полезно?

Решение

Используйте действия и фильтры

Если вы думаете, что люди хотели бы добавить или изменить некоторые данные: предоставлять Apply_filters () Перед возвращением.

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

Может быть, все будет иначе, если бы WordPress имела возможность автоматически установить плагины, на которых зависели другие плагины? Поскольку мне обычно приходится писать много функциональности, которые мне нужны с нуля, потому что клиенты хотят, чтобы вещи были определенным образом и доступные плагины, в то время как 90% там, не позволяйте мне гибкости обновлять оставшиеся 10%.

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

Давайте возьмем пример из Другой вопрос:

Пример: я хочу что -то сделать в своем плагине, когда кто -то ретвитит статью. Если бы был собственный крючок в том, что популярный плагин ретвита заключается в том, что я мог бы зацепить и отключиться, это было бы здорово. Нет, поэтому я могу изменить их плагин, чтобы включить его, но это работает только для моей копии, и я не хочу пытаться перераспределить это.

Связанный

Другие советы

Загружать сценарии/css с wp_enqueue_script а также wp_enqueue_style

Плагины не должны загружать / пытаться загружать дублирующиеся версии файлов JS / CSS, особенно jQuery и других файлов JS, включенных в Core WP.

Плагины всегда должны использовать wp_enqueue_script а также wp_enqueue_style При связывании файлов JS и CSS и никогда не через <script> теги.

Связанный

Поддержка I18n

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

Обратите внимание, что очень важно загружать языковые файлы во время init действие, чтобы пользователь мог подключиться к этому действию.

Смотрите Кодекс: I18n для разработчиков WordPress

А также эта статья: Правильная загрузка языковых файлов WP.

Начиная с WordPress 4.6+

WP 4.6 изменил порядок загрузки и проверил местоположения, это намного упростило задачу разработчикам и пользователям.

Рассматривая плагин с текстовым доменом "my-plugin", WordPress теперь сначала будет искать файл перевода в:
/wp-контент/языки/плагины/my-plugin-en_US.mo

Если ему не удастся найти его там, он будет искать тот, где плагин указывает ему искать (обычно в папке pluigns 'language', если следовать кодексу):
/wp-контент/плагины/my-plugin/языки/my-plugin-en_US.mo

Наконец, если языковой файл не найден, он проверит расположение по умолчанию:
/wp-контент/языки/мойплагин-en_US.mo

Первая проверка была добавлена в версии 4.6 и предоставляет пользователям определенное место для добавления языкового файла, поскольку раньше им нужно было знать, куда разработчик добавил языковой файл, теперь пользователю просто нужно знать textdomain плагина:/wp-контент/языки/плагины/ТЕКСТОВЫЙ ДОМЕН-LOCAL.mo


Ниже приведен старый способ (не актуален со времен WP 4.6+)

[...]
Наконец, я хотел бы отметить, что это важно для загрузите пользовательские языковые файлы пользователя из WP_LANG_DIR перед загрузкой языковых файлов, поставляемых вместе с плагином.Когда для одного и того же домена загружается несколько mo-файлов, будет использоваться первый найденный перевод.Таким образом, языковые файлы, предоставляемые плагином, будут служить резервным вариантом для строк, не переведенных пользователем.

public function load_plugin_textdomain()
{
    $domain = 'my-plugin';
    // The "plugin_locale" filter is also used in 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.Посмотрите на Кодекс при отладке для получения более подробной информации.

Сначала используйте существующие функции в WordPress Core

Если вы можете: Используйте существующие функции, включенные в WordPress Core вместо того, чтобы писать свой собственный. Разработайте пользовательские функции PHP только в том случае, если в ядре WordPress нет подходящей ранее существовавшей функции.

Одним из преимуществ вы можете использовать "Прогоревшие уведомления" легко контролировать функции, которые следует заменить. Другое преимущество заключается в том, что пользователи могут просматривать функциональную документацию в кодексе и лучше понять, что делает плагин, даже если они не являются опытным разработчиком PHP.

Связанный

Удаление должно удалить все данные плагина

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

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

Связанный

Предотвратить инъекцию SQL с входными данными

Плагин должен дезинфицировать весь пользовательский ввод, полученный прямо или косвенно (например, через $_POST или же $_GET) перед использованием входных значений для запроса базы данных MySQL.

Видеть: Форматирование заявлений SQL.

Префикс все глобальные элементы пространства имен

Плагин должен должным образом префикс всех глобальных элементов пространства имен (константы, функции, классы, переменные, даже такие вещи, как пользовательские таксономии, типы публикаций, виджеты и т. Д.). Например, не создавайте функцию, вызванную init(); Вместо этого назовите это что -то вроде jpb_init().

Это обычное значение должно использовать тремя или четыре буквы префикса перед именами или использовать Функция пространства имен PHP. Анкет Сравнивать: Однобуквенное префикс для констант класса PHP?

Связанный

Используйте код PHP5, ориентированный на класс и объект

Нет причин не писать чистый, объектно-ориентированный код PHP5. Поддержка PHP4 будет исходить после следующего выпуска (WP 3.1). Конечно, вы можете префикс всех имен ваших функций, чтобы в конечном итоге undless_long_function_names_with_lots_of_underscores, но гораздо проще просто написать простой класс и объединить все в этом. Кроме того, поместите свой класс в отдельный файл и назовите его соответственно, чтобы вы могли легко расширить и сохранить его:

// in functions.php
require 'inc/class-my-cool-plugin.php';
new MyCoolPlugin();

// in inc/class-my-cool-plugin.php
class MyCoolPlugin {
    function __construct() {
        // add filter hooks, wp_enqueue_script, etc.

        // To assign a method from your class to a WP 
        // function do something like this
        add_action('admin_menu', array($this, "admin"));
    }

    public function admin() {
        // public methods, for use outside of the class
        // Note that methods used in other WP functions 
        // (such as add_action) should be public
    }

    private function somethingelse() {
        // methods you only use inside this class
    }
}

Деактивация не должна провоцировать потери данных

Плагин не должна удалить любые данные на дезактивация.

Связанный

Включите только файлы, которые вам нужны ...

Если вы находитесь в передней части, не включайте код, который относится к области администратора.

Объявить о потери данных о удалении плагина

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

Связанный

Пусть имя папки плагина будет изменено

/plugins/pluginName/{различные}

«Плагиннам», используемое для папки, всегда должна быть изменена.

Обычно это обрабатывается путем определения констант и неизменно используя их по всему плагину.

Излишне говорить, что многие популярные плагины - грешники.

Связанный:

  • plugins_url() Для легкой связи с ресурсами, включенным в плагин.

Используйте обработку ошибок WordPress (встроенный)

Не просто return; Если какой -то пользовательский ввод был неправильным. Доставить им некоторую информацию о том, что было сделано неправильно.

function some_example_fn( $args = array() ) 
{
    // If value was not set, build an error message
    if ( ! isset( $args['some_value'] ) )
        $error = new WP_Error( 'some_value', sprintf( __( 'You have forgotten to specify the %1$s for your function. %2$s Error triggered inside %3$s on line %4$s.', TEXTDOMAIN ), '$args[\'some_value\']', "\n", __FILE__, __LINE__ ) );

    // die & print error message & code - for admins only!
    if ( isset( $error ) && is_wp_error( $error ) && current_user_can( 'manage_options' ) ) 
        wp_die( $error->get_error_code(), 'Theme Error: Missing Argument' );

    // Elseif no error was triggered continue...
}

Одна ошибка (объект) для всех

Вы можете настроить глобальный объект ошибки для вашей темы или плагина во время начальной загрузки:

function bootstrap_the_theme()
{
    global $prefix_error, $prefix_theme_name;
    // Take the theme name as error ID:
    $theme_data = wp_get_theme();
    $prefix_theme_name = $theme_data->Name;
    $prefix_error = new WP_Error( $theme_data->Name );

    include // whatever, etc...
}
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' ) ) // some required value not set
        $prefix_error->add( $prefix_theme_name, sprintf( 'The function %1$s needs the argument %2$s set.', __FUNCTION__, '$args[\'whatever\']' ) );

    // continue function...
}

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

function dump_theme_errors()
{
    global $prefix_error, $prefix_theme_name;

    // Not an admin? OR: No error(s)?
    if ( ! current_user_can( 'manage_options' ) ! is_wp_error( $prefix_error ) )
        return;

    $theme_errors = $prefix_error->get_error_messages( $prefix_theme_name );
    echo '<h3>Theme Errors</h3>';
    foreach ( $theme_errors as $error )
        echo "{$error}\n";
}
add_action( 'shutdown', 'dump_theme_errors' );

Вы можете найти дополнительную информацию в это кв. Анкет Связанный билет, чтобы исправить «совместную» WP_Error а также wp_die() Связан оттуда, и еще один билет последует. Комментарии, критики и так ценится.

Минимизировать имена, добавленные в глобальное пространство имен

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

Это можно сделать путем инкапсулирования функций плагина в класс или с помощью PHP имен функции. Анкет Префикс все может помочь, но не так гибко.

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

Связанный

Комментарий с использованием phpdoc

Лучшая практика находится близко к стилю PHPDOC. Если вы не используете IDE, такой как «Затмение», вы можете просто взглянуть в руководстве PHPDOC.

Вам не нужно точно знать, как это работает. Профессиональные разработчики могут в любом случае читать код и просто нуждаться в этом в качестве резюме. Хобби -кодеры и пользователи могут оценить то, как вы объясняете это на том же уровне знаний.

Используйте API настройки перед add_option

Вместо добавления параметров в БД через функцию add_option, вы должны сохранить их как массив с использованием Настройки API Это позаботится обо всем для вас.

Используйте API модификации темы перед add_option

А Модификации API это довольно простая конструкция и безопасная способ, которая позволяет добавлять и извлекать параметры. Все сохраняется как сериализованное значение в вашей базе данных. Легко, безопасно и просто.

Защитите конфиденциальность пользователей плагинов

(Ранее: анонимное общение API)

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

Плагины хоста на wordpress.org

Использовать SVN репозиторий Предоставлено на WordPress.org Для хостинга плагинов. Это делает для более легкого обновления пользовательского опыта, и если вы никогда раньше не использовали SVN, это заставляет вас действительно понять, используя его в контексте, который его оправдывает.

Предоставить контроль доступа с помощью разрешений

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

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

Импорт / Экспорт Настроек плагина

Это не так часто встречается среди плагинов, но если у вашего плагина есть (некоторые) настройки, это следует обеспечить импорт / экспорт данных, таких как конфигурация и пользовательский ввод.

Импорт / экспорт улучшает удобство использования плагина.

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

Похожие

Организовать свой код

Это всегда трудно читать код, который не записан в том порядке, который он выполняется. Сначала включите/требуется, определите, WP_ENQUEUE_STYLE & _SCRICT и т. Д., Затем функции, которые нуждаются в плагине/теме и, наконец, строитель (Ex. Edmin Ecrece, материал, которые интегрируются в тему и т. Д.).

Попробуйте разделить такие вещи, как CSS и JS в их собственных папках. Также попробуйте сделать это с помощью функций, которые являются только помощниками, такими как уставки для массива и аналогичные. Сохранение «основного» файла как можно более чистый и простой в прочтении - это способ, который помогает пользователям, разработчикам и вам, когда вы пытаетесь обновить за год и не видели код в течение более длительного времени.

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

Умереть стилем

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

С использованием wp_die() также помогает, что ваши плагины / темы совместимы с WordPress TestSuite.

Связанный:

Обеспечить справочные экраны для пользователей

Ничевично сказать, что RTFM (нажмите на помощь) в качестве ответа, чем необходимость отвечать на вопрос снова и снова.

/**
  * Add contextual help for this screen
  * 
  * @param $rtfm
  * @uses get_current_screen
  */ 
  function ContextualHelp( /*string*/ $rtfm) 
  { 
     $current_screen = get_current_screen();
     if ($current_screen->id == $this->_pageid) 
     {
        $rtfm .= '<h3>The WordPress Plugin - Screen A</h3>';
        $rtfm .= '<p>Here are some tips: donate to me ' .
     }
     return $rtfm; 
  }
add_action('contextual_help', array($this,'ContextualHelp'),1,1);

Обновление / примечание: (См. Комментарии Kaiser): приведенный выше пример должен использоваться в классе

Предлагайте расширяемые формы

Когда плагин предлагает возможность для входных данных, он всегда должен иметь крючок в конце, прямо перед кнопкой «Отправить» и/или «сбросить», поэтому разработчики могут легко расширить форму не только полями, но и кнопками.

Видеть: Настройки API

Связанный

Включите функцию всегда через крючок, не напрямую.

Пример:

  • Не используйте для включения класса плагина через новый без крючка

  • Используйте Hook Plugins_Loaded

    // add the class to WP                                   
    function my_plugin_start() {                                                               
        new my_plugin();   
    }                                                        
    add_action( 'plugins_loaded', 'my_plugin_start' );
    

Обновлять:маленький живой пример: Плагин-SVN-Prunk-Pageи псевдо -пример

//avoid direct calls to this file where wp core files not present
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() {
        }

    } // end class

    function plugin_start() {

        new plugin_class();
    }

    add_action( 'plugins_loaded', 'plugin_start' );
} // end class_exists

Вы также можете загрузить через MU_PLUGINS_LOADED на MultiSite-Install, см. Кодекс для справки: http://codex.wordpress.org/plugin_api/action_referenceТакже вы видите, как Inlcude WP с этим крючком: http://adambrown.info/p/wp_hooks/hook/plugins_loaded?version=2.1&file=wp-settings.phpЯ использую это очень часто, и это не так сложно и рано, лучше, как новый класс ();

Лицензионные плагины по лицензии, совместимой с GPL

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

(Это есть был проблемой и серьезно точка дебатов оба в прошлом и подарок.)

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

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

Минимизировать побочные эффекты удаленных данных и веб-сервисов

Плагин должен Кэш/щит веб -сервис и/или Запросы XMLRPC/SOAP через уровень кэширования/предоставления данных Если вы используете их, чтобы не делать фронт-запросы, ожидающие (медленного) ответа на веб-сервис.

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

Одним из возможных шагов (примером отправки на ping.fm): Создайте буферную таблицу, скажем: ping_fm_buffer_post (дата, время, сообщение, отправленное_тейс, статус)

  1. На каждый раз, когда вы хотите отправлять обновление на ping.fm, добавьте его в эту таблицу.
  2. Теперь нам нужно создать плагин для обработки этих данных. Этот плагин будет работать через Crontab, чтобы проверить каждое обновление, которое еще не отправлено
  3. Поскольку у нас есть эта таблица, мы также можем перечислить каждое сообщение, представленное на ping.fm и проверить статус каждого поста. На случай, если есть проблемы на стороне Ping.fm, мы можем повторно отдать ее.

Проверьте свой плагин

У нас должно быть окончательно иметь некоторые инструменты тестирования в нашей среде разработки плагинов.

На основе этот ответ по Итан Сейферт На вопрос о тестировании, это хорошая практика, чтобы следовать:

  • Ваше модульное тестирование должно проверить наименьшее количество поведения, которое может выполнить класс.
  • Когда вы подходите к уровню функционального тестирования, именно здесь вы можете проверить, что вы кодируете с помощью зависимостей WordPress.
  • В зависимости от того, что делает ваш плагин-рассмотрите возможность использования тестов на основе селена, которые проверяют наличие данных в DOM с помощью идентификаторов
Лицензировано под: CC-BY-SA с атрибуция
Не связан с wordpress.stackexchange
scroll top