Introduction

As a WordPress developer building custom themes, you often need fine-grained control over every pixel and every interaction. When implementing gated content – resources, videos, or pages that require an access request – this need for control becomes even more critical. Generic solutions might offer basic functionality, but they often fall short when it comes to integrating seamlessly with a bespoke theme's design language and user experience.

This article will guide you through the process of detecting locked content programmatically within your WordPress theme and displaying custom markup, styling, and interactive elements. We'll leverage PHP functions and template tags, demonstrating how plugins like WordPress Gatekeeper Pro provide the essential hooks for this level of customisation, allowing you to maintain full design authority.

The Developer's Approach to Gated Content

When content is locked, you don't just want a simple "access denied" message. You might need to:

  • Display a custom overlay on a resource card in an archive loop.
  • Replace the main content area with a branded access request form.
  • Show a unique call-to-action button that aligns with your theme's aesthetic.
  • Apply specific CSS styles to locked elements, like a blurred image or a "locked" badge.

Achieving this requires direct access to the content's "locked" status from within your theme's PHP template files. This is where dedicated template tags and conditional logic become invaluable, enabling true wordpress custom theme restricted content integration.

Leveraging Gatekeeper Pro for Detection

WordPress Gatekeeper Pro is designed with developers in mind, offering a robust set of PHP functions and template tags. These tools empower you to query the locked status of any post or custom post type directly within your theme. The core idea is to use conditional logic: "If this content is locked, show X; otherwise, show Y."

The primary function we'll focus on for detection is a variation of SauceCode\Gatekeeper\Core\Gate::is_content_locked( $post_id ), which checks if a specific post is marked as locked by the plugin. There are also template tags like gatekeeper_pro_is_locked( $post_id ) for simpler usage in theme files. For checking if a user *currently* has access to a resource, you can use gatekeeper_pro_has_access( $post_id ), which is often the inverse of gatekeeper_pro_is_locked().

Step-by-Step Tutorial: Implementing Custom Markup

Let's walk through integrating custom markup into a single post template (e.g., single.php or single-your_custom_post_type.php) or a content part (e.g., content-single.php).

Step 1: Identify Your Target Content and Template File

First, determine where you want to implement the custom logic. This is typically:

  • Single Post/Page Templates: For individual content items (e.g., single.php, page.php, or custom post type templates like single-whitepaper.php).
  • Archive/Loop Templates: For lists of content (e.g., archive.php, category.php, or template parts used within a WP_Query loop).

For this tutorial, we'll assume we're modifying a single post template to either display the content or a custom gated experience.

Step 2: Check for Gatekeeper Pro Activation (Optional but Recommended)

Before calling any plugin-specific functions, it's good practice to ensure the plugin is active. This prevents fatal errors if the plugin is deactivated.

<?php
if ( function_exists( 'gatekeeper_pro_is_locked' ) ) {
    // Gatekeeper Pro is active, proceed with logic
} else {
    // Gatekeeper Pro is not active, display default content or a fallback message
    the_content();
}
?>

Step 3: Detect Locked Status with Template Tags

Within your chosen template file, you'll use the gatekeeper_pro_is_locked() template tag to check the status of the current post. This function takes an optional post ID; if omitted, it defaults to the current post in the loop.

<?php
global $post; // Ensure $post is available
$is_locked = false;

if ( function_exists( 'gatekeeper_pro_is_locked' ) ) {
    $is_locked = gatekeeper_pro_is_locked( $post->ID );
}

if ( $is_locked ) {
    // Content is locked, show custom gated experience
} else {
    // Content is not locked, or has been unlocked for the current user, show actual content
}
?>

Gatekeeper Pro handles the complexities of checking for valid access tokens, whether they are per-item or sitewide, and whether they've expired. The gatekeeper_pro_is_locked() function provides a straightforward boolean result, making your wordpress php content gating logic clean. Alternatively, gatekeeper_pro_has_access( $post->ID ) can be used to explicitly check if the current visitor holds an approved token for that content.

