From 8e7c5df1b9ec07445f372bdbf3272d76295405cd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:43:41 +0000 Subject: [PATCH] chore: sync funkycommerce-headless from monorepo Source: coded-letter/coded-letter-monorepo@85e3fb0fe8ae963804a546effc243d1359feff2b --- .monorepo-source.json | 2 +- assets/video-hero-block.js | 2 ++ functions.php | 6 ++++-- inc/control-center.php | 33 ++++++++++++++++++++++++++++----- inc/multilingual-content.php | 16 ++++++++++++++++ inc/native-shortcodes.php | 6 ++++-- inc/navigation-commerce.php | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- readme.txt | 7 ++++++- style.css | 2 +- 11 files changed, 67 insertions(+), 15 deletions(-) diff --git a/.monorepo-source.json b/.monorepo-source.json index 4a9da44..c1dea3a 100644 --- a/.monorepo-source.json +++ b/.monorepo-source.json @@ -1,7 +1,7 @@ { "productId": "funkycommerce-headless", "repository": "coded-letter/superfunky-theme", - "source": "coded-letter/coded-letter-monorepo@d16d4008f1dc5c092d4866337e74d458994039a0", + "source": "coded-letter/coded-letter-monorepo@85e3fb0fe8ae963804a546effc243d1359feff2b", "sourcePath": "workspace/backend/wordpress/themes/free/funkycommerce-headless", "installSlug": "funkycommerce-headless", "kind": "theme", diff --git a/assets/video-hero-block.js b/assets/video-hero-block.js index 1c305b9..acbbb1e 100644 --- a/assets/video-hero-block.js +++ b/assets/video-hero-block.js @@ -18,6 +18,7 @@ poster: { type: 'string', default: '' }, kicker: { type: 'string', default: '' }, title: { type: 'string', default: 'Video hero' }, + headingLevel: { type: 'string', default: 'h2' }, description: { type: 'string', default: '' }, primaryCtaLabel: { type: 'string', default: '' }, primaryCtaHref: { type: 'string', default: '' }, @@ -52,6 +53,7 @@ el( SelectControl, { label: i18n.__( 'View', 'funkycommerce-headless' ), value: a.variant, options: [ { label: 'Full bleed', value: 'fullbleed' }, { label: 'Atmospheric glow', value: 'glow' }, { label: 'Split media/content', value: 'split' }, { label: 'Minimal editorial', value: 'minimal' }, { label: 'Compact strip', value: 'strip' } ], onChange: field( 'variant' ) } ), el( TextControl, { label: i18n.__( 'Kicker', 'funkycommerce-headless' ), value: a.kicker, onChange: field( 'kicker' ) } ), el( TextControl, { label: i18n.__( 'Heading', 'funkycommerce-headless' ), value: a.title, onChange: field( 'title' ) } ), + el( SelectControl, { label: i18n.__( 'Heading level', 'funkycommerce-headless' ), value: a.headingLevel, options: [ { label: 'H1', value: 'h1' }, { label: 'H2', value: 'h2' }, { label: 'H3', value: 'h3' }, { label: 'H4', value: 'h4' }, { label: 'H5', value: 'h5' }, { label: 'H6', value: 'h6' } ], onChange: field( 'headingLevel' ) } ), el( TextareaControl, { label: i18n.__( 'Description', 'funkycommerce-headless' ), value: a.description, onChange: field( 'description' ) } ), el( TextControl, { label: i18n.__( 'Primary button label', 'funkycommerce-headless' ), value: a.primaryCtaLabel, onChange: field( 'primaryCtaLabel' ) } ), el( TextControl, { label: i18n.__( 'Primary button URL', 'funkycommerce-headless' ), value: a.primaryCtaHref, onChange: field( 'primaryCtaHref' ) } ), diff --git a/functions.php b/functions.php index f947bd2..f485c83 100644 --- a/functions.php +++ b/functions.php @@ -9,7 +9,7 @@ exit; } -define( 'FUNKYCOMMERCE_HEADLESS_VERSION', '1.2.15' ); +define( 'FUNKYCOMMERCE_HEADLESS_VERSION', '1.2.16' ); /** * Whether Superfunky Pro is active and licensed. @@ -424,6 +424,7 @@ function funkycommerce_content_shortcode_schemas() { 'poster' => array( 'default' => '', 'type' => 'url' ), 'kicker' => array( 'default' => '' ), 'title' => array( 'default' => __( 'Video hero', 'funkycommerce-headless' ) ), + 'heading_level' => array( 'default' => 'h2', 'enum' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ) ), 'description' => array( 'default' => '' ), 'primary_cta_label' => array( 'default' => '' ), 'primary_cta_href' => array( 'default' => '', 'type' => 'url-path' ), @@ -917,6 +918,7 @@ function funkycommerce_register_video_hero_block() { 'attributes' => array( 'src' => array( 'type' => 'string', 'default' => '' ), 'variant' => array( 'type' => 'string', 'default' => 'fullbleed' ), 'poster' => array( 'type' => 'string', 'default' => '' ), 'kicker' => array( 'type' => 'string', 'default' => '' ), 'title' => array( 'type' => 'string', 'default' => 'Video hero' ), + 'headingLevel' => array( 'type' => 'string', 'default' => 'h2' ), 'description' => array( 'type' => 'string', 'default' => '' ), 'primaryCtaLabel' => array( 'type' => 'string', 'default' => '' ), 'primaryCtaHref' => array( 'type' => 'string', 'default' => '' ), 'secondaryCtaLabel' => array( 'type' => 'string', 'default' => '' ), 'secondaryCtaHref' => array( 'type' => 'string', 'default' => '' ), 'align' => array( 'type' => 'string', 'default' => 'left' ), @@ -932,7 +934,7 @@ function funkycommerce_register_video_hero_block() { function funkycommerce_render_video_hero_block( $attributes ) { $map = array( - 'src' => 'src', 'variant' => 'variant', 'poster' => 'poster', 'kicker' => 'kicker', 'title' => 'title', 'description' => 'description', + 'src' => 'src', 'variant' => 'variant', 'poster' => 'poster', 'kicker' => 'kicker', 'title' => 'title', 'headingLevel' => 'heading_level', 'description' => 'description', 'primaryCtaLabel' => 'primary_cta_label', 'primaryCtaHref' => 'primary_cta_href', 'secondaryCtaLabel' => 'secondary_cta_label', 'secondaryCtaHref' => 'secondary_cta_href', 'align' => 'align', 'height' => 'height', 'overlayOpacity' => 'overlay_opacity', diff --git a/inc/control-center.php b/inc/control-center.php index b0f8ba4..2763492 100644 --- a/inc/control-center.php +++ b/inc/control-center.php @@ -508,7 +508,7 @@ function funkycommerce_sanitize_control_center( $input ) { $output['backend_noindex_acknowledged'] = $previous['backend_noindex_acknowledged'] ?? 'no'; } - $languages = function_exists( 'funkycommerce_available_language_slugs' ) ? funkycommerce_available_language_slugs() : array(); + $languages = funkycommerce_control_center_language_slugs(); foreach ( $languages as $language ) { $tagline_key = 'store_tagline_' . $language; $promo_key = 'promo_text_' . $language; @@ -533,6 +533,22 @@ function funkycommerce_sanitize_control_center( $input ) { return $output; } +/** + * Return Polylang languages or the site's default language for editable UI strings. + */ +function funkycommerce_control_center_language_slugs() { + $languages = function_exists( 'funkycommerce_available_language_slugs' ) ? funkycommerce_available_language_slugs() : array(); + if ( $languages ) { + return $languages; + } + if ( function_exists( 'funkycommerce_site_default_language_slug' ) ) { + return array( funkycommerce_site_default_language_slug() ); + } + $locale = (string) get_option( 'WPLANG', '' ); + $slug = sanitize_key( strtolower( strtok( $locale ?: 'en_US', '_-' ) ) ); + return array( $slug ?: 'en' ); +} + /** * Keep old option consumers working while the rest of the backend is migrated. */ @@ -762,6 +778,7 @@ function funkycommerce_storefront_control_settings( $language = '' ) { 'quietSeconds' => max( 2, min( 300, (int) ( $settings['recent_orders_quiet_seconds'] ?? 8 ) ) ), 'openLinksInNewTab' => 'yes' === ( $settings['recent_orders_links_new_tab'] ?? 'yes' ), ), + 'soundsEnabled' => 'yes' === ( $settings['sounds_enabled'] ?? 'no' ), 'loading' => array( 'enabled' => 'yes' === ( $settings['loader_enabled'] ?? 'yes' ), 'customUrl' => esc_url_raw( $settings['loader_custom_url'] ?? '' ), @@ -1378,16 +1395,22 @@ function funkycommerce_render_control_center() { $field ) : funkycommerce_render_control_field( $key, $field, $settings[ $key ] ?? ( $field['default'] ?? '' ) ); endforeach; ?> - +

-

- +

+
__( 'Store tagline', 'funkycommerce-headless' ), 'type' => 'text' ), $settings[ 'store_tagline_' . $slug ] ?? '' ); funkycommerce_render_control_field( 'promo_text_' . $slug, array( 'label' => __( 'Promotional message', 'funkycommerce-headless' ), 'type' => 'text' ), $settings[ 'promo_text_' . $slug ] ?? '' ); - $ui_strings = wp_json_encode( funkycommerce_storefront_ui_strings_for_language( $slug ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); + $ui_strings = wp_json_encode( + array_merge( + funkycommerce_storefront_ui_strings_for_language( 'en' ), + funkycommerce_storefront_ui_strings_for_language( $slug ) + ), + JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE + ); funkycommerce_render_control_field( 'ui_strings_' . $slug, array( 'label' => __( 'Storefront UI strings', 'funkycommerce-headless' ), 'type' => 'json', 'default' => '{}' ), $ui_strings ?: '{}' ); ?>
diff --git a/inc/multilingual-content.php b/inc/multilingual-content.php index 821d4a2..14289b1 100644 --- a/inc/multilingual-content.php +++ b/inc/multilingual-content.php @@ -41,6 +41,15 @@ function funkycommerce_polylang_taxonomies( $taxonomies, $is_settings ) { } add_filter( 'pll_get_taxonomies', 'funkycommerce_polylang_taxonomies', 10, 2 ); +function funkycommerce_site_default_language_slug() { + $locale = (string) get_option( 'WPLANG', '' ); + if ( '' === $locale ) { + $locale = 'en_US'; + } + $slug = sanitize_key( strtolower( strtok( $locale, '_-' ) ) ); + return $slug ?: 'en'; +} + function funkycommerce_available_language_slugs() { if ( ! function_exists( 'pll_languages_list' ) ) { return array(); @@ -274,6 +283,13 @@ function funkycommerce_language_data( $slug ) { 'locale' => '', ); if ( ! function_exists( 'pll_languages_list' ) ) { + $locale = (string) get_option( 'WPLANG', '' ); + $locale = $locale ?: 'en_US'; + if ( funkycommerce_site_default_language_slug() === $slug ) { + $translations = function_exists( 'wp_get_available_translations' ) ? wp_get_available_translations() : array(); + $data['name'] = (string) ( $translations[ $locale ]['native_name'] ?? $locale ); + $data['locale'] = $locale; + } return $data; } diff --git a/inc/native-shortcodes.php b/inc/native-shortcodes.php index 6f9fd59..d1ffdfb 100644 --- a/inc/native-shortcodes.php +++ b/inc/native-shortcodes.php @@ -965,9 +965,10 @@ function funkycommerce_native_render_video_hero( $atts ) { $ctas = funkycommerce_native_cta_link( $a['primary_cta_label'], $a['primary_cta_href'], $a['primary_cta_target'], $a['primary_cta_rel'], 'funkycommerce-native-cta funkycommerce-native-cta--primary' ); $ctas .= funkycommerce_native_cta_link( $a['secondary_cta_label'], $a['secondary_cta_href'], $a['secondary_cta_target'], $a['secondary_cta_rel'], 'funkycommerce-native-cta funkycommerce-native-cta--secondary' ); $height = preg_match( '/^\d+(px|vh|%)$/', $a['height'] ) ? $a['height'] : '70vh'; + $heading_tag = in_array( $a['heading_level'], array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), true ) ? $a['heading_level'] : 'h2'; return sprintf( - '
%3$s%4$s
%6$s

%7$s

%8$s%9$s
', + '
%3$s%4$s
%6$s<%18$s>%7$s%8$s%9$s
', esc_attr( $a['align'] ), esc_attr( $height ), $poster, @@ -984,7 +985,8 @@ function funkycommerce_native_render_video_hero( $atts ) { $a['muted'] ? '🔇' : '🔊', $starts_playing ? esc_attr__( 'Pause background video', 'funkycommerce-headless' ) : esc_attr__( 'Play background video', 'funkycommerce-headless' ), $starts_playing ? '❚❚' : '▶', - esc_attr( $a['variant'] ) + esc_attr( $a['variant'] ), + $heading_tag ); } diff --git a/inc/navigation-commerce.php b/inc/navigation-commerce.php index 096426e..df81c46 100644 --- a/inc/navigation-commerce.php +++ b/inc/navigation-commerce.php @@ -492,6 +492,7 @@ function funkycommerce_register_navigation_commerce_graphql() { 'aiAssistant' => array( 'type' => array( 'non_null' => 'FunkyCommerceAiAssistant' ) ), 'footer' => array( 'type' => array( 'non_null' => 'FunkyCommerceFooter' ) ), 'recentOrders' => array( 'type' => array( 'non_null' => 'FunkyCommerceRecentOrders' ) ), + 'soundsEnabled' => array( 'type' => array( 'non_null' => 'Boolean' ) ), 'loading' => array( 'type' => array( 'non_null' => 'FunkyCommerceLoading' ) ), 'features' => array( 'type' => array( 'non_null' => 'FunkyCommerceFeatures' ) ), 'payments' => array( 'type' => array( 'non_null' => 'FunkyCommercePaymentPresentation' ) ), @@ -544,6 +545,7 @@ function funkycommerce_register_navigation_commerce_graphql() { 'aiAssistant' => $controls['aiAssistant'], 'footer' => $controls['footer'], 'recentOrders' => $controls['recentOrders'], + 'soundsEnabled' => $controls['soundsEnabled'], 'loading' => $controls['loading'], 'features' => $controls['features'], 'payments' => $controls['payments'], diff --git a/package-lock.json b/package-lock.json index d6cfb4e..e142a6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "funkycommerce-headless-theme", - "version": "1.2.15", + "version": "1.2.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "funkycommerce-headless-theme", - "version": "1.2.15", + "version": "1.2.16", "devDependencies": { "autoprefixer": "^10.4.20", "esbuild": "^0.28.2", diff --git a/package.json b/package.json index 6549a9e..5ad199c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "funkycommerce-headless-theme", "private": true, - "version": "1.2.15", + "version": "1.2.16", "description": "Tailwind/build tooling for the FunkyCommerce Headless WordPress theme's native frontend assets (block templates, template parts, loader, and Spotify slot).", "scripts": { "build:css": "tailwindcss -i ./assets/css/theme-source.css -o ./assets/dist/theme.css --minify", diff --git a/readme.txt b/readme.txt index debd107..10f58dd 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: headless, woocommerce, wpgraphql, full-site-editing Requires at least: 6.7 Tested up to: 6.8 Requires PHP: 7.4 -Stable tag: 1.2.15 +Stable tag: 1.2.16 License: GPL-2.0-or-later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -15,6 +15,11 @@ Control Center, the theme also ships a complete native WordPress rendering path "Native frontend theme" below) with accessible header/footer/navigation templates and core front/home/singular/archive/search/404 routes styled to match the storefront. +== 1.2.16 highlights == + +* Adds validated H1-H6 controls to video heroes and keeps static hero heading levels consistent in native and headless rendering. +* Fixes root fragment links from nested routes, honors the interaction-sound toggle, and exposes default-language UI strings without requiring Polylang. + == 1.2.15 highlights == * Disables automatic paragraph and line-break insertion across WordPress-rendered content. diff --git a/style.css b/style.css index 6bd4b8f..0259556 100644 --- a/style.css +++ b/style.css @@ -7,7 +7,7 @@ Description: A minimal, content-first block theme for polished WordPress preview Requires at least: 6.7 Tested up to: 6.8 Requires PHP: 7.4 -Version: 1.2.15 +Version: 1.2.16 Update URI: https://github.com/coded-letter/superfunky-theme License: GPL-2.0-or-later License URI: https://www.gnu.org/licenses/gpl-2.0.html