Melhores práticas objetivas para o desenvolvimento de plugins? [fechadas]

135

Iniciando um wiki da comunidade para coletar práticas recomendadas objetivas para o desenvolvimento de plugins. Esta pergunta foi inspirada nos comentários de @ EAMann sobre wp-hackers .

A idéia é colaborar com as melhores práticas objetivas, para que possamos eventualmente usá-las em algum processo de revisão da colaboração da comunidade.

ATUALIZAÇÃO: Depois de ver as primeiras respostas, fica claro que precisamos ter apenas uma idéia / sugestão / prática recomendada por resposta e as pessoas devem revisar a lista para garantir que não haja duplicatas antes da publicação.

MikeSchinkel
fonte
Eu realmente não entendo como o wiki da comunidade deve funcionar nisso (e nos outros) com o SE corretamente, mas talvez essa seja uma pergunta sobre o meta. Ele apenas se acumula na maioria das vezes, em respostas duvidosas.
hakre 23/08/10
@ hakre: Ótimo ponto. Depois de ver algo, vou adicionar à descrição que as pessoas devem adicionar apenas uma ideia por "resposta" e vou mudar minha resposta existente para múltipla.
MikeSchinkel

Respostas:

72

Usar ações e filtros

Se você acha que as pessoas gostariam de adicionar ou alterar alguns dados: forneça apply_filters () antes de retornar .

PS Uma coisa que eu acho um pouco decepcionante e que sua pergunta é a porcentagem de plug-ins criados apenas para usuários finais, ou seja, que não têm ganchos próprios. Imagine se o WordPress fosse projetado como a maioria dos plugins? Seria inflexível e uma solução muito específica.

Talvez as coisas fossem diferentes se o WordPress tivesse a capacidade de instalar automaticamente plugins dos quais outros plugins dependem? Normalmente, eu tenho que escrever muitas das funcionalidades que preciso do zero, porque os clientes querem as coisas de uma certa maneira e os plugins disponíveis, enquanto 90% lá, não me permitem a flexibilidade de atualizar os 10% restantes.

Eu realmente desejo que aqueles que lideram a comunidade WordPress identifiquem uma maneira de garantir que os plug-ins sejam recompensados ​​por seguir as melhores práticas (como adicionar ganchos para outros desenvolvedores), assim como boas respostas são recompensadas em um site StackExchange.

Vamos dar um exemplo de outra pergunta :

Exemplo: quero fazer algo no meu plug-in quando alguém retweetar um artigo. Se houvesse um gancho personalizado em qualquer plug-in de retweet popular que eu pudesse conectar e disparar, seria ótimo. Não há, então eu posso modificar o plug-in para incluí-lo, mas isso só funciona para a minha cópia e não quero tentar redistribuí-lo.

Relacionado

Arlen Beiler
fonte
55

Carregar scripts / CSS com wp_enqueue_scriptewp_enqueue_style

Os plug-ins não devem carregar / tentar carregar versões duplicadas de arquivos JS / CSS, especialmente jQuery e outros arquivos JS incluídos no WP Core.

Os plug-ins sempre devem usar wp_enqueue_scripte wp_enqueue_styleao vincular arquivos JS e CSS e nunca diretamente por meio de <script>tags.

Relacionado

hakre
fonte
1
Sugestão : pode valer a pena colocar uma pequena nota sobre o uso de dependências para lá (já que faz parte do sistema de enfileiramento).
t31os 17/02
Certo, mas o melhor é que você registre os estilos e scripts antes e depois enfileire esses scripts via ID. Isso é muito bom para outros desenvolvedores alterarem os scripts ou usá-los em plugins personalizados. Também é mais fácil alterar a ordem ou criar um arquivo de verão.
bueltge
2
além disso, carregue scripts e estilos nas páginas, quando necessário. scribu.net/wordpress/optimal-script-loading.html
MR
49

Suporte I18n

Todas as seqüências de saída devem ser vinculadas a um domínio de texto apropriado para permitir a internacionalização pelas partes interessadas, mesmo que o desenvolvedor não tenha interesse em traduzir seu próprio plug-in.

Observe que é muito importante carregar os arquivos de idioma durante a initação para que o usuário possa se conectar à ação.

Veja o Codex: I18n para desenvolvedores de WordPress

E também este artigo: Carregando os arquivos de idioma WP corretamente .

