Um guia simples para organizar classes centradas no WordPress
Uma das coisas que tenho feito um esforço muito mais concentrado, provavelmente mais do que já fiz antes, é gerenciar a separação de preocupações entre as classes responsáveis pela interface com o WordPress e as responsáveis por trabalhar com o domínio do problema.
Por exemplo, digamos que você esteja trabalhando em um plug-in e ele se comunicará com uma API de terceiros. Além disso, este plugin também oferecerá menus, tipos de postagem, taxonomias e assim por diante na área de administração do WordPress.
Há duas áreas de responsabilidade aqui:
- a área responsável pela solução geral do problema,
- a área responsável pela interface com o WordPress.
Você pode argumentar que é importante testar as áreas de unidade que se comunicam com o WordPress, mas também sei que essas são APIs testadas e verdadeiras que têm seu próprio conjunto de testes.
Em vez disso, devemos nos concentrar no teste de unidade e separar nossa lógica de negócios do WordPress.
Mas não é esse o objetivo deste post. Em vez disso, trata-se mais de uma maneira de potencialmente apresentar um projeto quando uma parte dele fará interface com o WordPress.
Já falei sobre a importância e as vantagens dos namespaces em posts anteriores para não me aprofundar muito nessa discussão aqui.
Em vez disso, estou interessado em falar sobre a organização de arquivos no nível do sistema de arquivos e no nível do namespace, para que sejam claramente separados em suas áreas de especialização e para que possamos ter certeza de que estamos, digamos, focando nossos testes de unidade (e outros testes) em áreas que são mais críticas.
Abstraindo Meta Boxes
Eu gosto de ter certeza de que meu diretório e estrutura de arquivos espelham os meus namespaces. Claro, ajuda na organização dos arquivos, mas também na organização conceitual.
Ou seja, se eu for trabalhar com meta boxes, então eu sei que provavelmente posso encontrar os arquivos de meta box em um diretório aninhado com o diretório pai do WordPress e dentro de um subdiretório Admin seguido por um diretório MetaBox.
Para esse fim, como seria um conjunto de classes projetadas para trabalhar com meta caixas, deveríamos escrever código para elas de maneira reutilizável? Dado o que sabemos sobre meta boxes, sabemos que provavelmente precisaremos do seguinte:
- uma classe abstrata que define o tipo de postagem ao qual cada meta box será vinculada,
- duas funções para a meta box – uma para registrá-la, outra para exibir o conteúdo,
- um diretório para conter a visualização ou a apresentação da meta box,
- um arquivo que servirá como a referida visualização.
Dados os pontos acima, talvez a estrutura de diretórios ficaria assim:
Em seguida, temos o código que espelha essa estrutura. Ou seja, dentro do nosso diretório WordPress, teríamos o subdiretório Admin já que a meta box é exibida dentro da área de administração do WordPress, e teríamos o subdiretório View que conteria o arquivo responsável por exibir as informações.
Isso nos deixa com a necessidade de criar algumas classes, conforme listado acima. Talvez a classe base abstrata ficaria assim:
<?php
namespace AcmeWordPressAdminMetaBox;
abstract class AbstractMetaBox
{
protected $postType;
public function __construct()
{
$this->postType = 'acme_post_type';
}
abstract public function render();
abstract public function display();
}
Em seguida, uma implementação concreta estenderia a classe e ficaria assim:
<?php
namespace AcmeWordPressAdminMetaBox;
class AcmeMetaBox extends AbstractMetaBox
{
/**
* {@inheritdoc}
*/
public function render()
{
add_meta_box(
'acme-product-image',
'Product Image',
[$this, 'display'],
$this->postType,
'side',
'default'
);
}
/**
* {@inheritdoc}
*/
public function display()
{
include_once plugin_dir_path(__FILE__).'Views/acme-product-image.php';
}
}
E, finalmente, a visualização da classe conteria qualquer código de marcação e modelo para renderização de informações :
<div class="product-image-metabox">
<p>
<img src="<?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?>" alt="<?= esc_attr(get_the_title()); ?>" />
<input type="text" value="<?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?>" />
</p>
</div>
Isso nos dá exatamente o que precisamos de uma maneira bem organizada e reutilizável para trabalhar com meta caixas. Também pode ser repetido para itens como menus, tipos de postagem, taxonomias e assim por diante.
Mas eu discordo.
Uma palavra sobre teste de unidade (com PHPUnit)
Como mencionei anteriormente no post, acredito que as classes de teste de unidade que resolvem problemas exclusivos do nosso espaço de problemas são importantes. Isso significa que você precisa dizer ao seu arquivo de configuração PHPUnit para excluir seus arquivos centrados no WordPress.
A vantagem do que expus acima é que isso se torna trivialmente fácil. Simplificando, você pode adicionar isso ao seu arquivo phpunit.xml :
<testsuites>
<testsuite name="Plugin">
<directory>./tests</directory>
<exclude>./tests/phpunit</exclude>
<exclude>./src/WordPress</exclude>
</testsuite>
</testsuites>
Isso lhe dá a capacidade de se concentrar em escrever testes especificamente para o seu espaço de problema, ao mesmo tempo em que garante que você está escrevendo código baseado em WordPress escalável, sustentável e reutilizável.
Atualmente estou escrevendo um eBook (junto com uma variedade de outros conteúdos premium). Se você estiver interessado, confira o que você recebe.