Skip to content

Developer Docs ​

Convocept is built to be extended: every major step fires an action or filter, the front end talks to a small REST API, and every piece of markup comes from a template your theme can override. Everything on this page is public API.

PHP examples can go in your theme's functions.php or a small plugin.

Architecture overview ​

Convocept renders the thread in PHP and sends rendered HTML over REST, so markup is never duplicated in JavaScript. The public front end runs vanilla JavaScript only, loaded lazily; the settings screen is a React app in wp-admin.

Everything is prefixed convocept: the PHP namespace Convocept\, hooks, options, meta keys and tables convocept_, CSS classes and custom properties convocept-, and the REST namespace convocept/v1.

WhereWhat is stored
wp_comments / wp_commentmetaComments, as WordPress stores them. Meta: upvote counts and scores, pins, edit time, format, moderation log.
wp_convocept_subscriptionsEmail subscriptions.
wp_convocept_reactionsUpvotes, one row per reader and comment.
convocept_settings optionEvery setting.

The recommended way to extend Convocept:

  1. Hook into convocept_loaded, which fires once Convocept has registered its own hooks on plugins_loaded.
  2. Use the documented actions and filters.
  3. Register default values for your own settings with convocept_settings_defaults, and add a page to the settings screen with registerPanel.

Examples ​

Leave one category with the theme's comments:

php
add_filter( 'convocept_enabled', function ( $enabled, $post_id ) {
	return $enabled && ! has_category( 'announcements', $post_id );
}, 10, 2 );

Add a "Member" badge for logged-in authors:

php
add_filter( 'convocept_comment_badges', function ( $badges, $comment ) {
	if ( $comment->user_id ) {
		$badges[] = array(
			'label' => __( 'Member', 'my-theme' ),
			'type'  => 'member',
		);
	}
	return $badges;
}, 10, 2 );

Purge a page cache after settings change:

php
add_action( 'convocept_settings_saved', function () {
	if ( function_exists( 'rocket_clean_domain' ) ) {
		rocket_clean_domain();
	}
} );

Actions ​

HookSinceArgsFires
convocept_loaded1.0.0Plugin $pluginAfter Convocept registers its hooks on plugins_loaded. Add-ons register here.
convocept_activated1.0.0—After activation and migrations.
convocept_deactivated1.0.0—After deactivation cleanup.
convocept_uninstalled1.0.0bool $delete_dataAfter uninstall cleaned up a site (runs per site on multisite).
convocept_migrated1.0.0int $version, string $classAfter each database migration is applied.
convocept_render_thread_header1.0.0Thread $threadTop of the thread, before the header. For summaries and notices.
convocept_render_badges1.0.0WP_Comment $commentAfter a comment's badges, in its header.
convocept_render_comment_actions1.0.0WP_Comment $commentInside a comment's action bar, after Reply.
convocept_render_comment_footer1.0.0WP_Comment $commentEnd of a comment, before its replies.
convocept_render_composer_after1.0.0int $post_idAfter the comment form, inside the composer.
convocept_comment_created1.0.0int $comment_id, int|string $approved, Context $contextAfter a comment is created through Convocept (REST or our form).
convocept_comment_edited1.0.0WP_Comment $commentAfter a comment is edited through Convocept.
convocept_reaction_added1.0.0int $comment_id, string $reaction, int $countAfter a visitor upvotes (reaction up).
convocept_comment_status_changed1.0.0int $comment_id, string $actionAfter front-end moderation (approve, hold, spam, trash).
convocept_comment_pinned1.0.0int $comment_id, bool $pinnedAfter a comment is pinned or unpinned.
convocept_subscription_confirmed1.0.0int $subscription_idAfter a reader confirms a subscription.
convocept_unsubscribed1.0.0int $subscription_id, bool $allAfter a reader unsubscribes (one or all).
convocept_comment_imported1.0.0int $comment_id, string $source, array $itemAfter an importer creates a comment ($source e.g. disqus).
convocept_import_completed1.0.0Job $jobWhen an import finishes (counters in $job->counts).
convocept_settings_saved1.0.0array $new, array $oldAfter the settings screen saves. Page caches may still hold older pages; purge here.

Filters ​