Step 4: Implement Custom Markup for the Locked State

Now, inside the if ( $is_locked ) { ... } block, you can output any HTML markup you desire. This allows for complete wordpress custom theme restricted content design control.

<?php if ( $is_locked ) : ?>
    <div class="gatekeeper-custom-lock-overlay">
        <span class="lock-icon">🔒</span>
        <h3 class="lock-title">This Content is Restricted</h3>
        <p class="lock-message">Please submit an access request to view this exclusive resource.</p>
        <div class="gatekeeper-request-form-wrapper">
            <?php
            // Display the Gatekeeper Pro access request form
            // You can use the shortcode or the dedicated PHP function:
            // echo do_shortcode( '[gatekeeper_pro_request_form post_id="' . $post->ID . '"]' );
            if ( function_exists( 'gatekeeper_pro_display_request_form' ) ) {
                gatekeeper_pro_display_request_form( $post->ID );
            }
            ?>
        </div>
    </div>
<?php else : ?>
    <!-- Content is unlocked, show the actual post content -->
    <div class="entry-content">
        <?php the_content(); ?>
    </div>
<?php endif; ?>

In this example, we've created a custom div with specific classes. Inside, we've added a lock icon, a title, a message, and most importantly, the Gatekeeper Pro access request form via its dedicated PHP function. The post ID ensures the form is tied to the correct locked resource.

Step 5: Implement Custom Markup for the Unlocked State

The else block is where you display the actual content. Gatekeeper Pro automatically manages access tokens; once a user has an approved token, gatekeeper_pro_is_locked() will return false for them, allowing your theme to show the content as normal.

For more nuanced control, you might also use gatekeeper_get_the_status( $post_id ) which returns the specific status (e.g., 'pending', 'approved', 'disapproved', 'unlocked', 'locked'). This allows you to differentiate between a user who has requested access but is pending, and one who simply hasn't requested yet. When content is unlocked, you can also use template tags like gatekeeper_pro_get_download_url() or gatekeeper_pro_get_video_url() to securely serve protected files or stream videos.

<?php if ( $is_locked ) : ?>
    <!-- ... (Locked state markup from Step 4) ... -->
<?php else :
    $current_status = '';
    if ( function_exists( 'gatekeeper_get_the_status' ) ) {
        $current_status = gatekeeper_get_the_status( $post->ID );
    }

    if ( 'pending' === $current_status ) : ?>
        <div class="gatekeeper-custom-pending-message">
            <p><strong>Your access request is pending approval.</strong> We'll notify you via email shortly.</p>
        </div>
    <?php else : ?>
        <!-- Content is fully unlocked or not restricted -->
        <div class="entry-content">
            <?php the_content(); ?>
            <?php
            // For protected files, use specific template tags to get secure URLs
            if ( function_exists( 'gatekeeper_pro_get_download_url' ) && function_exists( 'gatekeeper_pro_get_video_url' ) ) {
                $download_url = gatekeeper_pro_get_download_url( $post->ID );
                $video_url = gatekeeper_pro_get_video_url( $post->ID );

                if ( $download_url ) {
                    echo '<p><a href="' . esc_url( $download_url ) . '" class="gatekeeper-download-button">Download Resource</a></p>';
                }
                if ( $video_url ) {
                    echo '<p><a href="' . esc_url( $video_url ) . '" class="gatekeeper-video-link">Watch Video</a></p>';
                    // Or embed a video player with the secure URL
                    // echo '<video controls src="' . esc_url( $video_url ) . '"></video>';
                }
            }
            ?>
        </div>
    <?php endif;
endif; ?>

This enhanced logic provides a better user experience by informing users about their request status instead of just showing the content or the request form again.

Step 6: Styling with Custom CSS

Once you have your custom HTML markup in place, the next step is to style it using CSS. This is where your theme's design shines through, applying the specific look and feel for your wordpress gated content css.

Add your CSS rules to your theme's style.css file or via your theme customiser. Target the classes you defined in your custom markup.