Desde o WordPress 4.6 ou superior

O WP 4.6 alterou a ordem de carregamento e os locais verificados, facilitando muito para desenvolvedores e usuários.

Considerando-se um plug-in com um textdomain 'my-plugin', WordPress irá agora olhar primeiro para um arquivo de tradução em:
/wp-content/languages/plugins/my-plugin-en_US.mo

Se ele não encontrar um, procurará um em que o plug-in o solicite (normalmente na pasta 'language' da pluigns, se seguir o codex):
/ wp-content / plugins / my-plugin / languages ​​/ my- plugin-en_US.mo

Por fim, se nenhum arquivo de idioma for encontrado, ele verificará o local padrão de:
/wp-content/languages/my-plugin-en_US.mo

A primeira verificação foi adicionada na 4.6 e fornece aos usuários um local definido para adicionar um arquivo de idioma, pois antes eles precisavam saber onde o desenvolvedor adicionou o arquivo de idioma, agora o usuário só precisa conhecer o domínio de texto do plug-in: / wp-content / idiomas / plugins / TEXTDOMAIN-LOCAL.mo


Abaixo está o caminho antigo (Não relevante desde o WP 4.6 ou superior)

[...]
Por fim, gostaria de salientar que é importante carregar arquivos de idioma do usuário personalizados de WP_LANG_DIR antes de carregar os arquivos de idioma que acompanham o plug-in . Quando vários arquivos mo são carregados para o mesmo domínio, a primeira tradução encontrada será usada. Dessa forma, os arquivos de idioma fornecidos pelo plug-in servirão como um substituto para seqüências de caracteres não traduzidas pelo usuário.

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/' 
    );
}
Stiofan O'Connor
fonte
Para mim, o mais importante. Não é muito trabalho extra fazer isso, mas uma das coisas que você pode tornar seu plug-in mais útil para milhões de usuários que não falam inglês como primeira língua. Você nem precisa traduzir nenhuma palavra, mas prepare tudo para ser traduzido.
2ndkauboy
Isso é uma coisa valiosa, mas fácil de fazer, só queria dizer que eu concordo e todo autor de plug-in deve estar fazendo isso.
t31os 17/02
48

Verifique se os plug-ins não geram erros com o WP_DEBUG

Sempre teste seus plugins com o recurso WP_DEBUGativado e, idealmente, ligue-o durante todo o processo de desenvolvimento. Um plug-in não deve gerar QUALQUER erro com ativado WP_DEBUG. Isso inclui avisos obsoletos e índices não verificados.

Para ativar a depuração, edite seu wp-config.phparquivo para que a WP_DEBUGconstante esteja definida como true. Veja o Codex on Debug para mais detalhes.

John P Bloch
fonte
Consulte a ATUALIZAÇÃO sobre ter apenas as melhores práticas por resposta; você pode se dividir em várias respostas?
MikeSchinkel
Claro, sem problemas. Me desculpe por isso.
John P Bloch
Obrigado, e não foi sua supervisão, foi minha. Revisei a pergunta para solicitar uma prática recomendada por resposta, com base na pergunta do @ hakre sobre duplicatas e como fazer isso funcionar.
MikeSchinkel
6
Se eu pudesse aprovar essa resposta duas vezes, eu o faria. É tão frustrante quando estou trabalhando em um site de desenvolvimento e preciso desativar o WP_DEBUG porque um plug-in que preciso usar está emitindo avisos e avisos em todo o lugar.
Ian Dunn
42

Primeiro use as funções existentes no WordPress Core

Se você puder: use as funções existentes incluídas no núcleo do WordPress em vez de escrever suas próprias. Desenvolva apenas funções PHP personalizadas quando não houver uma função pré-existente apropriada no núcleo do WordPress.

Um benefício é que você pode usar "avisos obsoletos de log" para monitorar facilmente as funções que devem ser substituídas. Outro benefício é que os usuários podem visualizar a documentação das funções no Codex e entender melhor o que o plug-in faz, mesmo que não sejam um desenvolvedor PHP experiente.

Relacionado

