Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

How to include a custom (query) string in a permalink? WordPress


Hello, I am a bit confused about how WordPress's permalink works, especially beyond Wordpress's own usage. My permalinks are like:


But in `single.php` I want to put another link to page itself but with different query string. When it is clicked the permalink structure may look like:


I want to get the value from `$_GET['action']`, so:

$_GET['action'] = %mystring%

my plan is to interpret it like:

if('xx' == $_GET['action']){
//do xx stuff
} else if ('yy'==$_GET['action']){
//do yy stuff

//show the single post as a single.php always shows

that means, I want to parse the `$_GET['action']` optionally. If I do not parse it even if it is available in query string, I want the page to be rendered correctly.

So to get this done, where should I actually work? Also how do I form the link for `<a>` tag? Usually we make link this way:

<a href="'.the_permalink().'">TEXT</a>

but you already know, I need to add some text before the original permalink of post.

Thanks in advance.

Answers (4)


Darrin Boutote answers:

$newlink = get_permalink( $post->ID );
$newlink = remove_query_arg('action', $newlink);
$newlink = add_query_arg ('action', 'XX-or-YY', $newlink) ;

<a href="<?php echo $newlink; ?>">TEXT</a>

Monster Coder comments:

Your structure seems working fine with default permalink structure
i am getting action=xx appended but my permalink structure is this:
so I am getting:
i want to get it like:

and I want to get the 'play' in action variable!

is that possible without changing anything at backend? i wish :
1. not to change permalink stucture to anything than current one:
2. to get pretty link for my custom strings too



Darrin Boutote comments:

If you want the page to behave differently based on the "action" variable, (i.e. 'action=xx' or 'action=yy') then I don't know any other way to append it to the url and still have the page template "get" the action.

For my own personal enlightenment, I'd love to see how to extract a query arg from a url without the use of '?action=xx'.

Monster Coder comments:

when URL is
wordpress identifies 50 (post_id) and spring2 (postname) as per permalink_structure! this is equivalent to:
I am not sure about the second portion (&title=spring2). but for an example, it is ok.

but what about .html? it is simply ignored by wordpress as it is in our permalink structure as static content. so isn't it possible that we put this static content dynamically? lolz, sounds funny :P. i mean we force wordpress to get ID and postname from the following url:
50-spring2-play.html and ignore the 'play'. this play will be available in $_GET['action'] much like wordpress gets ID in $_GET['p'];

I don't want to alter contents based on action. I will simply add some extra contents based on action!


wjm answers:

What you need is create some new Rewrite Rules
I have done it.

This code considers that your permalink structure is /%post_id%-%postname%/
and your new parameter is called "mystring"
you can replace mystring everywhere in the code, for whatever you need.

Add this to your functions.php file

require_once( TEMPLATEPATH . '/rewrite_rules.php');
function prefix_permalink( $permalink, $post, $leavename ) {
global $permalink_prefix;
$url = get_bloginfo( 'wpurl' );
return str_replace( $url.'/', $url.'/'.$permalink_prefix.'-', $permalink);

Add this at the end of your single.php template.
or wherever you want to display the link and use the mystring value.

* working with the following permalinnk structure: /%post_id%-%postname%/
* the new url parameter has the name "mystring"

//set the prefix
global $permalink_prefix;
$permalink_prefix = 'foofoo';

//retrieve "mystring" value
$mystring = get_query_var( 'mystring' );
echo '<p>Mystring: <strong>'.$mystring.'</strong></p>';

//add filter
add_filter( 'post_link', 'prefix_permalink', 10, 3);

//print link (this post)
echo '<p><a href="'.get_permalink( ). '">This Post</a></p>';

//print link (another post)

echo '<p><a href="'.get_permalink( 35 ). '">Other Post</a></p>';

//remove filter to avoid rewritting further links
remove_filter( 'post_link', 'prefix_permalink', 10, 3);

and download this file. and save it as rewrite_rules.php in your theme's folder (same as where functions.php is)

that rewrite rules works for paged posts, comment pages, feeds. you can add the "mystring" value to all those pages and the page will still load.

If you want to know how how change text in your links, please raise your prize as it is a lot of work so far.

let me know if it work (as it does on my end).
- wjm

wjm comments:

the above when visiting this page:
outputs this html:

this code

<p>Mystring: <strong>foofoo</strong></p>
<p><a href="http://localhost/foofoo-1-hello-world/">This Post</a></p>
<p><a href="http://localhost/foofoo-35-just-another-post/">Other Post</a></p>


Oleg Butuzov answers:

live sample (for suctom post_type)

add_filter('post_type_link', 'mylink', 2, 3);
function mylink($permalink, $post, $leavename){

global $wp_post_types,$wp_taxonomies, $wp_query;
$postType = get_post_type($post);
if (isset($wp_post_types[$postType]) && $wp_post_types[$postType]->_builtin == false && strpos($permalink, '%') !== false){

if (preg_match_all('/%([a-z]{1,})%/si', $permalink, $matches)){

foreach($matches[1] as $match){

if ($match == 'year'){
$permalink = str_replace("%$match%", date("Y", strtotime($post->post_date)), $permalink);

if (isset($wp_taxonomies[$match]) && in_array($postType, $wp_taxonomies[$match]->object_type) && intval($post->ID) > 0){
$id = intval($post->ID) > 0 ? intval($post->ID) : 0 ;

if (($data = get_the_post_type_taxonomy('alboum', $id))) {
$taxonomy = array_shift($data);
$slug = is_object($taxonomy) ? $taxonomy->slug : $taxonomy['slug'];
$permalink = str_replace("%$match%", $slug, $permalink);

return $permalink;

Oleg Butuzov comments:

In my example iam looking for connected taxonomies to my post type, and replacase it i link...

this is a part of come one of my plugins, so you can get a some kind of the list of links filters...

$linksArray = array(
foreach ($linksArray as $action){
add_action($action, array('WPML', 'links_append'));

Oleg Butuzov comments:

sample that fit your needs

$linksArray = array('get_the_guid','day_link','month_link','year_link','term_link','tag_link','author_link','feed_link','category_link','post_link','page_link');
foreach ($linksArray as $action){
add_action($action, 'links_append');

function links_append($link){
return @str_replace('%mystring%', @$_GET['action'], $link);

Monster Coder comments:

in my case, it is not custom post type!

Oleg Butuzov comments:

if your case i have provide sample.

Monster Coder comments:

sorry, i am not clear about the last solution! can you kindly help me understand that? also it is not working as I expected!


Lawrence Krubner answers:

Monster Coder,

I am Lawrence Krubner, I co-own this website (WP Questions) with Darren Hoyt. This is a very good question that you've asked. I, too, have sometimes wondered about how to customize WordPress's permalinks.

I notice that there are several experts who are devoting a fair amount of time to trying to get you the information that you need. You may wish to consider offering a little more than $8 for whatever final solution they come up with for you. You'll see on this page (when you are logged in) an "edit" link that you can use to increase the prize amount.

Also, please remember, when you pick winners, you can divide the prize money among those experts who gave you information that you found useful.

---- lawrence krubner

Monster Coder comments:

well, thanks for your suggestion! but wondering why you are saying such! I accept wim's suggestion as wim's already given some solution and said for further clarification prize money needs increased! that is fair! but being owner, I don't find any point for you to say such, at least outside PM!

here only one two solution is on the online! Until wim posted a solution, I was planning to use the solution by Darrin Boutote!

Moreover, in this site we are not paying anyone for solution, we are just giving little prize as thanks! isn't it? I have seen many other questions within $4-$6 where solution is given by more more programmers!

anyway, thanks!