Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

If so, how should the query URL be formatted? I've tried:

  • post_type=cat1&post_type=cat2
  • post_type=cat1,cat2
  • post_type=cat1+cat2

This bug report says you could use post_type[]=cat1&post_type[]=cat2 if not for the fact that "all request parameters are converted to strings". Is this still the case and what does it mean?

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

You could use add_feed() and create new feeds … for each post type combination a separate feed. That's not what I would call flexible, so I recommend to create an endpoint.

The following code creates an endpoint for the root of a WordPress installation. After refreshing the permalinks you get a regular feed at /multifeed/ (for pages only) or /multifeed/post+page+custom/ for almost any given combination.

I am not sure why, but it seems not to work for attachments.

<?php
/*
 * Plugin Name: T5 Multi Post Type Feed
 */

add_action(
    'init',
    array ( T5_Multi_Post_Type_Feed::get_instance(), 'plugin_setup' )
);
class T5_Multi_Post_Type_Feed
{
    /**
     * Plugin instance.
     *
     * @see get_instance()
     * @type object
     */
    protected static $instance = NULL;

    /**
     * Internal handler for WordPress
     *
     * @type string
     */
    protected static $query_var = 'multifeed';

    /**
     * Access this plugin’s working instance
     *
     * @wp-hook init
     * @since   2012.10.03
     * @return  object of this class
     */
    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;

        return self::$instance;
    }

    /**
     * Used for regular plugin work.
     *
     * @wp-hook init
     * @since   2012.10.03
     * @return  void
     */
    public function plugin_setup()
    {
        add_rewrite_endpoint( self::$query_var, EP_ROOT );
        add_filter( 'request', array ( $this, 'set_query_var' ) );
        // Hook in late to allow other plugins to operate earlier.
        add_action( 'template_redirect', array ( $this, 'render' ), 100 );
    }

    /**
     * Print the feed items.
     *
     * @wp-hook template_redirect
     * @since   2012.10.03
     * @return void
     */
    public function render()
    {
        if ( ! is_front_page() or ! get_query_var( self::$query_var ) )
        {
            return;
        }

        $args       = get_query_var( self::$query_var );
        $post_types = array_filter( explode( '+', $args ) );
        query_posts( array ( 'post_type' => $post_types ) );
        // make the post object accessible in this scope. Hat tip to @Rarst. :)
        global $post;
        require WPINC . '/feed-rss2.php';
        exit;
    }

    /**
     * Set the endpoint variable to a default value.
     *
     * If the endpoint was called without further parameters it does not
     * evaluate to TRUE otherwise.
     *
     * @wp-hook request
     * @since   2012.10.03
     * @param   array $vars
     * @return  array
     */
    public function set_query_var( $vars )
    {
        // make the following code shorter
        $q       = self::$query_var;
        $default = apply_filters( 't5_multipost_default_type', 'page' );

        if ( isset ( $vars[ $q ] ) and '' === $vars[ $q ] )
        {
            $vars[ $q ] = $default;
        }

        // Sometimes WP misinterprets the request as a page request
        // and returns a 404.
        if ( ( isset ( $vars['pagename'] ) and $q === $vars['pagename'] )
            or ( isset ( $vars['page'] )
                and isset ( $vars['name'] )
                and $q === $vars['name']
            )
        )
        {
            $vars['page'] = $vars['pagename'] = $vars['name'] = FALSE;
            $vars[ $q ] = $default;
        }
        return $vars;
    }

    /**
     * Get the URL for our endpoint.
     *
     * Usage:
     * $url = T5_Multi_Post_Type_Feed::get_instance()->get_endpoint_url(
     *      array( 'post', 'attachment' )
     * );
     *
     * @return  string
     * @wp-hook plugin_row_meta
     * @since   2012.09.21
     * @return  string
     */
    public function get_endpoint_url( $types = array( 'page' ) )
    {
        $post_types = implode( '+', $types );
        // If that is false, there are no pretty permalinks.
        $has_permalinks = get_option( 'permalink_structure' );
        $home = home_url( '/' );

        if ( ! $has_permalinks )
        {
            return add_query_arg(
                array ( self::$query_var => $post_types ),
                $home
            );
        }

        return user_trailingslashit( $home . self::$query_var . "/$post_types" );
    }
}

Install as plugin, refresh your permalink settings by just visiting that page – and that's it.

share|improve this answer
    
I'm not the owner of the blog so I can't modify it; just a user. –  Emre Oct 3 '12 at 21:06
    
In this case, the answer is: No, impossible. You have to be a developer or administrator to solve that problem. :) –  toscho Oct 3 '12 at 21:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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