hakre
fonte
Um dos maiores problemas aqui é saber que existe uma função existente apropriada. O que seria útil seria um local para postar código e / ou funcionalidades que permitam à comunidade comentar sobre qual função usar melhor. Talvez o StackExchange possa ser usado para isso?
MikeSchinkel
Puh. Isso seria bem difícil e acho que algum tipo de tarefa sem fim. Eu acho que estender o codex dessa maneira seria melhor, porque ele já existe.
Kaiser
Eu acho que estender o codex e talvez vincular a partir daí a threads de troca de ações relacionados seria bom o suficiente.
Kaiser
4
Um problema disso é que muitos dos núcleos não são realmente projetados estruturalmente para reutilização. Eu apenas tive que copiar e modificar levemente metade das funções de manipulação de imagem / metadados para criar meu próprio tipo pós-comportamental, apenas porque uma função como downsize () chama alguma função que inclui uma verificação codificada para pós-tipo = 'anexo ' Há muito disso, como o inflexível wp_count_posts (), sendo outro exemplo. Antes que você possa realmente reutilizar, o WP principal precisa de uma refatoração completa.
Wyrfel
Concordo totalmente com isso. Minha todos favorito exemplo: wp-login.php. Assim, "Se você puder" foi um bom começo para a resposta ...
kaiser
35

A desinstalação deve remover todos os dados de um plug-in

Ao ser removido de uma instalação do WordPress, um plug-in deve excluir todos os arquivos, pastas, entradas do banco de dados e tabelas que ele criou, bem como os valores das opções criados.

Os plug-ins podem oferecer uma opção para exportar / importar configurações, para que as configurações possam ser salvas fora do WordPress antes da exclusão.

Relacionado

hakre
fonte
4
Esse deve ser o comportamento padrão, sim, mas também deve solicitar ao usuário que mantenha alguns dados ... como ao desinstalar um videogame, pergunta se você deseja remover os jogos salvos e o material baixado. Um usuário pode estar desativando o plug-in apenas para fins de teste e não deseja voltar a configurar suas opções quando o reativar.
EAMann
1
Eu só estou falando sobre quando um plugin é completamente removido, não quando está desativado.
Travis Northcutt
2
Eu entendo que ... mas às vezes eu vou apagar plug-ins para que eu possa manualmente re-adicioná-los a partir de uma versão de backup ou beta que ainda não está hospedado no repositório ...
EAMann
4
@EAMann: para isso e para migrar plugins para outro servidor, um plug-in deve fornecer um mecanismo para exportar e importar configurações.
hakre
2
Eu já vi alguns plug-ins oferecerem um botão "Desinstalar" em suas configurações com grandes avisos em vermelho que excluirão todos os dados. Isso é separado da desativação e acho uma ótima maneira de lidar com isso. Nem todo mundo usa o botão "Excluir" para remover um plug-in.
Gabrielk
34

Impedir injeção de SQL com dados de entrada

Um plugin deve limpar todas as entradas do usuário recuperadas direta ou indiretamente (por exemplo, via $_POSTou$_GET ) antes de usar valores de entrada para consultar o banco de dados MySQL.

Consulte: Formatando instruções SQL .

hakre
fonte
5
Você também deve limpar os dados que saem do banco de dados. Basicamente, nunca confie em nenhum dado que não esteja codificado. codex.wordpress.org/Data_Validation também é uma boa referência.
Ian Dunn
31

Prefixar todos os itens de namespace global

Um plug-in deve prefixar adequadamente TODOS os itens de namespace global (constantes, funções, classes, variáveis ​​e até coisas como taxonomias personalizadas, tipos de postagem, widgets etc.). Por exemplo, não crie uma função chamada init(); em vez disso, nomeie algo como jpb_init().

É comum usar um prefixo de três ou quatro letras na frente dos nomes ou usar o recurso de espaço para nome do PHP . Compare: Prefixo de uma letra para constantes da classe PHP?

Relacionado

hakre
fonte
31

Use um código PHP5 orientado a classe e objeto

Não há razão para não escrever código PHP5 limpo e orientado a objetos. O suporte ao PHP4 será eliminado após o próximo lançamento (WP 3.1). Obviamente, você pode prefixar todos os nomes de funções para acabar com nomes_de_função_interessante_com_lotes_de_escores, mas é muito mais fácil escrever uma classe simples e agrupar tudo nela. Além disso, coloque sua classe em um arquivo separado e nomeie-o de acordo para que você possa estendê-lo e mantê-lo facilmente:

// 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
    }
}
Husky
fonte
não use o novo MyCoolPlugin (); eu acho que é melhor você ligar no WP via Hook: plugins_loaded
bueltge
Não tenho certeza sobre isso. De acordo com o codex, plugins_loaded é uma das primeiras coisas carregadas, então acho que faz pouca diferença fazer uma construção como essa ou adicioná-la como uma ação.
Husky
5
é apenas uma daquelas práticas recomendadas que a tornam mais agradável para todos.
Arlen Beiler
1
Até onde eu posso ver, adicionar um gancho ao plugins_loaded não oferece melhorias e não seria uma prática recomendada, pois não há melhorias, se houver algo que aumenta o uso da memória, diminui a velocidade, pois é necessário executar uma ação em vez de as ações serem adicionadas. Usar o OO também não deve ser considerado uma prática recomendada.
Backie
4
@IanDunn: se você deseja suporte ao PHP4, mas o suporte ao PHP4 foi retirado desde 2008, há mais de 4 anos. Ainda não há razão para usar verificações específicas do PHP4.
Husky
23

Inclua apenas os arquivos necessários ...

Se você estiver no front-end, não inclua código relacionado à área de administração.

Denis de Bernardy
fonte
21

Anuncie perda de dados na desinstalação de plugins

Após a desinstalação, um plug - in deve solicitar ao usuário que ele excluirá seus dados e receberá uma confirmação de que o usuário pode excluir os dados antes de fazê-lo, e um plug - in também deve permitir ao usuário a opção de manter os dados na desinstalação. (Essa ideia de @EAMann.)

Relacionado

hakre
fonte
3
O próprio Wordpress exibe uma mensagem de aviso no administrador, informando que isso acontece (pelo menos no porta-malas agora).
hakre 24/08/10
Além da mensagem de aviso exibida pelo WordPress, é impossível que o plug-in solicite ao usuário, pois no momento da desinstalação ele já está desativado. Mas veja o ingresso # 20578 .
JD
19

Permita que o nome da pasta do plugin seja alterado

/ plugins / pluginname / {vários}

O "nome do plug-in" usado para a pasta deve sempre ser alterável.

Normalmente, isso é tratado através da definição de constantes e do uso consistente por todo o plugin.

Escusado será dizer que muitos plugins populares são pecadores.

Relacionado:

  • plugins_url() para fácil vinculação aos recursos, incluído no plugin.
AndyBeard
fonte
Renomear a pasta do plug-in fará com que as atualizações automáticas sejam interrompidas, por isso não tenho certeza de que é a melhor coisa a fazer.
mtekk
Você precisaria reativar o plug-in depois de fazer a alteração de qualquer maneira (a alteração do nome provavelmente resultaria na desativação do plug-in); nesse momento, o WP recriará ou atualizará as entradas de banco de dados apropriadas relacionadas aos plug-ins (para que não ocorra interromper as atualizações).
t31os 17/02
Em vez de usar uma constante, use plugin_basename(__FILE__)para descobrir o nome local do plug-in. Isso é útil para ter cópias do mesmo plug-in (teste, várias contas em outro lugar, mas apenas uma por plug-in, ...) também.
Raphael
19

Use WordPress (embutido) Tratamento de erros

Não apenas return;se alguma entrada do usuário estiver errada. Entregue a eles algumas informações sobre o que foi feito errado.

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...
}

Um erro (objeto) para todos

Você pode configurar um objeto de erro global para o seu tema ou plug-in durante a inicialização:

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' );

Mais tarde, você pode adicionar erros ilimitados sob demanda:

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...
}

Então você pode buscá-los todos no final do seu tema. Dessa forma, você não interrompe a renderização da página e ainda pode gerar todos os seus erros para desenvolver

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' );

Você pode encontrar mais informações no presente Q . Um ticket relacionado para corrigir o "trabalho conjunto" de WP_Errore wp_die()está vinculado a partir daí e outro ticket será seguido. Comentários, críticas e tal são apreciados.

kaiser
fonte
Por que você instancia um objeto WP_Error se você acessa apenas suas propriedades e nunca passa a instância como um objeto?
ProfK 28/10
@ProfK Reescrevi para que fosse mais curto e o título / conteúdo wp_die();estava errado (invertido). Sobre o seu Q) Eu não entendo completamente. Quando você configurar uma instância da classe WP_Error você tem pleno acesso a seus dados através de funções como get_error_code();, get_error_message();, get_error_data();e as versões plurais. Você também pode instanciar apenas uma vez na inicialização do seu tema ou plug-in e simplesmente usar $error->add();para preencher outros erros e finalmente produzi-lo no rodapé $error->get_error_messages();para capturá-los todos.
Kaiser
@ProfK Vou postar atualizações futuras para este Q . Atualmente, estou inspecionando o comportamento da classe de erro wp e quero escrever um ticket sobre uma API de erro de tema público (rascunho já concluído). Você encontrará um link para outro ticket que aproxima WP_Errore wp_die()aproxima (já possui um patch) na parte inferior do Q. Qualquer comentário, sugestão, crítica e muito mais é muito apreciado.
kaiser
18

Minimizar nomes adicionados ao espaço para nome global

Um plug - in deve reduzir ao máximo seu impacto , minimizando o número de nomes que ele adiciona ao espaço para nome global .

Isso pode ser feito encapsulando as funções do plug-in em uma classe ou usando o recurso de namespaces do PHP . Prefixar tudo pode ajudar também, mas não é tão flexível.

Ao lado de funções e classes, um plug - in não deve introduzir variáveis ​​globais. O uso de classes normalmente as obsoleta e simplifica a manutenção do plugin.

Relacionado

hakre
fonte
Você pode, por favor, mover o "não deve introduzir variáveis ​​globais" para sua própria resposta? Que está relacionado por separado a partir desta questão e, na verdade, que eu gostaria de debater (tanto porque eu acho que podem discordar é casos especiais e porque eu quero aprender com as opiniões dos outros.)
MikeSchinkel
17

Comentar usando PhpDoc

As melhores práticas estão próximas do estilo PhpDoc. Se você não usa um IDE como "Eclipse", basta dar uma olhada no Manual do PhpDoc .

Você não precisa saber exatamente como isso funciona. Os desenvolvedores profissionais podem ler o código de qualquer maneira e só precisam disso como um resumo. Os codificadores e usuários de hobby podem apreciar a maneira como você o explica no mesmo nível de conhecimento.

kaiser
fonte
17

Use a API de configurações antes de add_option

Em vez de adicionar opções ao banco de dados por meio da função add_option, você deve armazená-las como uma matriz usando a API de configurações que cuida de tudo para você.

Use a API de modificações de temas antes de add_option

A API de modificações é uma construção bastante simples e uma maneira segura que permite adicionar e recuperar opções. Tudo é salvo como valor serializado no seu banco de dados. Fácil, seguro e simples.

kaiser
fonte
1
E, além disso, usar update_optione nunca add_option, a função de atualização criará a opção quando não existe .. :)
t31os
3
Eu não diria nunca usar add_option. Há um bom caso de uso em add_optionque, se a opção já está definida, ela não é alterada, então eu a uso na ativação para preservar as preferências do usuário possivelmente já existentes.
ProfK 28/10/11
1
Outro caso de uso para add_optioné quando você deseja desabilitar explicitamente o carregamento automático. update_optionforçará o carregamento automático a true, então você deseja desativar o carregamento automático, use add_optionao criar a opção inicialmente.
Dave Romsey
16

Proteger a privacidade dos usuários de plug-ins

(Anteriormente: Comunicação API anônima)

Se um plug-in se comunicar com um sistema externo ou API (por exemplo, algum serviço da Web), deverá fazê-lo anonimamente ou fornecer ao usuário uma opção anônima que garanta que nenhum dado relacionado ao usuário do plug-in vaze para uma segunda parte descontrolada.

EAMann
fonte
15

Plugins de host no WordPress.org

Use o repositório SVN fornecido no WordPress.org para hospedar plugins. Isso facilita a atualização da experiência do usuário e, se você nunca usou o SVN antes, faz com que você entenda usando-o em um contexto que o justifique.

MikeSchinkel
fonte
15

Fornecer controle de acesso usando permissões

Em muitos casos, os usuários podem não querer que todos tenham acesso às áreas criadas pelo seu plug-in, especialmente com plug-ins que realizam várias operações complexas, uma única verificação de capacidade codificada pode não ser suficiente.

No mínimo, tenha verificações de capacidade apropriadas para todos os diferentes tipos de procedimentos nos quais seu plug-in pode ser usado.

