Creación de un nuevo elemento de menú – WordPress

7 minutos de lectura

Estoy buscando una manera de crear un nuevo elemento que se pueda agregar a un menú.

Aquí están los detalles de mi problema: Yo uso WPML. WPML tiene esa característica agradable que puede agregar el conmutador a un menú, automáticamente. Lo agrega al final del menú, no hay control sobre eso.

La cuestión es que quiero que mi conmutador de idioma sea el elemento 4 de 6. Esa función para agregar automáticamente el elemento al final no se ajusta a mis necesidades.

Así que quiero crear un nuevo elemento que pueda usarse en apariencia->menú para poner mi conmutador de idioma exactamente en el lugar que quiero.

¿Hay alguna manera de hacerlo?

TLDR: quiero poder insertar código HTML/PHP personalizado en un elemento de menú (Apariencia->Menú). ¿Alguna función para hacerlo?

  • pregunta interesante, esperando la respuesta 😀

    – Fiido93

    6 de noviembre de 2015 a las 17:59

  • ¿Qué tal si crea un tipo de publicación personalizada “ui_elements” más o menos y vincula la funcionalidad a una publicación? Y luego lo agregas al menú.

    – xfan

    06/11/2015 a las 19:38

  • Estoy usando una plantilla prefabricada. así que realmente no puedo agregar/modificar una plantilla como me gustaría. Y bueno, si tuviera acceso a modificar el encabezado manualmente, mi menú se habría hecho directamente en el código.

    – Fredy31

    6 de noviembre de 2015 a las 20:26


De wp-includes/nav-menu-template.phpen Walker_Nav_Menu::start_el:

/**
 * Filter a menu item's starting output.
 *
 * The menu item's starting output only includes `$args->before`, the opening `<a>`,
 * the menu item's title, the closing `</a>`, and `$args->after`. Currently, there is
 * no filter for modifying the opening and closing `<li>` for a menu item.
 *
 * @since 3.0.0
 *
 * @param string $item_output The menu item's starting HTML output.
 * @param object $item        Menu item data object.
 * @param int    $depth       Depth of menu item. Used for padding.
 * @param array  $args        An array of {@see wp_nav_menu()} arguments.
 */
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

Lo que significa que puede agregar contenido HTML a un elemento del menú de navegación individual (justo antes del último li etiqueta) usando ese filtro. $item_output contiene el código HTML generado para el elemento hasta el momento. Ejemplo:

<?php

add_filter('walker_nav_menu_start_el', function ($item_output) {
    return $item_output . '<span>hello world</span>';
});

Eso agregaría <span>hello world</span> a cada elemento del menú de navegación HTML. un cierre li la etiqueta se agregará después de este filtro. Puedes usar el cuarto argumento ($args) para validar el menú de navegación de representación actual.

  • Incluso si esto lo soluciona, no puedo aceptarlo como respuesta. Nunca, NUNCA, modifiques el núcleo de WP.

    – Fredy31

    11/02/2016 a las 21:53

  • El gancho no modifica el núcleo. Lo proporciona el núcleo y está destinado a ser utilizado por complementos y temas para ajustes.

    – ojrask

    11 de febrero de 2016 a las 22:03

avatar de usuario
Nikola Miljković

Muy bien, tengo una solución temporal.

