Skip to content

Developer tools

Build on XFtoWP with hooks, templates and the XenForo API

XFtoWP handles the connection to your forum. Use the XenForo API, webhooks, actions, filters and the integrations class from your own theme or plugin, without editing XFtoWP.

Every hook, helper and API is included in every XFtoWP license.

functions.php

// Runs on WordPress when a new post is made on XenForo
function my_new_post( $request ) {
	$thread = xf_request( 'GET', 'thread', array(
		'route_id' => $request['data']->Thread->thread_id
	) );
	// Cache it, notify someone or update a post
}
add_action( 'xfwp_webhook_post_insert', 'my_new_post' );

License
Included

WordPress
6.2+

XenForo
2.3+

Auth
Handled

Ways to extend

From settings to custom code

All of these live outside the plugin folder, so updating XFtoWP doesn’t undo your work.

wp-admin 01

Settings

Set up User actions, Thread connect, widgets and strings.

your-theme/XFWP/ 02

Template overrides

Copy a template into your theme and edit its HTML there.

functions.php 03

Actions and filters

Change data and behavior with xfwp_ actions and filters.

xf_request() 04

XenForo API

Read and write any forum data your API user can access.

xfwp_webhook_* 05

Webhook actions

Run code on WordPress when something happens on XenForo.

wp-content/plugins/ 06

Integrations

Connect another plugin to User actions with XFWP_Integration.

XenForo API

Call the XenForo API

xf_request() makes GET, POST and DELETE requests to the XenForo API. XFtoWP holds the API key and connection, so there’s no client to write.

  • Any endpoint your API user can access
  • Route IDs and body parameters
  • Returns the response as a PHP object

Making XenForo API requests →

functions.php

$board_index = xf_request( 'GET', 'index' );
xf_request( 'POST', 'threads', array(
	'body' => array(
		'node_id' => 1234,
		'title'   => 'New thread title',
		'message' => 'My own thread content.'
	)
) );

Each call is a live request. Cache the result instead of calling it on every page load.

functions.php

function my_xf_webhook( $request ) {
	error_log( print_r( $request, true ) );
}
add_action( 'xfwp_webhook_post_insert', 'my_xf_webhook' );
// Also: xfwp_webhook_user_update
//       xfwp_webhook_user_upgrade_purchase_complete

The action name changes with the content type and event.

Webhooks

Webhook actions for XenForo events

When XenForo sends a webhook, XFtoWP runs xfwp_webhook_{content_type}_{event}, so your code can react to new posts, user updates or upgrade purchases.

  • One action per content type and event
  • $request holds the webhook data
  • Uses the events you pick in XenForo’s webhook settings

Custom webhook actions →

Custom user fields

Custom user fields from your own data

Two filters add your own field to the Custom user fields screen and set its value when a user syncs, with the WordPress user, their user meta and the post ID passed in.

  • xfwp_custom_fields adds the field
  • xfwp_custom_user_fields_data sets the value
  • Runs on every user sync and user action

Custom data in user fields →

functions.php

add_filter( 'xfwp_custom_fields', function( $fields ) {
	$fields['user']['random_number'] = array(
		'label' => 'Random number'
	);
	return $fields;
} );
add_filter( 'xfwp_custom_user_fields_data',
	function( $fields, $wp_user, $usermeta, $post_id ) {
		$fields['random_number'] = rand();
		return $fields;
	}, 10, 4 );

Use the Field ID of the custom user field in XenForo as the key.

xfwp-my-integration.php

class XFWP_My_Integration extends XFWP_Integration {
	public $name = 'my-plugin';
	public function init() {
		add_action( 'my_plugin_purchase',
			array( $this, 'complete' ) );
	}
	public function complete( $order ) {
		$this->users->update_user( $order->user_id, array(
			'action'  => 'product_purchase',
			'post_id' => $order->product_id
		) );
	}
}
add_action( 'plugins_loaded', function() {
	new XFWP_My_Integration;
} );

