Skip to main content

Developer Overview

Welcome to the ThemeRuby Multi Authors developer documentation. This guide will help you integrate the plugin into your themes and extend its functionality.

Quick Start for Developers​

1. Check if Plugin is Active​

Always check if the plugin is active before using its functions:

if ( function_exists( 'tmauthors_get_post_authors' ) ) {
// Plugin is active, use its functions
$authors = tmauthors_get_post_authors( get_the_ID() );
}

2. Display Authors in Your Theme​

Basic implementation in single.php or content.php:

<?php
if ( function_exists( 'tmauthors_the_authors' ) ) {
echo '<div class="post-authors">';
echo '<span class="byline">By: </span>';
tmauthors_the_authors();
echo '</div>';
}
?>

3. Query Posts by Author​

Use standard WP_Query with author parameters:

$query = new WP_Query( array(
'author__in' => array( 1, 5, 8 ), // Posts by these authors
'posts_per_page' => 10,
) );

Architecture​

How It Works​

ThemeRuby Multi Authors uses WordPress's built-in taxonomy system to manage author relationships:

Post ID 123
├── Taxonomy: ema_author
│ ├── Term: user-1-john-doe (User ID: 1)
│ ├── Term: user-5-jane-smith (User ID: 5)
│ └── Term: user-8-bob-johnson (User ID: 8)

Benefits of This Approach​

✅ No custom tables - Uses WordPress core ✅ Standard queries - Works with WP_Query ✅ Efficient - Leverages WordPress's optimized taxonomy queries ✅ Scalable - Handles thousands of posts and users ✅ Compatible - Works with any plugin/theme

Database Structure​

No custom tables! Uses standard WordPress tables:

  • wp_terms - Stores author terms
  • wp_term_taxonomy - Links to ema_author taxonomy
  • wp_term_relationships - Links posts to author terms
  • wp_termmeta - Stores user ID for each term

Key Concepts​

Primary vs Co-Authors​

  • Primary Author: The post_author field in wp_posts (always exists)
  • Co-Authors: Additional authors stored as taxonomy terms

The plugin handles both seamlessly - when you call tmauthors_get_post_authors(), it returns all authors (primary + co-authors).

Author Terms​

Each WordPress user gets a corresponding taxonomy term:

User: john-doe (ID: 123)
↓
Term: user-123-john-doe
↓
Term Meta: user_id = 123

This mapping is automatic and happens when:

  • User is assigned as author for the first time
  • User is created/updated

Caching Strategy​

The plugin uses multi-level caching:

  1. Object Cache - WordPress transient/object cache
  2. Per-Request Cache - Stores results for current page load
  3. Database Cache - MySQL query cache (server-level)

Cache is automatically cleared when:

  • Authors are assigned/removed
  • Posts are updated
  • Users are modified

API Structure​

Template Tags​

Public functions for use in themes:

// Get authors
tmauthors_get_post_authors( $post_id )

// Display authors
tmauthors_the_authors( $post_id, $args )

// Check multiple authors
tmauthors_has_multiple_authors( $post_id )

// Set authors
tmauthors_set_post_authors( $post_id, $author_ids )

👉 Complete Template Tags Reference

Hooks & Filters​

Customize plugin behavior:

// Modify author list
add_filter( 'tmauthors_post_authors', $callback, 10, 2 );

// Customize author display
add_filter( 'tmauthors_display', $callback, 10, 3 );

// After authors assigned
add_action( 'tmauthors_assigned', $callback, 10, 2 );

👉 Complete Hooks & Filters Reference

WP_Query Integration​

Query posts by author:

// Single author
new WP_Query( array( 'author' => 5 ) );

// Multiple authors (OR)
new WP_Query( array( 'author__in' => array( 1, 5, 8 ) ) );

// Exclude authors
new WP_Query( array( 'author__not_in' => array( 3, 6 ) ) );

// By author name
new WP_Query( array( 'author_name' => 'john-doe' ) );

👉 WP_Query Integration Guide

Common Use Cases​

1. Display Authors in Theme​

