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');
    				}
    			}
    
    		}
    
    	});
    }

    Teaching UV unwrapping

    Thursday, March 18th, 2010

    Getting to grips with 2D to 3D

    This is a simple little exercise I came up with for showing students how to convert 2D to 3D and vise versa. The idea is to not go straight to 3D, but in stead give them a hands-on task that gets the idea into their heads. It’s not a completely new thing for most students, but the relation to UV unwrapping is. And of course it is fun to try to make it challenging as well.


    The example

    To give my students some idea of what I expected them to do I showed them an example I made the night before class. It’s a basic svg I made in Inkscape that I printed on A4 paper.

    I could have just made a single T shape to make a single cube, but since I was teaching university level students that was a bit too simple. In stead I made this, which turns into 2 cubes that are connected at a corner. The real world result that I glued together the night before class, and showed my students in the morning is below here.


    The task

    After showing the students my example, I provided them all with paper, rulers, pencils, glue or tape, and scissors. Then put them right to work. The task I gave them was was rather simple…

    Make something more complicated than a single cube!


    The results

    As usual my students surprised me with their inventiveness. The range of designs they came up with was really nice. Especially the surprises and “misinterpretations” that I really didn’t see coming. All I did during the class was walk around and give some pointers.


    Round up

    That’s basicly all this class was. After finishing the exercise we got stuck in in Blender 3D to UV unwrap the models they had made the day before. It was a lot easier for me to teach them that technique after they had done exactly the opposite with paper (which is what this exercise is). All in all this was a fun hour to break up the week of staring at computer screens, and I’ll definitely repeat it in future.

    I hope this helps you, and if you have similar fun ways of teaching your students, please let me know. I’m always looking for novel ways of getting these complex ideas into students heads.

    Dolf

    Getting python to work on Xampp

    Wednesday, March 17th, 2010

    I spent most of today (Dec 14 2009) messing around trying to get xampp to interpret python scripts. Usually xampp only works with php, at least on my windows system (windows 32 bit vista). But since I’m developing something for a python server I needed to get it to work.

    I read a lot, found a heap of documentation about mod_python (mod_python.so), and only after half a day found out that that’s really not a very nice solution. And I already had python 2.5 installed as well. mod_python seems nice, and has a lot of links to it on google, but it’s overkill/weird and rarely needed.

    So, if you’re like me, and have python & xampp installed on your system (and your pythonpath set in the environment variables), and need .py files to work… just do this.


    Configuring the server

    In the httpd.conf file for your apache installation (part of xampp) add the following all the way at the bottom. In my case the httpd.conf can be found here: C:\xampp\apache\conf

    1. #
    2. # For Python
    3. #
    4. AddHandler cgi-script .py
    5. ScriptInterpreterSource Registry-Strict

    Display clean text code for copying

    #
    # For Python
    #
    AddHandler cgi-script .py
    ScriptInterpreterSource Registry-Strict

    Configuring the python script

    Then in the top of the python script on your server, it already knows it should be python, but it doesn’t know yet where the python program is. So as the very first line in your python scripts on the server you have to say where python is installed. In my case that looks like this

    1. #!C:/Python25/python.exe

    Display clean python code for copying

    #!C:/Python25/python.exe

    Enabling index.py

    Of course it’s nice to have index.py files work just like index.php ones as well. So I added index.py to the following bit in the httpd.conf

    1. #
    2. # DirectoryIndex: sets the file that Apache will serve if a directory
    3. # is requested.
    4. #
    5. <IfModule dir_module>
    6.     DirectoryIndex index.php index.php4 index.php3 index.cgi index.pl index.html index.htm index.shtml index.phtml index.py
    7. </IfModule>

    Display clean text code for copying

    #
    # DirectoryIndex: sets the file that Apache will serve if a directory
    # is requested.
    #
    <IfModule dir_module>
        DirectoryIndex index.php index.php4 index.php3 index.cgi index.pl index.html index.htm index.shtml index.phtml index.py
    </IfModule>

    That’s it

    Now .py files are also interpreted by python on a xampp installed apache server, just like .php. I hope that helps you as much as it dit me, and maybe saves you some time.

    Dolf

    Shorten text

    Wednesday, March 17th, 2010

    This is a small function that shortens a string.
    It looks if the string is longer than a preset length, and if so cuts the text there.
    Then it removes the last word from the string (so your string ends neatly at a space), and adds three dots.

    1. // Shorten a text if nessecary
    2. function shortenText($txt='', $len=0){
    3.  
    4.         if(strlen($txt) > $len){
    5.  
    6.                 $txt = substr($txt, 0, $len);
    7.  
    8.                 $t = split("[\n\r\t ]+", $txt);
    9.                 $t = array_slice($t, 0, -1);
    10.                 $txt = join(' ', $t);
    11.  
    12.                 $txt .= '...';
    13.  
    14.         }
    15.  
    16.         return $txt;
    17. }

    Display clean php code for copying

    // Shorten a text if nessecary
    function shortenText($txt='', $len=0){
    
    	if(strlen($txt) > $len){
    
    		$txt = substr($txt, 0, $len);
    
    		$t = split("[\n\r\t ]+", $txt);
    		$t = array_slice($t, 0, -1);
    		$txt = join(' ', $t);
    
    		$txt .= '...';
    
    	}
    
    	return $txt;
    }

    Rot13

    Wednesday, March 17th, 2010

    Basic rot13 function for PHP (remember that this is NOT secure encryption!).
    It’s built into php nowadays, but if you have an old version you may not.

    1. // Rot 13 function for older php versions
    2. function rot13($text){
    3.         $length = strlen($text);
    4.         $newtext = '';
    5.          for($i = 0; $i < $length; $i++){
    6.                  $index = ord($text[$i]);
    7.                  // Rotate upper case.
    8.                  if($index > 64 && $index < 91){
    9.                          $index += 13;
    10.                          if($index > 90) $index -= 26;
    11.                          $newtext .= chr($index);
    12.                 // Rotate lower case.
    13.                 }elseif($index > 96 && $index < 123){
    14.                         $index += 13;
    15.                         if($index > 122) $index -= 26;
    16.                         $newtext .= chr($index);
    17.                  }else{ $newtext .= $text[$i]; }
    18.          }
    19.          return $newtext;
    20. }

    Display clean php code for copying

    // Rot 13 function for older php versions
    function rot13($text){
    	$length = strlen($text);
    	$newtext = '';
    	 for($i = 0; $i < $length; $i++){
    		 $index = ord($text[$i]);
    		 // Rotate upper case.
    		 if($index > 64 && $index < 91){
    			 $index += 13;
    			 if($index > 90) $index -= 26;
    			 $newtext .= chr($index);
    		// Rotate lower case.
    		}elseif($index > 96 && $index < 123){
    			$index += 13;
    			if($index > 122) $index -= 26;
    			$newtext .= chr($index);
    		 }else{ $newtext .= $text[$i]; }
    	 }
    	 return $newtext;
    }

    Make a random string

    Wednesday, March 17th, 2010

    This is a tiny function that makes a random string of predefined length.
    It does not use letters and numbers that could be confusing, like O and 0.

    1. // Make a random string
    2. function makeRandomString($length){
    3.         $str = array('a', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z', '2', '4', '5', '6', '7', '8', '9');
    4.         $nkeys = array_rand($str, $length);
    5.         $nstr = '';
    6.         foreach($nkeys as $key){ $nstr .= $str[$key]; }
    7.         return $nstr;
    8. }

    Display clean php code for copying

    // Make a random string
    function makeRandomString($length){
    	$str = array('a', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z', '2', '4', '5', '6', '7', '8', '9');
    	$nkeys = array_rand($str, $length);
    	$nstr = '';
    	foreach($nkeys as $key){ $nstr .= $str[$key]; }
    	return $nstr;
    }

    Make image version

    Wednesday, March 17th, 2010

    This is a function I use to make multiple versions such as thumbnails of uploaded images.
    There’s three methods for resizing available in it (mask, fit & limit).

    1. // Function for making a new resized copy of a file
    2. // mask makes the shortest edge match the mask, so it will be bigger than the mask, always resizes!
    3. // fit makes the longest edge match, always resizes!
    4. // limit makes the image fit, but won't stretch if it's smaller.
    5. function makeImageVersion($newWidth, $newHeight, $filePath, $newName, $fileExtension, $method){
    6.  
    7.         // Find out the original size of the image
    8.         list($wO, $hO) = getimagesize($filePath);
    9.  
    10.         // Get the ratios it would take to resize
    11.         $wR = $newWidth / $wO;
    12.         $hR = $newHeight / $hO;
    13.  
    14.         // Figure out which ratio we need
    15.         switch($method){
    16.                 case 'mask':
    17.                         if($wR > $hR){ $ratio = $wR; }
    18.                         else{ $ratio = $hR; }
    19.                         break;
    20.                 case 'limit':
    21.                         if($wR < 1 && $wR < $hR){ $ratio = $wR; }
    22.                         elseif($hR < 1){ $ratio = $hR; }
    23.                         else{ $ratio = 1; }
    24.                         break;
    25.                 case 'fit':
    26.                 default:
    27.                         if($wR > $hR){ $ratio = $hR; }
    28.                         else{ $ratio = $wR; }
    29.                         break;
    30.         }
    31.  
    32.         $wN = round($wO * $ratio);
    33.         $hN = round($hO * $ratio);
    34.  
    35.         $iP = imagecreatetruecolor($wN, $hN);
    36.         imageAlphaBlending($iP, false);
    37.         imageSaveAlpha($iP, true);
    38.  
    39.         if($fileExtension == 'jpg'){ $iI = imagecreatefromjpeg($filePath); }
    40.         elseif($fileExtension == 'png'){        $iI = imagecreatefrompng($filePath); }
    41.         else{ $iI = imagecreatefromgif($filePath); }
    42.  
    43.         imagecopyresampled($iP, $iI, 0, 0, 0, 0, $wN, $hN, $wO, $hO);
    44.  
    45.         if($fileExtension == 'jpg'){ imagejpeg($iP, $newName, 90); }
    46.         elseif($fileExtension == 'png'){ imagepng($iP, $newName); }
    47.         else{ imagegif($iP, $newName); }
    48. }

    Display clean php code for copying

    // Function for making a new resized copy of a file
    // mask makes the shortest edge match the mask, so it will be bigger than the mask, always resizes!
    // fit makes the longest edge match, always resizes!
    // limit makes the image fit, but won't stretch if it's smaller.
    function makeImageVersion($newWidth, $newHeight, $filePath, $newName, $fileExtension, $method){
    
    	// Find out the original size of the image
    	list($wO, $hO) = getimagesize($filePath);
    
    	// Get the ratios it would take to resize
    	$wR = $newWidth / $wO;
    	$hR = $newHeight / $hO;
    
    	// Figure out which ratio we need
    	switch($method){
    		case 'mask':
    			if($wR > $hR){ $ratio = $wR; }
    			else{ $ratio = $hR; }
    			break;
    		case 'limit':
    			if($wR < 1 && $wR < $hR){ $ratio = $wR; }
    			elseif($hR < 1){ $ratio = $hR; }
    			else{ $ratio = 1; }
    			break;
    		case 'fit':
    		default:
    			if($wR > $hR){ $ratio = $hR; }
    			else{ $ratio = $wR; }
    			break;
    	}
    
    	$wN = round($wO * $ratio);
    	$hN = round($hO * $ratio);
    
    	$iP = imagecreatetruecolor($wN, $hN);
    	imageAlphaBlending($iP, false);
    	imageSaveAlpha($iP, true);
    
    	if($fileExtension == 'jpg'){ $iI = imagecreatefromjpeg($filePath); }
    	elseif($fileExtension == 'png'){	$iI = imagecreatefrompng($filePath); }
    	else{ $iI = imagecreatefromgif($filePath); }
    
    	imagecopyresampled($iP, $iI, 0, 0, 0, 0, $wN, $hN, $wO, $hO);
    
    	if($fileExtension == 'jpg'){ imagejpeg($iP, $newName, 90); }
    	elseif($fileExtension == 'png'){ imagepng($iP, $newName); }
    	else{ imagegif($iP, $newName); }
    }

    File put contents

    Wednesday, March 17th, 2010

    file_put_contents() is in php nowadays, but if you’re on an old server you may need your own.
    This simply checks if the function’s there, and if not it makes the function.

    1. // Replacement for file_put_contents if it doesn't exist
    2. if(!function_exists('file_put_contents')){
    3.         function file_put_contents($file, $data){
    4.                 $fp = fopen($file, 'w');
    5.                 fwrite($fp, $data);
    6.                 fclose($fp);
    7.         }
    8. }

    Display clean php code for copying

    // Replacement for file_put_contents if it doesn't exist
    if(!function_exists('file_put_contents')){
    	function file_put_contents($file, $data){
    		$fp = fopen($file, 'w');
    		fwrite($fp, $data);
    		fclose($fp);
    	}
    }

    Check url

    Wednesday, March 17th, 2010

    This is a function that checks to see if a url exists.
    Not mine btw, but for the life of me I can’t remember where I got it.

    1. // Check if a url exists
    2. function isValidUrl($url){
    3.                 $url = @parse_url($url);
    4.  
    5.                 if ( ! $url) {
    6.                         return false;
    7.                 }
    8.  
    9.                 $url = array_map('trim', $url);
    10.                 $url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
    11.                 $path = (isset($url['path'])) ? $url['path'] : '';
    12.  
    13.                 if ($path == '')
    14.                 {
    15.                         $path = '/';
    16.                 }
    17.  
    18.                 $path .= ( isset ( $url['query'] ) ) ? "?$url[query]" : '';
    19.  
    20.                 if ( isset ( $url['host'] ) AND $url['host'] != gethostbyname ( $url['host'] ) )
    21.                 {
    22.                         if ( PHP_VERSION >= 5 )
    23.                         {
    24.                                 $headers = get_headers("$url[scheme]://$url[host]:$url[port]$path");
    25.                         }
    26.                         else
    27.                         {
    28.                                 $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
    29.  
    30.                                 if ( ! $fp )
    31.                                 {
    32.                                         return false;
    33.                                 }
    34.                                 fputs($fp, "HEAD $path HTTP/1.1\r\nHost: $url[host]\r\n\r\n");
    35.                                 $headers = fread ( $fp, 128 );
    36.                                 fclose ( $fp );
    37.                         }
    38.                         $headers = ( is_array ( $headers ) ) ? implode ( "\n", $headers ) : $headers;
    39.                         return ( bool ) preg_match ( '#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers );
    40.                 }
    41.                 return false;
    42. }

    Display clean php code for copying

    // Check if a url exists
    function isValidUrl($url){
    		$url = @parse_url($url);
    
    		if ( ! $url) {
    			return false;
    		}
    
    		$url = array_map('trim', $url);
    		$url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
    		$path = (isset($url['path'])) ? $url['path'] : '';
    
    		if ($path == '')
    		{
    			$path = '/';
    		}
    
    		$path .= ( isset ( $url['query'] ) ) ? "?$url[query]" : '';
    
    		if ( isset ( $url['host'] ) AND $url['host'] != gethostbyname ( $url['host'] ) )
    		{
    			if ( PHP_VERSION >= 5 )
    			{
    				$headers = get_headers("$url[scheme]://$url[host]:$url[port]$path");
    			}
    			else
    			{
    				$fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
    
    				if ( ! $fp )
    				{
    					return false;
    				}
    				fputs($fp, "HEAD $path HTTP/1.1\r\nHost: $url[host]\r\n\r\n");
    				$headers = fread ( $fp, 128 );
    				fclose ( $fp );
    			}
    			$headers = ( is_array ( $headers ) ) ? implode ( "\n", $headers ) : $headers;
    			return ( bool ) preg_match ( '#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers );
    		}
    		return false;
    }

    Normal smooth method

    Wednesday, March 17th, 2010

    On this post I’ll try to explain how the method for the Normal Smooth script works.


    Concept

    The idea is to reposition verticles so your mesh ends up nice and smooth. Of course there is already a function in Blender that does it, but that doesn’t take the actual “surface” of the mesh into account. So say you have a part of a perfect sphere selected, and you run the current internal function, it would flatten that selection, or even make it concave (hollow). That’s what we don’t want. In stead if you try to smooth a perfect sphere, it should not change anything. You can’t get smoother than a sphere!

    See below here… that’s not nicely smoothed!


    Smoothing the normal way

    I’ll explain the concept in 2D. Lets say we want to smooth the position of vertex A and it’s connected to vertex B and C. Then we get the vertex normals for B and C. We then rotate those normal vectors 90 degrees towards A and make them half the length of the distance between that specific vert (B or C) and A. Once we have those, we find the points at the ends of those two vectors and place vert A at the midpoint between them.

    But let me explain with a picture, which should help.


    That’s just the basics

    Of course there is a lot more that you can do with a script. Like looking further along the surface and using more normals. Also in 3d at times you have quads and you need to figure out what you want to do with the vert at the far end of the quad. Having non manifold meshes can be tricky too.

    At least I hope this explains the idea a bit, and as ideas go…. it’s not too bad

    Dolf