eddiemoya
fonte
12

Configurações de importação / exportação de plug-in

Não é tão comum entre plugins, mas se o seu plug-in tiver (algumas) configurações, ele deverá fornecer a Importação / Exportação de dados, como configuração e entrada do usuário .

Importar / Exportar melhora a usabilidade de um plugin.

Um exemplo de plugin que possui essa funcionalidade de importação e exportação (e também um mecanismo de desfazer) é o Breadcrumb NavXT (Wordpress Plugin) (divulgação completa: algum código pequeno por mim, a maioria foi feito pelo mtekk).

Relacionado

hakre
fonte
12

Organize seu código

É sempre difícil ler o código que não está escrito na ordem em que é executado. Primeiro inclua / exija, defina, wp_enqueue_style & _script, etc., depois as funções que o plugin / tema precisa e, finalmente, o construtor (por exemplo, tela de administrador, itens que se integram ao tema, etc.).

Tente separar coisas como css e js em suas próprias pastas. Tente também fazer isso com funções que são apenas auxiliares, como niveladores de matriz e similares. Manter o arquivo "principal" o mais limpo e fácil de ler possível é uma maneira de ajudar usuários, desenvolvedores e você, quando você tenta atualizar em um ano e não vê o código há mais tempo.

Também é bom ter uma estrutura que você repita com frequência, para sempre encontrar o caminho. Desenvolver uma estrutura conhecida em diferentes projetos dará a você tempo para torná-la melhor e, mesmo que seu cliente mude para outro desenvolvedor, você nunca ouvirá "ele deixou o caos". Isso cria sua reputação e deve ser uma meta de longo prazo.

kaiser
fonte
Receio que isso seja um pouco exagerado no estilo que as pessoas debateriam e não nas melhores práticas objetivas com as quais todas as pessoas respeitadas concordariam. É muito importante que abordemos apenas as melhores práticas objetivas, para que as pessoas estejam dispostas a concordar em "abençoar" a lista, em vez de ter itens controversos, não importa o quão bem-intencionados.
MikeSchinkel
11

Morrer com estilo

morra de maneira decente Todas as funções de um plug-in (e até mesmo temas) devem ser usadas wp_die()em locais críticos para oferecer ao usuário um pouco de informação sobre o que aconteceu. Os erros de php são irritantes e wp_diepodem dar ao usuário uma boa mensagem de estilo sobre o que o plug-in (ou eles) fizeram de errado. Além disso, se o usuário tiver desativado a depuração, o plug-in será interrompido.

O uso wp_die()também ajuda a que seus plugins / temas sejam compatíveis com o wordpress testsuite .

Relacionado:
hakre
fonte
11

Fornecer telas de ajuda para usuários

É melhor dizer RTFM (clique em ajuda) como resposta do que ter que responder à pergunta várias vezes.

