{"id":233422,"date":"2023-02-13T17:00:00","date_gmt":"2023-02-13T14:00:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233422"},"modified":"2022-11-10T23:36:09","modified_gmt":"2022-11-10T20:36:09","slug":"tutorial-wordpress-menu-personalizado-para-postagens-ou-paginas-na-barra-lateral","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/tutorial-wordpress-menu-personalizado-para-postagens-ou-paginas-na-barra-lateral\/","title":{"rendered":"Tutorial WordPress: Menu personalizado para postagens ou p\u00e1ginas na barra lateral"},"content":{"rendered":"\n<p>Este post \u00e9 para voc\u00ea que gerencia um site WordPress que possui muito conte\u00fado, possivelmente muitas p\u00e1ginas estruturadas em hierarquia, e deseja uma melhor navega\u00e7\u00e3o fora do menu principal. Para ajudar a navegar no site, um menu personalizado relacionado \u00e0 postagem atual ajudar\u00e1 tremendamente. O problema de colocar um widget de menu na barra lateral (ou onde voc\u00ea quiser) \u00e9 que a barra lateral \u00e9 comum. Nesta postagem, aprenderemos como mostrar um menu personalizado adicional na barra lateral, permitindo que postagens, p\u00e1ginas ou tipos de postagem personalizados escolham um menu.<\/p>\n<p>Adicione o c\u00f3digo abaixo no seu tema <code>functions.php<\/code>ou dentro do c\u00f3digo do seu plugin.<\/p>\n<h2>Permitir que postagens ou p\u00e1ginas escolham um menu<\/h2>\n<p>Criar menus no WordPress \u00e9 f\u00e1cil e voc\u00ea pode usar o widget Menu para exibir um menu na barra lateral. O problema \u00e9 que a barra lateral \u00e9 global e o mesmo menu ser\u00e1 exibido em todos os lugares. E se voc\u00ea quiser que menus espec\u00edficos sejam exibidos em p\u00e1ginas espec\u00edficas? Voc\u00ea tamb\u00e9m aprender\u00e1 como garantir que o menu escolhido seja herdado pelas p\u00e1ginas filhas. Dessa forma, voc\u00ea s\u00f3 precisa selecionar o menu na p\u00e1gina pai. Quaisquer subp\u00e1ginas tamb\u00e9m mostrar\u00e3o o mesmo menu sem a necessidade de editar todas elas.<\/p>\n<h3>Adicionando uma metabox para escolher o menu<\/h3>\n<p>O primeiro passo \u00e9 criar uma metabox em posts ou p\u00e1ginas onde temos a op\u00e7\u00e3o de escolher um menu. Usamos a fun\u00e7\u00e3o <code>add_meta_box()<\/code>e decidimos para quais tipos de postagem queremos mostr\u00e1-la.<\/p>\n<pre><code>add_action('add_meta_boxes', function() {\n    add_meta_box('metabox-sidebar-menu', __('Sidebar Menu', 'txtdomain'), 'awp_sidebar_menu_metabox_callback', ['post', 'page']);\n});<\/code><\/pre>\n<p>Ajuste o c\u00f3digo acima para os tipos de t\u00edtulo e postagem desejados. O exemplo acima adicionar\u00e1 a metabox a posts e p\u00e1ginas. O terceiro par\u00e2metro, que chamei <code>awp_sidebar_menu_metabox_callback<\/code>de, \u00e9 a fun\u00e7\u00e3o respons\u00e1vel por renderizar o conte\u00fado da metabox. Vamos definir isso a seguir. Isto \u00e9 o que precisaremos fazer em nossa metabox:<\/p>\n<pre><code>function awp_sidebar_menu_metabox_callback($post) {\n    \/\/ Get all menus\n\u00a0\n    \/\/ Get the current saved menu, if set\n\u00a0\n    \/\/ Output HTML with a select showing all menus, and mark the currently saved one as selected\n}<\/code><\/pre>\n<p>Podemos obter uma matriz com todos os menus salvos no WordPress com <code>wp_get_nav_menus()<\/code>. Quanto \u00e0 busca do menu escolhido atual, armazenamos o menu escolhido como um post meta <code>awp_sidebar_menu<\/code>(chame-o como quiser), e simplesmente buscaremos o valor com base na corrente <code>$post<\/code>fornecida a n\u00f3s na fun\u00e7\u00e3o metabox. Salvaremos os IDs de menu porque \u00e9 tudo o que precisamos para exibir um menu. E ent\u00e3o produzimos HTML para um select que percorre os menus. A sa\u00edda HTML da metabox \u00e9 realmente com voc\u00ea, o exemplo abaixo \u00e9. Tamb\u00e9m inclu\u00ed a funcionalidade nonce para seguran\u00e7a.<\/p>\n<pre><code>function awp_sidebar_menu_metabox_callback($post) {\n    \/\/ Get all menus\n    $menus = wp_get_nav_menus();\n\u00a0\n    \/\/ Get the current saved menu, if set\n    $current_selected = get_post_meta($post-&gt;ID, 'awp_sidebar_menu', true);\n\u00a0\n    \/\/ Output HTML with a select showing all menus, and mark the currently saved one as selected\n    wp_nonce_field('awp_sidebar_menu_metabox_nonce', 'awp_sidebar_menu_nonce');\n    ?&gt;&lt;div class=\"awp-metabox-item\"&gt;\n        &lt;div class=\"awp-metabox-label\"&gt;&lt;label&gt;&lt;?php _e('Choose menu', 'txtdomain'); ?&gt;&lt;\/label&gt;&lt;\/div&gt;\n        &lt;div class=\"awp-metabox-input\"&gt;&lt;?php\n        if (empty($menus)) {\n            echo '&lt;p&gt;'. __('No menus created.', 'txtdomain'). '&lt;\/p&gt;';\n        } else { ?&gt;\n            &lt;select name=\"awp-sidebar-menu\" id=\"awp-sidebar-menu\"&gt;\n                &lt;?php \n                echo '&lt;option value=\"\"&gt;'. __('Choose menu', 'txtdomain'). '&lt;\/option&gt;';\n                foreach ($menus as $menu) { \n                    echo '&lt;option value=\"'. $menu-&gt;term_id. '\" '.selected($current_selected, $menu-&gt;term_id).'&gt;'.$menu-&gt;name.'&lt;\/option&gt;';\n                } ?&gt;\n            &lt;\/select&gt;\n        &lt;?php } ?&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;&lt;?php\n}<\/code><\/pre>\n<p>Na sa\u00edda HTML estou imprimindo uma etiqueta. Se n\u00e3o houver nenhum menu salvo no WordPress, ele simplesmente exibir\u00e1 um par\u00e1grafo. Caso contr\u00e1rio, uma sele\u00e7\u00e3o \u00e9 gerada com IDs de menu como valores e nomes de menu como r\u00f3tulo. Tamb\u00e9m estou adicionando uma op\u00e7\u00e3o vazia para permitir que as postagens n\u00e3o mostrem um menu. Estou usando a fun\u00e7\u00e3o auxiliar do WordPress <code>[selected](https:\/\/developer.wordpress.org\/reference\/functions\/selected\/)()<\/code>para marcar a op\u00e7\u00e3o salva atual como selecionada.<\/p>\n<p>Se voc\u00ea editar uma postagem ou p\u00e1gina, dever\u00e1 ver a metabox aparecer na parte inferior, mostrando sua sele\u00e7\u00e3o. Incr\u00edvel! No entanto, neste momento, ele n\u00e3o salvar\u00e1 sua escolha de menu quando voc\u00ea salvar a postagem. Esse \u00e9 o pr\u00f3ximo passo.<\/p>\n<h3>Salvando a escolha do menu<\/h3>\n<p>Usamos o gancho <code>save_post<\/code>para criar uma fun\u00e7\u00e3o que salva qualquer escolha que adicionamos em nossa metabox. O <code>save_post<\/code>gancho \u00e9 acionado toda vez que uma postagem est\u00e1 sendo salva ou atualizada. Verificaremos o nonce primeiro (se voc\u00ea n\u00e3o tiver certeza do que s\u00e3o nonces, consulte este <a href=\"https:\/\/codex.wordpress.org\/WordPress_Nonces\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">guia do WordPress sobre nonces<\/a> ). Em seguida, verificamos novamente se o usu\u00e1rio tem permiss\u00e3o para atualizar postagens e atualiza nossa meta de postagem com a op\u00e7\u00e3o.<\/p>\n<pre><code>add_action('save_post', function($post_id) {\n    if (!isset($_POST['awp_sidebar_menu_nonce']) || !wp_verify_nonce($_POST['awp_sidebar_menu_nonce'], 'awp_sidebar_menu_metabox_nonce')) {\n        return;\n    }\n\u00a0\n    if (!current_user_can('edit_post', $post_id)) {\n        return;\n    }\n\u00a0\n    update_post_meta($post_id, 'awp_sidebar_menu', $_POST['awp-sidebar-menu']);\n});<\/code><\/pre>\n<p>Agora, quando voc\u00ea atualizar as postagens, tamb\u00e9m salvar\u00e1 sua escolha de menu.<\/p>\n<p>E \u00e9 isso para a parte da escolha do post. O pr\u00f3ximo passo \u00e9 realmente a sa\u00edda do menu se um menu foi selecionado.<\/p>\n<h3>Escolhendo uma posi\u00e7\u00e3o para o menu personalizado<\/h3>\n<p>Estou adicionando a sa\u00edda na barra lateral, mas voc\u00ea pode produzi-la em qualquer lugar nos modelos do seu tema. N\u00f3s s\u00f3 precisamos de um gancho predefinido ou definir o nosso pr\u00f3prio. Como exemplo, estou adicionando um gancho personalizado na parte superior da barra lateral, para que eu possa criar uma fun\u00e7\u00e3o vinculada a isso.<\/p>\n<p>Voc\u00ea pode simplesmente chamar <code>wp_nav_menu()<\/code>diretamente no modelo, mas eu recomendo criar um gancho personalizado, porque adicionaremos um pouco de c\u00f3digo e ele pode parecer confuso.<\/p>\n<p>No meu tema eu edito <code>sidebar.php<\/code>e logo antes <code>dynamic_sidebar()<\/code>com a barra lateral \u00e9 chamada (onde os widgets s\u00e3o adicionados), eu adiciono meu gancho personalizado com <code>do_action()<\/code>e um nome dado. Voc\u00ea pode cham\u00e1-lo como quiser, mas deve ser exclusivo no WordPress. Ent\u00e3o, pelo menos, prefixe-o com algo exclusivo para voc\u00ea.<\/p>\n<pre><code>&lt;aside class=\"sidebar\"&gt;\n    &lt;?php \n    do_action('awp_before_sidebar');\n    dynamic_sidebar('left-sidebar'); \n    ?&gt;\n&lt;\/aside&gt;<\/code><\/pre>\n<h3>Renderizando o card\u00e1pio<\/h3>\n<p>Agora podemos voltar para <code>functions.php<\/code>, definir uma fun\u00e7\u00e3o vinculada <code>awp_before_sidebar<\/code>e sua sa\u00edda ser\u00e1 exibida na barra lateral antes dos widgets. A fun\u00e7\u00e3o usar\u00e1 <a href=\"https:\/\/codex.wordpress.org\/Conditional_Tags#A_Single_Page.2C_a_Single_Post.2C_an_Attachment_or_Any_Other_Custom_Post_Type\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tags condicionais do WordPress<\/a> para verificar se estamos ou n\u00e3o exibindo um \u00fanico post ou p\u00e1gina. E se assim for, vou buscar o nosso post meta. Se a meta do post foi definida, geramos o menu chamando <code>[wp_nav_menu](https:\/\/developer.wordpress.org\/reference\/functions\/wp_nav_menu\/)()<\/code>e fornecendo o ID do menu salvo como <code>menu<\/code>par\u00e2metro.<\/p>\n<pre><code>add_action('awp_before_sidebar', function() {\n    if (is_singular()) {\n        global $post;\n\u00a0\n        $sidebar_menu = get_post_meta($post-&gt;ID, 'awp_sidebar_menu', true);\n    }\n\u00a0\n    if (!empty($sidebar_menu)) {\n        ?&gt;&lt;section class=\"widget awp-sidebar-menu\"&gt;\n            &lt;?php wp_nav_menu(['menu' =&gt; $sidebar_menu]); ?&gt;\n        &lt;\/section&gt;&lt;?php\n    }\n});<\/code><\/pre>\n<p>Voc\u00ea deve ajustar o HTML ao redor do menu para ajust\u00e1-lo ao restante do conte\u00fado. No c\u00f3digo acima eu envolvo o menu no mesmo HTML que todos os widgets na barra lateral s\u00e3o encapsulados para que o estilo do widget do tema se aplique ao nosso menu personalizado.<\/p>\n<p>\u00c9 isso! Sempre que voc\u00ea escolher um menu em uma postagem ou p\u00e1gina, o menu ser\u00e1 exibido acima da barra lateral ao visualizar essa postagem ou p\u00e1gina.<\/p>\n<p>Mas podemos dar um passo adiante. Se voc\u00ea quiser que as p\u00e1ginas filhas mostrem o mesmo menu da barra lateral definido em qualquer um dos pais, continue lendo.<\/p>\n<h2>Permitir que as p\u00e1ginas filhas herdem o menu do pai<\/h2>\n<p>Esse recurso adicional faz sentido se voc\u00ea tiver muitas p\u00e1ginas em uma hierarquia ou um tipo de postagem personalizado com a hierarquia ativada. Seria muito complicado editar todas as p\u00e1ginas filhas e escolher o mesmo menu. Nesse caso, seria melhor escolher o menu na p\u00e1gina pai e deixar automaticamente todas as subp\u00e1ginas &quot;herdarem&quot; essa op\u00e7\u00e3o de menu. Se qualquer subp\u00e1gina escolher outro menu, esse menu ser\u00e1 exibido uma vez em vez do &quot;herdado&quot;.<\/p>\n<p>Dentro da nossa fun\u00e7\u00e3o ligada a <code>awp_before_sidebar<\/code>, adicionaremos um peda\u00e7o de c\u00f3digo, dentro da verifica\u00e7\u00e3o se estivermos visualizando um \u00fanico post ou p\u00e1gina:<\/p>\n<pre><code>        ...\n        $sidebar_menu = get_post_meta($post-&gt;ID, 'awp_sidebar_menu', true);\n        if (!empty($sidebar_menu)) {\n            $parents = get_post_ancestors($post-&gt;ID);\n            if (!empty($parents)) {\n                \/\/ go step by step up the parents tree\n                for ($i = 0; $i &lt; count($parents); $i++) {\n                    $sidebar_menu = get_post_meta($post-&gt;ID, 'awp_sidebar_menu', true);\n                    if (!empty($sidebar_menu)) {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\u00a0\n    if (!empty($sidebar_menu)) {\n        ...<\/code><\/pre>\n<p>O que o c\u00f3digo acima faz se nenhum menu foi encontrado na p\u00e1gina atual est\u00e1 buscando todos os pais com <code>[get_post_ancestors](https:\/\/developer.wordpress.org\/reference\/functions\/get_post_ancestors\/)()<\/code>. Esta fun\u00e7\u00e3o retorna uma matriz de IDs de postagem pai classificados primeiro pelo pai mais pr\u00f3ximo. Se a p\u00e1gina n\u00e3o tiver pais (por exemplo, se for uma postagem), uma matriz vazia ser\u00e1 retornada. E se houver algum pai, percorremos cada pai um por um e verificamos se eles definiram nossa meta de postagem. Se um for encontrado, interrompemos a travessia dos pais e <code>$sidebar_menu<\/code>ser\u00e1 definido e o menu ser\u00e1 exibido posteriormente com <code>wp_nav_menu()<\/code>.<\/p>\n<p>E \u00e9 isso para a funcionalidade de &#8220;heran\u00e7a&quot;!<\/p>\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>Neste post vamos aprender como mostrar um menu personalizado na barra lateral (ou onde voc\u00ea quiser), permitindo que posts ou p\u00e1ginas escolham um menu.<\/p>\n","protected":false},"author":1,"featured_media":224072,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[930,722,722,837,920,1110,920,806,806,837,930,846,846,867,867],"tags":[1170],"class_list":["post-233422","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-assuntos","category-desenvolvedor","category-guia-para-iniciantes","category-outro","category-n-a","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\/233422","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=233422"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233422\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/224072"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=233422"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=233422"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=233422"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}