| @@ -4,13 +4,13 @@ | ||
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | use FluentCart\App\Hooks\Handlers\CPTHandler; |
| 7 | 7 | use FluentCart\App\Modules\Data\ProductDataSetup; |
| 8 | +use FluentCart\App\Modules\Templating\AssetLoader; | |
| 8 | 9 | use FluentCart\App\Services\Renderer\ProductCardRender; |
| 9 | 10 | |
| 10 | 11 | class DynamicData |
| 11 | 12 | { |
| 12 | - | |
| 13 | 13 | public function register() |
| 14 | 14 | { |
| 15 | 15 | add_filter('bricks/dynamic_tags_list', function ($tags) { |
| 16 | 16 | $fctTags = $this->getTagsPairs(); |
| @@ -33,10 +33,12 @@ | ||
| 33 | 33 | { |
| 34 | 34 | return [ |
| 35 | 35 | 'fct_product_title:linked' => __('Product Title', 'fluent-cart'), |
| 36 | 36 | 'fct_product_image' => __('Product Image', 'fluent-cart'), |
| 37 | + 'fct_product_excerpt' => __('Product Excerpt', 'fluent-cart'), | |
| 37 | 38 | 'fct_product_price' => __('Product Price', 'fluent-cart'), |
| 38 | - 'fct_product_view_button' => __('Product Link Button', 'fluent-cart'), | |
| 39 | + 'fct_product_button' => __('Product Button', 'fluent-cart'), | |
| 40 | + 'fct_product_view_button' => __('Product Button', 'fluent-cart'), // Legacy alias for backward compatibility | |
| 39 | 41 | ]; |
| 40 | 42 | } |
| 41 | 43 | |
| 42 | 44 | public function renderValue($tag, $post, $context = 'text') |
| @@ -66,9 +68,11 @@ | ||
| 66 | 68 | switch ($tagName) { |
| 67 | 69 | case 'fct_product_title': |
| 68 | 70 | $productName = $post->post_title; |
| 69 | 71 | if (in_array('linked', $tagParts)) { |
| 70 | - $productName = '<a href="' . get_permalink($post) . '">' . $productName . '</a>'; | |
| 72 | + $productName = '<a href="' . get_permalink($post) . '" data-fct-field="product-title">' . $productName . '</a>'; | |
| 73 | + } else { | |
| 74 | + $productName = '<span data-fct-field="product-title">' . $productName . '</span>'; | |
| 71 | 75 | } |
| 72 | 76 | return $productName; |
| 73 | 77 | case 'fct_product_image': |
| 74 | 78 | $productModel = ProductDataSetup::getProductModel($post->ID); |
| @@ -74,25 +78,41 @@ | ||
| 74 | 78 | $productModel = ProductDataSetup::getProductModel($post->ID); |
| 75 | 79 | if ($productModel) { |
| 76 | 80 | ob_start(); |
| 77 | 81 | (new ProductCardRender($productModel))->renderProductImage(); |
| 78 | - return ob_get_clean(); | |
| 82 | + $content = ob_get_clean(); | |
| 83 | + | |
| 84 | + $badgesHtml = BricksHelper::renderProductBadges($productModel, BricksHelper::$imageBadgeSettings); | |
| 85 | + | |
| 86 | + return '<span data-fct-field="product-image">' . $content . $badgesHtml . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- renderProductBadges() escapes its own output | |
| 79 | 87 | } |
| 80 | 88 | break; |
| 89 | + case 'fct_product_excerpt': | |
| 90 | + $excerpt = $post->post_excerpt; | |
| 91 | + if ($excerpt) { | |
| 92 | + return '<span data-fct-field="product-excerpt">' . wp_kses_post($excerpt) . '</span>'; | |
| 93 | + } | |
| 94 | + return ''; | |
| 81 | 95 | case 'fct_product_price': |
| 82 | 96 | $productModel = ProductDataSetup::getProductModel($post->ID); |
| 83 | 97 | if ($productModel) { |
| 98 | + // Price markup relies on the .fct-sr-only rule shipped with the | |
| 99 | + // single product styles; without it the labels render visibly. | |
| 100 | + AssetLoader::loadSingleProductAssets(); | |
| 84 | 101 | ob_start(); |
| 85 | 102 | (new ProductCardRender($productModel))->renderPrices(); |
| 86 | - return ob_get_clean(); | |
| 103 | + $content = ob_get_clean(); | |
| 104 | + return '<span data-fct-field="product-price">' . $content . '</span>'; | |
| 87 | 105 | } |
| 88 | 106 | break; |
| 107 | + case 'fct_product_view_button': // Legacy alias for backward compatibility | |
| 89 | 108 | case 'fct_product_button': |
| 90 | 109 | $productModel = ProductDataSetup::getProductModel($post->ID); |
| 91 | 110 | if ($productModel) { |
| 92 | 111 | ob_start(); |
| 93 | 112 | (new ProductCardRender($productModel))->showBuyButton(); |
| 94 | - return ob_get_clean(); | |
| 113 | + $content = ob_get_clean(); | |
| 114 | + return '<span data-fct-field="product-button">' . $content . '</span>'; | |
| 95 | 115 | } |
| 96 | 116 | break; |
| 97 | 117 | } |
| 98 | 118 | |