Last active
May 1, 2025 03:51
-
-
Save jasperf/750bf94df6c68d2ce48abab41283d2b8 to your computer and use it in GitHub Desktop.
Register Patterns in Sage 11 theme as loading from patterns directory by default does not work
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Register custom block pattern categories and patterns. | |
*/ | |
add_action('init', function () { | |
// First register the block type | |
register_block_type('nynaeve/website-packages', [ | |
'render_callback' => function ($attributes, $content) { | |
return $content; // Simply return the content as is | |
}, | |
]); | |
// Register standard pattern categories that our patterns may use | |
register_block_pattern_category( | |
'pricing', | |
[ | |
'label' => __('Pricing', 'nynaeve'), | |
] | |
); | |
// Register our custom pattern category | |
register_block_pattern_category( | |
'nynaeve-patterns', | |
[ | |
'label' => __('Nynaeve Patterns', 'nynaeve'), | |
] | |
); | |
/** | |
* Get processed pattern content with caching | |
* | |
* @param string $pattern_file Path to pattern file | |
* @return string Processed pattern content | |
*/ | |
function get_processed_pattern_content($pattern_file) | |
{ | |
static $cache = []; | |
if (isset($cache[$pattern_file])) { | |
return $cache[$pattern_file]; | |
} | |
// Capture output from the pattern file | |
ob_start(); | |
include $pattern_file; | |
$output = ob_get_clean(); | |
// Store in cache for future use | |
$cache[$pattern_file] = $output; | |
return $output; | |
} | |
/** | |
* Extract pattern metadata from file contents | |
* | |
* @param string $file_contents The contents of the pattern file | |
* @return array Associative array of pattern metadata | |
*/ | |
function extract_pattern_metadata($file_contents) | |
{ | |
$metadata = [ | |
'title' => '', | |
'slug' => '', | |
'description' => '', | |
'categories' => [], | |
]; | |
// Extract all metadata at once with a single regex | |
preg_match_all('/(?:Title|Slug|Categories|Description):\s*(.+)$/m', $file_contents, $matches, PREG_SET_ORDER); | |
foreach ($matches as $match) { | |
$line = $match[0]; | |
$value = trim($match[1]); | |
if (strpos($line, 'Title:') === 0) { | |
$metadata['title'] = __($value, 'nynaeve'); | |
} elseif (strpos($line, 'Slug:') === 0) { | |
$metadata['slug'] = $value; | |
} elseif (strpos($line, 'Description:') === 0) { | |
$metadata['description'] = __($value, 'nynaeve'); | |
} elseif (strpos($line, 'Categories:') === 0) { | |
$metadata['categories'] = array_map('trim', explode(',', $value)); | |
} | |
} | |
// Set default category if none specified | |
if (empty($metadata['categories'])) { | |
$metadata['categories'] = ['nynaeve-patterns']; | |
} | |
return $metadata; | |
} | |
/** | |
* Get theme files modification timestamp | |
* Used to invalidate cache when files change | |
* | |
* @return int Latest modification timestamp | |
*/ | |
function get_patterns_modification_time() | |
{ | |
$pattern_files = glob(get_theme_file_path('resources/patterns/*.php')); | |
$latest_time = 0; | |
foreach ($pattern_files as $file) { | |
$mod_time = filemtime($file); | |
if ($mod_time > $latest_time) { | |
$latest_time = $mod_time; | |
} | |
} | |
return $latest_time; | |
} | |
/** | |
* Register all block patterns from the patterns directory | |
* | |
* This function scans the theme's patterns directory for PHP files, | |
* extracts metadata from each pattern file (title, slug, description, categories), | |
* and registers each pattern with WordPress. It handles error logging | |
* for file access issues and provides meaningful defaults when metadata is missing. | |
* | |
* Each registered pattern is tracked in the returned array for cache management | |
* and later verification of registration status. | |
* | |
* @return array Registered patterns data as [slug => string, file => string] | |
*/ | |
function register_all_block_patterns() | |
{ | |
$pattern_files = glob(get_theme_file_path('resources/patterns/*.php')); | |
$registered = []; | |
foreach ($pattern_files as $file) { | |
try { | |
$file_contents = file_get_contents($file); | |
if ($file_contents === false) { | |
error_log("Nynaeve: Failed to read pattern file: {$file}"); | |
continue; | |
} | |
// Extract all metadata at once | |
$metadata = extract_pattern_metadata($file_contents); | |
if (empty($metadata['slug'])) { | |
continue; | |
} | |
// Set title default if needed | |
if (empty($metadata['title'])) { | |
$metadata['title'] = basename($file); | |
} | |
// Get pattern content | |
$pattern_content = get_processed_pattern_content($file); | |
register_block_pattern( | |
$metadata['slug'], | |
[ | |
'title' => $metadata['title'], | |
'description' => $metadata['description'], | |
'content' => $pattern_content, | |
'categories' => $metadata['categories'], | |
] | |
); | |
$registered[] = [ | |
'slug' => $metadata['slug'], | |
'file' => wp_normalize_path($file), | |
]; | |
} catch (\Exception $e) { | |
error_log("Nynaeve: Error registering pattern from {$file}: ".$e->getMessage()); | |
} | |
} | |
return $registered; | |
} | |
// Auto-register all patterns from resources/patterns directory | |
// Use transient caching to improve performance | |
if (function_exists('register_block_pattern')) { | |
// Get cached pattern data | |
$patterns_data = get_transient('nynaeve_registered_patterns'); | |
$last_mod_time = get_transient('nynaeve_patterns_last_modified'); | |
$current_mod_time = get_patterns_modification_time(); | |
// Check if cache needs refreshing: | |
// 1. No cached patterns | |
// 2. Pattern files have been modified since cache was created | |
if (! $patterns_data || ! $last_mod_time || $current_mod_time > $last_mod_time) { | |
$patterns_data = register_all_block_patterns(); | |
if (! empty($patterns_data)) { | |
set_transient('nynaeve_registered_patterns', $patterns_data, DAY_IN_SECONDS); | |
set_transient('nynaeve_patterns_last_modified', $current_mod_time, DAY_IN_SECONDS); | |
} | |
} else { | |
// Check if we need to re-register any patterns | |
// (e.g., after plugin updates that might clear registrations) | |
$needs_refresh = false; | |
if (! empty($patterns_data)) { | |
foreach ($patterns_data as $pattern) { | |
if (! registered_pattern_exists($pattern['slug'])) { | |
$needs_refresh = true; | |
break; | |
} | |
} | |
if ($needs_refresh) { | |
$patterns_data = register_all_block_patterns(); | |
set_transient('nynaeve_registered_patterns', $patterns_data, DAY_IN_SECONDS); | |
} | |
} | |
} | |
// Apply filters to allow other code to refresh patterns | |
add_filter('nynaeve_refresh_block_patterns', function ($refresh) { | |
if ($refresh) { | |
delete_transient('nynaeve_registered_patterns'); | |
delete_transient('nynaeve_patterns_last_modified'); | |
} | |
return $refresh; | |
}); | |
} | |
}, 9); // Lower priority so it runs BEFORE other pattern registrations | |
/** | |
* Check if a registered pattern exists | |
* | |
* @param string $pattern_slug The pattern slug to check | |
* @return bool Whether the pattern exists | |
*/ | |
function registered_pattern_exists($pattern_slug) | |
{ | |
if (! class_exists('\WP_Block_Patterns_Registry') || ! method_exists('\WP_Block_Patterns_Registry', 'get_instance')) { | |
return false; | |
} | |
$registry = \WP_Block_Patterns_Registry::get_instance(); | |
return $registry->is_registered($pattern_slug); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Title: FAQ Section | |
* Slug: nynaeve/faq-section | |
* Description: A collapsible FAQ section with common questions and answers. | |
* Categories: text, nynaeve-patterns | |
* Keywords: faq, questions, answers, collapsible | |
* Viewport Width: 1500 | |
* Block Types: core/group | |
* Inserter: true | |
*/ | |
?> | |
<!-- wp:group {"align":"full","className":"faq-section-container has-bggray-background-color","style":{"spacing":{"padding":{"top":"4rem","right":"2rem","bottom":"4rem","left":"2rem"}}}} --> | |
<div class="wp-block-group faq-section-container has-bggray-background-color has-background alignfull" style="padding-top:4rem;padding-right:2rem;padding-bottom:4rem;padding-left:2rem"> | |
<!-- wp:heading {"className":"faq-heading","textAlign":"center","textColor":"black","fontSize":"3xl","fontFamily":"open-sans"} --> | |
<h2 class="faq-heading has-black-color has-text-color has-text-align-center has-3xl-font-size has-open-sans-font-family">Frequently Asked Questions</h2> | |
<!-- /wp:heading --> | |
<!-- wp:group {"className":"faq-items","style":{"spacing":{"blockGap":"1rem"}}} --> | |
<div class="wp-block-group faq-items"> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">What's included in the Standard package?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<p class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family">You'll receive a 3–5‑page site built on our customizable block theme, hosted on a shared server, fully responsive, with basic on‑page SEO and a vertical‑specific child‑theme tailored to your brand.</p> | |
<!-- /wp:paragraph --> | |
</div> | |
<!-- /wp:group --> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">What's included in the Premium package?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<p class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family">The Premium package includes a customized Sage based hybrid theme with bespoke design components, version control, VPS hosting on our Trellis stack for optimal performance, comprehensive SEO setup and optimization, advanced analytics integration, and a 6-month maintenance plan with regular updates and support.</p> | |
<!-- /wp:paragraph --> | |
</div> | |
<!-- /wp:group --> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">How long does each package take to launch?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:list {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<ul class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family"> | |
<li><strong>Standard:</strong> ~2–3 weeks from kickoff to go‑live.</li> | |
<li><strong>Premium:</strong> ~4–6 weeks, including design mockups, development sprints, and initial SEO setup.</li> | |
</ul> | |
<!-- /wp:list --> | |
</div> | |
<!-- /wp:group --> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">What is a "hybrid theme"?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<p class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family">It's a custom WordPress theme base on Sage combining block‑based templates for easy content editing with classic PHP templates for bespoke design elements—giving you the best of both worlds.</p> | |
<!-- /wp:paragraph --> | |
</div> | |
<!-- /wp:group --> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">What does the 6‑month maintenance plan cover?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<p class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family">Monthly core, plugin, and theme updates; security monitoring; performance tweaks; and up to 4 small content or styling changes per month.</p> | |
<!-- /wp:paragraph --> | |
</div> | |
<!-- /wp:group --> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">Do I need to supply content and images?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<p class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family">Yes—client‑provided copy and high‑res images streamline the build. We can recommend stock sources or content‑writing partners if needed.</p> | |
<!-- /wp:paragraph --> | |
</div> | |
<!-- /wp:group --> | |
<!-- wp:group {"className":"faq-item","style":{"spacing":{"blockGap":"0"}}} --> | |
<div class="wp-block-group faq-item"> | |
<!-- wp:heading {"level":3,"className":"faq-question","fontSize":"lg","fontFamily":"open-sans","textColor":"black"} --> | |
<h3 class="faq-question has-black-color has-text-color has-lg-font-size has-open-sans-font-family">What is the Trellis stack?</h3> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"className":"faq-answer","textColor":"textbodygray","fontFamily":"open-sans"} --> | |
<p class="faq-answer has-textbodygray-color has-text-color has-open-sans-font-family">Trellis is a modern, Ansible‑driven provisioning system for WordPress, providing automated security, caching, and server hardening—ideal for high‑performance VPS hosting.</p> | |
<!-- /wp:paragraph --> | |
</div> | |
<!-- /wp:group --> | |
</div> | |
<!-- /wp:group --> | |
</div> | |
<!-- /wp:group --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Title: Modern Pricing Table | |
* Slug: nynaeve/modern-pricing-table | |
* Description: A modern comparison of website packages with pricing and feature details in a two-column layout. | |
* Categories: pricing, nynaeve-patterns | |
* Keywords: pricing, packages, features, columns, websites, comparison | |
* Viewport Width: 1500 | |
* Block Types: core/group | |
* Post Types: | |
* Inserter: true | |
*/ | |
?> | |
<!-- wp:group {"metadata":{"categories":["pricing, nynaeve-patterns"],"patternName":"nynaeve/modern-pricing-table","name":"Modern Pricing Table"},"align":"full","className":"modern-pricing-table-container has-bggray-background-color","style":{"spacing":{"padding":{"right":"2rem","left":"2rem","top":"4rem","bottom":"4rem"}},"backgroundColor":{"slug":"bggray","name":"BgGray","color":"#ebeced"}},"backgroundColor":"primary-accent"} --> | |
<div class="wp-block-group alignfull modern-pricing-table-container has-bggray-background-color has-primary-accent-background-color has-background" style="padding-top:4rem;padding-right:2rem;padding-bottom:4rem;padding-left:2rem"><!-- wp:heading {"className":"has-text-align-center","textColor":"black","fontSize":"3xl","fontFamily":"open-sans"} --> | |
<h2 class="wp-block-heading has-text-align-center has-black-color has-text-color has-open-sans-font-family has-3-xl-font-size">Website Packages.</h2> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"align":"center","className":"pricing-subtitle","textColor":"textbodygray","fontSize":"lg"} --> | |
<p class="has-text-align-center pricing-subtitle has-textbodygray-color has-text-color has-lg-font-size">Choose the package that best fits your business needs</p> | |
<!-- /wp:paragraph --> | |
<!-- wp:group {"layout":{"type":"constrained","contentSize":"64rem"}} --> | |
<div class="wp-block-group"><!-- wp:group --> | |
<div class="wp-block-group"><!-- wp:columns {"style":{"spacing":{"blockGap":{"top":"2rem","left":"2rem"}}}} --> | |
<div class="wp-block-columns"><!-- wp:column {"style":{"border":{"width":"1px","color":"#cbcbcb","radius":"0.5rem"},"spacing":{"padding":{"top":"2rem","right":"2rem","bottom":"2rem","left":"2rem"}}},"backgroundColor":"base"} --> | |
<div class="wp-block-column has-border-color has-base-background-color has-background" style="border-color:#cbcbcb;border-width:1px;border-radius:0.5rem;padding-top:2rem;padding-right:2rem;padding-bottom:2rem;padding-left:2rem"><!-- wp:heading {"style":{"spacing":{"margin":{"bottom":"0.5rem"}}}} --> | |
<h2 class="wp-block-heading" style="margin-bottom:0.5rem">Standard</h2> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"style":{"spacing":{"margin":{"top":"0","bottom":"1.5rem"}}},"textColor":"textbodygray","fontSize":"lg"} --> | |
<p class="has-textbodygray-color has-text-color has-lg-font-size" style="margin-top:0;margin-bottom:1.5rem">Perfect for small websites that need a professional presence.</p> | |
<!-- /wp:paragraph --> | |
<!-- wp:heading {"level":3,"style":{"spacing":{"margin":{"top":"1.5rem","bottom":"1.5rem"}}}} --> | |
<h3 class="wp-block-heading" style="margin-top:1.5rem;margin-bottom:1.5rem"><strong>€799</strong> <span style="font-weight:normal;font-size:1rem;color:#98999a">starting price</span></h3> | |
<!-- /wp:heading --> | |
<!-- wp:group --> | |
<div class="wp-block-group"><!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon"} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"textbodygray"} --> | |
<p class="has-textbodygray-color has-text-color">Shared hosting with trusted hosting partners</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:separator {"className":"is-style-separator-dotted is-style-default","style":{"color":{"background":"#cbcbcb"}}} --> | |
<hr class="wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-separator-dotted is-style-default" style="background-color:#cbcbcb;color:#cbcbcb"/> | |
<!-- /wp:separator --> | |
<!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon"} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"textbodygray"} --> | |
<p class="has-textbodygray-color has-text-color">Responsive, mobile friendly design</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:separator {"className":"is-style-separator-dotted","style":{"color":{"background":"#cbcbcb"}}} --> | |
<hr class="wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-separator-dotted" style="background-color:#cbcbcb;color:#cbcbcb"/> | |
<!-- /wp:separator --> | |
<!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon"} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"textbodygray"} --> | |
<p class="has-textbodygray-color has-text-color">Basic SEO setup</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:separator {"className":"is-style-separator-dotted","style":{"color":{"background":"#cbcbcb"}}} --> | |
<hr class="wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-separator-dotted" style="background-color:#cbcbcb;color:#cbcbcb"/> | |
<!-- /wp:separator --> | |
<!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon"} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Not included icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"textbodygray"} --> | |
<p class="has-textbodygray-color has-text-color">Turnkey Theme tailored to your business</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:buttons {"style":{"spacing":{"margin":{"top":"2rem"}}},"layout":{"type":"flex","justifyContent":"left"}} --> | |
<div class="wp-block-buttons" style="margin-top:2rem"><!-- wp:button {"backgroundColor":"black","textColor":"base","className":"is-style-fill","style":{"border":{"radius":"0.5rem"}}} --> | |
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-color has-black-background-color has-text-color has-background wp-element-button" style="border-radius:0.5rem">Get Started</a></div> | |
<!-- /wp:button --></div> | |
<!-- /wp:buttons --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:column --> | |
<!-- wp:column {"style":{"border":{"color":"#017cb6","width":"2px","radius":"0.5rem"},"spacing":{"padding":{"top":"2rem","right":"2rem","bottom":"2rem","left":"2rem"}}},"backgroundColor":"black"} --> | |
<div class="wp-block-column has-border-color has-black-background-color has-background" style="border-color:#017cb6;border-width:2px;border-radius:0.5rem;padding-top:2rem;padding-right:2rem;padding-bottom:2rem;padding-left:2rem"><!-- wp:heading {"className":"premium-heading","style":{"spacing":{"margin":{"bottom":"0.5rem"}}},"textColor":"white"} --> | |
<h2 class="wp-block-heading premium-heading has-white-color has-text-color" style="margin-bottom:0.5rem">Premium <span class="has-ctablue-color has-text-color has-background has-xs-font-size" style="border-radius:1rem;background-color:#e8f7fd;padding:0.5rem 1rem;font-size:0.75rem;margin-left:0.5rem"><strong>MOST POPULAR</strong></span></h2> | |
<!-- /wp:heading --> | |
<!-- wp:paragraph {"style":{"spacing":{"margin":{"top":"0","bottom":"1.5rem"}}},"textColor":"white","fontSize":"lg"} --> | |
<p class="has-white-color has-text-color has-lg-font-size" style="margin-top:0;margin-bottom:1.5rem">Fully customized solution with advanced features.</p> | |
<!-- /wp:paragraph --> | |
<!-- wp:heading {"level":3,"style":{"spacing":{"margin":{"top":"1.5rem","bottom":"1.5rem"}}},"textColor":"white"} --> | |
<h3 class="wp-block-heading has-white-color has-text-color" style="margin-top:1.5rem;margin-bottom:1.5rem"><strong>€2499</strong> <span style="font-weight:normal;font-size:1rem;color:#98999a">starting price</span></h3> | |
<!-- /wp:heading --> | |
<!-- wp:group --> | |
<div class="wp-block-group"><!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon","style":{"color":{"duotone":["#ffffff","#ffffff"]}}} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"white"} --> | |
<p class="has-white-color has-text-color">Premium VPS hosting (Trellis stack with Micro Caching, A+ SSL, WP CLI)</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:separator {"className":"is-style-separator-dotted","style":{"color":{"background":"#ffffff40"}}} --> | |
<hr class="wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-separator-dotted" style="background-color:#ffffff40;color:#ffffff40"/> | |
<!-- /wp:separator --> | |
<!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon","style":{"color":{"duotone":["#ffffff","#ffffff"]}}} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"white"} --> | |
<p class="has-white-color has-text-color">Custom hybrid theme (block + classic elements) | |
</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:separator {"className":"is-style-separator-dotted","style":{"color":{"background":"#ffffff40"}}} --> | |
<hr class="wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-separator-dotted" style="background-color:#ffffff40;color:#ffffff40"/> | |
<!-- /wp:separator --> | |
<!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon","style":{"color":{"duotone":["#ffffff","#ffffff"]}}} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"white"} --> | |
<p class="has-white-color has-text-color">Advanced SEO optimization</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:separator {"className":"is-style-separator-dotted","style":{"color":{"background":"#ffffff40"}}} --> | |
<hr class="wp-block-separator has-text-color has-alpha-channel-opacity has-background is-style-separator-dotted" style="background-color:#ffffff40;color:#ffffff40"/> | |
<!-- /wp:separator --> | |
<!-- wp:group {"className":"feature-item"} --> | |
<div class="wp-block-group feature-item"><!-- wp:group {"style":{"spacing":{"blockGap":"0.5rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | |
<div class="wp-block-group"><!-- wp:image {"width":"24px","height":"24px","className":"feature-icon","style":{"color":{"duotone":["#ffffff","#ffffff"]}}} --> | |
<figure class="wp-block-image is-resized feature-icon"><img src="<?php echo esc_url(get_theme_file_uri('resources/images/icons/pricing/check-circle.svg')); ?>" alt="Check icon" style="width:24px;height:24px"/></figure> | |
<!-- /wp:image --> | |
<!-- wp:paragraph {"textColor":"white"} --> | |
<p class="has-white-color has-text-color">6-month maintenance plan</p> | |
<!-- /wp:paragraph --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> | |
<!-- wp:buttons {"style":{"spacing":{"margin":{"top":"2rem"}}},"layout":{"type":"flex","justifyContent":"left"}} --> | |
<div class="wp-block-buttons" style="margin-top:2rem"><!-- wp:button {"backgroundColor":"base","textColor":"black","style":{"border":{"radius":"0.5rem"}}} --> | |
<div class="wp-block-button"><a class="wp-block-button__link has-black-color has-base-background-color has-text-color has-background wp-element-button" style="border-radius:0.5rem">Get Started</a></div> | |
<!-- /wp:button --></div> | |
<!-- /wp:buttons --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:column --></div> | |
<!-- /wp:columns --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --></div> | |
<!-- /wp:group --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment