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.

I'm working on a site where there are multiple content types in addition to the built-in ones (see list below). I'd like to establish the ability to mark related content in any direction, from any content type to any other.

The content types are:

  • post
  • page
  • topic (from bbpress)
  • case (custom types from here on down)
  • note
  • question
  • therapy_guideline

Below I have code from my functions.php used to set up possible connections from posts to the other content types:

p2p_register_connection_type(
    array(
        'name' => 'post-to-post',
        'from' => 'post',
        'to' => 'post'
    )
);

p2p_register_connection_type(
    array(
        'name' => 'post-to-page',
        'from' => 'post',
        'to' => 'page'
    )
);

p2p_register_connection_type(
    array(
        'name' => 'post-to-topic',
        'from' => 'post',
        'to' => 'topic'
    )
);

p2p_register_connection_type(
    array(
        'name' => 'post-to-case',
        'from' => 'post',
        'to' => 'case'
    )
);

p2p_register_connection_type(
    array(
        'name' => 'post-to-note',
        'from' => 'post',
        'to' => 'note'
    )
);

p2p_register_connection_type(
    array(
        'name' => 'post-to-question',
        'from' => 'post',
        'to' => 'question'
    )
);

p2p_register_connection_type(
    array(
        'name' => 'post-to-therapy_guideline',
        'from' => 'post',
        'to' => 'therapy_guideline'
    )
);

That's just for establishing relationships from posts to other content types. I've repeated these incantations to establish the other various connections - 28 in total. I cringe at the repetition. This could get really awkward if more content types are added, and if they need to be able to connect to all (or most) of the other types.

It's occurred to me that I could use a loop to iterate over each of these content types and generate a connection to each other type, but that doesn't feel right. I've also read about the reciprocal value, but that seems to be from a content type back to the same type. Is there a way to simplify creating connections between distinct content types without having to do it for each direction (from and to)?

My intent is to facilitate the selection of related content relative to the current content, via the backend when creating/editing content. Then to display a "Related Content" section following the display of said current content. These related content pieces could be across the spectrum of content types in use, but would be manually selected to ensure maximum relevance.

I am using custom taxonomies across these content types, and had considered using that for finding related content, but the taxonomies would still be too broad. Manual selection seems to be the way to go.

share|improve this question

closed as off-topic by birgire, G. M., Johannes Pille, kaiser Sep 22 at 15:51

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

6 Answers 6

up vote 5 down vote accepted
+50

Why not do...

$my_post_types = array(
    'post', 
    'page', 
    'topic', 
    'case', 
    'note', 
    'question', 
    'therapy_guideline'
);

p2p_register_connection_type( array(
    'name' => 'my_post_relationships',
    'from' => $my_post_types,
    'to' => $my_post_types,
    'sortable' => 'any',
    'reciprocal' => false,
    'cardinality' => 'many-to-many',
    'title' => array(
        'from' => 'Children',
        'to' => 'Parent',
        ),
    'admin_column' => 'any',
    )
);

Or something similar?

Edit:

A way to possibly get your multiple boxes without all that typing, using the aforementioned array.

foreach($my_post_types as $post_type){
    // use line below if you don't ever need to relate posts to posts, pages to pages, etc.
    $temp_array = array_diff($my_post_types, array($post_type));

    p2p_register_connection_type( array(
        'name' => 'my_'.$post_type.'_connections',
        'from' => $temp_array, // use $my_post_types if you didn't define $temp_array
        'to' => $post_type,
        'sortable' => 'any',
        'reciprocal' => false,
        'cardinality' => 'many-to-many',
        'admin_column' => 'any',
        )
    )
}

The temp array makes it so each post type is related to every other post type, but not itself. Not sure if that's something you want or not, easy enough to remove.

share|improve this answer
    
I didn't know an array could be used for the to and from fields. Reviewing the docs shows the slightest mention of this ability, but none of the code examples I saw showed it in use. –  Grant Palin Jun 2 '13 at 5:31
    
