Articles on: Product Roadmap

WordPress Product Roadmap Plugin - Developer Guide

WordPress Product Roadmap Plugin - Developer Guide


Table of Contents


Architecture Overview


Plugin Structure

product-roadmap/
├── includes/
│ ├── class-roadmap-admin.php # Admin interface
│ ├── class-roadmap-api.php # REST API endpoints
│ ├── class-roadmap-comments.php # Comment integration
│ ├── class-roadmap-cpt.php # Custom post types
│ ├── class-roadmap-migration.php # Database migrations
│ ├── class-roadmap-notifications.php # Email notifications
│ ├── class-roadmap-permissions.php # Access control
│ ├── class-roadmap-settings.php # Settings management
│ ├── class-roadmap-shortcode.php # Shortcode handler
│ ├── class-roadmap-suggestions.php # Feature suggestions
│ ├── class-roadmap-template.php # Template loader
│ └── class-roadmap-voting.php # Voting system
├── vue-app/ # Vue.js application
├── assets/ # CSS and JS files
├── templates/ # PHP templates
└── product-roadmap.php # Main plugin file


Key Classes

  • Roadmap_Plugin: Main plugin class
  • Roadmap_CPT: Handles custom post type registration
  • Roadmap_API: REST API implementation
  • Roadmap_Shortcode: Shortcode rendering
  • Roadmap_Voting: Vote management


Hooks Reference


Action Hooks


Plugin Lifecycle Hooks


roadmap_plugin_activated

do_action('roadmap_plugin_activated');

Fired when the plugin is activated. Use for initial setup.


roadmap_plugin_deactivated

do_action('roadmap_plugin_deactivated');

Fired when the plugin is deactivated.


roadmap_plugin_loaded

do_action('roadmap_plugin_loaded');

Fired after the plugin is fully loaded.


Item Management Hooks


roadmap_before_save_item

do_action('roadmap_before_save_item', $item_id, $item_data);

Fired before a roadmap item is saved.


roadmap_after_save_item

do_action('roadmap_after_save_item', $item_id, $item_data);

Fired after a roadmap item is saved.


roadmap_before_delete_item

do_action('roadmap_before_delete_item', $item_id);

Fired before a roadmap item is deleted.


roadmap_after_delete_item

do_action('roadmap_after_delete_item', $item_id);

Fired after a roadmap item is deleted.


Voting Hooks


roadmap_before_vote

do_action('roadmap_before_vote', $item_id, $user_id, $vote_value);

Fired before a vote is recorded.


roadmap_after_vote

do_action('roadmap_after_vote', $item_id, $user_id, $vote_value);

Fired after a vote is recorded.


roadmap_vote_removed

do_action('roadmap_vote_removed', $item_id, $user_id);

Fired when a vote is removed.


Suggestion Hooks


roadmap_suggestion_submitted

do_action('roadmap_suggestion_submitted', $suggestion_data);

Fired when a new suggestion is submitted.


roadmap_suggestion_approved

do_action('roadmap_suggestion_approved', $item_id);

Fired when a suggestion is approved.


Display Hooks


roadmap_before_shortcode_output

do_action('roadmap_before_shortcode_output', $atts);

Fired before shortcode output is rendered.


roadmap_after_shortcode_output

do_action('roadmap_after_shortcode_output', $atts);

Fired after shortcode output is rendered.


roadmap_before_item_display

do_action('roadmap_before_item_display', $item);

Fired before an individual item is displayed.


roadmap_after_item_display

do_action('roadmap_after_item_display', $item);

Fired after an individual item is displayed.


Filter Hooks


Permission Filters


roadmap_can_vote

$can_vote = apply_filters('roadmap_can_vote', $can_vote, $user_id, $item_id);

Filter whether a user can vote on an item.


roadmap_can_suggest

$can_suggest = apply_filters('roadmap_can_suggest', $can_suggest, $user_id);

Filter whether a user can submit suggestions.


roadmap_can_edit_item

$can_edit = apply_filters('roadmap_can_edit_item', $can_edit, $item_id, $user_id);

Filter whether a user can edit an item.


Display Filters


roadmap_item_classes

$classes = apply_filters('roadmap_item_classes', $classes, $item);

Filter CSS classes for roadmap items.


roadmap_shortcode_attributes

$atts = apply_filters('roadmap_shortcode_attributes', $atts);

Filter shortcode attributes before processing.


roadmap_template_path

$template = apply_filters('roadmap_template_path', $template, $template_name);

Filter template file paths.


roadmap_board_columns

$columns = apply_filters('roadmap_board_columns', $columns);

Filter board view columns.


Data Filters


roadmap_item_data

$item_data = apply_filters('roadmap_item_data', $item_data, $item_id);

Filter item data before saving.


roadmap_default_statuses

