Skip to content

Instantly share code, notes, and snippets.

@felipelavinz
Created March 29, 2012 15:04
Show Gist options
  • Select an option

  • Save felipelavinz/2238268 to your computer and use it in GitHub Desktop.

Select an option

Save felipelavinz/2238268 to your computer and use it in GitHub Desktop.
generate a dynamic sitemap from wordpress emnus
<?php
class av_sitemap{
private $args;
public $transient_id;
public $transient_data;
function __construct( $args ){
$this->args = wp_parse_args( $args, array(
'main_menu' => 'principal',
'skip' => null,
'depth' => 0,
'walker' => new Sitemap_Menu_Walker(),
'container' => 'div',
'container_class' => 'sitemap',
'container_id' => 'sitemap',
'menu_class' => 'sitemap-menu',
'menu_id' => 'sitemap-menu-id',
'cache' => 0,
'echo' => 1
) );
if ( $this->args['cache'] ) $this->transient_id = md5( $this->args['main_menu'] . $this->args['skip'] );
}
private function get_transient( ){
if ( $this->transient_data ) {
return $this->transient_data;
} else {
$data = get_transient($this->transient_id);
if ( $data ) {
$this->transient_data = $data;
return $data;
} else {
return false;
}
}
return false;
}
public function show( ){
if ( $this->args['cache'] && $this->get_transient() && !isset($_GET['nocache']) ) {
echo $this->transient_data;
return true;
} else {
$this->build();
$out = $this->walk_menus();
if ( (int)$this->args['cache'] > 0 && !isset($_GET['nocache']) ) set_transient( $this->transient_id , $out, 60 * 60 * (int)$this->args['cache'] );
if ( $this->args['echo'] ) echo $out;
else return $out;
}
return false;
}
private function order_items( $a, $b ){
if ( $a->menu_order === $b->menu_order) return 0;
if ( $a->menu_order > $b->menu_order ) return 1;
else return -1;
}
private function walk_menus(){
$out = '';
// temporarily override echo, so the loop won't echo before it's time
$echo = $this->args['echo'];
$this->args['echo'] = 0;
foreach ( $this->menus as $menu ) {
$nav_menu = '';
// get menu items... we have already retrieved and filtered them
$sorted_menu_items = $this->menus_items[$menu->term_id];
// sort items based on "menu_order"
usort( $sorted_menu_items, array($this, 'order_items') );
// do container
if ( $args->container ) {
$allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) );
if ( in_array( $args->container, $allowed_tags ) ) {
$show_container = true;
$class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-'. $menu->slug .'-container"';
$id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : '';
$nav_menu .= '<'. $args->container . $id . $class . '>';
}
}
// walk through the items to get them as HTML
$items = walk_nav_menu_tree( $sorted_menu_items, $this->args['depth'], (object)$this->args );
unset( $sorted_menu_items );
$nav_menu .= '<ul class="'. esc_attr($this->args['menu_class']) .'" id="'. esc_attr($menu->slug.'-sitemap') .'">'. $items .'</ul>';
$nav_menu .= '</' . $args->container . '>';
$out .= $nav_menu;
unset($items);
}
$this->args['echo'] = $echo;
return $out;
}
private function build(){
$this->get_menus();
$this->filter_menus();
$this->get_all_items();
$this->blend_items();
}
private function filter_menus(){
if ( !empty( $this->args['skip'] ) ) {
if ( is_string( $this->args['skip'] ) ) {
$skip_id = array_search( $this->args['skip'], $this->ids_to_slugs );
unset( $this->menus[$skip_id] );
} else {
// if it's not a string, assume it's an array
foreach ( $ths->menus as $id => $menu ) if ( in_array($menu->slug, $this->args['skip']) ) unset( $this->menus[$id]);
}
}
}
private function get_menus(){
$_menus = wp_get_nav_menus();
$this->menus = $this->ids_to_slugs = array();
foreach($_menus as $menu ) {
$this->menus[$menu->term_id] = $menu;
$this->ids_to_slugs[$menu->term_id] = $menu->slug;
}
unset($_menus);
$this->main_menu_id = array_search($this->args['main_menu'], $this->ids_to_slugs);
}
private function get_all_items(){
// get all items
$this->menus_items = array();
foreach ( $this->menus as $menu ) $this->menus_items[$menu->term_id] = wp_get_nav_menu_items( $menu->term_id );
}
private function blend_items(){
/**
* go through the main menu and check if the elements are navigation menus
* if so, merge the items from that menu into the main menu
**/
if ( isset($this->args['main_menu']) && !empty($this->main_menu_id) && !empty($this->menus_items[$this->main_menu_id]) ) {
foreach ( $this->menus_items[$this->main_menu_id] as $k => $item ) {
if ( $item->object === 'nav_menu' && !empty($this->menus_items[$item->object_id]) ) {
// go through the (sub)menu items; if it's a first-level element, we'll change that
// to get it into the main menu hierarchy
foreach ( $this->menus_items[$item->object_id] as $subitem) {
if ( $subitem->menu_item_parent == '0' ) {
$subitem->menu_item_parent = $item->menu_item_parent;
}
}
$this->menus_items[$this->main_menu_id] = array_merge( $this->menus_items[$this->main_menu_id], $this->menus_items[$item->object_id] );
// unset the menu, so we don't show it twice
unset( $this->menus_items[$item->object_id], $this->menus[$item->object_id] );
}
}
$this->menus_items[$this->main_menu_id] = array_filter( $this->menus_items[$this->main_menu_id], array($this, 'array_filter'));
}
}
private function array_filter( $item ){
if ( $item->object === 'nav_menu' ) return false;
else return true;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment