views:

535

answers:

2

I have created a wordpress plugin that has a filter on the_content, looking for a specific tag then outputting the plugin content in place of that tag.

I would now like to use rewrite rules to call the plugin and output the data within the template, but I'm not finding much help.

Can someone provide an example, or some guidance on how to add a rewrite rule using the built in wp methods and calling my methods in the plugin which outputs some content.

Ideally I would like shop/ to be matched and then pass everything after shop to my dispatch method on my plugin so that i can have shop/category/shirts or shop/product/the-cool-shirt. My dispatch method would handle breaking apart the rest of the url and calling methods accordingly.

Thanks in advance.

A: 

This can get rather interesting. I had to do this for a plugin at one point, I don't have it in front of me, so this it out of memory, but the general idea should be correct.

<?php

add_action('init', 'rewrite_rules');     


function rewrite_rules() {
    global $wp, $wp_rewrite;
    $wp_rewrite->add_rule('(widget1|widget2|widget3)/([a-zA-Z0-9_-]{3,50})$', 'index.php?pagename=listing&category=$matches[1]&subcategory=$matches[2]', 'top' );
    $wp->add_query_var( 'category' );
    $wp->add_query_var( 'subcategory' );
    $wp_rewrite->flush_rules();
}

?>

Using regular expressions is a monumental task in itself, I believe I used this site: http://tools.netshiftmedia.com/regexlibrary/ for help.

I also used FakePage plugin to actually display my custom "dynamic" pages, as I called them, but I suppose everything in WP is technically dynamic.

http://scott.sherrillmix.com/blog/blogger/creating-a-better-fake-post-with-a-wordpress-plugin/

Let me know if you need more help.

Andy
A: 

I did something very similar not long ago, and I did it by cheating.

If you find the built in rewrite rules too complicated or unable to do the job, you may find it easier to catch the request and filter the results. A simplified version:

add_action('parse_request', 'my_parse_request');

function my_parse_request (&$wp) {
  $path = $wp->request;

  $groups = array();
  if (preg_match("%shop/product/([a-zA-Z0-9-]+)%", $path, $groups)) {
    $code = $groups[1];
    $product = get_product($code); // your own code here
    if (isset($product)) {
      add_filter('the_posts', 'my_product_filter_posts');
    }
  }
}

function my_product_filter_posts ($posts) {
  ob_start();
  echo "stuff goes here";  //  your body here
  $content = ob_get_contents();
  ob_end_clean();

  return array(new DummyResult(0, "Product name", $content));
}

To explain:

  1. The action on parse_request is called before the database lookup. Based on the URL, it installs the other actions and filters.

  2. The filter on posts replaces the results of the database lookup with fake results.

DummyResult is a simple class that has the same fields as a post, or just enough of them to get away with it:

class DummyResult {
  public $ID;
  public $post_title;
  public $post_content;

  public $post_author;
  public $comment_status = "closed";
  public $post_status = "publish";
  public $ping_status = "closed";
  public $post_type = "page";
  public $post_date = "";

  function __construct ($ID, $title, $content) {
    $this->ID = $ID;
    $this->post_title = $title;
    $this->post_content = $content;

    $this->post_author = get_default_author(); // implement this function
  }
}

There's a lot of homework left for the reader in the above, but it's an ugly, working approach. You'll probably want to add a filter for template_redirect, to replace the normal page template with a product-specific one. And you may need to adjust the URL regex if you want pretty permalinks.

Marcus Downing