/* Styles for the custom lock overlay */
.gatekeeper-custom-lock-overlay {
    background-color: #f7f7f7;
    border: 1px solid #e0e0e0;
    padding: 40px;
    text-align: center;
    margin-bottom: 30px;
    border-radius: 8px;
}

.gatekeeper-custom-lock-overlay .lock-icon {
    font-size: 4em;
    color: #888;
    display: block;
    margin-bottom: 15px;
}

.gatekeeper-custom-lock-overlay .lock-title {
    font-size: 1.8em;
    color: #333;
    margin-bottom: 10px;
}

.gatekeeper-custom-lock-overlay .lock-message {
    font-size: 1.1em;
    color: #666;
    margin-bottom: 25px;
}

/* Styles for the pending message */
.gatekeeper-custom-pending-message {
    background-color: #fff3cd;
    border: 1px solid #ffeeba;
    color: #856404;
    padding: 15px 20px;
    border-radius: 5px;
    margin-bottom: 20px;
}

You can also use CSS to apply effects to the content itself when it's locked, such as a blur filter or a dimmed overlay, before the custom markup appears. For example, if you're showing a preview of the content, you might blur it visually and then place your request form on top.

Advanced Customisations and Best Practices

Integrating with Archive Loops and Resource Cards

The same principles apply when displaying gated content in archive pages or custom resource libraries. Instead of wrapping the_content(), you'd wrap your custom resource card markup. Gatekeeper Pro offers a [gatekeeper_resource_card] shortcode and Elementor widget that can render a complete card with lock overlays, badges, and action buttons dynamically. However, for ultimate theme integration, using the PHP detection method allows you to build your own custom card structure entirely.

<?php
// Inside a WP_Query loop
if ( have_posts() ) : while ( have_posts() ) : the_post();
    $post_id = get_the_ID();
    $is_locked_in_loop = function_exists( 'gatekeeper_pro_is_locked' ) ? gatekeeper_pro_is_locked( $post_id ) : false;
?>
    <article id="post-<?php the_ID(); ?>" <?php post_class( $is_locked_in_loop ? 'gatekeeper-locked-item' : '' ); ?>>
        <!-- Your custom resource card markup -->
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
        <div class="entry-summary">
            <?php the_excerpt(); ?>
        </div>

        <?php if ( $is_locked_in_loop ) : ?>
            <div class="gatekeeper-archive-lock-overlay">
                <span class="lock-small-icon">🔒</span>
                <span class="lock-badge">Restricted</span>
                <a href="<?php the_permalink(); ?>" class="view-resource-button">Request Access</a>
            </div>
        <?php endif; ?>
    </article>
<?php endwhile; endif; ?>

This code adds a class to the post container and a specific overlay for locked items in an archive, providing a clear visual cue to users browsing a list of resources.

Customising the Request Form and User Experience

While this tutorial focuses on the detection and custom markup, remember that Gatekeeper Pro allows extensive customisation of the access request form itself. You can configure fields, labels, and even integrate with Formidable Forms if you prefer. These settings ensure that your form, even when rendered via gatekeeper_pro_display_request_form() or its shortcode, matches your data collection requirements and branding.

Simplifying Output with gatekeeper_pro_display_content_gate()

For scenarios where you want Gatekeeper Pro to handle the conditional display of the content versus the gate automatically, you can use gatekeeper_pro_display_content_gate(). This template tag takes a post ID and will output either the content or the configured content gate (which can include the request form), based on the user's access status. This can simplify your theme's template logic, especially for more straightforward gating requirements, reducing the amount of manual if/else checks.

Performance Considerations

Gatekeeper Pro is built with performance in mind. It uses transients and smart caching to minimise database queries. When you detect locked content using its functions, these checks are optimised. Additionally, for pages displaying locked content, the plugin sends appropriate no-cache headers to ensure dynamic content is always served correctly, especially when integrated with major caching plugins.

Accessibility Best Practices

When creating custom overlays and interactive elements for gated content, always consider accessibility. Ensure: