{"id":230842,"date":"2022-12-06T14:36:00","date_gmt":"2022-12-06T11:36:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230842"},"modified":"2022-12-06T14:47:32","modified_gmt":"2022-12-06T11:47:32","slug":"organizando-tipos-visualizacoes-e-assinantes-do-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/organizando-tipos-visualizacoes-e-assinantes-do-wordpress\/","title":{"rendered":"Organizando tipos, visualiza\u00e7\u00f5es e assinantes do WordPress"},"content":{"rendered":"\n<p>Uma das coisas que me vejo tentando fazer regularmente \u00e9 simplificar a forma como estou construindo funcionalidades focadas no WordPress. <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/um-guia-simples-para-organizar-classes-centradas-no-wordpress\/\" title=\"Recentemente falei sobre isso\">Recentemente falei sobre isso<\/a><\/strong>, mas pensei em expandir um pouco mais.<\/p>\n<p>Ou seja, pensei em apresentar a abordagem que adoto ao construir coisas como tipos de postagem personalizados, taxonomias, meta caixas e assim por diante.<\/p>\n<p>Geralmente, pense nisso como uma estrat\u00e9gia que sigo para construir aspectos de um projeto que interage diretamente com o WordPress, mas pode exigir alguns componentes, como:<\/p>\n<ul>\n<li>classes que se registram no WordPress atrav\u00e9s de v\u00e1rios ganchos,<\/li>\n<li>classes que requerem chamadas para certas APIs do WordPress<\/li>\n<li>e classes que requerem uma visualiza\u00e7\u00e3o personalizada.<\/li>\n<\/ul>\n<p>Claro, nem tudo que faz interface com o WordPress precisar\u00e1 de todos os itens acima (por exemplo, um tipo de postagem personalizado precisa de uma visualiza\u00e7\u00e3o? N\u00e3o. Mas uma caixa meta precisa).<\/p>\n<h2>Organizando os tipos do WordPress<\/h2>\n<p>Com isso dito, vou pegar um exemplo mais envolvente, como uma caixa meta e, em seguida, detalhar uma maneira pela qual acho que pode ser implementada. Vou anotar as coisas que considero necess\u00e1rias e as que s\u00e3o opcionais.<\/p>\n<p>E, como eu disse, estou usando uma meta box como exemplo porque tenho uma refer\u00eancia anterior e envolve a maior quantidade de trabalho, enquanto outra coisa, como uma taxonomia personalizada, pode n\u00e3o exigir todas (apenas um subconjunto) das pe\u00e7as .<\/p>\n<p>Com isso dito, deixe-me expor minha abordagem.<\/p>\n<h3>Precisamos de assinantes<\/h3>\n<p>J\u00e1 falei sobre esse padr\u00e3o espec\u00edfico o suficiente a ponto de simplesmente <a href=\"https:\/\/en.wikipedia.org\/wiki\/Publish%E2%80%93subscribe_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">vincular a uma defini\u00e7\u00e3o dele<\/a>. Se voc\u00ea est\u00e1 lendo esta p\u00e1gina, provavelmente conhece os v\u00e1rios ganchos e como us\u00e1-los no WordPress.<\/p>\n<p>Foto de Alexander Andrews no Unsplash<\/p>\n<p>Mas a raz\u00e3o pela qual quero mencion\u00e1-lo \u00e9 porque, em vez de pensar em conectar uma fun\u00e7\u00e3o para disparar sempre que algo acontecer, quero que voc\u00ea pense em um objeto que se inscreve em um evento quando ele ocorre.<\/p>\n<p>Isso significa que precisaremos de um tipo de classe de assinante.<\/p>\n<h3>Aulas de API do WordPress<\/h3>\n<p>Em segundo lugar, precisamos de classes que sejam respons\u00e1veis \u200b\u200bpela interface direta com o WordPress. Essas s\u00e3o as classes que chamam a API do WordPress e registram o que s\u00e3o respons\u00e1veis \u200b\u200bpor fazer.<\/p>\n<p>Ou seja, talvez eles definam um tipo de postagem personalizado ou talvez, como dito, definam uma meta box.<\/p>\n<h3>Definindo visualiza\u00e7\u00f5es<\/h3>\n<p>Por fim, \u00e9 importante observar que para algumas funcionalidades personalizadas para a \u00e1rea de administra\u00e7\u00e3o do WordPress (ou mesmo \u00e1reas voltadas para o p\u00fablico), voc\u00ea pode querer incluir uma visualiza\u00e7\u00e3o ou um modelo ou uma parcial (geralmente me refiro a eles como visualiza\u00e7\u00f5es) que trabalho para representar os dados para uma meta box.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162654-61e741fa06c63.jpg\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162654-61e741fa06c63.jpg\" alt=\"Organizando tipos, visualiza\u00e7\u00f5es e assinantes do WordPress\"><\/a><\/p>\n<p>Foto de Saketh Garuda no Unsplash<\/p>\n<p>\u00c0s vezes, isso ser\u00e1 simplesmente informativo. \u00c0s vezes, isso exigir\u00e1 que ele poste de volta no servidor e serialize os dados. Embora eu ache que falar sobre o \u00faltimo seria realmente ben\u00e9fico, est\u00e1 fora do escopo atual deste post.<\/p>\n<p>Talvez em um post futuro.<\/p>\n<h2>Organiza\u00e7\u00e3o de aulas<\/h2>\n<p>O que tudo isso disse, como seria colocar tudo isso para fora? No m\u00ednimo, estamos olhando para:<\/p>\n<ul>\n<li>um assinante,<\/li>\n<li>um tipo WordPress,<\/li>\n<li>uma vista<\/li>\n<\/ul>\n<p>E, no m\u00e1ximo, voc\u00ea pode estar interessado em definir interfaces ou classes abstratas para ajudar a impor um contrato entre os v\u00e1rios tipos do WordPress. Este tamb\u00e9m \u00e9 um princ\u00edpio orientado a objetos saud\u00e1vel sobre o qual falarei em um post futuro.<\/p>\n<p>Por enquanto, por\u00e9m, vamos falar sobre como configurar cada um deles.<\/p>\n<h3>O Assinante<\/h3>\n<p>Simplificando, o assinante \u00e9 respons\u00e1vel por ouvir sempre que o WordPress gera um evento (publica um evento). E quando percebe que sim, ele dispara uma fun\u00e7\u00e3o que est\u00e1 ligada a ele.<\/p>\n<p>Isso geralmente \u00e9 definido no padr\u00e3o de registro. Se voc\u00ea n\u00e3o leu esse post, eu recomendo, mas configurar o c\u00f3digo para ele <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-00-acme-meta-box-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">\u00e9 bem f\u00e1cil:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nclass AcmeMetaBoxSubscriber extends AbstractSubscriber\n{\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    public function load()\n    {\n        (new AcmeMetaBox())-&gt;render();\n    }\n}\n<\/code><\/pre>\n<p>A partir da\u00ed, sempre que o evento for gerado, a fun\u00e7\u00e3o ser\u00e1 acionada. Aqui est\u00e1 a coisa: A fun\u00e7\u00e3o tem que ser parte de uma determinada classe. Assim, a necessidade do tipo WordPress<\/p>\n<h3>O tipo WordPress<\/h3>\n<p>Eu gosto de considerar os tipos de coisas que fazem interface com o WordPress como WordPress-types (assim como nossas linguagens de programa\u00e7\u00e3o t\u00eam tipos nativos, como strings e inteiros). O WordPress tem taxonomias, meta boxes, menus e assim por diante.<\/p>\n<p>Para que nosso assinante funcione adequadamente, ele precisa estar ciente do nosso tipo de WordPress. Mantendo-se consistente com o exemplo da caixa meta, <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-01-acme-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">eis como pode ser:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nclass AcmeMetaBox extends AbstractMetaBox\n{\n    public function render()\n    {\n        add_meta_box(\n            'acme-data',\n            'Acme Data',\n            [$this, 'display'],\n            $this-&gt;postType,\n            'normal',\n            'high'\n        );\n    }\n\n    public function display()\n    {\n        include_once plugin_dir_path(__FILE__).'Views\/acme-data.php';\n    }\n}\n<\/code><\/pre>\n<p>Em seguida, precisamos garantir que o registro esteja ciente dessa classe.<\/p>\n<h3>A vista<\/h3>\n<p>Finalmente, para uma meta box, precisamos ter certeza de que h\u00e1 uma visualiza\u00e7\u00e3o que pelo menos exibir\u00e1 informa\u00e7\u00f5es. Serializar informa\u00e7\u00f5es e, em seguida, atualizar a visualiza\u00e7\u00e3o para o usu\u00e1rio \u00e9 um pouco diferente.<\/p>\n<p>Mas como pode ser uma vista? <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-02-acme-data-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">F\u00e1cil<\/a><\/strong> :<\/p>\n<pre><code>&lt;div class=\"acme-data-metabox\"&gt;\n  &lt;?php echo __('Acme Data', 'acme-meta-box'); ?&gt;\n  &lt;p class=\"description\"&gt;\n    This is the content of the metabox.\n  &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>\u00c9 apenas marca\u00e7\u00e3o b\u00e1sica que renderiza informa\u00e7\u00f5es para o usu\u00e1rio.<\/p>\n<h2>Amarrando tudo junto<\/h2>\n<p>Sempre que coloco tudo isso junto, geralmente tenho uma classe de plug-in que inicia tudo. Se um projeto for grande, pode haver mais de um, mas neste caso, acho que n\u00e3o h\u00e1 problema em mostrar como \u00e9 usando uma \u00fanica classe.<\/p>\n<p>Ent\u00e3o, primeiro, a classe principal do plugin <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-03-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">se parece com isso:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nclass Plugin\n{\n    private $registry;\n\n    public function __construct(Registry $registry)\n    {\n        $this-&gt;registry = $registry;\n    }\n\n    public function start()\n    {\n        array_map(function ($subscriber) {\n            add_action($subscriber-&gt;getHook(), [$subscriber, 'load']);\n        }, $this-&gt;registry-&gt;getRegisteredSubscribers());\n    }\n}\n<\/code><\/pre>\n<p>E o bootstrap do plugin <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-04-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">se parece com isso:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('acmeApiRegistry', function() use ($registry) {\n    return $registry;\n});\n\n\/\/ Register all of our objects with a basic registry.\n$registry-&gt;add('acmeMetaBoxSubscriber', new AcmeMetaBoxSubscriber('add_meta_boxes'));\n\n$plugin = new Plugin($registry);\n$plugin-&gt;start();<\/code><\/pre>\n<p>E, a partir da\u00ed, todo o resto \u00e9 posto em movimento.<\/p>\n<h2>E quanto \u00e0 funcionalidade mais avan\u00e7ada?<\/h2>\n<p>Eu levanto essa quest\u00e3o porque eu j\u00e1 falei um pouco sobre isso no in\u00edcio do post. Ou seja, falei sobre:<\/p>\n<ol>\n<li>a ideia de postar dados de volta no servidor (e provavelmente l\u00ea-los novamente),<\/li>\n<li>e falei sobre o uso de interfaces.<\/li>\n<\/ol>\n<p>Essas s\u00e3o duas coisas que eu acho que valem a pena explorar com mais detalhes. Mas antes de fazer isso, estabelecer as bases para como eu organizo essas informa\u00e7\u00f5es \u00e9 que elas s\u00e3o constru\u00eddas especialmente porque s\u00e3o constru\u00eddas em postagens anteriores, como <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/usando-o-padrao-de-registro-no-wordpress\/\" title=\"o padr\u00e3o de registro\">o padr\u00e3o de registro<\/a><\/strong>, e tamb\u00e9m organizando classes centradas no WordPress por meio de <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/um-guia-simples-para-organizar-classes-centradas-no-wordpress\/\" title=\"caixas meta\">caixas meta<\/a><\/strong>.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A organiza\u00e7\u00e3o de tipos, visualiza\u00e7\u00f5es, assinantes e outros materiais relacionados do WordPress pode ser sistem\u00e1tica. Isso \u00e9 uma coisa boa, pois nos d\u00e1 uma maneira repet\u00edvel de construir v\u00e1rios projetos para nossos clientes.<\/p>\n","protected":false},"author":1,"featured_media":162655,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[867],"tags":[1170],"class_list":["post-230842","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230842","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=230842"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230842\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/162655"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230842"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230842"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230842"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}