Skip to content

Hooks and filters

Loveshack exposes filters for the behavior most likely to need site-specific adjustment. Use them from a child theme's functions.php or an MU plugin rather than editing the theme.

Names, not signatures

This page lists the available filters and what each one governs. Check the docblock at the apply_filters() call site for the exact arguments before using one — see the source path noted in each group.

Module loading

Loveshack loads its modules through filtered file lists, which is how a child theme adds or removes an entire module rather than overriding a single function.

Filter Governs
loveshack_theme_files Core theme modules
loveshack_customizer_files Customizer modules
loveshack_template_tag_files Template tag modules
loveshack_subscriber_files Subscriber modules
loveshack_subscriber_admin_files Subscriber admin modules
loveshack_subscriber_digest_files Digest modules
loveshack_subscriber_settings_files Frontend settings modules

A child theme can also override any of these files by placing a file at the same relative path — that path is resolved by loveshack_require_theme_file() and needs no filter at all.

Subscriptions and access

Filter Governs
lss_subscription_tiers The tier definitions
loveshack_user_subscription_tier_ids Which tiers a user holds
loveshack_user_has_subscription_tier_access The final access decision for a tier
lss_access_granting_subscription_statuses Which subscription statuses grant access
lss_frontend_subscription_options Options offered on the frontend
lss_subscriber_settings_sections Sections shown on /settings/
lss_allowed_roles Roles treated as subscribers
lss_user_allowed Per-user allow decision

loveshack_user_has_subscription_tier_access is the single point every gate flows through — the single post view, the private feed, and the digest all consult it. Filtering it changes access everywhere at once, which is exactly why it should be filtered carefully.

Stripe

Filter Governs
lss_stripe_checkout_session_params Parameters sent when creating a Checkout session
lss_stripe_checkout_allow_promotion_codes Whether promotion codes are accepted at checkout

Digests

Filter Governs
lss_digest_excerpt_words Excerpt length in digest emails
lss_digest_max_sends_per_run Cap on emails sent per processing run
lss_digest_post_query_limit Posts queried per digest
lss_digest_user_query_limit Subscribers processed per run
lss_test_notification_post_query_limit Posts queried for test notifications

The two per-run limits are the levers for a large subscriber list: lowering them keeps each cron run short, at the cost of taking more runs to work through the list.

Private feeds

Filter Governs
lss_personal_feed_item_limit Items in a personal feed
lss_personal_feed_query_limit Query size behind that feed

Authentication and email

Filter Governs
lss_token_ttl Lifetime of sign-in tokens
lss_subscribe_minimum_seconds Minimum time before a subscribe submission is accepted
lss_request_throttle_ttl Request throttling window
lss_request_throttle_email_limit Sign-up and sign-in emails one address can receive per hour, across all IPs (default 10)
lss_unconfirmed_cleanup_user_query_limit Batch size for unconfirmed-subscriber cleanup
lss_passwordless_email_headers Headers on passwordless sign-in email
loveshack_passwordless_email_headers Headers on passwordless sign-in email
loveshack_subscribers_email_headers Headers on subscriber email
lss_email_types Email types editable in the Customizer and their default texts
lss_prepared_email A built email before it is sent or previewed

lss_subscribe_minimum_seconds and lss_request_throttle_ttl are anti-abuse controls. Loosening them makes automated sign-up abuse easier; tightening them can reject genuine fast typists.

Stripe

Filter Governs
lss_allow_stripe_customer_replacement Whether a payment may replace the Stripe customer already linked to an account. Off by default, because Checkout does not verify the payer's email
lss_allow_mollie_customer_replacement Whether a payment may replace the Mollie customer already linked to an account. Off by default, because the guest checkout email is not verified
lss_stripe_payment_method_names Display names of Stripe payment method types in the payment methods loaded for the checkout step
lss_stripe_payment_method_currencies Currencies each local Stripe payment method works in. Methods whose currencies none of the tiers use are left out of the checkout step's list

Updates

Filter Governs
loveshack_update_api_username Update API username
loveshack_update_api_application_password Update API Application Password
loveshack_update_api_key Legacy shared API key

These exist so credentials can come from a secrets provider at runtime instead of the database. See Updates.

Content and media

Filter Governs
loveshack_content_width Theme content width
loveshack_post_teaser_image_id Image used for a post teaser
loveshack_file_attachment_post_types Post types offering file attachments
loveshack_video_embed Video embed output
loveshack_link_preview_proxy_request The outbound link-preview request
loveshack_activitypub_social_actor_choices Actor choices offered in the Customizer

Stream post type API

Plugins and child themes add their own post types to the mixed stream with one call, made from the loveshack_register_stream_post_types action so the post type already exists:

add_action( 'loveshack_register_stream_post_types', function () {
    loveshack_register_stream_post_type(
        'my_type',
        array(
            'label'           => __( 'Thing', 'my-plugin' ),
            'source'          => 'My Plugin',
            'stream_template' => MY_PLUGIN_DIR . 'templates/stream-item.php',
            'single_template' => MY_PLUGIN_DIR . 'templates/single.php',
            'markdown'        => true,
        )
    );
} );
Argument Default Governs
label Post type singular name Filter pill and post type label
source Empty Plugin or child theme name shown next to the type under Loveshack → Custom Post Types
stream_template Blog post card Template rendered for each stream item
single_template WordPress resolution Template for the single view
markdown false Text is Markdown
reactions true Accepts reactions, following the All Posts setting
comments true Comment support, open per the site default
author true Author support
feed true Included in RSS feeds, personal feeds, and digest emails
activitypub false ActivityPub support
enabled_default true In the stream until changed under Loveshack → Custom Post Types

Registered types appear as checkboxes under Loveshack → Custom Post Types, with a URL slug field for every type that has an archive slug. A saved slug replaces the one the post type was registered with, and the rewrite rules are rebuilt on the next request. The helpers loveshack_get_stream_post_types(), loveshack_get_registered_stream_post_types(), loveshack_stream_post_type_is_enabled(), and loveshack_get_stream_post_type_label() read the registry.

Filter Governs
loveshack_stream_post_types Post types in the mixed stream
loveshack_feed_post_types Post types in RSS feeds, personal feeds, and digests
loveshack_markdown_post_types Post types whose text is Markdown
loveshack_reaction_post_types Post types that accept reactions
loveshack_reactions_per_user_limit Different reactions one user can leave on a post (default 10)
loveshack_stream_post_type_enabled Whether one registered type is in the stream

Actions

Hook Fires
lss_process_subscriber_digests Every 10 minutes, to process digests
loveshack_register_stream_post_types On init, once post types exist, to register stream post types
loveshack_stream_before_items Before the first item of a stream view, with the view as argument
loveshack_post_reactions_updated After a reaction is added to a post, with the post ID and the URLs that show it, for page caches to purge