/**
  * 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);

update / note: (veja os comentários do kaiser): o exemplo acima deve ser usado em uma classe

edelwater
fonte
Deve estar na caixa de ferramentas de todos (contanto que você precise explicar uma tela específica da interface do usuário). 1
kaiser
Btw: Você deve mencionar que isso deve residir em uma classe e como interagir com $ this -> _ page_id e como seria se você adicionasse o gancho de ação de um functions.php ou um arquivo de plug-in sem uma classe .
Kaiser
9

inclua a função sempre via Hook, não diretamente.

Exemplo:

  • Não use para incluir a classe do plugin via new without hook

  • Use os plugins do Hook_loaded

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

Atualização: um pequeno exemplo ao vivo: Plugin-svn-trunk-page e um pseudo exemplo

//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

Você também pode carregar via mu_plugins_loaded no multisite-install, consulte o codex para referência de ação: http://codex.wordpress.org/Plugin_API/Action_Reference Também aqui você vê como inlcude o wP com este gancho: http: // adambrown. info / p / wp_hooks / hook / plugins_loaded? version = 2.1 & file = wp-settings.php Eu uso isso com muita frequência e não é tão difícil e precoce, melhor como uma nova classe difícil ();

bueltge
fonte
@bueltige --- você poderia explicar isso um pouco mais
NetConstructor.com
3
um pequeno exemplo ao vivo: [Plugin-svn-trunk-page] svn.wp-plugins.org/filter-rewrite-rules/trunk/… e um pseudo exemplo //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
bueltge
2
@ Netconstructor.co - eu tenho atualizar o fio, o comentário ist feio para o código
bueltge
8

Plug-ins de licença sob uma licença compatível com GPL

Plug-ins e temas devem ser licenciados sob uma licença compatível com WordPress. Isso permite que eles sejam re-distribuídos com o WordPress como um "programa". Uma licença recomendada é a GPL . Certifique-se de que todas as bibliotecas de códigos incluídas no plug-in sejam compatíveis com a mesma licença.

(Este tem sido um problema e um sério ponto de debate, tanto no passado quanto no presente .)

EAMann
fonte
Vamos deixar isso com a compatibilidade da GPL no momento: core.trac.wordpress.org/ticket/14685
hakre
8

A descrição do seu plugin deve detalhar com precisão as funções do seu plugin. Existem 10 plugins de postagem em destaque. Todos eles exibem posts em destaque, mas muitos têm recursos diferentes. Deve ser fácil comparar seu plug-in com plugins semelhantes lendo a descrição.

Você deve evitar se gabar de quão simples é o seu plug-in, a menos que seja realmente muito básico. Você deve incluir links úteis na descrição, como o link para as configurações.

Greg
fonte
7

Minimize os efeitos colaterais de fontes de dados remotas e serviços da Web

Um plug - in deve armazenar em cache / proteger serviços da Web e / ou XMLRPC / SOAP por meio de uma camada de cache / provedor de dados, se você usá-los para não fazer com que as solicitações anteriores aguardem uma resposta (lenta) do serviço da web.

Isso inclui o download de feeds RSS e outras páginas. Crie seus plugins para que eles solicitem dados em segundo plano.

Um STEP possível é (Pegue a postagem no ping.fm como exemplo): Crie uma tabela de buffer, digamos: ping_fm_buffer_post (data, hora, mensagem, submit_time, status)

  1. Sempre que você desejar enviar atualizações para o ping.fm, adicione-as a esta tabela.
  2. Agora, precisamos criar um plug-in para lidar com esses dados. Este plugin será executado via crontab para verificar todas as atualizações que ainda não foram enviadas
  3. Como temos essa tabela, também podemos listar todas as mensagens enviadas ao ping.fm e verificar o status de cada postagem. Caso haja algum problema do lado do ping.fm, podemos enviá-lo novamente.
hakre
fonte
Eu realmente não entendo para onde você está indo exatamente com isso. Você pode fornecer alguns links para material de apoio?
precisa saber é o seguinte
Além disso, não sei exatamente o que é "Net Overhead" . Não existe um termo melhor? Se for mais claro, será uma regra objetiva melhor. E Prevenir " é impossível; " Minimizar "em vez disso?
MikeSchinkel
Você (provavelmente) está certo. Palavras erradas e prevenção nunca são possíveis, minimize os melhores ajustes.
hakre
7

Teste seu plugin

Devemos definitivamente ter algumas ferramentas de teste em nosso ambiente de desenvolvimento de plugins.

Com base nesta resposta de Ethan Seifert a uma pergunta de teste, estas são boas práticas a serem seguidas:

  • Seu teste de unidade deve testar a menor quantidade de comportamento que uma classe pode executar.
  • Quando você chega ao nível de teste funcional, é aqui que você pode testar seu código com dependências do Wordpress.
  • Dependendo do que o seu plug-in faz - considere usar testes baseados no Selenium que testam a presença de dados no DOM usando IDs
Fernando Briano
fonte
Embora o teste seja importante, dizer que os testes de unidade devem testar o menor em vez do maior parece imprudente. Se você está tendo dificuldades para testar os problemas dependentes do WordPress, basta mergulhar no núcleo do WordPress, encontrará várias variáveis ​​globais internas que podem ser usadas para verificar se os itens funcionaram.
Backie
1
Mas cobrir o menor primeiro é básico, para que você possa alcançar os testes funcionais com o WordPress, como a resposta diz, não é?
Fernando Briano
1
Este é um plug-in, não um aplicativo. Você pode testar um aplicativo Java sem o Java Runtime? Sim, escrevendo Java como uma maquete e teste seu plug-in. Provavelmente, os erros estão na sua maquete. *) isenção de responsabilidade ou compilação no código nativo.
Edelwater