// In single.php
if ( function_exists( 'tmauthors_get_post_authors' ) ) {
$authors = tmauthors_get_post_authors( get_the_ID() );

if ( count( $authors ) > 1 ) {
echo '<div class="co-authors">Co-authored by: ';
} else {
echo '<div class="single-author">By: ';
}

foreach ( $authors as $index => $author ) {
if ( $index > 0 ) echo ', ';
echo '<a href="' . get_author_posts_url( $author->ID ) . '">';
echo esc_html( $author->display_name );
echo '</a>';
}

echo '</div>';
}
function my_popular_authors_widget() {
global $wpdb;

// Get authors with most posts
$popular_authors = $wpdb->get_results( "
SELECT t.term_id, tm.meta_value as user_id, COUNT(*) as post_count
FROM {$wpdb->term_relationships} tr
JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
JOIN {$wpdb->termmeta} tm ON t.term_id = tm.term_id
WHERE tt.taxonomy = 'ema_author'
AND tm.meta_key = 'user_id'
GROUP BY t.term_id
ORDER BY post_count DESC
LIMIT 10
" );

foreach ( $popular_authors as $popular ) {
$user = get_user_by( 'id', $popular->user_id );
echo '<li>' . $user->display_name . ' (' . $popular->post_count . ' posts)</li>';
}
}

3. Custom Author Archive​

// In author.php
$author_id = get_queried_object_id();

// Get all posts by this author (automatic with archive filtering)
if ( have_posts() ) {
while ( have_posts() ) {
the_post();

// Show if this is co-authored
$authors = tmauthors_get_post_authors( get_the_ID() );
if ( count( $authors ) > 1 ) {
echo '<span class="co-authored-badge">Co-authored</span>';
}
}
}

4. REST API Integration​

// Add authors to REST API response
add_action( 'rest_api_init', function() {
register_rest_field( 'post', 'authors', array(
'get_callback' => function( $post ) {
$authors = tmauthors_get_post_authors( $post['id'] );
return array_map( function( $author ) {
return array(
'id' => $author->ID,
'name' => $author->display_name,
'url' => get_author_posts_url( $author->ID ),
);
}, $authors );
},
) );
} );

Best Practices​

1. Always Check for Plugin​

// ✅ Good
if ( function_exists( 'tmauthors_get_post_authors' ) ) {
$authors = tmauthors_get_post_authors();
}

// ❌ Bad - will error if plugin deactivated
$authors = tmauthors_get_post_authors();

2. Use Proper Escaping​

// ✅ Good
echo esc_html( $author->display_name );

// ❌ Bad - security risk
echo $author->display_name;

3. Cache Expensive Queries​

// ✅ Good
$cache_key = 'my_authors_query_' . $post_id;
$authors = wp_cache_get( $cache_key );

if ( false === $authors ) {
$authors = tmauthors_get_post_authors( $post_id );
wp_cache_set( $cache_key, $authors, 'my_plugin', 3600 );
}

// ❌ Bad - queries database every time
$authors = tmauthors_get_post_authors( $post_id );

4. Provide Fallbacks​

// ✅ Good - works even if plugin deactivated
if ( function_exists( 'tmauthors_get_post_authors' ) ) {
$authors = tmauthors_get_post_authors();
} else {
// Fallback to default WordPress author
$author = get_user_by( 'id', get_post_field( 'post_author' ) );
$authors = array( $author );
}

foreach ( $authors as $author ) {
echo $author->display_name;
}

Performance Considerations​

Query Optimization​

The plugin uses optimized queries:

-- Efficient LEFT JOIN used by plugin
SELECT p.*, GROUP_CONCAT(u.ID) as author_ids
FROM wp_posts p
LEFT JOIN wp_term_relationships tr ON p.ID = tr.object_id
LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'ema_author'
LEFT JOIN wp_termmeta tm ON tt.term_id = tm.term_id AND tm.meta_key = 'user_id'
WHERE p.post_status = 'publish'
GROUP BY p.ID

Caching Recommendations​

  1. Enable Object Cache - Redis/Memcached for best performance
  2. Enable Plugin Cache - Settings > ThemeRuby Multi Authors
  3. Use Page Caching - WP Super Cache, W3 Total Cache, etc.

Database Indexes​

The plugin uses WordPress's standard indexes. For large sites (10,000+ posts), consider adding:

-- Optional index for better performance on large sites
CREATE INDEX idx_ema_user_id ON wp_termmeta (meta_key, meta_value)
WHERE meta_key = 'user_id';

Code Standards​

The plugin follows:

  • ✅ WordPress Coding Standards
  • ✅ WordPress PHP Documentation Standards
  • ✅ WPCS (WordPress Coding Standards)
  • ✅ PHP_CodeSniffer compatible

Browser Support​

JavaScript supports:

  • ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
  • ✅ IE11 with polyfills (if needed)
  • ✅ Mobile browsers (iOS Safari, Chrome Mobile)

Debugging​

Enable Debug Mode​

// In wp-config.php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'SCRIPT_DEBUG', true );

Plugin Debug Filter​

// Enable plugin-specific debugging
add_filter( 'tmauthors_debug', '__return_true' );

Check Queries​

// Show SQL queries
define( 'SAVEQUERIES', true );

// In template
global $wpdb;
print_r( $wpdb->queries );

Next Steps​

For Theme Developers​

  1. Theme Integration Guide - Complete theme integration
  2. Template Tags - All available functions
  3. Display Examples - Styling examples

For Plugin Developers​

  1. Hooks & Filters - Extend functionality
  2. WP_Query Integration - Query customization
  3. GitHub Repository - Contribute code

Support​

For development questions:


Ready to integrate?