User profiles and object associations

I’m coming over from Drupal and I’m very used to the way Drupal handles users and objects (called nodes over there.) I have to learn how WordPress handles these same situations.

Since we’re going to be confused with the same words that mean different things, I will define some of them here:

  • Node – In Drupal, everything is a node. A post is a node. A page is a node. A product is a node.
  • Author – In Drupal, every node has an author. Think of the WordPress post author.
  • Product – In Drupal, a product is a node. On my site, I sell books. So a book is a product which is a node.
  • Book Author – In the normal sense, a book’s author is the person who wrote it. I’m going to refer to this as book-author from now on to avoid confusion with node author. Every book-author is a user on the site.

On my site, since every node needs an author, when I create the products I associate the author of the node with the book-author. Imagine creating a post on WordPress and saying the post author is someone other than yourself. Same thing.

On the user’s profile page (the book-author’s profile) I can list the books they have written (with links to the actual product node) on their profile page. I simply have a section where I render each product where they are the node author.

Now I need to learn the way WordPress handles this situation whether via a plugin or code in the functions.php. So far I’ve been reading up on the user profiles and they aren’t near the same as Drupal.

  1. How do I associate a user as a book-author? I assume this will be some kind of custom role in WordPress; however, I’ve been reading up on that and it seems the roles in WordPress are related only to posting permissions and the like.

  2. How do I associate a user (book-author) to a product? I’m using the WooCommerce plugin. I know I can create a custom field on the product, call it Author, and then put a name in there but this will just render as simple text. I need to associate this field as a link to the user (book-author) profile and be able to associate this product on the user’s profile.

  3. Is the user profile even the appropriate way to handle this in WordPress? Or should I be looking into some other kind of template? Perhaps a custom post type that has a block of code in the template that will render a listing of products based on the post’s title (used here as the author name) or something like that? If that’s a good way to do it, how then do I associate links back to this custom post page? i.e. when clicking a user’s name in a comment it should now go to that associated custom post instead of the user profile.

Sorry if all of this is confusing. It’s out of the box behavior in Drupal and since this is literally my second week using WordPress it’s all a bit confusing to me as well.

NOTE: an admin should create a Drupal tag. Doing a quick search I find many posts in relation to Drupal here and it may better assist users who are familiar with both platforms find questions they can expertly answer. 😉

2 Answers
2

I don’t know Drupal, however, seems to me that what is “node” in drupal is “post type” in WordPress.

By default WordPress has several post types: posts, pages, atthachments, menu items, revisions (these post types are often referred as “built-in”).

You can register any number of custom post types, aka CPT.

Post types, in database, differe one from another just for the ‘post_type’ column in posts table.

However, the “behavior” they have can be very different, and depend on the post type registration arguments.

So you can have post type hierachical and not hierachical, post type that need a specific user capability to be edited, post type ‘public’ and not public and so on.

As example, menu items nad revisions are not public: the default UI is hidden and WordPress has a different UI fo them.

In WordPress every post, regardless the type, has an author. (just like nodes have authors in Drupal, for what I can understand).

Post to author relation is one-to-many (a post can have only one author and an author can have many posts). This relation, in database, is handled via a post_author field in the post table.

That field refere to an ID in the users table: so the unique author for the post is an user: has a username, a passwrd, a profile, and so on.

In you case, “Book” should be a post type, and if it’s good for you that book author is a real user, you can use link books and authors using the post author field.

That will be easy to do because default post creation/editing UI has a field to set up the users, and also there are some default template tags that you can use (like the_author and related).

In addition you can use the template hierarchy to easily customize the author archive (in WordPress an “archive” is web page that shows a set of posts that share a feature: a taxonomy archive is a page showing posts with same taxonomy, just like an author archive is a page showing posts of a specific author).

If your authors are not real people, but is only a way to connect books, you may consider use a different approach, because if book authors are post authors (so users) they should have an email, an account and so on…

Alternatives are, in fact, using another post type for authors, or using a taxonomy.