$statuses = apply_filters('roadmap_default_statuses', $statuses);

Filter default status terms.


roadmap_default_categories

$categories = apply_filters('roadmap_default_categories', $categories);

Filter default category terms.


roadmap_vote_count

$count = apply_filters('roadmap_vote_count', $count, $item_id);

Filter vote count display.


Settings Filters


roadmap_settings_tabs

$tabs = apply_filters('roadmap_settings_tabs', $tabs);

Add custom settings tabs.


roadmap_settings_fields

$fields = apply_filters('roadmap_settings_fields', $fields, $tab);

Add custom settings fields.


roadmap_settings_defaults

$defaults = apply_filters('roadmap_settings_defaults', $defaults);

Filter default settings values.


API Filters


roadmap_api_item_response

$response = apply_filters('roadmap_api_item_response', $response, $item, $request);

Filter REST API item response.


roadmap_api_permissions

$allowed = apply_filters('roadmap_api_permissions', $allowed, $request);

Filter REST API permissions.


REST API Endpoints


Authentication

All endpoints require WordPress REST API authentication using nonces.


Endpoints


Get Items

GET /wp-json/roadmap/v1/items

Parameters:

  • product: Filter by product slug
  • status: Filter by status slug
  • category: Filter by category slug
  • page: Page number
  • per_page: Items per page


Get Single Item

GET /wp-json/roadmap/v1/items/{id}


Create Item

POST /wp-json/roadmap/v1/items

Required capabilities: edit_roadmap_items


Body:

{
"title": "Item Title",
"content": "Description",
"status": "planned",
"categories": ["feature"],
"priority": "high",
"progress": 0
}


Update Item

PUT /wp-json/roadmap/v1/items/{id}

Required capabilities: edit_roadmap_items


Delete Item

DELETE /wp-json/roadmap/v1/items/{id}

Required capabilities: delete_roadmap_items


Submit Vote

POST /wp-json/roadmap/v1/vote

Body:

{
"item_id": 123,
"vote_value": 1
}


Get Settings

GET /wp-json/roadmap/v1/settings

Returns statuses, categories, and configuration.


JavaScript Integration


Global JavaScript Object

// Available on pages with roadmap
window.roadmapData = {
api_url: 'https://site.com/wp-json/roadmap/v1',
nonce: 'security_nonce',
user: {
id: 1,
can_vote: true,
can_edit: false,
can_suggest: true
},
settings: {
enable_voting: true,
enable_comments: true
}
};


Custom Events


roadmap:vote:submitted

document.addEventListener('roadmap:vote:submitted', (e) => {
console.log('Vote submitted for item:', e.detail.itemId);
});


roadmap:item:updated

document.addEventListener('roadmap:item:updated', (e) => {
console.log('Item updated:', e.detail.item);
});


Vue.js Component Access

// Access Vue app instance
const app = document.querySelector('#roadmap-app').__vue_app__;

// Access component methods
app.config.globalProperties.$roadmap.refresh();


Database Schema


Custom Tables


wp_roadmap_votes

CREATE TABLE wp_roadmap_votes (
id bigint(20) NOT NULL AUTO_INCREMENT,
item_id bigint(20) NOT NULL,
user_id bigint(20) NOT NULL,
vote_value tinyint(1) DEFAULT 1,
voted_at datetime DEFAULT CURRENT_TIMESTAMP,
ip_address varchar(45),
PRIMARY KEY (id),
UNIQUE KEY user_item (user_id, item_id),
KEY item_id (item_id),
KEY user_id (user_id)
);


Post Meta Keys

  • _roadmap_priority: Item priority (low, medium, high, critical)
  • _roadmap_progress: Completion percentage (0-100)
  • _roadmap_target_date: Target completion date
  • _roadmap_start_date: Start date
  • _roadmap_end_date: End date
  • _roadmap_vote_count: Cached vote count
  • _roadmap_github_issue: Associated GitHub issue URL
  • _roadmap_external_link: External reference URL


Custom Post Types


roadmap_item

$args = array(
'labels' => array(
'name' => 'Roadmap Items',
'singular_name' => 'Roadmap Item'
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'excerpt', 'comments'),
'menu_icon' => 'dashicons-chart-line',
'show_in_rest' => true,
'capability_type' => 'roadmap_item',
'map_meta_cap' => true
);


Taxonomies


roadmap_status

  • Hierarchical: No
  • Public: Yes
  • Show in REST: Yes


roadmap_category

  • Hierarchical: Yes
  • Public: Yes
  • Show in REST: Yes


roadmap_product

  • Hierarchical: No
  • Public: Yes
  • Show in REST: Yes


Extending the Plugin


Adding Custom Templates

// Add custom template
add_filter('roadmap_template_path', function($template, $template_name) {
if ($template_name === 'custom-view') {
return plugin_dir_path(__FILE__) . 'templates/custom-view.php';
}
return $template;
}, 10, 2);


