getTagsPairs(); foreach ($fctTags as $name => $label) { $tags[] = [ 'name' => '{' . $name . '}', 'label' => $label, 'group' => 'Product - FluentCart', ]; } return $tags; }); add_filter('bricks/dynamic_data/render_tag', [$this, 'renderValue'], 20, 3); add_filter('bricks/dynamic_data/render_content', [$this, 'renderValue'], 20, 3); add_filter('bricks/frontend/render_data', [$this, 'renderValue'], 20, 3); } public function getTagsPairs() { return [ 'fct_product_title:linked' => __('Product Title', 'fluent-cart'), 'fct_product_image' => __('Product Image', 'fluent-cart'), 'fct_product_excerpt' => __('Product Excerpt', 'fluent-cart'), 'fct_product_price' => __('Product Price', 'fluent-cart'), 'fct_product_button' => __('Product Button', 'fluent-cart'), 'fct_product_view_button' => __('Product Button', 'fluent-cart'), // Legacy alias for backward compatibility ]; } public function renderValue($tag, $post, $context = 'text') { if (!is_string($tag)) { return $tag; } if (strpos($tag, 'fct_product_') === false) { return $tag; } if (!$post) { $post = BricksHelper::getFormCurrentPost(); } if (!$post || $post->post_type !== 'fluent-products') { return $tag; } $tagKey = str_replace(['{', '}'], '', $tag); // explode : $tagParts = explode(':', $tagKey); $tagName = array_shift($tagParts); switch ($tagName) { case 'fct_product_title': $productName = $post->post_title; if (in_array('linked', $tagParts)) { $productName = '' . $productName . ''; } else { $productName = '' . $productName . ''; } return $productName; case 'fct_product_image': $productModel = ProductDataSetup::getProductModel($post->ID); if ($productModel) { ob_start(); (new ProductCardRender($productModel))->renderProductImage(); $content = ob_get_clean(); $badgesHtml = BricksHelper::renderProductBadges($productModel, BricksHelper::$imageBadgeSettings); return '' . $content . $badgesHtml . ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- renderProductBadges() escapes its own output } break; case 'fct_product_excerpt': $excerpt = $post->post_excerpt; if ($excerpt) { return '' . wp_kses_post($excerpt) . ''; } return ''; case 'fct_product_price': $productModel = ProductDataSetup::getProductModel($post->ID); if ($productModel) { // Price markup relies on the .fct-sr-only rule shipped with the // single product styles; without it the labels render visibly. AssetLoader::loadSingleProductAssets(); ob_start(); (new ProductCardRender($productModel))->renderPrices(); $content = ob_get_clean(); return '' . $content . ''; } break; case 'fct_product_view_button': // Legacy alias for backward compatibility case 'fct_product_button': $productModel = ProductDataSetup::getProductModel($post->ID); if ($productModel) { ob_start(); (new ProductCardRender($productModel))->showBuyButton(); $content = ob_get_clean(); return '' . $content . ''; } break; } return $tag; } }