Creating relationships between multiple content types

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:

Read More
  • 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.

Related posts

Leave a Reply

6 comments

  1. 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.

  2. 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/

  3. 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).

  4. 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.

  5. 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.

  6. 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.