{"id":229570,"date":"2022-11-05T17:44:00","date_gmt":"2022-11-05T14:44:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229570"},"modified":"2022-11-09T08:30:53","modified_gmt":"2022-11-09T05:30:53","slug":"melhorias-na-legibilidade-do-wp_query-para-manutencao","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/melhorias-na-legibilidade-do-wp_query-para-manutencao\/","title":{"rendered":"Melhorias na legibilidade do WP_Query (para manuten\u00e7\u00e3o)"},"content":{"rendered":"\n<p>Trabalhar com <a href=\"https:\/\/tommcfarlin.com\/passing-variables-in-wordpress-wp-query\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Query<\/a>, especialmente quando voc\u00ea est\u00e1 fazendo algum trabalho personalizado fora do usual &quot;obter alguns posts e exibi-los em um modelo&quot; pode ser poderoso. Isso \u00e9 especialmente verdadeiro para alguns dos argumentos avan\u00e7ados (como usar <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/WP_Meta_Query\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Meta_Query<\/a>, por exemplo) .<\/p>\n<p>Tamb\u00e9m \u00e9 legal que a configura\u00e7\u00e3o do processo tenha uma maneira padr\u00e3o de fazer as coisas. Nomeadamente:<\/p>\n<ol>\n<li>Defina os argumentos,<\/li>\n<li>Instanciar WP_Query,<\/li>\n<li>Verifique se h\u00e1 postagens,<\/li>\n<li>Passe por eles,<\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=g2JNxeWO_wA\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Acabe com eles<\/a>.<\/li>\n<\/ol>\n<div class=\"sds-iframe-wrapper fitvidsignore\" style=\"position:relative;padding-top:56.25%;max-width:100%;\"><iframe allowfullscreen style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" src=\"\/\/www.youtube.com\/embed\/g2JNxeWO_wA\" frameborder=\"0\"><\/iframe><\/div>\n<p>Mas se voc\u00ea chegar onde est\u00e1 fazendo qualquer trabalho avan\u00e7ado, como trabalhar com um tipo de postagem personalizado de uma solu\u00e7\u00e3o de terceiros, ter que carregar m\u00eddia lateralmente, determinar se algo existe antes de realmente fazer qualquer trabalho com ele, ent\u00e3o pode ser um um pouco mais complicado de trabalhar, n\u00e3o \u00e9?<\/p>\n<p>Descobri que, como com qualquer coisa na programa\u00e7\u00e3o, dividi-lo em m\u00f3dulos muito mais leg\u00edveis (ou fun\u00e7\u00f5es ou partes ou como voc\u00ea quiser cham\u00e1-los) pode facilitar muito o trabalho.<\/p>\n<p>Ent\u00e3o, aqui est\u00e1 uma maneira de trabalhar para melhorar a legibilidade do WP_Query em uma variedade de coisas que fiz recentemente.<\/p>\n<h2>Melhorias na legibilidade do WP_Query<\/h2>\n<p>Antes de passar por qualquer exemplo, vale ressaltar que existem algumas coisas que a forma como o WP_Query est\u00e1 configurado que n\u00e3o podemos fazer.<\/p>\n<p>Por exemplo, uma vez que a consulta \u00e9 instanciada, talvez n\u00e3o possamos fazer coisas muito mais avan\u00e7adas com ela (quer dizer, configurar qualquer teste de unidade que n\u00e3o exija o n\u00facleo do WordPress ser\u00e1 imposs\u00edvel).<\/p>\n<p>Essa \u00e9 a cara de quem n\u00e3o consegue seguir seu c\u00f3digo.<\/p>\n<p>Com isso dito, aqui est\u00e1 um exemplo de como ele pode parecer quando voc\u00ea come\u00e7a e, em seguida, como ele pode ser refatorado para ter fun\u00e7\u00f5es menores, cada uma das quais \u00e9 mais intencional do que um m\u00e9todo longo.<\/p>\n<h3>Um exemplo<\/h3>\n<p>Para este post, digamos que eu precise consultar o banco de dados para todos os posts e posts publicados e quero orden\u00e1-los pelo ID.<\/p>\n<p>Em seguida, quero determinar se alguma ferramenta de terceiros atribuiu alguns metadados a ela que correspondam a um modelo que eu possa atribuir programaticamente posteriormente, dado um tema que tenho.<\/p>\n<p>Talvez a vers\u00e3o inicial do c\u00f3digo possa ser algo <a href=\"https:\/\/gist.github.com\/tommcfarlin\/90b954c3afde140c8573d1934172537f#file-00-wp-query-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/\/ Assume this is defined within the context of a class.\nconst MAPPING = [\n        'employers'       =&gt; 'page-past-word.php',\n        'biography'       =&gt; 'page-biography.php',\n        'accomplishments' =&gt; 'page-csv.php',\n    ];\n\n\/* Snip the rest of the class for brevity *\/\n\npublic function map_templates() {\n\n  $args = [\n    'post_type'      =&gt; array( 'post', 'page' ),\n    'post_status'    =&gt; 'publish',\n    'orderby'        =&gt; 'ID',\n    'order'          =&gt; 'ASC',\n    'posts_per_page' =&gt; -1,\n  ];\n  $template_query = new WP_Query( $args );\n\n    if ($template_query-&gt;have_posts()) {\n        while ($template_query-&gt;have_posts()) {\n            $template_query-&gt;the_post();\n\n            $template_id = get_post_meta( $post_id, 'third_party_template_id', true );\n            if ('' === $template_id) {\n                continue;\n            }\n\n                \/\/ The third-party's template post name can be used to map our custom template.\n            $template_info = get_post( $template_id );\n            $template_name = $template_info-&gt;post_name;\n\n            if (isset( self::MAPPING[ $template_name ])) {\n\n                $template_file = self::MAPPING[ $template_name ];\n                update_post_meta( $post_id, '_wp_page_template', $template_file );\n            }\n        }\n    }\n}\n<\/code><\/pre>\n<p>Isso \u00e9 muito c\u00f3digo para fazer um pouco de trabalho para uma fun\u00e7\u00e3o. No m\u00ednimo, ele estabelece tudo o que precisa acontecer, n\u00e3o \u00e9?<\/p>\n<p>Antes de continuar lendo, observe que o array de mapeamento \u00e9 apenas um exemplo, mas as chaves representam a meta-chave para\u00a0 mape\u00e1 <strong>-lo<\/strong>, e isso nos ajuda a mapear a defini\u00e7\u00e3o do\u00a0 valor <strong>_wp_page_template<\/strong> quando chegar a hora de mape\u00e1-lo para os arquivos de modelo reais do WordPress.<\/p>\n<p>Ent\u00e3o, como isso pode ser dividido?<\/p>\n<h3>1 Chute a coisa toda fora<\/h3>\n<p>A primeira coisa que queremos fazer \u00e9 criar uma fun\u00e7\u00e3o que coloque tudo em movimento. Existem algumas maneiras que voc\u00ea pode escolher para fazer isso.<\/p>\n<p>Aqui est\u00e1 como eu optei <a href=\"https:\/\/gist.github.com\/tommcfarlin\/90b954c3afde140c8573d1934172537f#file-01-map-page-templates-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">por faz\u00ea-lo<\/a> :<\/p>\n<pre><code>&lt;?php\n\npublic function map_page_templates() {\n\n  $posts = $this-&gt;load_posts_and_pages();\n  if ($posts-&gt;have_posts()) {\n    $this-&gt;assign_templates( $posts );\n  }\n}<\/code><\/pre>\n<p>Simplificando, ele usar\u00e1 algumas fun\u00e7\u00f5es auxiliares \u2013 todas as quais documentarei abaixo \u2013 e, em seguida, atribuir\u00e1 os modelos que tivermos no array de mapeamento definido acima.<\/p>\n<h3>2 Carregar Posts e P\u00e1ginas<\/h3>\n<p>Naturalmente, a primeira coisa que queremos fazer \u00e9 configurar uma fun\u00e7\u00e3o para chamar que retornar\u00e1 usar os resultados da consulta:<\/p>\n<pre><code>&lt;?php\n\nprivate function load_posts_and_pages() {\n\n  $args = [\n    'post_type'      =&gt; array( 'post', 'page' ),\n    'post_status'    =&gt; 'publish',\n    'orderby'        =&gt; 'ID',\n    'order'          =&gt; 'ASC',\n    'posts_per_page' =&gt; -1,\n  ];\n  $posts = new WP_Query( $args );\n\n  return $posts;\n}\n<\/code><\/pre>\n<p>Isso retorna os resultados da consulta. Dessa forma, podemos determinar se precisamos fazer algum trabalho adicional que dizemos na ess\u00eancia na etapa anterior:<\/p>\n<pre><code>&lt;?php\n\npublic function map_page_templates() {\n\n  $posts = $this-&gt;load_posts_and_pages();\n  if ($posts-&gt;have_posts()) {\n    $this-&gt;assign_templates( $posts );\n  }\n}<\/code><\/pre>\n<p>Se n\u00e3o, ent\u00e3o terminamos. Caso contr\u00e1rio, obviamente, continuamos.<\/p>\n<h3>3 Recupere o ID do modelo de terceiros<\/h3>\n<p>Em seguida, a ideia de atribuir modelos \u2013 como mostrado no c\u00f3digo acima \u2013 parece bastante simples, mas h\u00e1 algumas coisas que precisamos fazer primeiro:<\/p>\n<ol>\n<li>iterar pelas postagens,<\/li>\n<li>pegue o ID de terceiros do modelo,<\/li>\n<li>pegue o nome do modelo de terceiros,<\/li>\n<li>atribua o modelo da constante de mapeamento definida anteriormente na classe.<\/li>\n<\/ol>\n<p>A itera\u00e7\u00e3o inicial da fun\u00e7\u00e3o pode ser <a href=\"https:\/\/gist.github.com\/tommcfarlin\/90b954c3afde140c8573d1934172537f#file-03-assign-templates-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim<\/a> :<\/p>\n<pre><code>&lt;?php\n\nprivate function assign_templates( WP_Query $posts) {\n\n  while ($posts-&gt;have_posts()) {\n    $posts-&gt;the_post();\n\n    $template_id = $this-&gt;get_template_id( get_the_ID() );\n    if ('' === $template_id) {\n      continue;\n    }\n\n    $template_name = $this-&gt;get_template_name( $template_id );\n    if (null === $template_name) {\n      continue;\n    }\n\n    $this-&gt;assign_template( get_the_ID(), $template_name );\n  }\n  wp_reset_postdata();\n}\n<\/code><\/pre>\n<p>Mas como voc\u00ea pode ver, ainda existem fun\u00e7\u00f5es auxiliares que precisam de defini\u00e7\u00f5es. Coisas como a capacidade de obter o ID do modelo, o nome do modelo e, finalmente, atribuir o modelo.<\/p>\n<p>Observe, no entanto, que se alguma das fun\u00e7\u00f5es auxiliares n\u00e3o retornar um valor \u00fatil, continuamos com o loop. Isso \u00e9 necess\u00e1rio se n\u00e3o por outro motivo al\u00e9m de ter certeza de que n\u00e3o estamos tentando mapear modelos que n\u00e3o existem (mas acho que tamb\u00e9m facilita um pouco a leitura).<\/p>\n<h3>4 Encontre o arquivo para o qual o ID do modelo mapeia<\/h3>\n<p>Em seguida, uma pequena fun\u00e7\u00e3o pode ser usada para examinar o ID do modelo de terceiros e determinar se podemos mapear esse valor para as p\u00e1ginas que existem <a href=\"https:\/\/gist.github.com\/tommcfarlin\/90b954c3afde140c8573d1934172537f#file-04-get-template-id-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">em nosso banco de dados<\/a>.<\/p>\n<pre><code>&lt;?php\n\nprivate function get_template_id( $post_id) {\n\n  $template_id = get_post_meta( $post_id, 'third_party_template_id', true );\n  return $template_id;\n}\n<\/code><\/pre>\n<p>Se n\u00e3o puder, podemos retornar uma string vazia e fazer com que a fun\u00e7\u00e3o que invocou essa verifica\u00e7\u00e3o espec\u00edfica para ver se vale a pena continuar com o loop que definimos.<\/p>\n<h3>5 Pegue o nome do modelo<\/h3>\n<p>Supondo que tenhamos um ID de postagem v\u00e1lido, agora precisamos <a href=\"https:\/\/gist.github.com\/tommcfarlin\/90b954c3afde140c8573d1934172537f#file-05-get-template-name-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">recuperar o nome<\/a> do modelo do array de mapeamento definido anteriormente no post:<\/p>\n<pre><code>&lt;?php\n\nprivate function get_template_name( $template_id) {\n\n  $template_info = get_post( $template_id );\n  $template_name = $template_info-&gt;post_name;\n\n  if (isset( self::MAPPING[ $template_name ])) {\n    return $template_name;\n  } else {\n    return null;\n  }\n}\n<\/code><\/pre>\n<p>Aqui est\u00e1 a coisa: ou vamos retornar o nome do modelo, ou vamos retornar um valor nulo. Novamente, isso \u00e9 para que possamos determinar se precisamos continuar com o loop de atribui\u00e7\u00e3o de modelos ou n\u00e3o.<\/p>\n<h3>6 Atribuir o Modelo<\/h3>\n<p>Por fim, podemos pegar o ID do modelo fornecido pelo terceiro e us\u00e1-lo para <a href=\"https:\/\/gist.github.com\/tommcfarlin\/90b954c3afde140c8573d1934172537f#file-06-assign-template-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">mapear para o arquivo<\/a> que inclu\u00edmos em nosso trabalho, conforme descrito anteriormente na postagem:<\/p>\n<pre><code>&lt;?php\n\nprivate function assign_template( $post_id, $template_name) {\n\n  $template_file = self::MAPPING[ $template_name ];\n  update_post_meta( $post_id, '_wp_page_template', $template_file );\n}\n<\/code><\/pre>\n<p>E \u00e9 assim que voc\u00ea pode criar c\u00f3digos e fun\u00e7\u00f5es muito menores, mais f\u00e1ceis de ler e usar ao trabalhar com consultas um pouco mais complicadas.<\/p>\n<h2>E assim, melhorias de legibilidade<\/h2>\n<p>Para aqueles acostumados a escrever m\u00e9todos longos de leitura ou fazer coisas da maneira que muitos tutoriais na web mostram como fazer as coisas no WordPress, isso pode parecer um monte de c\u00f3digo in\u00fatil.<\/p>\n<p>Mas considere isso:<\/p>\n<ol>\n<li>M\u00e9todos mais longos s\u00e3o mais dif\u00edceis de ler,<\/li>\n<li>Eles podem ser mais dif\u00edceis de depurar,<\/li>\n<li>E eles n\u00e3o dividem o problema em partes mais gerenci\u00e1veis.<\/li>\n<\/ol>\n<p>Claro, eu adoraria dividir isso em ainda mais classes com suas responsabilidades, e acredito que isso possa ser feito, mas dada a natureza do WP_Query, isso exigiria um pouco mais de trabalho.<\/p>\n<p>Por isso, tentei atingir o m\u00e1ximo de meio-termo poss\u00edvel.<\/p>\n<p>Se voc\u00ea estiver trabalhando com usos ainda um pouco mais avan\u00e7ados de WP_Query, recomendo pelo menos considerar dividi-lo em partes menores.<\/p>\n<p>Isso ajuda a cuidar da legibilidade, potencialmente qualquer manuten\u00e7\u00e3o, e escrever um c\u00f3digo mais limpo em vez de um m\u00e9todo longo com muitas condicionais e depend\u00eancia de uma variedade de outros dados.<\/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>Trabalhar com a legibilidade do WP_Query pode ser um desafio. Aqui est\u00e1 um exemplo de como eu desmembro o uso da API em alguns dos meus pr\u00f3prios trabalhos.<\/p>\n","protected":false},"author":1,"featured_media":220946,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,722,867],"tags":[1170],"class_list":["post-229570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/229570","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=229570"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/229570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/220946"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=229570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=229570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=229570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}