0

I am working on a Wordpress site which is displaying results from an Events API on a given page.

the page is at /whats-on.

I want to provide links on the page which are formatted like mysite.com/whats-on/name-of-the-event which will link to another page displaying event detail. If I just add the links, Wordpress will try and find a post with the name 'name-of-the-event' and display a 404.

Is there a way to bypass this behaviour? How would I add rewrites from within a plugin?

UPDATED CODE:

class SpektrixPlugin {

    public function activate() {
        global $wp_rewrite;
        flush_rewrite_rules();
        add_action('init',array($this, 'properties_add_rewrite_rules'));
        add_filter('query_vars', array($this, 'properties_add_query_vars'));
    }

    public function properties_add_query_vars( $vars) {
        $vars[] = "event"; // name of the var as seen in the URL
        return $vars;
    }

    public function properties_add_rewrite_rules() {
        //Change your_page_id with the ID of the whats-on page
        add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?p=8&event='.$matches[1] , 'top' );
    }

    public function spektrix_list_events() {
        $api = new SpektrixApiClient();
        return $api->getAllEvents();
    }
}

$SpektrixEvents= new SpektrixPlugin();

register_activation_hook( __file__, array($SpektrixEvents, 'activate') );

1 Answer 1

3

You need to add rewrite rules and the query_vars to fit your needs.

For example. In your functions.php or plugin file:

// Register a new vars to be used in the rewrite rules
add_filter('query_vars', 'properties_add_query_vars');
function properties_add_query_vars( $vars) {
    $vars[] = "my_action"; // name of the var as seen in the URL
    return $vars;
}

// Add the new rewrite rule to existings ones
add_action('init','properties_add_rewrite_rules');
function properties_add_rewrite_rules() {
    //Change your_page_id with the ID of the whats-on page
    add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?page_id=your_page_id&my_action='.$matches[1] , 'top' );
}

And then in the template for whats-on page (create a page-whats-on.php template file, see this):

global $wp_query;
if(isset($wp_query->query_vars('my_action')) && $wp_query->query_vars('my_action') == 'some_action'){
    //Do what you want
}

Don't foget to flush the rewrite rules before you try to test your new rewrite rules. You can do this by going to settings->permalinks and click on Save button.

EDIT

In your updated question you have some issues in your code.

  1. There was a error in my code, where the query var for the page is page_id and I wrote just p. Sorry for that.
  2. The rewrite rules and custom query vars should be added on init action hook, only the flush_rewrite_rules(); should run only on activation hook due performance reasons (I asked a related question myself).

I've tested this code and it is working:

class SpektrixPlugin {

    public function __construct(){
        add_filter('query_vars', array($this, 'add_query_vars'));
        add_action('init', array($this, 'add_rewrite_rules'));
    }

    public function activate() {
        flush_rewrite_rules();
    }

    public function deactivate() {
        flush_rewrite_rules();
    }

    public function add_query_vars($vars) {
        $vars[] = "event"; // name of the var as seen in the URL
        return $vars;
    }

    public function add_rewrite_rules() {
        //Change your_page_id with the ID of the whats-on page
        add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?page_id=8&event=$matches[1]' , 'top' );
    }

    public function spektrix_list_events() {
       //$api = new SpektrixApiClient();
       //return $api->getAllEvents();
       return 'Test';
    }
}

$SpektrixEvents = new SpektrixPlugin();

register_activation_hook( __file__, array($SpektrixEvents, 'activate') );
register_deactivation_hook( __file__, array($SpektrixEvents, 'deactivate') );

Now you need to check when the query var event is present. In your case, I think that, as I said before, the best way to make this check is in the page tempalte. You can create a specific template for you page with ID 8. Just create a page-8.php file and put it in you theme folder (you can also put it in a plugin folder but this require extra work). In page-8.php You can make something like this:

<?php
  get_header();

  global $wp_query;
  if($wp_query->get('event') == 'event'){
       echo $SpektrixEvents->spektrix_list_events();
  }

  get_footer();
 ?>

Now If you go to yoursite.com/whats-on/event/ your get "Test" printed.

8
  • Thanks. Is the above intended to go in a theme's functions.php? How would I do this in a plugin? I'm also not sure why I would need wp_query? I am not querying the DB.
    – codecowboy
    Sep 4, 2013 at 19:33
  • The first piece of code goes in functions.php or in a plugin file. The second piece of code must go preferably in a specific page template file for your page /whats-on. I've used $wp_query to check if the the custom query var is set and get its value, not to query the database. After the checking you can query directly to database or whatever you want to do. Please, note that these recomendations is because you have asked to rewrite to the specific page /whats-on.
    – cybmeta
    Sep 4, 2013 at 19:42
  • I've updated the question with some code. I still get a 404 when going to mysite.com/whats-on/name-of-the-event. Can you spot anything I've done wrong? Been up for many hours :-/. I have flushed the rewrite rules
    – codecowboy
    Sep 4, 2013 at 20:51
  • See, my updated answer.
    – cybmeta
    Sep 4, 2013 at 23:01
  • Thanks again. I've got a little further. However, those rewrite flushes don't seem to be working and I have to manually hit save in the permalinks settings.
    – codecowboy
    Sep 5, 2013 at 6:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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