my_plugin_purchase stands in for your plugin’s own purchase hook.

Integrations API

Integrations API for other plugins

Extend XFWP_Integration in your own plugin, then call update_user() from that plugin’s hooks to run User actions such as promotions, registrations and messages.

  • Built the same way as the MemberPress integration
  • update_user() runs the actions set for a product
  • Optional products(), strings() and settings methods

Plugin Integrations API →

Bulk Actions API

Add your own Bulk Actions

Extend XFWP_Bulk_Action and register it with the xfwp_bulk_actions filter. Your action gets the Bulk Actions screen, batches, safety checks and run results.

  • Start from WordPress or XenForo users
  • Limit it to connected users
  • Return a result for each user

my-bulk-badge.php

class My_Bulk_Badge extends XFWP_Bulk_Action {
	public $sources = array( 'wp' );
	public $connected_only = true;
	public function label() {
		return 'Award a badge';
	}
	public function verb() {
		return 'Award';
	}
	public function progress() {
		return 'Awarding badges…';
	}
	public function run( $bulk, $pair ) {
		update_user_meta( $pair['wp_user']->ID, 'my_badge', 1 );
		return array_replace( $pair['row'], array(
			'outcome' => 'success',
			'message' => 'Badge awarded.'
		) );
	}
}

Add about() and review() to describe the action on screen, then load the class on plugins_loaded if XFWP_Bulk_Action exists.

At a glance

What’s included

Authentication handled

Your code uses the API key saved in XFtoWP settings and never handles credentials.

Two-way events

WordPress hooks run on the way out. XenForo webhooks run on the way in.

Options and meta helpers

Use xf_option() for XFtoWP settings and xf_post_meta() for post meta.

Custom register forms

Add XFtoWP syncing to registration forms from other plugins.

Post types and user roles

Add Thread connect to more post types and user roles.

Cache clearing

Clear your page cache when new replies or forum data load.

Setup guides for every option: read the docs →

Questions about Developer tools

Frequently asked questions

Have another question? Ask in the support forums.

Do I need my own XenForo API key in code?

No. xf_request() uses the key saved in XFtoWP settings, so your code passes only the method, route and parameters.

Will plugin updates overwrite my code?

Not if it’s outside the plugin folder. Put actions and filters in your theme or a custom plugin, and template overrides in your theme’s XFWP/ folder.

Where do template overrides go?

In an XFWP/ folder in your active theme, with the same path and file name as the template in the plugin’s templates/ folder.

Can I run code when something happens on XenForo?

Yes. Add a webhook in XenForo, then hook into the xfwp_webhook_{content_type}_{event} action on WordPress.

Can I connect a store or membership plugin XFtoWP doesn’t support?

Yes. Extend XFWP_Integration and call update_user() from that plugin’s purchase or expiration hooks.

Can I add my own bulk action?

Yes. Extend XFWP_Bulk_Action and add it with the xfwp_bulk_actions filter. It appears in the Bulk Actions menu with the built-in actions.

Can I add Thread connect to other post types?

Yes, with the xfwp_comments_post_types filter.

How often should I call the API?

Each xf_request() call is a live request to your forum, so cache the result instead of calling it on every page load.

XFtoWP features

All features →

User syncing

Sync registrations, logins, groups and fields.

Bulk Actions

Import users both ways or refresh them all.

Thread connect

Forum threads under posts, replies as comments.

XF Content widget

Stats, latest posts and featured threads.

Strings Manager

Translate or edit every text string.

Developer tools

Templates, hooks, filters and API requests.

Get Developer tools with XFtoWP

One license includes Developer tools, every other XFtoWP feature, and a year of updates and support.

$79 · 40% off renewals

Instant download

Docs & forum support

Get sneak peaks, release note, success stories, and other interesting WordPress and XenForo content sent to your inbox.

Unsubscribe anytime.