Choosing the correct filter to truncate slugs

Hey

I've found this awesome slug trimmer plugin which removes specific words from, and limits the number of characters in a slug.

The issue is that it only works when a posts slug is removed and the post is updated.

I need it to work automatically when the product/posts are imported, or at least from a button or bulk editing action. I believe i just need to switch the filter "name_save_pre" what would be a good filter for this?

Here is the code:

<?php
/*
Plugin Name: Slug Trimmer
Plugin URI: http://pietersz.co.uk
Description: Shorten post slugs
Version: 1.0
Author: Graeme Pietersz
Author URI: http://pietersz.co.uk
*/

/*
Copyright Graeme Pietersz 2006

Licensed under the terms of the GPL version 2, see:
http://www.gnu.org/licenses/gpl.txt

Provided without warranty, inluding any implied warrant of merchantability or fitness for purpose.
*/

add_filter('name_save_pre', 'slug_trim', 0);

$slug_trim_options = array('max' => 15, 'min' => 5, 'wordlen' => 4, 'truncate' => TRUE, truncate_max => 25); #default values

function slug_trim($slug) {
	if ($slug) return $slug;
	global $wpdb;
	global $slug_trim_options;
	global $slug_trim_wordlen;
	$options = get_option(slug_trim_options);
	if (! $options) $options = $slug_trim_options;
	$title = $_POST['post_title'];
	if (strlen($title) > $options['max']) {
		$title_a = explode(' ',$title);
		for ($i = 1; $i <= $options['wordlen']; $i++) {
			$title_old = $title_a;
			$slug_trim_wordlen = $i;
			$title_a = array_filter($title_a, 'slug_trim_words');
			$title = implode(' ',$title_a);
			if (strlen($title) < $options['min']) {
				$title = implode(' ',$title_old);
				break;
			}
			if (strlen($title) <= $options['max']) {
				break;
			}
		}
		if ((strlen($title) > $options['truncate_max']) && $options['truncate']) {
			$title_a = explode(' ',$title);
			$title = '';
			foreach ($title_a as $i) {
				$title_old = $title;
				$title = $title . ' ' . $i;
				if (strlen($title) > ($options['truncate_max'])) {
					if (strlen($title_old) >= $options['min']) $title = $title_old;
					break;
				}
			}
		}
		return sanitize_title($title);
	} else {
		return '';
	}
}
function slug_trim_words($word) {
	global $slug_trim_wordlen;
	return(!(strlen($word) <= $slug_trim_wordlen));
}

add_action('admin_menu', 'slug_trim_admin');

function slug_trim_admin() {
	 add_options_page('Slug Trimmer','Slug Trimmer', 8, __FILE__, 'slug_trim_conf');
}

function slug_trim_conf() {
	global $slug_trim_options;
	if ($_POST['slug_max']) {
		check_admin_referer('slug_trim_conf');
		$options['max'] = (int) $_POST['slug_max'];
		$options['min'] = (int) $_POST['slug_min'];
		$options['wordlen'] = (int) $_POST['slug_wordlen'];
		$options['truncate'] = (bool) $_POST['slug_truncate'];
		$options['truncate_max'] = (int) $_POST['truncate_max'];
		update_option(slug_trim_options, $options);
		$slug_trim_options = $options;
	} else {
		$options = get_option(slug_trim_options);
		if (! $options) $options = $slug_trim_options;
	}
	?><div class="wrap"><h2>Slug Trimmer Options</h2>
<form method="post" action="">
<?php
if ( function_exists('wp_nonce_field') )
wp_nonce_field('slug_trim_conf');
?>
<table class ="optiontable">
<tr><th>Maximum length of slug:</th><td><input type="text" name="slug_max" size="2" value="<?php print $options['max'];?>" /></td></tr>
<tr><th>Minimum length of slug:</th><td><input type="text" name="slug_min" size="2" value="<?php print $options['min'];?>" /></td></tr>
<tr><th>Remove words of up to this length (if necessary):</th><td><input type="text" name="slug_wordlen" size="2" value="<?php print $options['wordlen'];?>" /></td></tr>
<tr><th>Truncate if necessary:</th><td><select name="slug_truncate"><option value="1"<?php if ($options['truncate'] == TRUE) echo ' selected="selected"'?>>Yes</option><option value="0"<?php if ($options['truncate'] == FALSE) echo ' selected="selected"'?>>No</option></select></td></tr>
<tr><th>Truncate after this number of characters:</th><td><input type="text" name="truncate_max" size="2" value="<?php print $options['truncate_max'];?>" /></td></tr>
</table>
<p class="submit">
<input type="submit" value="<?php _e('Update Settings »') ?>">
</p>
</form></div>
	<?php
	$options = get_option(slug_trim_options);
}
?>
  • Vaughan

    Hi Robert,

    I'm surprised that works at all, it's from 2006 & name_save_pre is no longer present in WP.

    You could perhaps try the following in your theme functions.php

    add_filter( 'sanitize_title', 'slug_trim', 1 );
    function slug_trim($slug) {
    	if ($slug) return $slug;
    	global $wpdb;
    
        $options = array(
                'max' => 15,
                'min' => 5,
                'wordlen' => 4,
                'truncate' => TRUE,
                truncate_max => 25
            ); #default values
    
    	global $slug_trim_options;
    	global $slug_trim_wordlen;
    
    	$title = $_POST['post_title'];
    	if (strlen($title) > $options['max']) {
    		$title_a = explode(' ',$title);
    		for ($i = 1; $i <= $options['wordlen']; $i++) {
    			$title_old = $title_a;
    			$slug_trim_wordlen = $i;
    			$title_a = array_filter($title_a, 'slug_trim_words');
    			$title = implode(' ',$title_a);
    			if (strlen($title) < $options['min']) {
    				$title = implode(' ',$title_old);
    				break;
    			}
    			if (strlen($title) <= $options['max']) {
    				break;
    			}
    		}
    		if ((strlen($title) > $options['truncate_max']) && $options['truncate']) {
    			$title_a = explode(' ',$title);
    			$title = '';
    			foreach ($title_a as $i) {
    				$title_old = $title;
    				$title = $title . ' ' . $i;
    				if (strlen($title) > ($options['truncate_max'])) {
    					if (strlen($title_old) >= $options['min']) $title = $title_old;
    					break;
    				}
    			}
    		}
    		return sanitize_title($title);
    	} else {
    		return '';
    	}
    }
    function slug_trim_words($word) {
    	global $slug_trim_wordlen;
    	return(!(strlen($word) <= $slug_trim_wordlen));
    }

    Hopefully that should truncate the titles & permalinks to the values you set in the $options array at the top of the function. I haven't tested this though.

    Hope this helps

  • Robert

    Hey thanks for the reply. That code didn't do anything. It did work when I switched the filter back to "name_save_pre", but only in the way that the above code works, not when the product is imported, but when the slug is removed and then the product is saved.

    I guess name_save_pre hasn't be deprecated, it has been renamed..I guess that's why it still works? I don't know, it doesn't make sense.