Come aggiungere un Link Personalizzato a un Menu con URL relativo all'URL del blog
Parte del mio lavoro consiste nel creare siti WordPress. Di solito lavoro sul mio laptop fino a quando non ho qualcosa di abbastanza buono da caricare sul server di test dove il cliente lo esamina.
Creo un VirtualHost per ogni nuovo progetto, quindi lavoro sempre con un'installazione WordPress in un dominio che assomiglia a http://local.example.com/
, ma quando il sito viene caricato sul server di test (non controllato da me), il dominio potrebbe diventare qualcosa come http://testserver.com/arbitrary/path/example/
.
Il problema è che se aggiungo un link personalizzato a un menu che punta, ad esempio, a /events/
, funzionerebbe bene localmente creando un link a http://local.example.com/events/
, ma nel server di test, il link punterà a http://testserver/events/
, che ovviamente non è corretto.
Quello che voglio è dare al link personalizzato un URL che funzioni sia nel mio ambiente locale che nel server di test.
Gestisco già il problema del cambio delle opzioni WordPress home
e siteurl
attraverso:
- la modifica di queste impostazioni nel database locale
- la creazione di un dump del database
- l'aggiornamento del database sul server
- il ripristino delle opzioni locali
Non voglio utilizzare URL completi per i link personalizzati e dover sostituire questi con l'URL del server ogni volta che devo aggiornare il database del server.
Per i link all'interno del contenuto dei post, esiste un plugin che risolve il problema aggiungendo due shortcode: http://wordpress.org/extend/plugins/url-shortcodes/, ma non sono riuscito a trovare qualcosa di simile per i Link Personalizzati.
Funziona ma cambia anche l'URL includendo index.php. Nel caso di un'applicazione a pagina singola con link #, prima aggiornerebbe la pagina e poi ti porterebbe alla destinazione (solo la prima volta). Comunque un'idea valida

Puoi utilizzare il filtro nav_menu_link_attributes
per controllare e modificare l'attributo href di ogni voce del menu prima che venga visualizzato.
In questo esempio, cerchiamo qualsiasi attributo href che inizi con /
e prependiamo l'URL del sito di test in quel caso:
function wpd_nav_menu_link_atts( $atts, $item, $args, $depth ){
if( '/' == substr( $atts['href'], 0, 1 ) ){
$atts['href'] = 'http://testserver.com/example' . $atts['href'];
}
return $atts;
}
add_filter( 'nav_menu_link_attributes', 'wpd_nav_menu_link_atts', 20, 4 );
Potresti creare un semplice plugin con questo codice e attivarlo solo sul tuo server di test, oppure creare una sorta di flag che applica condizionalmente questo filtro quando è presente l'ambiente del sito di test.

Utilizzo del tag <base href=" ">
nell'head meta fornirà un URL base a tutti gli anchor relativi nella pagina.
Riferimento:
https://www.w3.org/TR/html4/struct/links.html
12.4 Informazioni sul percorso: l'elemento BASE
Link personalizzati relativi in WordPress:
Se vuoi che l'URL del sito sia l'URL base di tutti gli anchor, aggiungi questo al file theme/header.php all'interno del tag <head>
:
<base href="<?php echo site_url(); ?>/">
So che potrebbe essere tardi per te, ma potrebbe aiutare qualcun altro.

Non funziona con percorsi come ehepperle.com/sites/in-progress/some-wp-site-root/
a meno che non si imposti esplicitamente la root del sito. La velocità di sviluppo web non migliora in modo evidente usando il tag base
, poiché quando si migra su un altro sito bisognerà ridefinire la base. Tuttavia, posso vedere il valore nella riduzione della lunghezza dei valori href.

Nella configurazione del Menu, su un URL personalizzato è possibile utilizzare link relativi al [blogurl]. Il segreto è iniziare l'URL relativo con un singolo /
. Quando un singolo / inizia l'URL personalizzato, il sistema non anteporrà il tipico http://
e quindi l'URL corrente del blog verrà generato nell'URL di destinazione al momento dell'esecuzione.
ESEMPIO
Se vuoi andare alla tua home page, inserisci semplicemente /
come URL personalizzato.
Se vuoi andare alla pagina indice nella cartella bbforums
, inserisci /bbforums
come URL personalizzato.
Ciò ti consente di spostare un sito su un dominio di test senza dover codificare manualmente il nuovo blogURL in tutti i link personalizzati per i menu.
Ad esempio:
Se il mio blog è http://example.com
e voglio testarlo in un sottodominio http://test.example.com
, il sito può essere spostato tra test e produzione senza problemi ai menu utilizzando la convenzione degli URL relativi menzionata sopra. Ho testato con successo questo approccio utilizzando il plugin XCloner per spostare il sito.

Questo non funziona per gli URL dei blog che hanno delle barre, ad esempio http://www.example.com/blog/. Seguendo la voce di menu '/' ti porterebbe semplicemente a http://example.com.

Per prima cosa devi installare questo plugin per gli shortcode degli URL.
Aggiungi questo codice al tuo file functions.php
nel tuo tema:
class description_walker extends Walker_Nav_Menu {
function start_el( &$output, $item, $depth, $args ) {
global $wp_query;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
$class_names = ' class="'. esc_attr( $class_names ) . '"';
$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) . '"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) . '"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) . '"' : '';
// echo $item->url;
$string = explode( '::', $item->url, 3 );
if ( $string[1] ) {
$string[1] = str_replace( '-', ' ', $string[1] );
$item->url = do_shortcode( "[$string[1]]" );
}
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
$prepend = '<strong>';
$append = '</strong>';
$description = ! empty( $item->description ) ? '<span>' . esc_attr( $item->description ) . '</span>' : '';
if ( $depth != 0 ) {
$description = $append = $prepend = "";
}
$item_output = $args->before;
$item_output .= '<a'. $attributes . '>';
$item_output .= $args->link_before . $prepend . apply_filters( 'the_title', $item->title, $item->ID ) . $append;
$item_output .= $description . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
Poi devi chiamare la funzione wp_nav_menu
dai file dei template:
$arg = array(
'menu' => "main-menu",
'echo' => true,
'fallback_cb' => 'wp_page_menu',
'depth' => 0,
'walker' => new description_walker()
);
wp_nav_menu( $arg );
Questo è tutto. Poi vai alla sezione menu nel back-end.
Per esempio, se voglio assegnare l'URL di una pagina a un link personalizzato, lo aggiungerò così:
http://::blogurl-id='1302'::
Ora puoi andare nel front-end e verificare che lo shortcode funzioni.
