Skip to content

Core Functions & API

Public functions provided by BuddyPress Hashtags for use in themes, plugins, and custom code. Most functions are defined in includes/bpht-general-functions.php; exceptions are noted under each function.


Records hashtag usage in the database. Inserts a new row in bpht_hashtags_items linking the hashtag to a content item, then either creates a new row in bpht_hashtags or increments its ht_count. If an identical (user_id, item_id, type, hashtag_items) row already exists in bpht_hashtags_items, the function does nothing (prevents double-counting on page refresh).

Fires the buddypress_hashtag_inserted action after the write completes.

bpht_db_buddypress_hashtag_entry( string $ht_name, string $ht_type, string|int $post_id = '0' ): void

Parameters

Name Type Description
$ht_name string Hashtag name without the # prefix
$ht_type string Content type: buddypress, bbpress, post, page, or profile
$post_id string|int Activity ID, post ID, or other content identifier. Pass '0' or omit when no ID is available.

Returns: void

// Record a hashtag used in a BuddyPress activity.
bpht_db_buddypress_hashtag_entry( 'WordPress', 'buddypress', 1234 );
// Record a hashtag from a custom content type, with no associated item ID.
bpht_db_buddypress_hashtag_entry( 'news', 'buddypress' );

Returns whether non-alphanumeric (Unicode) hashtags are active. Reads the allow_non_an_ht key from bpht_general_settings, then passes it through the bpht_alpha_numeric_hashtags_enabled filter so the behavior can be overridden in code.

When multisite is active and the plugin is network-activated, the function reads from get_site_option() instead of get_option().

bpht_alpha_numeric_hashtags_enabled(): bool

Returns: true if Unicode/non-alphanumeric hashtags are enabled; false otherwise.

if ( bpht_alpha_numeric_hashtags_enabled() ) {
// Regex will match any non-whitespace sequence after #.
// Standard mode: only word characters [\p{L}\w-].
}

Returns hashtags associated with a user from the bpht_hashtags_items table.

When $type is 'profile', this returns hashtags the user is following. When $type is 'buddypress', it returns hashtags the user has used in activities.

bpht_get_user_hashtags( int $user_id, string $type = '' ): array|false

Parameters

Name Type Description
$user_id int WordPress user ID. If empty, falls back to bp_loggedin_user_id().
$type string Row type to filter by. Defaults to 'buddypress' when left empty. Pass 'profile' to get followed hashtags.

Returns: Array of stdClass objects, each with a hashtag_items property containing the hashtag name. Returns false if no rows found.

// Get hashtags followed by user 42.
$followed = bpht_get_user_hashtags( 42, 'profile' );
if ( $followed ) {
foreach ( $followed as $row ) {
echo '#' . esc_html( $row->hashtag_items ) . '<br>';
}
}

Removes a hashtag from a user’s records. Deletes matching rows from both bpht_hashtags_items and bpht_hashtags using a JOIN DELETE query with a LIKE '%tag%' match. The LIKE pattern means partial matches are also deleted — pass the exact hashtag name to avoid unintended deletions.

bpht_delete_user_hashtag( int $user_id, string $tag ): bool

Parameters

Name Type Description
$user_id int WordPress user ID. If empty, falls back to bp_loggedin_user_id().
$tag string Hashtag name without #.

Returns: true if the query ran without error (including when zero rows were deleted), false on database error.

$removed = bpht_delete_user_hashtag( get_current_user_id(), 'wordpress' );
if ( ! $removed ) {
// Database error; no rows matching 'wordpress' were found or deletion failed.
}

Returns the hashtag names indexed for a specific post or page. Queries bpht_hashtags_items for rows matching both item_id and type. Results are lowercased and deduplicated.

Used internally on single post/page views to build the JavaScript indexedHashtags array so the client-side linkifier only converts hashtags that are actually present in that post.

bpht_get_post_hashtags( int $post_id, string $type = 'post' ): array

Parameters

Name Type Description
$post_id int WordPress post or page ID
$type string Content type stored in the type column. Typically 'post', 'page', 'topic', or 'reply'.

Returns: Array of lowercase hashtag strings. Empty array if none found or if the table does not exist.

$tags = bpht_get_post_hashtags( get_the_ID(), get_post_type() );
foreach ( $tags as $tag ) {
echo '<a href="' . esc_url( home_url( '?s=%23' . $tag ) ) . '">#' . esc_html( $tag ) . '</a> ';
}

