diff --git a/.github/workflows/test-php.yml b/.github/workflows/test-php.yml
index d4b6317..b8b0af0 100644
--- a/.github/workflows/test-php.yml
+++ b/.github/workflows/test-php.yml
@@ -47,7 +47,7 @@ jobs:
- name: Setup PHP version
uses: shivammathur/setup-php@v2
with:
- php-version: '7.1'
+ php-version: '7.2'
extensions: simplexml, mysql
tools: phpunit-polyfills
- name: Checkout source code
@@ -69,4 +69,4 @@ jobs:
- name: Install composer
run: composer install --prefer-dist --no-progress --no-suggest
- name: Run phpunit
- run: phpunit
+ run: composer run-script phpunit
diff --git a/.gitignore b/.gitignore
index fab41ab..48ff83e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ assets/js/build
languages/neve-fse.pot
.DS_Store
+.phpunit.result.cache
diff --git a/assets/img/neve-fse-img13.webp b/assets/img/neve-fse-img13.webp
new file mode 100644
index 0000000..8f4e3cd
Binary files /dev/null and b/assets/img/neve-fse-img13.webp differ
diff --git a/assets/img/neve-fse-img14.webp b/assets/img/neve-fse-img14.webp
new file mode 100644
index 0000000..75d2588
Binary files /dev/null and b/assets/img/neve-fse-img14.webp differ
diff --git a/assets/js/src/design-pack-notice.js b/assets/js/src/design-pack-notice.js
index b7c382c..0bb1ba4 100644
--- a/assets/js/src/design-pack-notice.js
+++ b/assets/js/src/design-pack-notice.js
@@ -2,7 +2,9 @@ import { createRoot } from '@wordpress/element';
import DesignPackNotice from './components/DesignPackNotice';
-const container = document.getElementById( 'neve-fse-design-pack-notice' );
+const container = document.createElement( 'div' );
+container.id = 'neve-fse-design-pack-notice';
+document.body.appendChild( container );
if ( container ) {
createRoot( container ).render( );
diff --git a/assets/js/src/welcome-notice.js b/assets/js/src/welcome-notice.js
index 946088f..6d3ff4e 100644
--- a/assets/js/src/welcome-notice.js
+++ b/assets/js/src/welcome-notice.js
@@ -8,8 +8,10 @@ function handleWelcomeNotice( $ ) {
installing,
done,
activationUrl,
+ onboardingUrl,
ajaxUrl,
nonce,
+ otterRefNonce,
otterStatus,
} = neveFSEData;
@@ -30,16 +32,28 @@ function handleWelcomeNotice( $ ) {
const activateOtter = async () => {
installText.text( activating );
await activatePlugin( activationUrl );
+
+ await $.post( ajaxUrl, {
+ nonce: otterRefNonce,
+ action: 'neve_fse_set_otter_ref',
+ } );
+
installSpinner.removeClass( 'dashicons-update' );
installSpinner.addClass( 'dashicons-yes' );
installText.text( done );
setTimeout( hideAndRemoveNotice, 1500 );
+ window.location.href = onboardingUrl;
};
$( installBtn ).on( 'click', async () => {
installSpinner.removeClass( 'hidden' );
installBtn.attr( 'disabled', true );
+ if ( otterStatus === 'active' ) {
+ window.location.href = onboardingUrl;
+ return;
+ }
+
if ( otterStatus === 'installed' ) {
await activateOtter();
return;
diff --git a/composer.json b/composer.json
index ae2652e..b303f96 100644
--- a/composer.json
+++ b/composer.json
@@ -51,6 +51,7 @@
"format": "phpcbf --standard=phpcs.xml --report-summary --report-source -s --runtime-set testVersion 7.0- ",
"phpcs": "phpcs --standard=phpcs.xml -s --runtime-set testVersion 7.0-",
"lint": "composer run-script phpcs",
- "phpcs-i": "phpcs -i"
+ "phpcs-i": "phpcs -i",
+ "phpunit": "phpunit"
}
}
diff --git a/composer.lock b/composer.lock
index a01d8f0..aedaf3e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -8,16 +8,16 @@
"packages": [
{
"name": "codeinwp/themeisle-sdk",
- "version": "3.3.14",
+ "version": "3.3.29",
"source": {
"type": "git",
"url": "https://github.com/Codeinwp/themeisle-sdk.git",
- "reference": "662952078c57b12e4d3af9bc98ef847ea3500206"
+ "reference": "4d63bc81ec0357c8675dac1e35511fd81104605d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/662952078c57b12e4d3af9bc98ef847ea3500206",
- "reference": "662952078c57b12e4d3af9bc98ef847ea3500206",
+ "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/4d63bc81ec0357c8675dac1e35511fd81104605d",
+ "reference": "4d63bc81ec0357c8675dac1e35511fd81104605d",
"shasum": ""
},
"require-dev": {
@@ -42,9 +42,9 @@
],
"support": {
"issues": "https://github.com/Codeinwp/themeisle-sdk/issues",
- "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.3.14"
+ "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.3.29"
},
- "time": "2024-02-27T17:30:04+00:00"
+ "time": "2024-08-21T08:03:45+00:00"
}
],
"packages-dev": [
@@ -1962,16 +1962,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.9.0",
+ "version": "3.10.2",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
- "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b"
+ "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
- "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/86e5f5dd9a840c46810ebe5ff1885581c42a3017",
+ "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017",
"shasum": ""
},
"require": {
@@ -2038,7 +2038,7 @@
"type": "open_collective"
}
],
- "time": "2024-02-16T15:06:51+00:00"
+ "time": "2024-07-21T23:26:44+00:00"
},
{
"name": "symfony/polyfill-ctype",
diff --git a/inc/Admin.php b/inc/Admin.php
index 22f06b5..ee39709 100644
--- a/inc/Admin.php
+++ b/inc/Admin.php
@@ -22,6 +22,13 @@ class Admin {
*/
private $suspend_survey = true;
+ /**
+ * Otter reference key.
+ *
+ * @var string
+ */
+ const OTTER_REF = 'otter_reference_key';
+
/**
* Admin constructor.
*/
@@ -59,6 +66,8 @@ public function setup_admin_hooks() {
add_action( 'enqueue_block_editor_assets', array( $this, 'add_fse_design_pack_notice' ) );
add_action( 'wp_ajax_neve_fse_dismiss_design_pack_notice', array( $this, 'remove_design_pack_notice' ) );
+ add_action( 'activated_plugin', 'after_otter_activation' );
+ add_action( 'wp_ajax_neve_fse_set_otter_ref', array( $this, 'set_otter_ref' ) );
}
/**
@@ -78,11 +87,12 @@ public function add_fse_design_pack_notice() {
true,
array(),
array(
- 'nonce' => wp_create_nonce( 'neve-fse-dismiss-design-pack-notice' ),
- 'ajaxUrl' => esc_url( admin_url( 'admin-ajax.php' ) ),
- 'ajaxAction' => 'neve_fse_dismiss_design_pack_notice',
- 'buttonLink' => tsdk_utmify( 'https://themeisle.com/plugins/fse-design-pack', 'editor', 'neve-fse' ),
- 'strings' => array(
+ 'nonce' => wp_create_nonce( 'neve-fse-dismiss-design-pack-notice' ),
+ 'otterRefNonce' => wp_create_nonce( 'neve-fse-set-otter-ref' ),
+ 'ajaxUrl' => esc_url( admin_url( 'admin-ajax.php' ) ),
+ 'ajaxAction' => 'neve_fse_dismiss_design_pack_notice',
+ 'buttonLink' => tsdk_utmify( 'https://themeisle.com/plugins/fse-design-pack', 'editor', 'neve-fse' ),
+ 'strings' => array(
'dismiss' => __( 'Dismiss', 'neve-fse' ),
'recommends' => __( 'Neve FSE recommends', 'neve-fse' ),
'learnMore' => __( 'Learn More', 'neve-fse' ),
@@ -95,8 +105,6 @@ public function add_fse_design_pack_notice() {
),
'designPackNoticeData'
);
-
- echo '
';
}
/**
@@ -270,6 +278,14 @@ public function render_welcome_notice() {
admin_url( 'plugins.php' )
)
),
+ 'onboardingUrl' => esc_url(
+ add_query_arg(
+ array(
+ 'onboarding' => 'true',
+ ),
+ admin_url( 'site-editor.php' )
+ )
+ ),
'activating' => __( 'Activating', 'neve-fse' ) . '…',
'installing' => __( 'Installing', 'neve-fse' ) . '…',
'done' => __( 'Done', 'neve-fse' ),
@@ -421,6 +437,10 @@ private function should_show_welcome_notice(): bool {
private function get_otter_status(): string {
$status = 'not-installed';
+ if ( is_plugin_active( 'otter-blocks/otter-blocks.php' ) ) {
+ return 'active';
+ }
+
if ( file_exists( ABSPATH . 'wp-content/plugins/otter-blocks/otter-blocks.php' ) ) {
return 'installed';
}
@@ -428,6 +448,63 @@ private function get_otter_status(): string {
return $status;
}
+ /**
+ * Run after Otter Blocks activation.
+ *
+ * @param string $plugin Plugin name.
+ *
+ * @return void
+ */
+ public function after_otter_activation( $plugin ) {
+ if ( 'otter-blocks/otter-blocks.php' !== $plugin ) {
+ return;
+ }
+
+ if ( ! class_exists( '\ThemeIsle\GutenbergBlocks\Plugins\FSE_Onboarding' ) ) {
+ return;
+ }
+
+ $status = get_option( \ThemeIsle\GutenbergBlocks\Plugins\FSE_Onboarding::OPTION_KEY, array() );
+ $slug = get_stylesheet();
+
+ if ( ! empty( $status[ $slug ] ) ) {
+ return;
+ }
+
+ // Dismiss after two days from activation.
+ $activated_time = get_option( 'neve_fse_install' );
+
+ if ( ! empty( $activated_time ) && time() - intval( $activated_time ) > ( 2 * DAY_IN_SECONDS ) ) {
+ update_option( Constants::CACHE_KEYS['dismissed-welcome-notice'], 'yes' );
+ return;
+ }
+
+ $onboarding = add_query_arg(
+ array(
+ 'onboarding' => 'true',
+ ),
+ admin_url( 'site-editor.php' )
+ );
+
+ wp_safe_redirect( $onboarding );
+ exit;
+ }
+
+ /**
+ * Update Otter reference key.
+ *
+ * @return void
+ */
+ public function set_otter_ref() {
+ if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( $_POST['nonce'] ), 'neve-fse-set-otter-ref' ) ) {
+ return;
+ }
+
+ update_option( self::OTTER_REF, 'neve-fse' );
+
+ wp_send_json_success();
+ }
+
/**
* Add NPS form.
*
diff --git a/inc/Block_Patterns.php b/inc/Block_Patterns.php
index 5d6eb45..d5d7452 100644
--- a/inc/Block_Patterns.php
+++ b/inc/Block_Patterns.php
@@ -96,6 +96,13 @@ private function setup_properties() {
'layout/columns-image-and-text',
'layout/portfolio-columns',
'layout/columns-image-and-text-inv',
+ 'layout/hero-with-feature-columns',
+ 'layout/columns-testimonials-inv',
+ 'layout/columns-with-services-text',
+ 'layout/contact-section',
+ 'layout/hero-with-text',
+ 'layout/map-section',
+ 'layout/faq-section',
// Post patterns.
'loops/post-loop-1',
diff --git a/inc/Core.php b/inc/Core.php
index 7798b2a..48f491a 100644
--- a/inc/Core.php
+++ b/inc/Core.php
@@ -85,6 +85,66 @@ public function setup() {
)
);
+ add_theme_support(
+ 'otter-onboarding',
+ array(
+ 'logo' => NEVE_FSE_URL . 'assets/img/neve-fse-logo.svg',
+ 'templates' => array(
+ 'archive' => array(
+ 'archive-list' => array(
+ 'file' => NEVE_FSE_DIR . 'library/archive/archive-list.php',
+ 'title' => __( 'Archive List', 'neve-fse' ),
+ ),
+ 'archive-cover' => array(
+ 'file' => NEVE_FSE_DIR . 'library/archive/archive-cover.php',
+ 'title' => __( 'Archive Cover', 'neve-fse' ),
+ ),
+ ),
+ 'single' => array(
+ 'single-post-cover-boxed' => array(
+ 'file' => NEVE_FSE_DIR . 'library/single/single-post-cover-boxed.php',
+ 'title' => __( 'Single Post Cover Boxed', 'neve-fse' ),
+ ),
+ 'single-post-cover' => array(
+ 'file' => NEVE_FSE_DIR . 'library/single/single-post-cover.php',
+ 'title' => __( 'Single Post Cover', 'neve-fse' ),
+ ),
+ ),
+ 'front-page' => array(
+ 'front-page-alt' => array(
+ 'file' => NEVE_FSE_DIR . 'library/front-page/front-page-2.php',
+ 'title' => __( 'Homepage 2', 'neve-fse' ),
+ ),
+ 'front-page-alt-2' => array(
+ 'file' => NEVE_FSE_DIR . 'library/front-page/front-page-3.php',
+ 'title' => __( 'Homepage 4', 'neve-fse' ),
+ ),
+ ),
+ ),
+ 'page_templates' => array(
+ 'about-page' => array(
+ 'file' => NEVE_FSE_DIR . 'library/templates/about-page.php',
+ 'title' => __( 'About Page', 'neve-fse' ),
+ 'template' => 'template-plain',
+ ),
+ 'contact-page' => array(
+ 'file' => NEVE_FSE_DIR . 'library/templates/contact-page.php',
+ 'title' => __( 'Contact Page', 'neve-fse' ),
+ 'template' => 'template-plain',
+ ),
+ 'portfolio-page' => array(
+ 'file' => NEVE_FSE_DIR . 'library/templates/portfolio-page.php',
+ 'title' => __( 'Portfolio Page', 'neve-fse' ),
+ 'template' => 'template-plain',
+ ),
+ 'services-page' => array(
+ 'file' => NEVE_FSE_DIR . 'library/templates/services-page.php',
+ 'title' => __( 'Services Page', 'neve-fse' ),
+ 'template' => 'template-plain',
+ ),
+ ),
+ )
+ );
register_nav_menus( array( 'primary' => esc_html__( 'Primary Menu', 'neve-fse' ) ) );
}
diff --git a/inc/patterns/layout/columns-testimonials-inv.php b/inc/patterns/layout/columns-testimonials-inv.php
new file mode 100644
index 0000000..1d456fc
--- /dev/null
+++ b/inc/patterns/layout/columns-testimonials-inv.php
@@ -0,0 +1,104 @@
+ __( 'Three Columns with Testimonials Inverted', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'Columns', 'testimonial', 'client', 'review' ),
+ 'content' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"...Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis..."
+
+
+
+
JANE DOE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"...Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis..."
+
+
+
+
JOHN DOE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"...Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis..."
+
+
+
+
MARIA DOE
+
+
+
+
+
+
+
+
+
+
+
+ ',
+);
diff --git a/inc/patterns/layout/columns-with-services-text.php b/inc/patterns/layout/columns-with-services-text.php
new file mode 100644
index 0000000..41c6dae
--- /dev/null
+++ b/inc/patterns/layout/columns-with-services-text.php
@@ -0,0 +1,73 @@
+ __( 'Columns with Services Text', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'columns', 'services', 'features', '3col' ),
+ 'content' => '
+
+
+
+
+
Service Title
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.
+
+
+
+
+
+
+
+
+
+
Service Title
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.
+
+
+
+
+
+
+
+
+
+
Service Title
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.
+
+
+
+
+
+
+
+',
+);
diff --git a/inc/patterns/layout/contact-section.php b/inc/patterns/layout/contact-section.php
new file mode 100644
index 0000000..930a1e8
--- /dev/null
+++ b/inc/patterns/layout/contact-section.php
@@ -0,0 +1,43 @@
+ __( 'Columns Section', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'contact' ),
+ 'content' => '
+
+
+
+
Subheader
+
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
+
+
+
+
(555) 123-4567
+
+
+
+
+
+
+',
+);
diff --git a/inc/patterns/layout/faq-section.php b/inc/patterns/layout/faq-section.php
new file mode 100644
index 0000000..3cd80fa
--- /dev/null
+++ b/inc/patterns/layout/faq-section.php
@@ -0,0 +1,66 @@
+ __( 'FAQ Section', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'faq', 'columns' ),
+ 'content' => '
+
+
+
+
Questions? We\'re here to help!
+
+
+
+
Need more help? Contact us!
+
+
+
+
+
+
+
What areas do you service?
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
+
+
+
+
+
+
+
How do I schedule a consultation?
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
+
+
+
+
+
+
+
What should I expect during the initial consultation?
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
+
+
+
+
+
+
+
Do you offer customized garden designs?
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
+
+
+
+
+
+',
+);
diff --git a/inc/patterns/layout/hero-with-feature-columns.php b/inc/patterns/layout/hero-with-feature-columns.php
new file mode 100644
index 0000000..09e2b14
--- /dev/null
+++ b/inc/patterns/layout/hero-with-feature-columns.php
@@ -0,0 +1,59 @@
+ __( 'Hero section with feature columns', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'columns', 'hero' ),
+ 'content' => '
+
+
+
+
+
+
+
+
Create and grow your
unique website today
+
+
+
+
Build a website for your business or brand, with Neve FSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+);
diff --git a/inc/patterns/layout/hero-with-text.php b/inc/patterns/layout/hero-with-text.php
new file mode 100644
index 0000000..7801f2d
--- /dev/null
+++ b/inc/patterns/layout/hero-with-text.php
@@ -0,0 +1,43 @@
+ __( 'Hero section with text', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'hero' ),
+ 'content' => '
+
+
+
+
+
+
Create and grow your
unique website today
+
+
+
+
Build a website for your business or brand, with Neve FSE
+
+
+
+
+
+
+
+
+',
+);
diff --git a/inc/patterns/layout/map-section.php b/inc/patterns/layout/map-section.php
new file mode 100644
index 0000000..eb8ff4c
--- /dev/null
+++ b/inc/patterns/layout/map-section.php
@@ -0,0 +1,29 @@
+ __( 'Map Section', 'neve-fse' ),
+ 'categories' => array( 'neve-fse' ),
+ 'keywords' => array( 'contact' ),
+ 'content' => '
+
+
+
+
+',
+);
diff --git a/inc/patterns/templates/single-post-cover-boxed.php b/inc/patterns/templates/single-post-cover-boxed.php
index d4479a3..49aaf13 100644
--- a/inc/patterns/templates/single-post-cover-boxed.php
+++ b/inc/patterns/templates/single-post-cover-boxed.php
@@ -23,8 +23,8 @@
-
-
+
+
diff --git a/inc/patterns/templates/single-post-cover.php b/inc/patterns/templates/single-post-cover.php
index d65f3c2..c79a452 100644
--- a/inc/patterns/templates/single-post-cover.php
+++ b/inc/patterns/templates/single-post-cover.php
@@ -23,8 +23,8 @@
-
-
+
+
diff --git a/library/archive/archive-cover.php b/library/archive/archive-cover.php
new file mode 100644
index 0000000..c6d9696
--- /dev/null
+++ b/library/archive/archive-cover.php
@@ -0,0 +1,14 @@
+
+
+
+
+';
diff --git a/library/archive/archive-list.php b/library/archive/archive-list.php
new file mode 100644
index 0000000..8df3026
--- /dev/null
+++ b/library/archive/archive-list.php
@@ -0,0 +1,14 @@
+
+
+
+
+';
diff --git a/library/front-page/front-page-2.php b/library/front-page/front-page-2.php
new file mode 100644
index 0000000..f8d7862
--- /dev/null
+++ b/library/front-page/front-page-2.php
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
diff --git a/library/front-page/front-page-3.php b/library/front-page/front-page-3.php
new file mode 100644
index 0000000..b2b13f2
--- /dev/null
+++ b/library/front-page/front-page-3.php
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
diff --git a/library/single/single-post-cover-boxed.php b/library/single/single-post-cover-boxed.php
new file mode 100644
index 0000000..08d2594
--- /dev/null
+++ b/library/single/single-post-cover-boxed.php
@@ -0,0 +1,14 @@
+
+
+
+
+';
diff --git a/library/single/single-post-cover.php b/library/single/single-post-cover.php
new file mode 100644
index 0000000..853f70d
--- /dev/null
+++ b/library/single/single-post-cover.php
@@ -0,0 +1,14 @@
+
+
+
+
+';
diff --git a/library/templates/about-page.php b/library/templates/about-page.php
new file mode 100644
index 0000000..9ddf55e
--- /dev/null
+++ b/library/templates/about-page.php
@@ -0,0 +1,28 @@
+
+
+
+
+
+
About
+
+
+
+
+
+
+
+
+
+
+
+
+';
diff --git a/library/templates/contact-page.php b/library/templates/contact-page.php
new file mode 100644
index 0000000..f6ef3ef
--- /dev/null
+++ b/library/templates/contact-page.php
@@ -0,0 +1,26 @@
+
+
+
+
+
+
Contact
+
+
+
+
+
+
+
+
+
+
+';
diff --git a/library/templates/portfolio-page.php b/library/templates/portfolio-page.php
new file mode 100644
index 0000000..2d595d1
--- /dev/null
+++ b/library/templates/portfolio-page.php
@@ -0,0 +1,26 @@
+
+
+
+
+
+
Portfolio
+
+
+
+
+
+
+
+
+
+
+';
diff --git a/library/templates/services-page.php b/library/templates/services-page.php
new file mode 100644
index 0000000..c33fe99
--- /dev/null
+++ b/library/templates/services-page.php
@@ -0,0 +1,28 @@
+
+
+
+
+
+
Services
+
+
+
+
+
+
+
+
+
+
+
+
+';
diff --git a/templates/template-plain.html b/templates/template-plain.html
new file mode 100644
index 0000000..c7c383e
--- /dev/null
+++ b/templates/template-plain.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 6f688bf..cf809b1 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -8,6 +8,11 @@
define( 'NEVE_FSE_IGNORE_SOURCE_CHECK', true );
$_tests_dir = getenv( 'WP_TESTS_DIR' );
+
+if ( class_exists( '\Yoast\PHPUnitPolyfills\Autoload' ) === false ) {
+ require_once dirname( dirname( __FILE__ ) ) . '/vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php';
+}
+
if ( ! $_tests_dir ) {
$_tests_dir = '/tmp/wordpress-tests-lib';
}