Estos son los pasos:

  1. Abierto \wp-content\plugins\sitepress-multilingual-cms\inc\language-switcher.php
  2. Ir a algún lugar alrededor de la línea 786dónde está function wp_nav_menu_items_filter($items, $args){
  3. Agregue esto justo después del primero {:

    $tempitems = $items;  
    $tempitemsexplode = explode("\n", $tempitems);  
    $items = "";  
    $id = 2; //This is where widget will be located: example, if you want it to be at place 4, write 5
    
  4. Justo antes de if ( $abs_menu_id == $settings_menu_id || false === $abs_menu_id ) { Agrega esto:

    $id = 2;  
    for ($i = 0; $i < $id; $i++){  
        $items .= $tempitemsexplode[$i];  
    }  
    for($i = 0; $i < count($tempitemsexplode); $i++){  
        If ($i == $id){  
    
  5. Ir al final de la función y antes:
    }
    return $items;

    Agregar: }}

  6. Ahora, antes return $items; Agregar:

    for ($i = $id; $i < count($tempitemsexplode); $i++){  
        $items .= $tempitemsexplode[$i];  
    }
    

Si te quedas atascado, así es como me parece toda esa función:

function wp_nav_menu_items_filter($items, $args){
    $tempitems = $items;
    $tempitemsexplode = explode("\n", $tempitems);
    $items = "";
    global $sitepress_settings, $sitepress;

    $current_language = $sitepress->get_current_language();
    $default_language = $sitepress->get_default_language();
    // menu can be passed as integer or object
    if(isset($args->menu->term_id)) $args->menu = $args->menu->term_id;

    $abs_menu_id = icl_object_id($args->menu, 'nav_menu', false, $default_language );
    $settings_menu_id = icl_object_id( $sitepress_settings[ 'menu_for_ls' ], 'nav_menu', false, $default_language );

    $id = 2;
    for ($i = 0; $i < $id; $i++){
        $items .= $tempitemsexplode[$i];
    }

    for($i = 0; $i < count($tempitemsexplode); $i++){
        If ($i == $id){
            if ( $abs_menu_id == $settings_menu_id  || false === $abs_menu_id ) {

                $languages = $sitepress->get_ls_languages();


                $items .= '<li class="menu-item menu-item-language menu-item-language-current">';
                if(isset($args->before)){
                    $items .= $args->before;
                }
                $items .= '<a href="#" onclick="return false">';
                if(isset($args->link_before)){
                    $items .= $args->link_before;
                }

                $language_name="";
                if ( $sitepress_settings[ 'icl_lso_native_lang' ] ) {
                    $language_name .= $languages[ $current_language ][ 'native_name' ];
                }
                if ( $sitepress_settings[ 'icl_lso_display_lang' ] && $sitepress_settings[ 'icl_lso_native_lang' ] ) {
                    $language_name .= ' (';
                }
                if ( $sitepress_settings[ 'icl_lso_display_lang' ] ) {
                    $language_name .= $languages[ $current_language ][ 'translated_name' ];
                }
                if ( $sitepress_settings[ 'icl_lso_display_lang' ] && $sitepress_settings[ 'icl_lso_native_lang' ] ) {
                    $language_name .= ')';
                }



                $alt_title_lang = esc_attr($language_name);

                if( $sitepress_settings['icl_lso_flags'] ){
                    $items .= '<img class="iclflag" src="' . $languages[ $current_language ][ 'country_flag_url' ] . '" width="18" height="12" alt="' . $alt_title_lang . '" title="' . esc_attr( $language_name ) . '" />';
                }

                $items .= $language_name;

                if(isset($args->link_after)){
                    $items .= $args->link_after;
                }
                $items .= '</a>';
                if(isset($args->after)){
                    $items .= $args->after;
                }

                unset($languages[ $current_language ]);
                $sub_items = false;
                $menu_is_vertical = !isset($sitepress_settings['icl_lang_sel_orientation']) || $sitepress_settings['icl_lang_sel_orientation'] == 'vertical';
                if(!empty($languages)){
                    foreach($languages as $lang){
                        $sub_items .= '<li class="menu-item menu-item-language menu-item-language-current">';
                        $sub_items .= '<a href="'.$lang['url'].'">';

                        $language_name="";
                        if ( $sitepress_settings[ 'icl_lso_native_lang' ] ) {
                            $language_name .= $lang[ 'native_name' ];
                        }
                        if ( $sitepress_settings[ 'icl_lso_display_lang' ] && $sitepress_settings[ 'icl_lso_native_lang' ] ) {
                            $language_name .= ' (';
                        }
                        if ( $sitepress_settings[ 'icl_lso_display_lang' ] ) {
                            $language_name .= $lang[ 'translated_name' ];
                        }
                        if ( $sitepress_settings[ 'icl_lso_display_lang' ] && $sitepress_settings[ 'icl_lso_native_lang' ] ) {
                            $language_name .= ')';
                        }
                        $alt_title_lang = esc_attr($language_name);

                        if( $sitepress_settings['icl_lso_flags'] ){
                            $sub_items .= '<img class="iclflag" src="'.$lang['country_flag_url'].'" width="18" height="12" alt="'.$alt_title_lang.'" title="' . $alt_title_lang . '" />';
                        }
                        $sub_items .= $language_name;

                        $sub_items .= '</a>';
                        $sub_items .= '</li>';

                    }
                    if( $sub_items && $menu_is_vertical ) {
                        $sub_items="<ul class="sub-menu submenu-languages">" . $sub_items . '</ul>';
                    }
                }

                if( $menu_is_vertical ) {
                    $items .= $sub_items;
                    $items .= '</li>';
                } else {
                    $items .= '</li>';
                    $items .= $sub_items;
                }
            }
        }
    }

    for ($i = $id; $i < count($tempitemsexplode); $i++){
        $items .= $tempitemsexplode[$i];
    }

    return $items;

}

Intentaré que sea más fácil cambiar dónde desea colocar el widget.
Comenta si tienes problemas. ¡Buena suerte!

Editar: Explicación de lo que hace esta función modificada.
Esta función se utiliza para agregar un selector de idioma al menú.
Cuando se llama a esta función, tenemos $items cadena que contiene todos los elementos del menú.
Transferí todos los elementos del menú de $items a $tempitems y establecer $items a cadena vacía.
¿Por qué? Porque ahora podemos insertar un widget como primer elemento del menú o entre algunos elementos del menú.

Luego explotamos eso $tempitems cadena para que podamos usar otro orden.

Cuando ahora especificas $id esto se convierte en nuestra compensación.

Y ahora en el primer bucle, con la ayuda de $idagregamos algunos elementos temporales para vaciar $items cadena, y luego el widget de idioma y al final los elementos de menú restantes.

avatar de usuario
SER64

Puede crear una nueva plantilla incluso si está utilizando una theme o template.

Simplemente copie el código de la plantilla que desea usar y modifíquelo en consecuencia en su localhost y cargue la copia modificada en el directorio del tema.

Asegúrese de guardar una copia en caso de que actualice el tema a una versión más nueva porque se sobrescribirá.

Otra opción sería desarrollar un tema infantil.

  • Ponerlo en un tema hijo sí. Es mejor que modificar WP Core o el núcleo del complemento WPML. No sé por qué esto fue derribado con tanta fuerza.

    – Fredy31

    11 de febrero de 2016 a las 21:54

¿Ha sido útil esta solución?