Creating Custom Status

// Add custom status programmatically
add_filter('roadmap_default_statuses', function($statuses) {
$statuses[] = array(
'name' => 'Beta Testing',
'slug' => 'beta-testing',
'description' => 'In beta testing phase'
);
return $statuses;
});


Adding Meta Fields

// Add custom meta box
add_action('add_meta_boxes', function() {
add_meta_box(
'roadmap_custom_field',
'Custom Field',
'render_custom_field',
'roadmap_item',
'side'
);
});

// Save custom meta
add_action('save_post_roadmap_item', function($post_id) {
if (isset($_POST['custom_field'])) {
update_post_meta($post_id, '_roadmap_custom_field',
sanitize_text_field($_POST['custom_field']));
}
});


Custom Voting Logic

// Modify voting permissions
add_filter('roadmap_can_vote', function($can_vote, $user_id, $item_id) {
// Only allow voting on items in certain status
$status = wp_get_post_terms($item_id, 'roadmap_status',
array('fields' => 'slugs'));

if (in_array('completed', $status)) {
return false;
}

return $can_vote;
}, 10, 3);


Code Examples


Display Roadmap Programmatically

// In theme template
<?php echo do_shortcode('[roadmap product="main" template="board"]'); ?>

// With custom attributes
<?php
$atts = array(
'product' => 'main',
'template' => 'board',
'items_per_page' => 20
);
echo Roadmap_Shortcode::render($atts);
?>


Get Roadmap Items

// Query roadmap items
$args = array(
'post_type' => 'roadmap_item',
'posts_per_page' => 10,
'tax_query' => array(
array(
'taxonomy' => 'roadmap_status',
'field' => 'slug',
'terms' => 'in-progress'
)
),
'meta_key' => '_roadmap_priority',
'orderby' => 'meta_value',
'order' => 'DESC'
);
$items = new WP_Query($args);


Custom API Endpoint

// Register custom endpoint
add_action('rest_api_init', function() {
register_rest_route('roadmap/v1', '/stats', array(
'methods' => 'GET',
'callback' => 'get_roadmap_stats',
'permission_callback' => '__return_true'
));
});

function get_roadmap_stats($request) {
global $wpdb;

$stats = array(
'total_items' => wp_count_posts('roadmap_item')->publish,
'total_votes' => $wpdb->get_var(
"SELECT COUNT(*) FROM {$wpdb->prefix}roadmap_votes"
),
'active_voters' => $wpdb->get_var(
"SELECT COUNT(DISTINCT user_id) FROM {$wpdb->prefix}roadmap_votes"
)
);

return rest_ensure_response($stats);
}


Email Notification

// Send custom notification
add_action('roadmap_after_vote', function($item_id, $user_id, $vote_value) {
$item = get_post($item_id);
$user = get_userdata($user_id);

$subject = sprintf('New vote on: %s', $item->post_title);
$message = sprintf(
'User %s voted on roadmap item "%s"',
$user->display_name,
$item->post_title
);

wp_mail(get_option('admin_email'), $subject, $message);
}, 10, 3);


Best Practices


Security

  1. Always validate and sanitize input
  2. Check capabilities before operations
  3. Use nonces for form submissions
  4. Escape output appropriately


Performance

  1. Cache expensive queries
  2. Use transients for vote counts
  3. Minimize database queries
  4. Implement pagination


Code Organization

  1. Follow WordPress coding standards
  2. Use meaningful hook names
  3. Document your extensions
  4. Prefix function names


Testing

  1. Test with different user roles
  2. Verify permission checks
  3. Test edge cases
  4. Check for conflicts


Migration Guide


From Version 1.x to 2.x

// Handle migration
register_activation_hook(__FILE__, function() {
$version = get_option('roadmap_plugin_version');

if (version_compare($version, '2.0.0', '<')) {
// Run migration
require_once 'includes/class-roadmap-migration.php';
Roadmap_Migration::migrate_to_v2();
}
});


Troubleshooting


Debug Mode

// Enable debug logging
define('ROADMAP_DEBUG', true);

// Log debug information
if (defined('ROADMAP_DEBUG') && ROADMAP_DEBUG) {
error_log('Roadmap Debug: ' . print_r($data, true));
}


Common Issues

  1. REST API not working: Check permalinks settings
  2. Votes not recording: Verify database tables exist
  3. Templates not loading: Check template hierarchy
  4. Permissions issues: Review capability mapping


Support


For developer support:

  1. GitHub repository for bug reports
  2. Developer documentation
  3. Code examples repository
  4. WordPress.org support forum


Remember to always test your customizations thoroughly and follow WordPress best practices for plugin development.

Updated on: 25/09/2025

Was this article helpful?

Share your feedback

Cancel

Thank you!