Making a category based menu with posts in wordpress 2.9.2

Sunday, May 23rd, 2010

I was not entirely happy with the way wordpress handles menus for this (my own) website. I like the idea of making all the content posts so they’re bound to a date and such. Then I’d like to see them in the menu based on the category they’re in. There are category menus, and even nice folding ones, but I couldn’t find one that displays all the posts per category in a nice way.

So I decided to hack one in myself. It’s a very nasty hack… and I just put a bunch of code in the sidebar.php of my template. But that said… it works and I now have a menu that does what I want.

If you’d like to use this… just remember it’s a great big bad hack and very inefficient!

Here’s the html/php code I added to my template’s sidebar.php:

  1. // Get the id of the current post so we can give it a "current" class later.
  2. $postid = $post->ID;
  3.  
  4. // Arguments for getting all the categories
  5. $args = array(
  6. 'show_option_all'    => '',
  7. 'orderby'            => 'name',
  8. 'order'              => 'ASC',
  9. 'show_last_update'   => 0,
  10. 'style'              => 'list',
  11. 'show_count'         => 0,
  12. 'hide_empty'         => 1,
  13. 'use_desc_for_title' => 0,
  14. 'child_of'           => 0,
  15. 'feed'               => '',
  16. 'feed_type'          => '',
  17. 'feed_image'         => '',
  18. 'exclude'            => '',
  19. 'exclude_tree'       => '',
  20. 'include'            => '',
  21. 'hierarchical'       => true,
  22. 'title_li'           => '',
  23. 'number'             => NULL,
  24. 'echo'               => 0,
  25. 'depth'              => 0,
  26. 'current_category'   => 1,
  27. 'pad_counts'         => 0,
  28. 'taxonomy'           => 'category' );
  29.  
  30. // Get all categories (in a silly html menu)
  31. $catmenu = wp_list_categories( $args );
  32.  
  33. // Split the menu to get all categories sepparately
  34. $cats = split('
  35. <li class="cat-item cat-item-', $catmenu);
  36.  
  37. $catmenu = '';
  38.  
  39. // Loop through the categories.
  40. foreach($cats as $key => $cat){
  41.  
  42.         $current = '';
  43.  
  44.         // Get the code and html sepparately
  45.         list($id, $code) = split('"><a', $cat);
  46.  
  47.         // Make sure they're there.
  48.         if($id && $code){
  49.  
  50.                 // If this is the current category, then remove that text and remember for later
  51.                 if(strpos($id, ' current-cat') !== False){
  52.                         $current = ' current-cat';
  53.                         $id = str_replace(' current-cat', '', $id);
  54.                 }
  55.  
  56.                 // In case we got an id... and this category doesn't have sub categories.
  57.                 if(is_numeric($id) && strpos($code, "
  58. <ul class='children'>") === False){
  59.  
  60.                         // Arguments for getting the categorie's posts
  61.                         $args = array(
  62.                                 'post_type' => 'post',
  63.                                 'post_status' => 'published',
  64.                                 'numberposts' => -1,
  65.                                 'category' => $id
  66.                                 );
  67.  
  68.                         // Get the posts
  69.                          $myposts = get_posts($args);
  70.  
  71.                          // If we got any posts returned
  72.                          if(count($myposts)){
  73.  
  74.                                 // Start a nice html post list
  75.                                 $postlist = "\n".'
  76. <ul class="posts">';
  77.  
  78.                                 // Check east post to see if it's current and add to the html
  79.                                  foreach($myposts as $post) {
  80.                                         $current_post = '';
  81.                                         if($postid == $post->ID){
  82.                                                 $current_post = ' class="current-post"';
  83.                                                 $current = ' current-cat';
  84.                                         }
  85.                                         $postlist .= "\n".'
  86. <li'.$current_post.'><a href="'.get_permalink($post->ID).'">'.$post->post_title.'</a></li>
  87.  
  88. ';
  89.                                  }
  90.  
  91.                                  $postlist .= "\n".'</ul>
  92.  
  93. ';
  94.  
  95.                                 // Add the post list to the code of the current category
  96.                                 $code = str_replace('</a>', '</a>'.$postlist, $code);
  97.  
  98.                         }
  99.  
  100.                 }
  101.  
  102.                 // Put everything that was split before back together
  103.                 $cat = '
  104. <li class="cat-item cat-item-'.$id.$current.'"><a'.$code;
  105.  
  106.         }
  107.  
  108.         // Add back into the complete category menu
  109.         $catmenu .= $cat;
  110. }
  111.  
  112. // Print out the category menu
  113. echo '
  114. <li id="menu">
  115. <ul>'.$catmenu.'</ul>
  116. </li>
  117.  
  118. ';

Display clean php code for copying

// Get the id of the current post so we can give it a "current" class later.
$postid = $post->ID;

// Arguments for getting all the categories
$args = array(
'show_option_all'    => '',
'orderby'            => 'name',
'order'              => 'ASC',
'show_last_update'   => 0,
'style'              => 'list',
'show_count'         => 0,
'hide_empty'         => 1,
'use_desc_for_title' => 0,
'child_of'           => 0,
'feed'               => '',
'feed_type'          => '',
'feed_image'         => '',
'exclude'            => '',
'exclude_tree'       => '',
'include'            => '',
'hierarchical'       => true,
'title_li'           => '',
'number'             => NULL,
'echo'               => 0,
'depth'              => 0,
'current_category'   => 1,
'pad_counts'         => 0,
'taxonomy'           => 'category' );

// Get all categories (in a silly html menu)
$catmenu = wp_list_categories( $args );

// Split the menu to get all categories sepparately
$cats = split('
  • ") === False){ // Arguments for getting the categorie's posts $args = array( 'post_type' => 'post', 'post_status' => 'published', 'numberposts' => -1, 'category' => $id ); // Get the posts $myposts = get_posts($args); // If we got any posts returned if(count($myposts)){ // Start a nice html post list $postlist = "\n".'
      '; // Check east post to see if it's current and add to the html foreach($myposts as $post) { $current_post = ''; if($postid == $post->ID){ $current_post = ' class="current-post"'; $current = ' current-cat'; } $postlist .= "\n".' '.$post->post_title.' '; } $postlist .= "\n".'
    '; // Add the post list to the code of the current category $code = str_replace('', ''.$postlist, $code); } } // Put everything that was split before back together $cat = '
    • '.$catmenu.'
  • ';

    And here is the javascript code I added to my template’s header.php:

    1. // Initialise javascript functions using jquery
    2. jQuery(document).ready(function(){
    3.  
    4.         initMenu();
    5.  
    6. });
    7.  
    8. // Start the menu functionality
    9. function initMenu(){
    10.         // Hide all the submenus by default
    11.         jQuery('#menu ul ul').hide();
    12.  
    13.         // Find the current post and make sure all the categories it's in are also "current", then show their kids.
    14.         jQuery('#menu .current-post').parents('li[id!=menu]').addClass('current-cat').children('ul').show();
    15.  
    16.         // Replace the click event of all category menu items except for "news"
    17.         // In stead make them fold down and up the sub menu
    18.         jQuery('#menu a').click(function(event){
    19.  
    20.                 thisItem = jQuery(this);
    21.  
    22.                 childList = thisItem.siblings('ul');
    23.  
    24.                 if(childList.length){
    25.  
    26.                         if(!(thisItem.html() == 'News' && childList.is(':hidden'))){
    27.  
    28.                                 event.preventDefault();
    29.  
    30.                                 if(childList.is(':hidden')){
    31.  
    32.                                         thisItem.addClass('clicked');
    33.  
    34.                                         childList.slideDown('fast');
    35.  
    36.                                         jQuery('#menu ul:visible').each(function(){
    37.  
    38.                                                 if(!(jQuery('.clicked', this).length || jQuery(this).siblings('.clicked').length)){
    39.                                                         jQuery(this).slideUp('fast');
    40.                                                 }
    41.  
    42.                                         });
    43.  
    44.                                         thisItem.removeClass('clicked');
    45.  
    46.                                 }else{
    47.                                         childList.slideUp('fast');
    48.                                 }
    49.                         }
    50.  
    51.                 }
    52.  
    53.         });
    54. }

    Display clean javascript code for copying

    // Initialise javascript functions using jquery
    jQuery(document).ready(function(){
    
    	initMenu();
    
    });
    
    // Start the menu functionality
    function initMenu(){
    	// Hide all the submenus by default
    	jQuery('#menu ul ul').hide();
    
    	// Find the current post and make sure all the categories it's in are also "current", then show their kids.
    	jQuery('#menu .current-post').parents('li[id!=menu]').addClass('current-cat').children('ul').show();
    
    	// Replace the click event of all category menu items except for "news"
    	// In stead make them fold down and up the sub menu
    	jQuery('#menu a').click(function(event){
    
    		thisItem = jQuery(this);
    
    		childList = thisItem.siblings('ul');
    
    		if(childList.length){
    
    			if(!(thisItem.html() == 'News' && childList.is(':hidden'))){
    
    				event.preventDefault();
    
    				if(childList.is(':hidden')){
    
    					thisItem.addClass('clicked');
    
    					childList.slideDown('fast');
    
    					jQuery('#menu ul:visible').each(function(){
    
    						if(!(jQuery('.clicked', this).length || jQuery(this).siblings('.clicked').length)){
    							jQuery(this).slideUp('fast');
    						}
    
    					});
    
    					thisItem.removeClass('clicked');
    
    				}else{
    					childList.slideUp('fast');
    				}
    			}
    
    		}
    
    	});
    }

    JQuery geshi

    Wednesday, March 17th, 2010

    Code highlighting using ajax with jquery and geshi

    1. $(document).ready(function(){
    2.  
    3.         // Initialise highlighting
    4.         if($('pre').length){
    5.                 $('pre').each(function(){
    6.                         highLight($(this));
    7.                 });
    8.         }
    9.  
    10. });
    11.  
    12. // Highlight item
    13. function highLight(thisItem){
    14.         snippet  = thisItem.html();
    15.         snippet = snippet.replace(/&amp;amp;/ig, escape('&'));
    16.         snippet = snippet.replace(/&lt;/ig, '<');
    17.         snippet = snippet.replace(/&gt;/ig, '>');
    18.         language = thisItem.attr('class');
    19.         $.ajax({
    20.                 type: "POST",
    21.                 url: '/scripts/highlight.php',
    22.                 data: 'language='+language+'&snippet='+snippet,
    23.                 dataType: "html",
    24.                 success: function(msg){
    25.                         if (msg){
    26.                                 msg = msg.replace('&amp;', '&');
    27.                                 thisItem.after(msg);
    28.                                 thisItem.hide();
    29.                         }
    30.                 }
    31.         });
    32. }

    Display clean javascript code for copying

    $(document).ready(function(){
    
    	// Initialise highlighting
    	if($('pre').length){
    		$('pre').each(function(){
    			highLight($(this));
    		});
    	}
    
    });
    
    // Highlight item
    function highLight(thisItem){
    	snippet  = thisItem.html();
    	snippet = snippet.replace(/&amp;amp;/ig, escape('&'));
    	snippet = snippet.replace(/&lt;/ig, '<');
    	snippet = snippet.replace(/&gt;/ig, '>');
    	language = thisItem.attr('class');
    	$.ajax({
    		type: "POST",
    		url: '/scripts/highlight.php',
    		data: 'language='+language+'&snippet='+snippet,
    		dataType: "html",
    		success: function(msg){
    			if (msg){
    				msg = msg.replace('&amp;', '&');
    				thisItem.after(msg);
    				thisItem.hide();
    			}
    		}
    	});
    }

    Make a safe url

    Wednesday, March 17th, 2010

    This is a function that makes a string url safe.
    Nice for creating friendly urls that are actually friendly.

    1. // Function for making sure text only uses url safe symbols
    2. function makeSafe(thisText, allowSpace){
    3.         var w = "!@#$%^&*()+=[]\\\';,./{}|\":<>?";
    4.         var s = 'abcdefghijklmnopqrstuvwxyz0123456789-_';
    5.         var x = new Array('àáâãäå', 'ç', 'èéêë', 'ìíîï', 'ñ', 'ðóòôõöø', 'ùúûü', 'ýÿ');
    6.         var r = new Array('a', 'c', 'e', 'i', 'n', 'o', 'u', 'y');
    7.  
    8.         if(allowSpace){
    9.                 s = s + ' ';
    10.         }
    11.  
    12.         thisText = thisText.toLowerCase();
    13.         var newText = new Array();
    14.  
    15.         for (i = 0; i < thisText.length; i++){
    16.                 thisChar = thisText.charAt(i);
    17.                 if(w.indexOf(thisChar) == -1){
    18.                         if(s.match(''+thisChar+'')){
    19.                                 newText[i] = thisChar;
    20.                         }else{
    21.                                 for (j = 0; j < x.length; j++){
    22.                                         if(x[j].match(thisChar)){
    23.                                                 newText[i] = r[j];
    24.                                         }
    25.                                 }
    26.                         }
    27.                 }
    28.         }
    29.  
    30.         return newText.join('');
    31. }

    Display clean javascript code for copying

    // Function for making sure text only uses url safe symbols
    function makeSafe(thisText, allowSpace){
    	var w = "!@#$%^&*()+=[]\\\';,./{}|\":<>?";
    	var s = 'abcdefghijklmnopqrstuvwxyz0123456789-_';
    	var x = new Array('àáâãäå', 'ç', 'èéêë', 'ìíîï', 'ñ', 'ðóòôõöø', 'ùúûü', 'ýÿ');
    	var r = new Array('a', 'c', 'e', 'i', 'n', 'o', 'u', 'y');
    
    	if(allowSpace){
    		s = s + ' ';
    	}
    
    	thisText = thisText.toLowerCase();
    	var newText = new Array();
    
    	for (i = 0; i < thisText.length; i++){
    		thisChar = thisText.charAt(i);
    		if(w.indexOf(thisChar) == -1){
    			if(s.match(''+thisChar+'')){
    				newText[i] = thisChar;
    			}else{
    				for (j = 0; j < x.length; j++){
    					if(x[j].match(thisChar)){
    						newText[i] = r[j];
    					}
    				}
    			}
    		}
    	}
    
    	return newText.join('');
    }

    Find root folder

    Wednesday, March 17th, 2010

    I use this tiny snippet that uses jquery to find the root folder of my website.
    It assumes jquery.js is included in the page.
    It’s usefull for finding out where to post ajax stuff to (so you have a complete root).

    For this website it would look in the header of the html for:
    <script type="text/javascript" src="http://www.macouno.com/js/jquery.js"></script>

    1. // Get the source directory of this script
    2. root = $('script[@src$=jquery.js]').attr('src').replace('js/jquery.js', '');
    3. if(!location.href.match('www')){
    4.         root = root.replace('www.', '');
    5. }

    Display clean javascript code for copying

    // Get the source directory of this script
    root = $('script[@src$=jquery.js]').attr('src').replace('js/jquery.js', '');
    if(!location.href.match('www')){
    	root = root.replace('www.', '');
    }

    Add to tinymce

    Wednesday, March 17th, 2010

    Because I will forget unless I save a copy here.
    This is a very basic function for adding a string to tinymce (I use it to add images that are listed elsewhere on a page).

    1. // Adding content to the end of the tinymce editor
    2. function addToTiny(newContent){
    3.         var inst = tinyMCE;
    4.         inst.execCommand('mceFocus',false,'content');
    5.         inst.execCommand('mceInsertContent', true, newContent);
    6. }

    Display clean javascript code for copying

    // Adding content to the end of the tinymce editor
    function addToTiny(newContent){
    	var inst = tinyMCE;
    	inst.execCommand('mceFocus',false,'content');
    	inst.execCommand('mceInsertContent', true, newContent);
    }
    click here to close

    Help keep these files free,
    and support further development!