In my brief testing so far, a snippet similar to the above works for me. The only downside is that all the content types are combined in one box for selection, while my previous code has each type separate. I like the separate boxes, but can probably live with the combined one thanks to the filtering ability. –  Grant Palin Jun 2 '13 at 5:33
    
I added a way to have more boxes without all that typing. You might wish to reverse the from and to fields. Not sure what works best for you. –  GhostToast Jun 2 '13 at 13:42
    
I tried the second solution as well, it showed the boxes for individual content types but still combined all content types within the boxes, defeating the point of the separate boxes. Perhaps something to do with using arrays to relate content types. The initial proposed solution will do for now, all types in one box with filtering. –  Grant Palin Jun 4 '13 at 19:50
    
Hmm. Did you try swapping the from and to fields? –  GhostToast Jun 4 '13 at 20:11

GhostToast seems to have answered your issue with repetition.

Implementing this for your specific situation should show related content: https://github.com/scribu/wp-posts-to-posts/wiki/Related-posts:

$related = p2p_type( 'posts_to_pages' )->get_related( get_queried_object() );

The only difference is that we replaced get_connected() with get_related().

For manually finding specific content this has proven useful to me in the past: http://wordpress.org/plugins/better-internal-link-search/

share|improve this answer

The actual question for me is: For what and how do you use the relationship information? Where is it displayed or do you need it for any further business logic?

As far as I know, there is no way with core functions for this.

If I wanted to achieve something like this without a plugin in the past, I wrote some custom PHP that automatically adds a taxonomy for saving relational information between post types. The main benefit in using an additional taxonomy over using post_meta is, that you can more easily query and access your content based on the relationship information.

If the overhead of a plugin was ok for the desired functionality, I used Advanced Custom Fields (relational or post object field types) which does all of this without any php with just some clicks in the backend (but uses post_meta to save the relationships).

share|improve this answer
    
Please see edit to OP, hope that clarifies the query. –  Grant Palin Apr 27 '13 at 6:17
    
I looked at the ACF functionality, looks simple to implement but apparently it doesn't support bidirectional relationships. –  Grant Palin May 28 '13 at 19:16

The best way to do that would be to register a non-hierarchical taxonomy, shared between the different post types you want to associate.

You can then use WP's built-in taxonomy querying to pull all associated content for any term. As a general rule of thumb, anything you're going to query by should be a taxonomy rather than a field, because querying by fields is a lot heavier on the DB.

share|improve this answer

If You want to create relation between custom post types the you can use plugin TYPES . Using this plugin you can create custom post type and also set relation between them like parent or child relation.

Another way you can save the relation value in post_meta table so that you can more easily query and access your content based on the relationship information.

share|improve this answer

You need this or more more complex ?

enter image description here

It is just a prototype example. therapy_guideline might have surgical_therapy_guideline, conservative_therapy_guideline, palliative_therapy_guideline, etc.

However complex you want, you can actually make it. You actually need to implement Semantic Web on that website. Easiest way to create semantics is to use RDFa data. You can use Enhanced Publication Plugin. There are many free resources for creating semantic web. You can use Apache Stanbol plus Open Refine (search in Google Project). What you will use depends on the bulk of possible queries and how scalable the database is, and obviously your knowledge. Enhanced Publication Plugin will incrementally add small data to WordPress's MySQL database (it is not even MySQLi). It is better to convert to PostgreSQL on nginx server if you want to go with WordPress plus Plugin and load on the server is very high.

Obviously you can use the RDFa, JSON or API with Apache Stanbol and use it with PHP or WordPress custom Hook. You can use the framework of Yet Another Related Post Plugin if you want to create a plugin.

share|improve this answer
    
There's not going to be a need to segment content deeper than they are already. Not to preclude parallel groupings though, but just no further breakdown as suggested. –  Grant Palin Jun 3 '13 at 21:00

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