how to dynamically set query parameter on menu item Hello I am a very experienced web dev who is brand new to Drupal and learning to build my first site in it.

I have a very simple site I am converting from pure code (html, css, jquery, angular, bootstrap, php) to drupal so that I can add a CMS backend to the site. On this site I need to track what ad campaign sent the user to the site to be stored with the users information later after they submit their email to be contacted again.

This is how it works currently on the non-drupal site: User clicks on a link on an 3rd party site that directs them to my-site.com/get-eBook.html?campaign=google. On get-eBook.html there is a menu item for /ebook-register.php, I use some PHP to grab the value of campaign from the URL and if it is not null I update the menu item to /ebook-register.php?campaign=google in order to pass the value along to the register page where it is used in a SQL statement and captured in the DB with the users email address.

Now I'm not sure how to accomplish the same thing in Drupal. I have my theme set up, I have two pages created (get-ebook and ebook-register) and I have my menu set up with the link to ebook-register. I however have no idea how I can grab the value of campaign on the get-ebook page and add that value onto the desired menu item being returned by the drupal core so that the value of campaign will be preserved when the user navigated from get-ebook to ebook-register.

Any ideas on how I can allow the menu to be maintained via the Drupal backend but still have the ability to dynamically add query parameters to the items after they're returned from the core?
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.