• neuville

    (@neuville)


    Hello,
    I’m trying to get a permalink structure like this:

    blog address/%category%/%tag%/%postname%.html

    the result is a broken page, since wordpress renders %tag% in the url (like https://www.example.com/category/%tag%/some-post.html)

    also, it works fine if I get rid of the %tag% part of the url (www.example.com/category/some-post.html is working perfectly)

    each post in the blog has just one tag, and could be useful to render it in the permalink to have a more organized structure for a new project I’m working on.

    anyone can help?

    thanks in advance,
    ciao!

Viewing 7 replies - 1 through 7 (of 7 total)
  • gsivorot

    (@gsivorot)

    I’m having the exact same problem. Time to dig through the code I think.

    Update:
    Apparently the permalink works if you go to the url directly. In your example if you go to https://www.example.com/category/your-tag-slug/some-post.html directly your post will show up. It seems it’s just a problem with generating the actual links. I’ll have to dig a little deeper.

    gsivorot

    (@gsivorot)

    Ok, I found the problem. It’s in the get_permalink() function in wp-includes/link-template.php. The tag isn’t even considered in constructing the permalink. I fixed it in the code below if you want to replace that function in the file. If you want I can probably post the entire file somewhere (or maybe I should just submit a patch). Anyway, here’s the code…

    function get_permalink($id = 0, $leavename = false) {
    	$rewritecode = array(
    		'%year%',
    		'%monthnum%',
    		'%day%',
    		'%hour%',
    		'%minute%',
    		'%second%',
    		$leavename? '' : '%postname%',
    		'%post_id%',
    		'%category%',
    		'%author%',
    		$leavename? '' : '%pagename%',
    		'%tag%',
    	);
    
    	if ( is_object($id) && isset($id->filter) && 'sample' == $id->filter )
    		$post = $id;
    	else
    		$post = &get_post($id);
    
    	if ( empty($post->ID) ) return false;
    
    	if ( $post->post_type == 'page' )
    		return get_page_link($post->ID, $leavename);
    	elseif ($post->post_type == 'attachment')
    		return get_attachment_link($post->ID);
    
    	$permalink = get_option('permalink_structure');
    
    	if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending')) ) {
    		$unixtime = strtotime($post->post_date);
    
    		$category = '';
    		if ( strpos($permalink, '%category%') !== false ) {
    			$cats = get_the_category($post->ID);
    			if ( $cats ) {
    				usort($cats, '_usort_terms_by_ID'); // order by ID
    				$category = $cats[0]->slug;
    				if ( $parent = $cats[0]->parent )
    					$category = get_category_parents($parent, false, '/', true) . $category;
    			}
    			// show default category in permalinks, without
    			// having to assign it explicitly
    			if ( empty($category) ) {
    				$default_category = get_category( get_option( 'default_category' ) );
    				$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
    			}
    		}
    		$tag = '';
    		if ( strpos($permalink, '%tag%') !== false ) {
    			$tags = get_the_tags($post->ID);
    			if ( $tags ) {
    				usort($tags, '_usort_terms_by_ID'); // order by ID
    				$tag = $tags[0]->slug;
    			}
    		}
    
    		$author = '';
    		if ( strpos($permalink, '%author%') !== false ) {
    			$authordata = get_userdata($post->post_author);
    			$author = $authordata->user_nicename;
    		}
    
    		$date = explode(" ",date('Y m d H i s', $unixtime));
    		$rewritereplace =
    		array(
    			$date[0],
    			$date[1],
    			$date[2],
    			$date[3],
    			$date[4],
    			$date[5],
    			$post->post_name,
    			$post->ID,
    			$category,
    			$author,
    			$post->post_name,
    			$tag,
    		);
    		$permalink = get_option('home') . str_replace($rewritecode, $rewritereplace, $permalink);
    		$permalink = user_trailingslashit($permalink, 'single');
    		return apply_filters('post_link', $permalink, $post, $leavename);
    	} else { // if they're not using the fancy permalink option
    		$permalink = get_option('home') . '/?p=' . $post->ID;
    		return apply_filters('post_link', $permalink, $post, $leavename);
    	}
    }

    NOTE: I have not tested whether the permalinks still work if there is no tag for a post. Let me know if you test that out.

    Thread Starter neuville

    (@neuville)

    Hello gsivorot,
    I changed the code and did the job.

    still not working. maybe some plugins are affecting this (I’m using decategorizer and redirection)

    MichaelH

    (@michaelh)

    From Using Permalinks article in Codex:

    For performance reasons, it is not a good idea to start your permalink structure with the category, tag, author, or postname fields. The reason is that these are text fields, and using them at the beginning of your permalink structure it takes more time for WordPress to distinguish your Post URLs from Page URLs (which always use the text “page slug” as the URL), and to compensate, WordPress stores a lot of extra information in its database (so much that sites with lots of Pages have experienced difficulties). So, it is best to start your permalink structure with a numeric field, such as the year or post ID. See wp-testers discussion of this topic.

    gsivorot

    (@gsivorot)

    @neuville

    I’m using redirection so that isn’t the problem. Decategorizer could definitely be the problem and (as MichaelH says) I probably wouldn’t use it anyway due to performance issues (unless you are running a very small site). Also, are you using the newest version of wordpress?

    Thread Starter neuville

    (@neuville)

    Yes, I’m using the 2.7.1

    about decategorizer: is there another way to get rid of the /category/ path instead of the plugin?

    thanks a lot for the help

    gsivorot

    (@gsivorot)

    There are ways to do it (like decategorizer). The real question is should you do it? It will work perfectly fine for a small site but once you have a lot of posts it will slow things down a lot.

    I haven’t looked through the code that much but I’m assuming from the warnings posted about it in the Docs that WordPress wouldn’t be able to tell if the page contains a post, page or category so it has to search ALL the posts AND ALL the category records in the database. To sum it up, the more posts/categories you have the slower your site would get.

    If I were you I’d just rename the “category” part in your path to something related to your site which would be great for Search Engine Optimization anyway. So if your site was about video games your link would look like https://www.mysite.com/video-games/new-releases-category

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Using %tag% in permalinks’ is closed to new replies.