{"id":233761,"date":"2023-02-21T13:52:00","date_gmt":"2023-02-21T10:52:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233761"},"modified":"2022-11-11T12:15:02","modified_gmt":"2022-11-11T09:15:02","slug":"tutorial-endpoints-de-url-personalizados-com-a-api-de-reescrita-do-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/tutorial-endpoints-de-url-personalizados-com-a-api-de-reescrita-do-wordpress\/","title":{"rendered":"Tutorial: Endpoints de URL personalizados com a API de reescrita do WordPress"},"content":{"rendered":"\n<p>J\u00e1 desejou poder estender postagens \u00fanicas, p\u00e1ginas ou seus tipos de postagem personalizados com um modelo personalizado que mant\u00e9m sua pr\u00f3pria estrutura de URL? Com o WordPress <a href=\"https:\/\/codex.wordpress.org\/Rewrite_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Rewrite API<\/a>, isso \u00e9 totalmente poss\u00edvel e nada dif\u00edcil.<\/p>\n<p>Neste tutorial, veremos como anexar uma \u00fanica visualiza\u00e7\u00e3o de tipo de postagem personalizada com outro slug que carrega um modelo diferente. Em outras palavras, se uma \u00fanica postagem de tipo de postagem personalizada tiver o URL &quot;example.com\/destination\/venice\/&quot;, voc\u00ea poder\u00e1 adicionar regras de URL para p\u00e1ginas separadas com informa\u00e7\u00f5es relacionadas a cada destino, por exemplo&quot;example.com\/destination\/venice \/activities\/&quot; e &#8220;example.com\/destination\/venice\/attractions\/&#8221;.<\/p>\n<p>Se voc\u00ea estiver interessado em como adicionar endpoints \u00e0 p\u00e1gina &#8220;Minha conta&#8221; do WooCommerce, tenho <a href=\"https:\/\/awhitepixel.com\/blog\/how-to-add-custom-endpoints-to-my-account-page-in-woocommerce\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">outro post<\/a> sobre isso!<\/p>\n<p>A API do WordPress Rewrite tem muitas fun\u00e7\u00f5es \u00fateis para escrever suas pr\u00f3prias regras de URL personalizadas. Voc\u00ea pode ter visto a fun\u00e7\u00e3o mais conhecida e ampla; <code>add_rewrite_rule()<\/code>. Este tutorial, no entanto, usa o similar <code>add_rewrite_endpoint()<\/code>, que \u00e9 muito \u00fatil para adicionar &#8220;endpoints&#8221; de URL (basicamente adicionando slugs de URL personalizados ap\u00f3s algo que j\u00e1 existe, por exemplo, ap\u00f3s o final de um \u00fanico post ou \u00fanica categoria). Voc\u00ea pode obter o mesmo resultado usando, <code>add_rewrite_rule()<\/code>mas o processo de adi\u00e7\u00e3o de endpoints \u00e9 mais simples.<\/p>\n<h2>O que vamos fazer<\/h2>\n<p>Este guia assumir\u00e1 que criamos dois tipos de postagem personalizados; &#8216;filme&#8217; e &#8216;ator&#8217;. A regra de permalink para um \u00fanico filme \u00e9 &#8220;example.com\/movie\/fight-club\/&#8221; e para um \u00fanico ator &#8220;example.com\/actor\/brad-pitt\/&#8221;. Queremos uma p\u00e1gina separada para cada filme que mostre todos os atores desse filme, localizada em &#8220;example.com\/movie\/fight-club\/actors\/&#8221; e, da mesma forma, uma p\u00e1gina separada para cada ator que mostre todos os filmes em que o ator participou, localizado em &#8220;example.com\/actor\/brad-pitt\/movies\/&#8221;.<\/p>\n<p>N\u00e3o entrarei em detalhes sobre como adicionar esses dois tipos de postagem personalizados; se voc\u00ea precisar de ajuda para fazer esta parte, recomendo ler meu post sobre <a href=\"https:\/\/awhitepixel.com\/blog\/how-to-create-custom-post-types-and-custom-taxonomies\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">como adicionar tipos de postagem personalizados<\/a>.<\/p>\n<h2>Escrevendo o c\u00f3digo<\/h2>\n<p>A primeira etapa \u00e9 chamar <code>add_rewrite_endpoint()<\/code>uma fun\u00e7\u00e3o vinculada a <code>init<\/code>(geralmente todas as fun\u00e7\u00f5es na API Rewrite s\u00e3o vinculadas a <code>init<\/code>). para registrar nossos dois endpoints desejados; &#8216;filmes&#8217; e &#8216;atores&#8217;. A <a href=\"https:\/\/codex.wordpress.org\/Rewrite_API\/add_rewrite_endpoint\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fun\u00e7\u00e3o<\/a> recebe dois argumentos; primeiro o ponto de extremidade que voc\u00ea deseja (por exemplo, &#8216;filmes&#8217;) e, em segundo lugar, uma constante para onde o ponto de extremidade deve &#8220;morar&#8221; (por exemplo, p\u00e1ginas, autor, arquivos, etc). Consulte a documenta\u00e7\u00e3o para quais constantes voc\u00ea pode usar; quanto a este exemplo, o geral <code>EP_PERMALINK<\/code>est\u00e1 bem:<\/p>\n<pre><code>add_action('init', function() {\n    add_rewrite_endpoint('movies', EP_PERMALINK);\n    add_rewrite_endpoint('actors', EP_PERMALINK);\n});<\/code><\/pre>\n<p>NB: Se o seu tipo de postagem personalizado \u00e9 hier\u00e1rquico, o que significa que tem <code>'hierarchical' =&gt; true<\/code>em seu <code>register_post_type()<\/code>, voc\u00ea precisa trocar a constante <code>EP_PERMALINK<\/code>por <code>EP_PAGES<\/code>.<\/p>\n<p>Depois de salvar este c\u00f3digo, voc\u00ea precisa ir para Configura\u00e7\u00f5es&gt; Permalinks e simplesmente clicar no bot\u00e3o Salvar para atualizar os permalinks. Sempre que voc\u00ea adiciona ou modifica uma regra de reescrita, voc\u00ea precisa atualizar seus permalinks para que ela funcione!<\/p>\n<h3>Manipulando as vars de consulta<\/h3>\n<p>A maneira como voc\u00ea, como desenvolvedor de temas ou plugins, pode descobrir se deve ou n\u00e3o mostrar os modelos para esses endpoints \u00e9 verificando &#8220;query vars&#8221;; basicamente o objeto de consulta global do WordPress. Fazemos isso chamando <code>get_query_var()<\/code>com a consulta como argumento (&#8216;filmes&#8217; ou &#8216;atores&#8217;).<\/p>\n<p>Se voc\u00ea j\u00e1 trabalhou com <code>add_rewrite_rule()<\/code>ou <code>get_query_var()<\/code>antes, voc\u00ea j\u00e1 deve estar ciente de que o WordPress n\u00e3o adiciona automaticamente vars de consulta personalizadas. Normalmente, voc\u00ea teria que filtrar <code>query_vars<\/code>e adicionar suas vari\u00e1veis \u200b\u200bpersonalizadas para que o WordPress as preenchesse. No entanto <code>add_rewrite_endpoint()<\/code>, automaticamente faz isso para n\u00f3s.<\/p>\n<p>No entanto, se tentarmos cham\u00e1 <code>get_query_var('movies')<\/code>-lo, nunca parecer\u00e1 definido. Isso porque ele assume que precisa ter um valor para ser definido. As regras de endpoint pressup\u00f5em que o que vem depois do endpoint \u00e9 o valor. Por exemplo, &#8220;example.com\/actor\/brad-pitt\/movies\/some-value\/&#8221; funcionaria, porque nesta p\u00e1gina <code>get_query_var('movies')<\/code>retornaria o valor &#8216;some-value&#8217;. Mas n\u00e3o \u00e9 isso que queremos, queremos que funcione apenas com o endpoint \u00fanico. Para resolver isso, precisamos nos conectar ao <code>request<\/code>filtro do WordPress e informar ao WordPress que, se estivermos em nossos endpoints, a consulta vars deve adicionar o endpoint com algum valor (acabamos de defini-lo como <code>true<\/code>).<\/p>\n<pre><code>add_filter('request', function($vars) {\n    if (isset($vars['movies'])) {\n        $vars['movies'] = true;\n    }\n    if (isset($vars['actors'])) {\n        $vars['actors'] = true;\n    }\n    return $vars;\n});<\/code><\/pre>\n<p>Se voc\u00ea tentar agora usar <code>get_query_vars('movies')<\/code>quando em &#8220;example.com\/actor\/brad-pitt\/movies\/&#8221; voc\u00ea obter\u00e1 o valor <code>true<\/code>(o importante \u00e9 que ele realmente foi definido).<\/p>\n<h3>Carregando modelo<\/h3>\n<p>A pr\u00f3xima etapa \u00e9 decidir o que deve acontecer nesses dois endpoints; ou em outras palavras, quais modelos voc\u00ea deseja carregar. Esta parte \u00e9 com voc\u00ea, voc\u00ea pode se conectar, <code>template_redirect<\/code>mas isso s\u00f3 \u00e9 recomendado se voc\u00ea quiser executar um redirecionamento real. Eu recomendo conectar-se ao <code>template_include<\/code>filtro e simplesmente dizer ao WordPress quais modelos usar quando estivermos em nossos endpoints personalizados. Vamos supor que o tema tenha os templates PHP <code>single-actor-movies.php<\/code>para &#8220;example.com\/actor\/\/movies\/ e <code>single-movie-actors.php<\/code>para &#8220;example.com\/movie\/\/actors\/&#8221;.<\/p>\n<pre><code>add_filter('template_include', function($template) {\n    if (is_singular() &amp;&amp; get_query_var('movies')) {\n        $post = get_queried_object();\n        return locate_template(['single-actor-movies.php']);\n    }\n    if (is_singular() &amp;&amp; get_query_var('actors')) {\n        $post = get_queried_object();\n        return locate_template(['single-movie-actors.php']);\n    }\n    return $template;\n});<\/code><\/pre>\n<p>Com esse filtro em vigor, o WordPress deve carregar os modelos fornecidos para nossos terminais personalizados e, dentro desses modelos, o <code>$post<\/code>objeto global seria o objeto de postagem \u00fanico relacionado antes do terminal &#8211; por exemplo, o objeto de postagem de ator \u00fanico quando estivermos no modelo para mostrar todos filmes em que o ator apareceu. Isso facilita a consulta das informa\u00e7\u00f5es que queremos mostrar.<\/p>\n<h2>Obtendo a URL para seu endpoint<\/h2>\n<p>Ter nossos endpoints e p\u00e1ginas personalizados \u00e9 bom e elegante, mas em algum lugar voc\u00ea precisaria vincular a eles. Por exemplo, no modelo de filme \u00fanico, voc\u00ea gostaria de um link &#8220;Ver todos os atores&#8221; que v\u00e1 para o seu endpoint.<\/p>\n<p>Infelizmente, n\u00e3o existe uma fun\u00e7\u00e3o WordPress t\u00e3o simples para isso. Voc\u00ea precisar\u00e1 criar o URL por conta pr\u00f3pria. Eu recomendo usar <code>[get_site_url](https:\/\/developer.wordpress.org\/reference\/functions\/get_site_url\/)()<\/code>para endpoints em todo o site ou, no caso acima, voc\u00ea se referiria a uma postagem espec\u00edfica <code>[get_the_permalink](https:\/\/developer.wordpress.org\/reference\/functions\/get_the_permalink\/)()<\/code>(dentro do loop ou fornecendo um ID de postagem) e anexando o endpoint depois dela, assim:<\/p>\n<pre><code>echo get_the_permalink(). '\/actors';<\/code><\/pre>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este tutorial mostra como estender seu tipo de postagem personalizado com um modelo personalizado que mant\u00e9m sua pr\u00f3pria estrutura de URL, usando a API de reescrita do WordPress.<\/p>\n","protected":false},"author":1,"featured_media":152349,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,898,722,722,837,1110,837,846,846,867,867],"tags":[1170],"class_list":["post-233761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-guia-para-iniciantes","category-n-a","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233761","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=233761"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233761\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/152349"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=233761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=233761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=233761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}