HookSinceValuePurpose
convocept_settings_defaults1.0.0array $defaultsRegister default values for add-on settings keys.
convocept_cron_hooks1.0.0string[] $hooksWP-Cron hooks cleared on deactivation. Add-ons append theirs.
convocept_enabled1.0.0bool $enabled, int $post_idWhether Convocept replaces a post's comments.
convocept_thread_query_args1.0.0array $args, int $post_id, string $sort, int $pageWP_Comment_Query args for a thread page.
convocept_excluded_comment_types1.0.0string[] $typesComment types never shown (default pingback, trackback).
convocept_thread_template_args1.0.0array $args, Thread $threadData passed to thread.php.
convocept_thread_header_args1.0.0array $args, Thread $threadData passed to thread-header.php (thread, sort links, Follow link).
convocept_thread_classes1.0.0string[] $classes, int $post_idCSS classes on the thread wrapper.
convocept_comment_view1.0.0array $view, WP_Comment $commentView data passed to comment.php.
convocept_comment_badges1.0.0array $badges, WP_Comment $commentBadges next to the author name (label, type).
convocept_locate_template1.0.0string $path, string $nameResolved path of a template.
convocept_comment_content1.0.0string $html, WP_Comment $commentRendered comment content.
convocept_before_submit1.0.0WP_Error|null $error, array $data, Context $contextReturn a WP_Error to reject a submission (message shown, status used).
convocept_moderation_checks1.0.0array<string, callable> $checksModeration checks; each gets (array $commentdata, Context $context) and returns a Decision or null.
convocept_min_submit_seconds1.0.0float $secondsMinimum time between the form appearing and submitting (default 3; 0 disables).
convocept_rate_limit1.0.0int $limit, string $action, int $windowAdjust or disable (0) a rate limit.
convocept_session_data1.0.0array $data, WP_REST_Request $requestSession data sent to the script.
convocept_front_config1.0.0array $configStatic script configuration (never per-visitor).
convocept_front_modules1.0.0string[] $scriptsScripts the inline loader injects after Convocept's (lazy add-on modules).
convocept_inline_css1.0.0string $cssInline stylesheet; return '' to style the thread yourself.
convocept_thread_html1.0.0string $html, int $post_idComplete thread HTML (assets are added here).
convocept_fragment_cache1.0.0bool $enabledWhether rendered comment lists are cached.
convocept_mailer1.0.0bool|null $sent, array $messageSend an email yourself (return true/false) instead of wp_mail().
convocept_should_notify1.0.0bool $notify, WP_Comment $commentWhether subscribers hear about a comment (importers return false).
convocept_structured_data_enabled1.0.0bool $enabled, int $post_idWhether a post's comments are described in JSON-LD (setting structured_data).
convocept_structured_data_comments1.0.0array $items, int $post_id, Thread $threadThe Comment items (replies nested under comment); runs after the cache.
convocept_structured_data_node1.0.0array $node, int $post_idStandalone article node printed in the footer when no SEO plugin graph carries the comments; [] prints nothing.
convocept_importers1.0.0array<string, Importer> $importersAdd import sources (Tools → Import and wp convocept import).
convocept_import_batch_size1.0.0int $limit, string $importerItems per import batch (default 500 in wp-admin, --batch-size in WP-CLI).
convocept_disqus_thread_post_id1.0.0int $post_id, array $threadPost a Disqus thread's comments go into; 0 skips the thread.
convocept_disqus_comment_data1.0.0array $commentdata, array $postComment data before a Disqus comment is inserted; [] skips it (e.g. set user_id).
convocept_settings_schema1.0.0array $schemaJSON schema per setting key (type, minimum, maximum, enum, pattern); validates the settings route and sets the screen's limits.
convocept_admin_boot_data1.0.0array $dataData the settings app starts with (window.convoceptAdminBoot).

REST routes (/wp-json/convocept/v1) ​

RouteMethodAccessPurpose
/sessionGETpublicWho is visiting: login state, name, REST nonce, moderator flag.
/posts/{id}/commentsGETpublicOne page of top-level comments (page, sort); returns html, page, pages, total.
/posts/{id}/commentsPOSTpublic (core rules apply)Create a comment (token: the form's signed convocept_token; without it the comment is held by the timing check); returns id, status, html, edit_token, edit_until, total, count_text (the heading, with the language's plural form).
/comments/{id}GETauthor in window / moderatorMarkdown source for the edit form. Guests send the edit token in an X-Convocept-Edit-Token header.
/comments/{id}PATCHauthor in window / moderatorEdit; returns id, status, html.
/previewPOSTpublic, rate-limitedRender Markdown; returns html.
/subscriptionsPOSTpublic, rate-limitedSubscribe without commenting (email, post_id 0 = site); same answer for every address.
/posts/{id}/updatesGETpublicComments newer than after; ETag + 304 when unchanged. Returns items, total, count_text.
/comments/{id}/repliesGETpublic (approved)Replies after offset; returns html, remaining, more_text (the "Show N more replies" label, or '').
/comments/{id}/reactionsPOSTpublic, rate-limitedactive true/false toggles the visitor's upvote; returns count, active.
/comments/{id}/moderatePOSTmoderate_comments + edit_commentaction: approve, hold, spam, trash; returns status, html.
/comments/{id}/pinPOSTmoderate_comments + edit_commentpinned true/false; top-level approved comments only.
/posts/{id}/pendingGETmoderate_comments + edit_postComments awaiting moderation, rendered.
/comments/{id}/contextGETpublic (approved)URL of the page showing the comment; returns url.
/settingsGETmanage_optionsEvery setting.
/settingsPOSTmanage_optionssettings: changed keys only. 400 with data.fields (message per key) and nothing saved when any value is invalid; else the complete new settings.
/importGETimport + moderate_commentsCurrent import job (or null), importers, upload limit.
/importPOSTimport + moderate_commentsMultipart file + importer: store the export privately and run the dry run.
/import/batchPOSTimport + moderate_commentsImport the next batch; returns the job.
/importDELETEimport + moderate_commentsCancel the import, or clear a finished one.

Settings screen (JavaScript) ​

  • window.convoceptAdmin.registerPanel( { id, group, title, icon, keys, render } ) — add a page to Comments → Convocept. group is settings, manage or more; keys are the settings the page edits (used to flag errors in the sidebar); render is a component receiving { draft, saved, update, errors, boot }. Enqueue the script with convocept-admin as a dependency; pages are read when the DOM is ready.

WP-CLI ​

See WP-CLI.

Query variables ​

  • convocept_sort — oldest, newest or top.
  • convocept_expand — top-level comment ID whose whole reply branch is shown.

Shortcode and block ​

  • [convocept_subscribe] — "subscribe without commenting" for the current post; [convocept_subscribe scope="site"] for every post; post_id="123" for a specific post.
  • Block Comment Subscription (convocept/subscribe) with the same post/site setting.

Templates ​

Copy any file from templates/ to {theme}/convocept/ to override it (see Theming): thread.php, thread-header.php, comment.php, composer.php, pagination.php, subscribe-form.php, subscription-manage.php, emails/confirm.php, emails/confirm-text.php, emails/notification.php, emails/notification-text.php. Each template's docblock lists the $args it receives.