{"id":230243,"date":"2022-11-23T15:43:00","date_gmt":"2022-11-23T12:43:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230243"},"modified":"2022-11-09T20:45:57","modified_gmt":"2022-11-09T17:45:57","slug":"trabalhando-com-classes-modelos-e-parciais-no-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/trabalhando-com-classes-modelos-e-parciais-no-wordpress\/","title":{"rendered":"Trabalhando com classes, modelos e parciais no WordPress"},"content":{"rendered":"\n<p>Quando me sentei para come\u00e7ar este post, planejei escrever algo muito mais envolvente do que o que vou compartilhar. Inicialmente, eu queria passar por uma de duas coisas:<\/p>\n<ul>\n<li>O guia completo para configurar um ambiente de desenvolvimento,<\/li>\n<li>Integrando Ferramentas de Qualidade de C\u00f3digo no PhpStorm<\/li>\n<\/ul>\n<p>A primeira seria focar em uma variedade de outras coisas sobre as quais falei, unindo-as todas e tendo uma refer\u00eancia definitiva. Mas isso \u00e9 algo que eu quero ter tempo para montar para garantir que seja feito corretamente.<\/p>\n<p>O segundo \u00e9 um que acho importante, mas estou em uma fase de transi\u00e7\u00e3o com algumas das minhas pr\u00f3prias ferramentas. At\u00e9 que isso seja feito, prefiro n\u00e3o escrever sobre isso.<\/p>\n<p>Mesmo assim, sempre h\u00e1 algo para cobrir, certo? Ent\u00e3o, hoje optei por algo mais simples: detalhando o uso de classes, templates e parciais em plugins do WordPress usando um exemplo simples.<\/p>\n<h2>Classes, modelos e parciais no WordPress<\/h2>\n<p>Para este t\u00f3pico em particular, uma pergunta imediata que pode vir \u00e0 mente \u00e9 simples: por que se preocupar em falar sobre isso?<\/p>\n<p>Porque \u00e9 2018 e ainda estamos vendo uma mistura bruta de PHP, CSS, marca\u00e7\u00e3o e JavaScript em um \u00fanico arquivo. Isso n\u00e3o \u00e9 para bater em outras tecnologias que fazem isso por padr\u00e3o (como React). Estou falando especificamente sobre plugins do WordPress e escrever c\u00f3digo sustent\u00e1vel de forma que seja f\u00e1cil [obviamente] manter, escrever e ler.<\/p>\n<h3>Um exemplo pr\u00e1tico<\/h3>\n<p>Digamos que voc\u00ea esteja trabalhando em uma p\u00e1gina de submenu para algo que aparecer\u00e1 em um menu personalizado. <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f72e1444fb01cff19de2c58f0aacab34#file-00-addmenupage-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Voc\u00ea registra sua p\u00e1gina<\/a> usando a API do WordPress:<\/p>\n<pre><code>&lt;?php\n\npublic function addMenuPage()\n{\n    add_menu_page(\n      'Acme Menu',\n      'Acme Menu',\n      'manage_options',\n      'acme-custom-menu',\n      array($this, 'display'),\n      'dashicons-dashboard',\n      30\n    );\n\n    add_submenu_page(\n      'acme-custom-menu',\n      'Acme Menu',\n      'Acme Menu',\n      'Acme Menu',\n      'acme-custom-menu',\n      array($this, 'display')\n    );\n}\n<\/code><\/pre>\n<p>Mas quando voc\u00ea configura uma fun\u00e7\u00e3o de retorno de chamada para exibir a p\u00e1gina, voc\u00ea <strong>n\u00e3o<\/strong> usa a fun\u00e7\u00e3o para misturar todos os v\u00e1rios idiomas juntos. Em vez disso, voc\u00ea o usa para <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/f72e1444fb01cff19de2c58f0aacab34#file-01-display-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">incluir um arquivo.<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\npublic function display()\n{\n    include_once $this-&gt;pluginPath. 'views\/acme-settings.php';\n}\n<\/code><\/pre>\n<p>Observe que no arquivo acima, fa\u00e7o refer\u00eancia a uma propriedade <strong>$this-&gt;pluginPath<\/strong>. Isso \u00e9 definido no construtor da classe para que eu possa acessar facilmente a raiz do plugin.<\/p>\n<p>De qualquer forma, como seria esse arquivo?<\/p>\n<h3>Um modelo e um parcial<\/h3>\n<p>Nesse caso, suponho que seu modelo \u00e9 o que fornecer\u00e1 informa\u00e7\u00f5es ao usu\u00e1rio e solicitar\u00e1 sua entrada. A parcial ser\u00e1 respons\u00e1vel por exibir uma mensagem de sucesso, erro ou aviso ao usu\u00e1rio.<\/p>\n<h4>Uma amostra<\/h4>\n<p>Para simplificar, manterei o modelo e o parcial o mais enxutos poss\u00edvel. Nesse caso, suponha que vamos renderizar uma p\u00e1gina, pedir ao usu\u00e1rio para salvar um valor e, se o valor for salvo com sucesso (e, portanto, existir na tabela <strong>wp_options<\/strong> ), exibiremos a mensagem de sucesso.<\/p>\n<p>Isso significa:<\/p>\n<ul>\n<li>o modelo exibir\u00e1 o t\u00edtulo da p\u00e1gina, informa\u00e7\u00f5es, entrada e bot\u00e3o salvar,<\/li>\n<li>a parcial exibir\u00e1 a mensagem de sucesso quando necess\u00e1rio.<\/li>\n<\/ul>\n<p>D\u00ea uma olhada no c\u00f3digo para <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/f72e1444fb01cff19de2c58f0aacab34#file-02-acme-settings-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o modelo abaixo:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\/**\n * Renders the settings page for the plugin.\n *\/\n?&gt;\n&lt;div class=\"wrap\"&gt;\n    &lt;h1 class=\"wp-heading-inline\"&gt;&lt;?php echo get_admin_page_title(); ?&gt;&lt;\/h1&gt;\n    &lt;?php if ($this-&gt;showSuccessMessage()) { ?&gt;\n      &lt;?php include_once 'partials\/settings-saved.php'; ?&gt;\n    ?&gt;\n    &lt;div id=\"acme-settings-schedule\"&gt;\n        &lt;form id=\"acme-form\" method=\"post\" action=\"&lt;?php echo esc_html(admin_url('admin-post.php')); ?&gt;\"\"&gt;\n            &lt;!-- This is where your settings go. --&gt;\n            &lt;p&gt;\n                &lt;?php\n                submit_button(\n                    'Save',\n                    'primary',\n                    'acme-save-settings',\n                    false\n                );\n                wp_nonce_field(\n                    'acme-save',\n                    'acme-save-nonce'\n                );\n                ?&gt;\n            &lt;\/p&gt;\n        &lt;\/form&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;\n<\/code><\/pre>\n<p>Observe que, sim, ele tem uma entrada, um bot\u00e3o salvar e um nonce, todos importantes (mas fora do escopo deste post) para salvar informa\u00e7\u00f5es.<\/p>\n<p>Mas observe tamb\u00e9m que ele tem uma fun\u00e7\u00e3o auxiliar que eu uso para verificar a presen\u00e7a de informa\u00e7\u00f5es salvas com sucesso. Esta fun\u00e7\u00e3o reside na mesma classe respons\u00e1vel por renderizar o template.<\/p>\n<h4>Parcial<\/h4>\n<p>Parece algo <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/f72e1444fb01cff19de2c58f0aacab34#file-03-showsuccessmessage-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\npublic function showSuccessMessage()\n{\n  return (false !== get_option('acme_custom_setting'));\n}\n<\/code><\/pre>\n<p>E a parcial resultante \u00e9 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/f72e1444fb01cff19de2c58f0aacab34#file-04-settings-saved-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">muito simples:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\/**\n * Renders the success message if the option has been properly saved.\n *\/\n?&gt;\n\n&lt;div class=\"notice-success notice is-dismissible\"&gt;\n    &lt;p&gt;Your settings have been successfully saved.&lt;\/p&gt;\n    &lt;button type=\"button\" class=\"notice-dismiss\"&gt;\n        &lt;span class=\"screen-reader-text\"&gt;Dismiss this notice.&lt;\/span&gt;\n    &lt;\/button&gt;\n&lt;\/div&gt;\n<\/code><\/pre>\n<p>Claro, sua implementa\u00e7\u00e3o da fun\u00e7\u00e3o pode variar. O objetivo n\u00e3o \u00e9 tanto mostrar como implementar a fun\u00e7\u00e3o, mas como aproveitar uma fun\u00e7\u00e3o para verificar informa\u00e7\u00f5es para exibir uma parcial.<\/p>\n<h2>H\u00e1 mais (mas n\u00e3o aqui)<\/h2>\n<p>Talvez isso seja algo que deva ser colocado no in\u00edcio do artigo.<\/p>\n<p>Para ser honesto, acho que \u00e9 uma daquelas coisas em que alguns podem achar mais \u00fatil v\u00ea-lo desde o in\u00edcio (mas depois falta o contexto do c\u00f3digo) e outros acham mais \u00fatil no final porque podem ver como tudo se encaixa juntos.<\/p>\n<p>Independentemente disso, espero que, em \u00faltima an\u00e1lise, forne\u00e7a clareza sobre como tudo isso se encaixa.<\/p>\n<p>Al\u00e9m disso, h\u00e1 muito espa\u00e7o em lugares para que as coisas sejam personalizadas, como:<\/p>\n<ul>\n<li>verificando se o usu\u00e1rio tem permiss\u00e3o para salvar,<\/li>\n<li>verificando o valor nonce,<\/li>\n<li>sanitizar e validar os dados,<\/li>\n<li>determinar o que constitui sucesso, avisos e erros.<\/li>\n<\/ul>\n<p>Mas se eu for cobrir todos os itens acima, estamos olhando para um post extraordinariamente longo ou uma longa s\u00e9rie de posts. Isso n\u00e3o \u00e9 algo que eu sou contra, mas tamb\u00e9m \u00e9 algo que eu n\u00e3o fa\u00e7o agora e vale o esfor\u00e7o neste momento.<\/p>\n<p>Nunca hesite em oferecer feedback. Mas, enquanto isso, espero que tudo isso ajude a fornecer uma base a partir da qual construir ao trabalhar em seu pr\u00f3ximo projeto.<\/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>Neste post, descrevo o uso de classes, templates e parciais em plugins do WordPress usando um exemplo simples.<\/p>\n","protected":false},"author":1,"featured_media":164763,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[722,806,846,867],"tags":[1170],"class_list":["post-230243","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvedor","category-php-8","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230243","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=230243"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230243\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/164763"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}