I am writing a plugin that needs to trigger an action based on URL's. The url scheme is the following:


where 12345 is a unique code used by the function triggered. My question is how can I trigger a function in the plugin based on such a link?

EDIT Thanks to the answers below I wrote the 3 following functions but I don't have what I want yet. add_

function add_endpoint(){
     add_rewrite_endpoint( 'action', EP_ROOT );
add_action('init',  'add_endpoint', 0);

function add_query_vars($vars){
     $vars[] = 'action';
     return $vars;
add_filter('query_vars', add_query_vars, 0);

function sniff_requests(){
    global $wp;
    error_log("request sniffed:".$wp->query_vars['action']);
add_filter('parse_request', sniff_requests, 0);

And the log says that all functions are triggered but it fails to display $wp->query_vars['action']. My guess is that the rewrite rule is not recognized by the system:

[26-Aug-2013 22:22:35 UTC] add_endpoint
[26-Aug-2013 22:22:35 UTC] query
[26-Aug-2013 22:22:35 UTC] request sniffed:
  • 2
    I think, you need an endpoint. – fuxia Aug 26 '13 at 12:43
  • I edited my question with the code to create the endpoint. However WP doesn't seem to handle it. Could you have a look and tell me what I am missing? Thanks – znat Aug 26 '13 at 23:09
  • did you flush rewrite rules? – Milo Aug 26 '13 at 23:12
  • At activation and de-activation. But shouldn't they get flushed after the endpoint is added (init)? – znat Aug 26 '13 at 23:14
  • they should not be flushed on init, that will flush them on every request, but you have to be sure to add the endpoint first on activation if that's where you're flushing them. a simple way to flush for testing is to visit the permalinks settings page in admin. aside from your unquoted function names in your add_filter calls, which I assume are typos, your code works for me. adding action to query vars is redundant though, that can be removed. add_rewrite_endpoint already adds it to query vars. – Milo Aug 27 '13 at 0:35

As @toscho says you need an endpoint.

Note code is untested.

* Flush rewrite rules
function install_my_plugin() {
register_activation_hook( __FILE__, 'install_my_plugin' );

* Flush rewrite rules
function unistall_my_plugin() {
register_deactivation_hook( __FILE__, 'unistall_my_plugin' );

* Add the endpoint
function my_plugin_endpoint() {
    add_rewrite_endpoint( 'action', EP_ROOT );
add_action( 'init', 'my_plugin_endpoint' );

function my_plugin_proxy_function( $query ) {    
  if ( $query->is_main_query() ) {
    // this is for security!
    $allowed_actions = array('123', '124', '125');
    $action = $query->get('action');
    if ( in_array($action, $allowed_actions) ) {
      switch ( $action ) {
        case '123' :
          return call_user_func('function_123');
        case '124' :
          return call_user_func('function_124');
        case '125' :
          return call_user_func('function_125');
add_action( 'pre_get_posts', 'my_plugin_proxy_function' );
  • probably don't want to hook pre_get_posts, it'll get triggered for every query on the page. – Milo Aug 26 '13 at 15:57
  • I edited my question with what I did based on your answer but the enpoint seems not recognized by wp. Could you please have a look? – znat Aug 26 '13 at 23:08
  • 2
    @Milo, do you think that a in_array check for every page can slow down the page loading? If so, what hook do you suggest? I usually use pre_get_posts in similar cases, because is the first available where condional tags work, but if there is one better I'm ready to change :) – gmazzap Aug 27 '13 at 0:32
  • 2
    @G.M. I missed the part where you're checking the query object passed to the pre_get_posts function, so that shouldn't trigger on multiple queries. you could maybe wrap that in if( $query->is_main_query() ) to only execute it for the main query. – Milo Aug 27 '13 at 0:41
  • 1
    @NathanZ on init it ensures that the query var used by the endpoint is added to the wp query vars. On activaction is needed because before flashing rules I need the endpopint is added. – gmazzap Aug 27 '13 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.