how to dynamically set query parameter on menu item
The way I would do this would be overriding the menu link.

You can override a menu link by doing a theme override of theme_menu_link() however you don't want to modify the structure of the markup you want to modify the data being printed (in this case the link query string) so I would recommend overriding the variables of that function in hook_preprocess_HOOK() (in this case hook_preprocess_menu_link()).

Template variable overriding is often done in the theme, and you can do it in your theme's template.php file, however in your case I would recommend a custom module because this is functionality not visual display. If you put it in your theme's template.php and then change themes it will stop working, which is probably not what you want.

So it would be best in a custom module.

If you look back at the docs for theme_menu_link() you can see that the link is created using the l() function and looking at the parameters to the l() function you see that the $options parameter can contain "Additional $options elements used by the url() function", which you can see from the url() docs includes the query string, which is a non-encoded array of key/value pairs.

So from that you can tell that in your theme function preprocessor you need to modify/add your query string in $element['#localized_options']['query'] something like this:

$variables['element']['#localized_options']['query']['campaign'] = 'google';


You can also see that the URL of the link is in $element['#href']. Since you probably want to affect all links that point to that path I would suggest overriding the link options based on path.

Since you can access the current page's query parameters using basic PHP's superglobal $_GET you then have all the information you need to set your menu item.

You can do it like this:

/**
 * Variable preprocessor for the themeing of menu links.
 *
 * @see theme_menu_link().
 */
function MODULENAME_preprocess_menu_link(&amp;$variables) {
  // If we have an ebook campaign code then add it to the ebook register
  // menu link.
  if ($variables['element']['#href'] == 'ebook-register.php' &amp;&amp; !empty($_GET['campaign'])) {
    // Just add our query array element instead of setting query to a new
    // array to avoid possibly overwriting other query parameters.
    $variables['element']['#localized_options']['query']['campaign'] = $_GET['campaign'];
  }
}


One other thing worth nothing is that generally in Drupal you shouldn't have pages as custom PHP scripts like ebook-register.php.

Instead you should have a custom module that implements hook_menu() to make the path 'ebook-register' call a custom callback that then contains your page logic. See the drupal menu system docs for more information (D6 &amp; D7 have the same menu system) and also the examples module's menu &amp; page examples.