diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d59ffb260..c59a882fb 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -33,7 +33,7 @@ jobs:
WORDPRESS_DB_SQL_DUMP_FILE: tests/Support/Data/dump.sql # Used to populate the test site database for WordPress 6.2.8
INSTALL_PLUGINS: "admin-menu-editor autoptimize beaver-builder-lite-version block-visibility contact-form-7 classic-editor custom-post-type-ui debloat elementor forminator jetpack-boost mailchimp-for-wp rocket-lazy-load woocommerce wordpress-seo wpforms-lite litespeed-cache wp-crontrol wp-super-cache w3-total-cache wp-fastest-cache wp-optimize sg-cachepress" # Don't include this repository's Plugin here.
INSTALL_PLUGINS_URLS: "https://downloads.wordpress.org/plugin/convertkit-for-woocommerce.1.6.4.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/01/convertkit-action-filter-tests.zip http://cktestplugins.wpengine.com/wp-content/uploads/2024/11/disable-doing-it-wrong-notices.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-js_composer.7.8.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode-core.zip" # URLs to specific third party Plugins
- INSTALL_THEMES_URLS: "http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/04/Divi.zip"
+ INSTALL_THEMES_URLS: "http://cktestplugins.wpengine.com/wp-content/uploads/2025/03/uncode.zip http://cktestplugins.wpengine.com/wp-content/uploads/2025/04/Divi.zip http://cktestplugins.wpengine.com/wp-content/uploads/2026/01/impeka.zip"
CONVERTKIT_API_KEY: ${{ secrets.CONVERTKIT_API_KEY }} # ConvertKit API Key, stored in the repository's Settings > Secrets
CONVERTKIT_API_SECRET: ${{ secrets.CONVERTKIT_API_SECRET }} # ConvertKit API Secret, stored in the repository's Settings > Secrets
CONVERTKIT_API_KEY_NO_DATA: ${{ secrets.CONVERTKIT_API_KEY_NO_DATA }} # ConvertKit API Key for ConvertKit account with no data, stored in the repository's Settings > Secrets
diff --git a/includes/class-convertkit-output-restrict-content.php b/includes/class-convertkit-output-restrict-content.php
index ac940b381..17e97b822 100644
--- a/includes/class-convertkit-output-restrict-content.php
+++ b/includes/class-convertkit-output-restrict-content.php
@@ -1227,21 +1227,24 @@ private function restrict_content( $content ) {
$call_to_action = apply_filters( 'convertkit_output_restrict_content_call_to_action', $call_to_action, $this->post_id );
// Fetch container CSS classes.
- $container_css_classes = $this->restrict_content_settings->get_by_key( 'container_css_classes' );
+ $container_css_classes = explode( ' ', $this->restrict_content_settings->get_by_key( 'container_css_classes' ) );
/**
* Define the container CSS classes to wrap the content preview and call to action within.
*
* @since 3.1.4
*
- * @param string $container_css_classes Container CSS classes.
- * @param int $post_id Post ID.
+ * @param array $container_css_classes Container CSS classes.
+ * @param int $post_id Post ID.
*/
$container_css_classes = apply_filters( 'convertkit_output_restrict_content_container_css_classes', $container_css_classes, $this->post_id );
+ // Remove empty CSS classes.
+ $container_css_classes = array_filter( $container_css_classes );
+
// If container CSS classes are set, return the content preview and call to action wrapped in the container.
- if ( $container_css_classes ) {
- return '
' . $content_preview . $call_to_action . '
';
+ if ( count( $container_css_classes ) ) {
+ return '' . $content_preview . $call_to_action . '
';
}
// Return the content preview and its call to action.
diff --git a/includes/functions.php b/includes/functions.php
index 038248f23..6ad62e1e0 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -641,6 +641,32 @@ function convertkit_output_intercom_messenger() {
}
+/**
+ * Checks if the given Theme is active.
+ *
+ * @since 3.1.4
+ *
+ * @param string $theme_name Theme name.
+ * @return bool
+ */
+function convertkit_is_theme_active( $theme_name ) {
+
+ // Assume Theme isn't active if we can't detect it.
+ if ( ! function_exists( 'wp_get_theme' ) ) {
+ return false;
+ }
+
+ // Check the Parent Theme if we're on a Child Theme.
+ if ( wp_get_theme()->parent() ) {
+ $theme = wp_get_theme()->parent();
+ } else {
+ $theme = wp_get_theme();
+ }
+
+ return strtolower( $theme->get( 'Name' ) ) === strtolower( $theme_name );
+
+}
+
/**
* Returns permitted HTML output when using wp_kses( ..., convertkit_kses_allowed_html()).
*
diff --git a/includes/integrations/class-convertkit-impeka.php b/includes/integrations/class-convertkit-impeka.php
new file mode 100644
index 000000000..42432c16c
--- /dev/null
+++ b/includes/integrations/class-convertkit-impeka.php
@@ -0,0 +1,50 @@
+setupKitPluginResources($I);
}
+ /**
+ * Test that restricting content by a Product specified in the Page Settings works when
+ * creating and viewing a new WordPress Page using the Impeka theme automatically
+ * adds Impeka's grve-container CSS class to the Restrict Content container,
+ * ensuring correct layout.
+ *
+ * @since 3.1.4
+ *
+ * @param EndToEndTester $I Tester.
+ */
+ public function testRestrictContentByProductWithImpekaTheme(EndToEndTester $I)
+ {
+ // Activate theme.
+ $I->useTheme('impeka');
+
+ // Programmatically create a Page using the Visual Composer Page Builder.
+ $pageID = $I->havePostInDatabase(
+ [
+ 'post_type' => 'page',
+ 'post_title' => 'Kit: Page: Restrict Content: Product: Impeka Theme with Visual Composer',
+ 'post_content' => 'Member-only content.',
+
+ // Don't display a Form on this Page, so we test against Restrict Content's Form.
+ 'meta_input' => [
+ '_wp_convertkit_post_meta' => [
+ 'form' => '0',
+ 'landing_page' => '',
+ 'tag' => '',
+ 'restrict_content' => 'product_' . $_ENV['CONVERTKIT_API_PRODUCT_ID'],
+ ],
+ ],
+ ]
+ );
+
+ // Test Restrict Content functionality.
+ $I->testRestrictedContentByProductOnFrontend(
+ $I,
+ urlOrPageID: $pageID,
+ options: [
+ 'visible_content' => '',
+ 'member_content' => 'Member-only content.',
+ 'settings' => [
+ // Test that the grve-container CSS class is added to the Restrict Content container.
+ 'container_css_classes' => 'grve-container',
+ ],
+ ],
+ );
+ }
+
/**
* Test that restricting content by a Product specified in the Page Settings works when
* creating and viewing a new WordPress Page using the Uncode theme both using
diff --git a/tests/Integration/ThemeDetectionTest.php b/tests/Integration/ThemeDetectionTest.php
new file mode 100644
index 000000000..cf0f50613
--- /dev/null
+++ b/tests/Integration/ThemeDetectionTest.php
@@ -0,0 +1,65 @@
+assertTrue(convertkit_is_theme_active( 'Twenty Twenty-Five' ));
+ $this->assertFalse(convertkit_is_theme_active( 'Impeka' ));
+
+ // Switch Theme.
+ switch_theme('impeka');
+ $this->assertFalse(convertkit_is_theme_active( 'Twenty Twenty-Five' ));
+ $this->assertTrue(convertkit_is_theme_active( 'Impeka' ));
+ }
+}
diff --git a/wp-convertkit.php b/wp-convertkit.php
index 3e15d62fd..4641bce42 100644
--- a/wp-convertkit.php
+++ b/wp-convertkit.php
@@ -145,6 +145,9 @@
require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/forminator/class-convertkit-forminator.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/forminator/class-convertkit-forminator-settings.php';
+// Impeka Integration.
+require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/class-convertkit-impeka.php';
+
// Uncode Integration.
require_once CONVERTKIT_PLUGIN_PATH . '/includes/integrations/class-convertkit-uncode.php';