Free Article Limit for Visitors (Metered Paywall)
Lets visitors read a few posts each month for free, then asks them to log in or sign up to keep reading; members always read without limits.
Opens WPIDE on
Code
// Free posts per visitor every 30 days.
$wpide_free_articles = 3;
$wpide_meter_read = array();
add_action( 'template_redirect', function () use ( $wpide_free_articles, &$wpide_meter_read ) {
if ( is_user_logged_in() || ! is_singular( 'post' ) ) {
return;
}
$read = isset( $_COOKIE['wpide_meter'] ) ? array_map( 'absint', explode( '.', sanitize_text_field( wp_unslash( $_COOKIE['wpide_meter'] ) ) ) ) : array();
$read = array_values( array_filter( array_unique( $read ) ) );
$id = get_queried_object_id();
if ( ! in_array( $id, $read, true ) && count( $read ) < $wpide_free_articles ) {
$read[] = $id;
setcookie( 'wpide_meter', implode( '.', $read ), array(
'expires' => time() + 30 * DAY_IN_SECONDS,
'path' => COOKIEPATH ? COOKIEPATH : '/',
'domain' => COOKIE_DOMAIN,
'secure' => is_ssl(),
'httponly' => true,
'samesite' => 'Lax',
) );
}
$wpide_meter_read = $read;
nocache_headers();
} );
add_filter( 'the_content', function ( $content ) use ( $wpide_free_articles, &$wpide_meter_read ) {
if ( is_user_logged_in() || ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
return $content;
}
$id = get_the_ID();
if ( in_array( $id, $wpide_meter_read, true ) ) {
$left = $wpide_free_articles - count( $wpide_meter_read );
return '<p class="wpide-meter-note"><small>' . esc_html( sprintf( _n( '%d free article left this month.', '%d free articles left this month.', $left ), $left ) ) . '</small></p>' . $content;
}
$html = '<p>' . esc_html( wp_trim_words( wp_strip_all_tags( strip_shortcodes( get_post_field( 'post_content', $id ) ) ), 40 ) ) . '</p>'
. '<div class="wpide-meter-wall"><p><strong>You have read your free articles for this month.</strong></p><p><a href="' . esc_url( wp_login_url( get_permalink() ) ) . '">Log in</a>';
if ( get_option( 'users_can_register' ) ) {
$html .= ' or <a href="' . esc_url( wp_registration_url() ) . '">sign up for free</a>';
}
return $html . ' to keep reading.</p></div>';
}, 1 );
Notes
The count is kept in a cookie, so it is a soft wall rather than strict protection. Exclude these posts from full-page caching for visitors, or the limit cannot apply.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.