` shell carrying * only the `data-affilun-reason` data attribute and the root * class. This satisfies selectors / counters while producing * no visible content. * - §23.1: The admin-facing `note` MUST NOT leak to non-admin * surfaces. Phase-5 gate: emit only when * `_render_meta.debug === true`. Slice 5h / Phase 11 may * tighten this with an explicit admin-capability check. * - §10 / §15: BEM class strings come pre-tokenized in * `$viewModel['classes']`. The template stamps them * verbatim and never synthesizes its own modifier strings, * except for the canonical `affilun-card--fallback` modifier * §13.3 specifies for the fallback variant root. * - All dynamic output is escaped with `esc_html` / * `esc_attr` / `esc_url`. * * The template exits on direct file access and also returns silently * when its single contract input is missing or has the wrong type. * * @package Affilun * * @var array $viewModel §8.4 array shape with `_render_meta` attached. */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! isset( $viewModel ) || ! is_array( $viewModel ) ) { return; } $affilun_classes = ( isset( $viewModel['classes'] ) && is_array( $viewModel['classes'] ) ) ? $viewModel['classes'] : array(); $affilun_render_meta = ( isset( $viewModel['_render_meta'] ) && is_array( $viewModel['_render_meta'] ) ) ? $viewModel['_render_meta'] : array(); $affilun_root_class = isset( $affilun_classes['root'] ) ? (string) $affilun_classes['root'] : 'affilun-card'; $affilun_title_class = isset( $affilun_classes['title'] ) ? (string) $affilun_classes['title'] : 'affilun-card__title'; $affilun_buttons_class = isset( $affilun_classes['buttons'] ) ? (string) $affilun_classes['buttons'] : 'affilun-card__buttons'; $affilun_reason = isset( $viewModel['reason'] ) ? (string) $viewModel['reason'] : ''; $affilun_title = ( isset( $viewModel['title'] ) && is_string( $viewModel['title'] ) && $viewModel['title'] !== '' ) ? $viewModel['title'] : null; $affilun_button = ( isset( $viewModel['primary_button'] ) && is_array( $viewModel['primary_button'] ) ) ? $viewModel['primary_button'] : null; $affilun_note = ( isset( $viewModel['note'] ) && is_string( $viewModel['note'] ) && $viewModel['note'] !== '' ) ? $viewModel['note'] : null; $affilun_locale = ( isset( $affilun_render_meta['locale'] ) && is_string( $affilun_render_meta['locale'] ) && $affilun_render_meta['locale'] !== '' ) ? $affilun_render_meta['locale'] : null; $affilun_debug = ! empty( $affilun_render_meta['debug'] ); $affilun_tracking_enabled = ! empty( $affilun_render_meta['tracking_enabled'] ); $affilun_locale_key = $affilun_locale === null ? 'ja' : strtolower( str_replace( '_', '-', $affilun_locale ) ); $affilun_is_ja = $affilun_locale_key === 'ja' || strpos( $affilun_locale_key, 'ja-' ) === 0; $affilun_fallback_copy = $affilun_is_ja ? '商品情報・価格・在庫状況はリンク先のAmazonでご確認ください。' : 'Check current product details, price, and availability on Amazon.'; $affilun_affiliate_disclosure = $affilun_is_ja ? '※本リンクはアフィリエイトリンクです。' : 'This is an affiliate link.'; $affilun_root_attr_class = $affilun_root_class . ' affilun-card--fallback'; $affilun_lang_attr = $affilun_locale !== null ? ' lang="' . esc_attr( $affilun_locale ) . '"' : ''; ?>
>