Checks whether a hashtag string is valid and should be saved or linkified. Rejects pure emoji sequences, HTML entity hex codes captured as hashtags (e.g. x1f60d from &#x1f60d;), pure numeric strings, and strings with no alphanumeric character.

Emoji checks are applied only when $context is 'activity' or 'bbpress'. For 'post' and 'page' contexts, only the purely-numeric and no-alphanumeric checks apply.

bpht_is_valid_hashtag( string $hashtag, string $context = 'activity' ): bool

Parameters

Name Type Description
$hashtag string Hashtag text without the # prefix
$context string Where the hashtag originates: 'activity', 'bbpress', 'post', or 'page'

Returns: true if the hashtag is valid; false otherwise.

bpht_is_valid_hashtag( 'WordPress', 'activity' ); // true
bpht_is_valid_hashtag( 'x1f60d', 'activity' ); // false — emoji entity
bpht_is_valid_hashtag( '1234', 'activity' ); // false — purely numeric, 4 digits
bpht_is_valid_hashtag( 'tag123', 'post' ); // true

Returns true if the string contains any character from the Unicode emoji ranges. Used internally by bpht_is_valid_hashtag() for activity and bbPress contexts.

bpht_contains_emoji( string $string ): bool

Parameters

Name Type Description
$string string String to test

Returns: bool

bpht_contains_emoji( 'hello' ); // false
bpht_contains_emoji( 'hi 😊' ); // true

Checks whether a hashtag appears in the profanity keyword list configured in the BuddyPress Profanity plugin (by Wbcom Designs). Returns false immediately if profanity filtering is disabled in the plugin settings, or if the BuddyPress Profanity plugin is not active.

This function requires the BuddyPress Profanity plugin. Without it, it always returns false.

bpht_is_profanity_hashtag( string $hashtag ): bool

Parameters

Name Type Description
$hashtag string Hashtag text without #

Returns: true if the hashtag is in the blocklist; false otherwise.

if ( bpht_is_profanity_hashtag( $tag ) ) {
// Do not save or display this hashtag.
continue;
}

Maps an internal database type code to a translated display string for use in the admin UI. Returns the type name passed through ucfirst() when no mapping exists.

bpht_get_type_display_name( string $db_type ): string

Parameters

Name Type Description
$db_type string The ht_type value from the database

Returns: string

Input Output
'activity' 'Activity'
'buddypress' 'Activity'
'bbpress' 'Forums'
'post' 'Post'
'page' 'Page'
'profile' 'Followed'
any other ucfirst( $db_type )

Note: both 'activity' and 'buddypress' return 'Activity'. The database uses 'buddypress' for new rows; 'activity' is a legacy value migrated in plugin version 3.5.2.

echo bpht_get_type_display_name( 'buddypress' ); // Activity
echo bpht_get_type_display_name( 'bbpress' ); // Forums
echo bpht_get_type_display_name( 'custom' ); // Custom

Defined in buddypress-hashtags.php on load.

Constant Description
BPHT_PLUGIN_VERSION Plugin version string (e.g. '3.6.0')
BPHT_DB_VERSION Database schema version string (e.g. '1.1')
BPHT_PLUGIN_FILE Absolute path to the main plugin file
BPHT_PLUGIN_BASENAME Plugin basename (e.g. 'buddypress-hashtag/buddypress-hashtags.php')
BPHT_PLUGIN_URL URL to the plugin directory (trailing slash)
BPHT_PLUGIN_PATH Filesystem path to the plugin directory (trailing slash)

All settings are stored in the bpht_general_settings WordPress option as an array. Read individual keys with a default:

$settings = get_option( 'bpht_general_settings', array() );
$min_length = isset( $settings['min_length'] ) ? (int) $settings['min_length'] : 3;
$max_length = isset( $settings['max_length'] ) ? (int) $settings['max_length'] : 16;
$suggestions_on = ! isset( $settings['enable_hashtag_suggestions'] )
|| $settings['enable_hashtag_suggestions'] === 'yes';
$unicode_on = isset( $settings['allow_non_an_ht'] ) && $settings['allow_non_an_ht'] === 'yes';
$profanity_filter = isset( $settings['prevent_profanity_hashtags'] )
&& $settings['prevent_profanity_hashtags'] === 'yes';

Important: inverted-logic keys. Three settings use “disable_X” naming for backward-compatibility reasons. The key is present in the array when the feature is disabled; absent when the feature is enabled.

Key Present in array Absent from array
disable_on_bbpress Hashtag support in bbPress is OFF Hashtag support in bbPress is ON
disable_on_blog_posts Hashtag support on posts/pages is OFF Hashtag support on posts/pages is ON
disable_follow_hashtag Follow hashtag feature is OFF Follow hashtag feature is ON
$bbpress_enabled = ! isset( $settings['disable_on_bbpress'] );
$blog_posts_enabled = ! isset( $settings['disable_on_blog_posts'] );
$follow_enabled = ! isset( $settings['disable_follow_hashtag'] );

On a multisite network where the plugin is network-activated, use get_site_option():

$settings = is_multisite() && is_plugin_active_for_network( plugin_basename( BPHT_PLUGIN_FILE ) )
? get_site_option( 'bpht_general_settings', array() )
: get_option( 'bpht_general_settings', array() );

These functions run automatically and are not intended for direct calls from external code. They are documented here for completeness.

Hooked to init. Migrates hashtag data from the legacy bpht_hashtags and bpht_bbpress_hashtags WordPress options into the bpht_hashtags custom table. Runs on every page load but writes only rows that do not already exist. Safe to leave in place.

bpht_migrate_hashtag_display_names_to_types()

Section titled “bpht_migrate_hashtag_display_names_to_types()”

Hooked to admin_init. One-time migration (guarded by bpht_type_migration_version option). Corrects ht_type values that were accidentally stored as display names ('Activity', 'Forums', etc.) instead of type codes ('activity', 'bbpress', etc.). Introduced in version 3.5.2.

Hooked to init. One-time cleanup (guarded by bpht_emoji_cleanup_version option). Removes rows from both custom tables where the hashtag name matches an emoji HTML-entity hex pattern (e.g. x1f60d) or a 4–6 digit decimal pattern. Introduced in version 3.5.4.

Source: buddypress-hashtags.php (main plugin file, lines 100-161)

Registered as the activation hook callback and also called by bpht_check_db_upgrade(). Creates or upgrades both custom tables using dbDelta(). Safe to call multiple times — dbDelta() is idempotent.