I have expanded a bit on tungd's answer to provide more genericity with that approach. This implementation allows adding arbitrary mappings between menu 'macros' and internal Wordpress URLs that only the backend knows about.
I've also decided to use !
as the prefix for these macros to avoid them clashing with named anchors - this includes an overhead to strip off the 'http://' from the link URL (as Wordpress will attempt to normalise these weird links). If that implementation bothers you, you can always remove the preg_replace()
call and use #
as your link prefix as before.
class Extendable_Menu_Walker extends Walker_Nav_Menu
{
protected static $custom_urls = array();
public static function setupUrls()
{
// calls to self::mapPostType($postTypeName) and
// self::createMapping($wildcard, $url) go here...
}
public function start_el(&$output, $item, $depth=0, $args=array(), $id=0)
{
$url = preg_replace('@^https?://@', '', $item->url);
if (isset( self::$custom_urls[ $url ] )) {
$item->url = self::$custom_urls[ $url ];
}
parent::start_el($output, $item, $depth, $args, $id);
}
public static function createMapping($urlKey, $realUrl)
{
self::$custom_urls['!' . $urlKey] = $realUrl;
}
public static function mapPostType($type)
{
self::createMapping('post_type_' . $type, get_post_type_archive_link($type));
}
}
add_action('init', array('Extendable_Menu_Walker', 'setupUrls'));