Subscribe2, just like WordPress, provides several API (Application Programming Interface) hooks to allow users and developers to modify the way the plugin works. This page aims to document the available hooks.

s2_excerpt_length – allows the length of the default excerpt to be modified. the default is approximately 55 words. Example code to change the excerpt length is as follows:

function my_excerpt() {
    // return whatever number of words you want the excerpt length to be
    return 30;
add_filter( 's2_excerpt_length', 'my_excerpt' );

s2_email_subject – allows the email subject to be changed at the point of sending. This is a global filter affecting all emails sent by Subscribe2 so you will probably want to do some string checks before making changes.

function my_email_subject( $subject ) {
    if ( strstr( $subject, 'Digest' ) ) {
        $subject = 'My Preferred Email Subject for Digest Emails';
    return $subject;
add_filter( 's2_email_subject', 'my_email_subject' );

s2_post_types – allows the registration of Custom Post Types in Subscribe2 so that notifications can be sent for new posts created in such a custom post type. This hook may need to be used with the ‘s2_taxonomies’ hook details next.

function my_post_types( $types ) {
    $types[] = 'my_post_type';
    return $types;
add_filter( 's2_post_types', 'my_post_types' );

s2_post_statuses – allows the registration of custom post statuses in Subscribe2 so that notifications can be sent for transitions from these statuses to published content. For example, this is useful when using the Edit Flow plugin which creates some custom statuses

function my_post_statuses( $statuses ) {
    $statuses[] = 'assigned';
    $statuses[] = 'in-progress';
    return $statuses;
add_filter( 's2_post_statuses', 'my_post_statuses' );

s2_taxonomies – allows the registration of Custom Taxonomies in Subscribe2 so that notifications assigned to such custom taxonomies can still generate an email notification.

function my_taxonomy_types( $taxonomies ) {
    $taxonomies[] = 'my_taxonomy_type';
    return $taxonomies;
add_filter( 's2_taxonomies', 'my_taxonomy_types' );

s2_capability – allows access to the Subscribe2 menu pages to be restricted or relaxed as users see fit. Each page has an individual slug for identification. Based on the slug the default user capability can be changed to allow lower level users to access the page or to block access for all but the highest level users. The WordPress Codex contains a list of capabilities associated with the default roles.

function s2_admin_changes( $capability, $menu ) {
    // $capability is the core WordPress capability to allow admin page access
    // $menu is the title of the page:
    //  'user' for access to personal subscription settings
    //  'manage' to allow access to the user management screen
    //  'settings' to allow access to the plugin settings
    //  'send' for access to the Send Email page

	// identify the menu you are changing capability for first
	// then return a new capability
	if ( $menu == 'send' ) {
		return 'read';

	return $capability;

add_filter( 's2_capability', 's2_admin_changes', 10, 2 );

s2_admin_email – Subscribe2 can be configured to send an email to all Administrator level users every time a public subscriber subscriber or unsubscribes. You may want to send these emails but change the list of recipients. The ‘s2_admin_email’ makes that possible.

The hook takes two variables, the list of recipients in array form and the type of email being sent. You can amend the array or completely replace it. You can also carry out different actions for the two email types.

function my_admin_filter( $recipients = array(), $email ) {
    // $recipients is an array of admin email addresses
    // $email will be 'subscribe' or 'unsubscribe'
    if ( $email == 'subscribe' ) {
        foreach ( $recipients as $key => $email ) {
            if ( $email == 'admin@mysite.com' ) {
                unset( $recipients[ $key ] );
        $recipients[] = 'different.user@mysite.com';
    return $recipients;
add_filter( 's2_admin_email', 'my_admin_filter', 10, 2 );

s2_clean_interval – Version 9.0 of Subscribe2 introduced an automated cleaning feature that deletes unconfirmed public subscribers from the database 28 days after the email address was entered. This hook allows the duration to be change or for this feature to be turned off.

function my_cleaner_interval() {
	// return the number of days before removal
	// returning 0 turns this feature off
	return 14;
add_filter( 's2_clean_interval', 'my_cleaner_interval' );

s2_reminder_interval – Version 10.10 of Subscribe2 introduced an automated reminder email feature that sends a reminder email to unconfirmed public subscribers two days after the email is originally entered. This hook allows the duration to be change or for this feature to be turned off.

function my_reminder_interval() {
	// return the number of days before removal
	// returning 0 turns this feature off
	return 7;
add_filter( 's2_reminder_interval', 'my_reminder_interval' );

These hooks allow the list of recipients (who will be Registered Subscribers) to be amended immediately prior to the email notification being sent. These hooks are quite useful to sites running role management plugins. Each of these filters passes 2 arguments. The first is an array of recipient email addresses and the second if the post ID number.

Based upon your desired functionality you can collect and assess information related to the post via the post ID number and then add recipients to or remove recipients from the email address array.

function s2member_filter( $subscribers, $post_id ) {
	// $subscribers is an array of subscriber email addresses
	$args = array(
		'role' => 's2member_level1',
		'fields' => array( 'user_email' )
	$s2_level1 = get_users($args);

	$args = array(
		'role' => 's2member_level2',
		'fields' => array( 'user_email' )
	$s2_level2 = get_users($args);

	$args = array(
		'role' => 's2member_level3',
		'fields' => array( 'user_email' )
	$s2_level3 = get_users( $args );

	$all_s2_members = array_merge( $s2_level1, $s2_level2, $s2_level3 );

	foreach ( $all_s2_members as $user ) {
		$s2members[] = $user->user_email;

	// we can do thins with the $postid also
	// like amend the subscribers list of the post id is in a specific category
	$categories = wp_get_post_categories( $post_id );
	if ( in_array( '1', $categories ) ) {
		//The post is in category 1 so do something different

	$filtered_subscribers = array_intersect($subscribers, $s2members);
} // end s2member_filter()

add_filter( 's2_send_plain_excerpt_subscribers', 's2member_filter', 10, 2 );
add_filter( 's2_send_plain_fullcontent_subscribers', 's2member_filter', 10, 2 );
add_filter( 's2_send_html_excerpt_subscribers', 's2member_filter', 10, 2 ;
add_filter( 's2_send_html_fullcontent_subscribers', 's2member_filter', 10, 2 );

s2_send_public_subscribers – works in an identical way to the four listed above however it applies to Public Subscribers only.

s2_registered_subscribers – filters the collection of Registered users from the database. As such is would impact on all email to registered users (see hooks above) as well as display in the admin area. It may be useful for adding your own email address to the list of recipients for testing.

s2_subscribe_confirm – allows the message displayed to a newly subscribing user that is displayed (after clicking the confirmation link in their email) to be customised.

function subscribe_change( $message ) {
	// default message is 'You have successfully subscribed!'
	$message .= 'A warm welcome to my blog. I hope you enjoy my email notifications and find them useful.';
	return $message;
add_filter( 's2_subscribe_confirmed', 'subscribe_change' );

s2_unsubscribe_confirm – allows the message displayed to a newly unsubscribing user that is displayed (after clicking the confirmation link in their email) to be customised.

function unsubscribe_change( $message ) {
	// default message is 'You have successfully unsubscribed!'
	$message .='I'm sorry to see you leave and I hope you found the emails useful.'
	return $message;
add_filter( 's2_unsubscribe_confirmed', 'unsubscribe_change' );

s2_confirm_subscribe_class – introduced in version 12.7. Allows button class to be filtered to enable local styling.

function unsubscribe_change( $message ) {
	// default message is 'You have successfully unsubscribed!'
	$message .='I'm sorry to see you leave and I hope you found the emails useful.'
	return $message;
add_filter( 's2_unsubscribe_confirmed', 'unsubscribe_change' );

s2_confirm_email – introduced in version 9.1. It allows the confirmation email containing the confirmation link to subscribe or unsubscribe to be filtered. The filter allows for differentiation between subscribers and unsubscribes. It also allows for alteration or a complete change of the email template defined in Subscribe2->Settings under the Templates tab.

function change_confirm( $body, $action ) {
	// $body is the template email text from the Subscribe2->Settings page in the Templates tab
	// $action is '1' if the action is subscribing and '0' if the action is unsubscribing
	// you can append to the $body variable, use string replace functions to return an entirely different template
	return $body . 'This is some extra added text from the extension function';
add_action( 's2_confirm_email', 'change_confirm', 10, 2 );

s2_confirm_link – allows the base URL for confirmation links to be changed. This can be useful when blogs are in site subdomains, for example your site URL is example.com but your blog is at example.com/blog

function change_confirm_link( $link ) {
	$link = 'http://www.example.com/blog/?s2=';
	return $link;
add_filter( 's2_confirm_link', 'change_confirm_link' );

These hooks allow the default button text to be changed without editing the code or any used translation files.

function change_subscribe_button_text() {
	// return your preferred button text
	return 'My Preferred Button Text';
add_filter( 's2_subscribe_button', 'change_subscribe_button_text' );

s2_form – this hook allows the Subscribe2 form output to be dynamically altered to suit the needs of an individual site.

function my_s2_form( $form ) {
	// To remove the 'Your Email:' prompt text from the form
	$form = str_replace( 'Your email:', '', $form );
	return $form;
add_filter( 's2_form', 'my_s2_form' );

s2_ajax_form – allows the Subscribe2 form output to be dynamically altered to suit the needs of an individual site but applies only to the AJAX popup form.

function my_s2_ajax_form( $form ) {
	// To remove the 'Your Email:' prompt text from the form
	$form = str_replace( 'Your email:', '', $form );
	return $form;
add_filter( 's2_ajax_form', 'my_s2_ajax_form' );

s2_authors – allows the display list of content authors to be refined. For example, old and unused author accounts can be removed from the list without the need to delete the user account.

function remove_author( $authors ) {
	// our function takes an array of author objects as the input
	// you can then cycle through the array and remove any that you like on either 'ID' or 'display_name'
	$i = 0;
	foreach ( $authors as $author ) {
		// example use an if statement to check if author ID should be removed compared to a known ID
		if ( $author->ID == 1 ) {
			unset( $authors[ $i ] );
	return $authors;
add_filter( 's2_authors', 'remove_author' );

These hooks allow the entire content of the email to be filter and amended immediately prior to sending. An example use for the ‘s2_html_email’ hook to add a stylesheet is below.

function my_s2html_filter( $message ) {
	if ( empty($message) ) { return; }
	list($first, $second) = explode('', $message, 2);
	$message = $first . '' . $second;
	return $message;
add_filter( 's2_html_email', 'my_s2html_filter' );

s2_word_wrap – by default Subscribe2 wraps the plain text emails at a count of 78 characters. This can be change if you desire. Bear in mind that internet email standards recommend that line length should not be more than 78 and must not be more than 998.

function my_s2_word_wrap() {
	return 100;
add_filter( 's2_word_wrap', 'my_s2_word_wrap' );

s2_jqueryui_css – When AJAX mode is enabled in Subscribe2 the usual form is replaced by a jQuery UI mods box. jQuery UI has many CSS themes to choose from and this hook allows you to easily use another CSS style from a CDN.

function custom_ajax_css() {
    return 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/ui-lightness/jquery-ui.css';
add_filter( 's2_jqueryui_css', 'custom_ajax_css' );

s2_email_headers – allows you to alter or remove the email headers subscribe2 uses at the time of sending. Headers include ‘From’, ‘Reply-To’, ‘Return-path’, ‘Precedence’ and ‘Content-Type’. If your hosting provider does not allow use of the ‘Reply-To’ header you an use code like this:

function my_s2_headers( $header ) {
	unset( $header['Reply-To'] );
	return $header;
add_filter( 's2_email_headers', 'my_s2_headers' );

s2_email_template – allows manipulation of the email template without editing it in the settings. as an example, it may prove useful on Multisite installs to add site wide text to the end of all emails.

function my_s2_template( $template ) {
	$template .= 'Some additional text I would like at the end';
	return $template;
add_filter( 's2_email_template', 'my_s2_template' );

s2_allow_site_switching – This hook is for Multisite installs. By default this is switch off to suppress sending emails when Multisite switches blogs and copies over content from one blog to another as this can result in duplicated emails. You can choose to reverse the default setting if you wish.

function my_site_switching() {
	return true;
add_filter( 's2_allow_site_switching', 'my_site_switching' );

s2_social_links – introduced in version 9.3 of Subscribe2. It is now possible to add social sharing links to the HTML notifications. Facebook and Twitter are enabled by default. If you prefer to switch this feature off you need the following code. Social Links uses the AddThis service and therefore offer a wide selection of available services.

function s2_social_links_off() {
	return array();
add_filter( 's2_social_links', 's2_social_links_off' );

Or if you prefer you can turn either Facebook or Twitter off and turn Google on. The following code for example adds Google and turns Facebook off.

function s2_social_twitter() {
	return array( 'twitter' );
add_filter('s2_social_links', 's2_social_twitter');

Subscribe2 includes Facebook and Twitter by default with only the former two activated. If you want to add your own additional social sharing sites you need to use the ‘s2_social_buttons’ filter. Have a look at the social_buttons() function in the class-s2-core.php file to see how this can be done.

s2_custom_keywords – introduced in version 9.3 of Subscribe2. It allows for developers to add their own custom keywords to Subscribe2 for inclusion in the notification template. The following code adds a {BITLYLINK} keyword to use in place of the current {PERMALINK} or {TINYLINK} keywords.

function bitly_keyword( $string, $token = 'PUT YOUR API TOKEN HERE' ) {
	global $mysubscribe2;
	$link = $mysubscribe2->get_tracking_link( $mysubscribe2->permalink );
	$bitlydata = wp_remote_get('https://api-ssl.bitly.com/v3/shorten?access_token=' . $token . '&longUrl=' . urlencode($link));
	$data = json_decode( wp_remote_retrieve_body( $bitlydata ) );
	if  ( 'ok' === strtolower( $data->status_txt ) && 200 === (int) $data->status_code ) {
		$bitlylink = '<a>data->url . '">' . $data->data->url . '</a>';
	} else {
		$bitlylink = '<a href="' . $link . '">' . $link . '</a>';
	return str_replace( '{BITLYLINK}', $bitlylink, $string );
add_filter( 's2_custom_keywords', 'bitly_keyword' );

s2_public_subscriber_format – available in Subscribe2 HTML only. It allows the email type of Public Subscribers to be changed. By default in Subscribe2 HTML the email type is full content HTML, in the free version of Subscribe2 is it a plain text excerpt. Using this hook the email type can be specified at site level.

function my_preferred_format() {
	// return one of the possible email types:
	// 'html_body' for a full content HTML email
	// 'html_excerpt_body' for an excerpt in HTML format
	// 'plain_body' for a full content plain text email
	// 'plain_excerpt_body' for an excerpt in plain text format
	return 'html_excerpt_body';
add_filter( 's2_public_subscriber_format', 'my_preferred_format' );

s2_lockout – Each time the form is used to subscribe a new email address the IP address is logged. If an IP address is adding lots of email address to your site you can set a time limit that needs to elapse between address submissions with this hook.

function lockout_period() {
	// number of seconds between data submits
	// default is 0 which disables this feature
	// 0 to 86399 are acceptable - 84399 is essentially a day
	return 86399;
add_filter( 's2_lockout', 'lockout_period' );

s2_image_size – allows images inserted to replace the {IMAGE} keyword to be resized. Default WordPress sizes can be used to physical sizes can be passed in an array.

function my_s2_image_size() {
	// return a pre-defined size like 'thumbnail' or 'full'
	// or return a physical size as an array like array(300, 300) or array(150, 150)

	// examples:
	return 'thumbnail';
	return 'full';
	return array( 300, 300 );
add_filter( 's2_image_size', 'my_s2_image_size' );

These hooks allow site specific styling and text wrapping to be applied to the URI links generated by the {UNSUBLINK} keyword.

function custom_public_unsublink( $link, $email_type ) {
	if ( 'text' === $email_type ) {
		return "To unsubscribe click here:\r\n" . $link;
	} else {
		return 'To unsubscribe click here:
<a href="' . $link . '">' . $link . '</a>';
add_filter( 's2_unsublink_public', 'custom_public_unsublink', 10, 2 );

function custom_registered_unsublink( $link, $email_type ) {
	if ( 'text' === $email_type ) {
		return "You may manage your subscription options from your profile\r\n" . $link;
	} else {
		return sprintf( 'You may manage your subscription options from your <a href="%s">profile</a>', $link );
add_filter( 's2_unsublink_registered', 'custom_registered_unsublink', 10, 2 );

s2_sanitize_email – allows email address passed through the Subscribe2 HTML sanitise_email() function to be filtered. I get asked about emails from time to time because Subsribe2 HTML complies fully with RFC3521; treating the user part of the email before the @ as case sensitive. Some people don’t like this, so this filter is a solution.

function my_s2_sanitize_email( $email ) {
	// return a filtered email address, for example with all letters in lower case

	return strtolower( $email );
add_filter( 's2_sanitize_email', 'my_s2_sanitize_email' );

s2_remote_embed_host – allows control over embedding of images from remote hosts when generating emails. In some circumstances you may not want to embed the remote image – perhaps due to slow performance from the remote server.

function disallowed_host( $allowed, $host ) {
	// return false; // if you want to link rather than embed all remote images
	if ( 's.w.org' === $host ) {
		$allowed = false;
	return $allowed;
add_filter( 's2_remote_embed_host', 'disallowed_host', 10, 2 );

s2_subscriber_dropdown_default – allows the default selection in the subscriber drop down on the Send Email page to be changed. By default ‘registered’ which selects Registered Subscribers. Other options are ‘all’, ‘public’, ‘confirmed’, ‘unconfirmed’ and ‘all_users’. Respectively these are All Registered Users and Public Subscribers, all Public Subscribers, only Confirmed Public Subscribers, only Unconfirmed Public Subscribers and All Registered Users.

function my_preferred_default( ) {
	// return 'all' or 'public' or 'confirmed' or 'unconfirmed' or 'all_users'
	return 'public';
add_filter( 's2_subscriber_dropdown_default', 'my_preferred_default' );

s2_captcha_element – Introduced in Version 11, this filter allows adjustments to be made to the display of the ReCaptcha form element if needed.

function align_captcha_left( $element, $site_key, $shortcode_args ) {
	// Below code amends badge to compact size of form is from Widget
	if ( 'true' === $shortcode_args['widget']  ) {
		$element = str_replace( 'data-sitekey=', 'data-size="compact" data-sitekey=', $element );
	return $element;
add_filter( 's2_captcha_element', 'align_captcha_left', 10, 3 );

s2_recaptcha_lang – Introduced in Version 11, this filter allows the preferred language for the ReCaptcha for element to be changed.

function my_recaptcha_lang( $lang ) {
	// Language codes are listed at https://developers.google.com/recaptcha/docs/language
	return 'de';
add_filter( 's2_recaptcha_lang', 'my_recaptcha_lang' );

s2_excerpt_on_words – Introduced in Version 11.5, this filter allows the excerpt to be generated on character count rather than words. This may be particularly useful for languages that use very few spaces the grammar construct – for example Japanese. By default written Excerpts are used first, content before an HTML <!–more–> tag second and the first 55 words of the main content as a final option. This filter alters the final option to use the first 55 characters instead of words. You can alter the length of the excerpt using the ‘s2_excerpt_length’ filter.

add_filter( 's2_excerpt_on_words', '__return_false' );