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 |