Taxonomies are another type of “entity” in WordPress. Every taxonomy can have unlimited terms (just like avery post type can have unlimited posts). Categories and tags are the 2 default taxonomies, but you can register unlimited custom taxonomies.

Regarding the way posts can be connected to other posts, in WordPress, out-of-the box, you have to way:

  1. One-to-Many relation of posts with same post type: this is the parent-child relationship that you can setup simply registring a post type as hierachical. Example is WordPress pages.
  2. Second type is a sort of “indirect” Many-to-Many relation using taxonomy. You can assign same taxonomy term to different posts (even of different post types) and the retrieve or show posts that share same term, “connecting” them. As example, you can create a taxonomy for every book author and assign the taxonomy to books, than using taxonomy archives to show posts.

So if your book authors are not real users taxonomy can be the right choose.

Now the WooCommerce “problem” (or better the problem you can have with WooCommerce). That plugin register a post type to handle products, the cpt name is ‘product’.

If you register a custom post type fo books, than you can’t sell them with WooCommerce, because only ‘Products’ (post with post type ‘product’) can be selled out-of-the box using that plugin.

I don’t know if there is any plugin that allow selling others custom post types. However an easy way to solve the problem can be using ‘Product’ post type for books and

  • register a custom taxonomy called ‘Product Type’ an create in it the term ‘Book’
  • a probably better alternative is create your own WooCommerce product type for Books. See this WPSE answer by @helgatheviking. WooCommerce product types are the way the plugin use to handle product with different features (simple, variable, downloadable, and so on).

Regarding connect book products to books authors, if you use post author, then simply assign the right author and then when you need to show the link to author archive use the_author_link template tag. If you use a taxonomy then use get_term_link template tag to show then link to the related archive.

There is an alternative I’ve not already mentioned. If book authors are not real users (so you don’t use pos author field) and you want create an author archive (a page that shows all authors) along with a “single view” of every author (e.g. a page with author biography, informations, photos…) probably you have to create another post type for authors.
That can be a problem: as said before, out-of-the-box there isn’t in WordPress a system to directly connect post with different post types (in your case ‘product’ and ‘author’).

A well known plugin, Posts2Posts can help to solve this problem, or you can handle that connection by yourself using a custom meta field (maybe ‘book_author_id') on product (or book) post type. In that case, the link to related author page can be shown in the loop (product archive or product single page) using get_permalink in combination with get_post_meta, something like:

$author = get_post( get_post_meta( get_the_ID(), 'book_author_id', TRUE) );
$title = apply_filters('the_title', $author->post_title);
$link = get_permalink($author);
echo '<a href="' . $link . '" title="' . $title. '">' . $title. '</a>';

After that, in the single author template (according to template hierarchy it will be 'single-author.php' you can show the author information (post content) along to all all book for that author, using a custom WP_Query using ‘meta_query’ argument, something like:

// single-author.php

the_post();

<h1>Author Name: <?php the_title() ?></h1>
<h2>Author Info</h2>
<div><?php the_content() ?></div>

<h2>Books by <?php the_title() ?></h2>
<?php
$args = array(
  'post_type' => 'products',
  'meta_query' => array(
    'meta_key' => 'book_author_id',
    'meta_value' => get_the_ID()
   )
);
$books = new WP_Query( $args );
if ( $books->have_posts() ) : while( $books->have_posts() ) : $books->the_post(); 
?>

<div class="book">
  <h3><?php the_title() ?></h3>
  <p><?php the_excerpt() ?></p>
  <a href="https://wordpress.stackexchange.com/questions/131444/<?php the_permalink() ?>">Details</a>
</div>

<?php endwhile; wp_reset_postdata(); else: ?> 
<div>Sorry, <?php the_title() ?> has no books.</div>
<?php endwif; ?>

However, if book authors are real users (the should have an account on the site) I strongly recommend to use post author to connect books with book authors and if you need to some information for author archive you can use the author description field in user profile page and use a custom page template in combination with an WP_User_Query if you want ot show an archive of all book authors.

Leave a Comment