$settings Settings. * * @return string */ public static function build_css( array $settings ): string { $style = isset( $settings['style'] ) && is_array( $settings['style'] ) ? $settings['style'] : array(); $border_style = Css::sanitize_border_style( $style['border_style'] ?? 'solid', 'solid' ); $border_color = Css::sanitize_color( $style['border_color'] ?? '#cbd5e1', '#cbd5e1' ); $border_width_top = isset( $style['border_width_top'] ) ? (int) $style['border_width_top'] : 1; $border_width_right = isset( $style['border_width_right'] ) ? (int) $style['border_width_right'] : 1; $border_width_bottom = isset( $style['border_width_bottom'] ) ? (int) $style['border_width_bottom'] : 1; $border_width_left = isset( $style['border_width_left'] ) ? (int) $style['border_width_left'] : 1; $border_radius = isset( $style['border_radius'] ) ? (int) $style['border_radius'] : 8; $padding_top = isset( $style['padding_top'] ) ? (int) $style['padding_top'] : 16; $padding_right = isset( $style['padding_right'] ) ? (int) $style['padding_right'] : 16; $padding_bottom = isset( $style['padding_bottom'] ) ? (int) $style['padding_bottom'] : 16; $padding_left = isset( $style['padding_left'] ) ? (int) $style['padding_left'] : 16; $margin_top = isset( $style['margin_top'] ) ? (int) $style['margin_top'] : 0; $margin_right = isset( $style['margin_right'] ) ? (int) $style['margin_right'] : 0; $margin_bottom = isset( $style['margin_bottom'] ) ? (int) $style['margin_bottom'] : 0; $margin_left = isset( $style['margin_left'] ) ? (int) $style['margin_left'] : 0; $bg_color = Css::sanitize_color( $style['bg_color'] ?? '#f8fafc', '#f8fafc' ); $item_text = Css::sanitize_color( $style['item_text_color'] ?? '#0f172a', '#0f172a' ); $item_font_size = isset( $style['item_font_size'] ) ? (int) $style['item_font_size'] : 16; $item_gap = isset( $style['item_gap'] ) ? (int) $style['item_gap'] : 10; $item_weight = ! empty( $style['item_bold'] ) ? '700' : '400'; $item_font_style = ! empty( $style['item_italic'] ) ? 'italic' : 'normal'; $item_decoration = ! empty( $style['item_underline'] ) ? 'underline' : 'none'; $item_list_style = Css::sanitize_list_style( $style['item_list_style'] ?? 'none', 'none' ); $header_container = isset( $style['header_container'] ) && is_array( $style['header_container'] ) ? $style['header_container'] : array(); $header_title = isset( $style['header_title'] ) && is_array( $style['header_title'] ) ? $style['header_title'] : array(); $header_border_top = isset( $header_container['border_width_top'] ) ? (int) $header_container['border_width_top'] : 0; $header_border_right = isset( $header_container['border_width_right'] ) ? (int) $header_container['border_width_right'] : 0; $header_border_bottom = isset( $header_container['border_width_bottom'] ) ? (int) $header_container['border_width_bottom'] : 0; $header_border_left = isset( $header_container['border_width_left'] ) ? (int) $header_container['border_width_left'] : 0; $header_border_radius = isset( $header_container['border_radius'] ) ? (int) $header_container['border_radius'] : 0; $header_border_style = Css::sanitize_border_style( $header_container['border_style'] ?? 'solid', 'solid' ); $header_border_color = Css::sanitize_color( $header_container['border_color'] ?? '#cbd5e1', '#cbd5e1' ); $header_bg_color = Css::sanitize_color( $header_container['bg_color'] ?? 'transparent', 'transparent' ); $header_padding_top = isset( $header_container['padding_top'] ) ? (int) $header_container['padding_top'] : 0; $header_padding_right = isset( $header_container['padding_right'] ) ? (int) $header_container['padding_right'] : 0; $header_padding_bottom = isset( $header_container['padding_bottom'] ) ? (int) $header_container['padding_bottom'] : 0; $header_padding_left = isset( $header_container['padding_left'] ) ? (int) $header_container['padding_left'] : 0; $header_margin_top = isset( $header_container['margin_top'] ) ? (int) $header_container['margin_top'] : 0; $header_margin_right = isset( $header_container['margin_right'] ) ? (int) $header_container['margin_right'] : 0; $header_margin_bottom = isset( $header_container['margin_bottom'] ) ? (int) $header_container['margin_bottom'] : 12; $header_margin_left = isset( $header_container['margin_left'] ) ? (int) $header_container['margin_left'] : 0; $header_title_style = isset( $header_title['font_style'] ) && is_array( $header_title['font_style'] ) ? $header_title['font_style'] : array(); $header_title_color = Css::sanitize_color( $header_title['color'] ?? '#0f172a', '#0f172a' ); $header_title_size = isset( $header_title['font_size'] ) ? (int) $header_title['font_size'] : 18; $header_title_weight = ! empty( $header_title_style['bold'] ) ? '700' : '400'; $header_title_italic = ! empty( $header_title_style['italic'] ) ? 'italic' : 'normal'; $header_title_underline = ! empty( $header_title_style['underline'] ) ? 'underline' : 'none'; $marker_css = self::build_marker_css( $item_list_style, $item_text ); return ".airygen-topic-cluster__header{margin:{$header_margin_top}px {$header_margin_right}px {$header_margin_bottom}px {$header_margin_left}px;padding:{$header_padding_top}px {$header_padding_right}px {$header_padding_bottom}px {$header_padding_left}px;border-style:{$header_border_style};border-color:{$header_border_color};border-width:{$header_border_top}px {$header_border_right}px {$header_border_bottom}px {$header_border_left}px;border-radius:{$header_border_radius}px;background:{$header_bg_color};}" . ".airygen-topic-cluster__title{margin:0;font-size:{$header_title_size}px;font-weight:{$header_title_weight};font-style:{$header_title_italic};text-decoration:{$header_title_underline};color:{$header_title_color};}" . ".airygen-topic-cluster{margin:{$margin_top}px {$margin_right}px {$margin_bottom}px {$margin_left}px;border-style:{$border_style};border-color:{$border_color};border-width:{$border_width_top}px {$border_width_right}px {$border_width_bottom}px {$border_width_left}px;border-radius:{$border_radius}px;background:{$bg_color};padding:{$padding_top}px {$padding_right}px {$padding_bottom}px {$padding_left}px;}" . '.airygen-topic-cluster__intro{margin:0 0 12px;font-size:.925rem;line-height:1.6;color:#475569;}' . ".airygen-topic-cluster__links{display:flex;flex-direction:column;gap:{$item_gap}px;}" . '.airygen-topic-cluster__item{display:flex;align-items:flex-start;gap:8px;}' . '.airygen-topic-cluster__item--parent{flex-direction:column;gap:6px;border:1px solid rgba(148,163,184,.35);border-radius:10px;background:rgba(255,255,255,.7);padding:12px;}' . '.airygen-topic-cluster__parent-label{font-size:.75rem;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:#64748b;}' . ".airygen-topic-cluster__item-marker{flex:0 0 auto;display:inline-flex;min-width:1rem;justify-content:center;color:{$item_text};font-size:{$item_font_size}px;line-height:1.5;}" . ".airygen-topic-cluster__link{color:{$item_text};font-size:{$item_font_size}px;font-weight:{$item_weight};font-style:{$item_font_style};text-decoration:{$item_decoration};text-underline-offset:2px;line-height:1.6;}" . ".airygen-topic-cluster__link[aria-current=\"page\"]{color:{$item_text};font-weight:600;}" . $marker_css; } /** * Render Topic Cluster navigation for a post. * * @param int $post_id Post ID. * * @return string */ public static function render( int $post_id ): string { $adapter = new WpDbAdapter(); $table = $adapter->table( Constants::TABLE_TOPIC_CLUSTER_RELATIONS ); $settings = \Airygen\Modules\TopicCluster\Admin\Settings::get(); if ( ! $adapter->table_exists( $table ) ) { return ''; } $current = self::fetch_entry( $adapter, $table, $post_id ); if ( null === $current ) { return ''; } $level = (int) $current['level']; if ( $level < 1 || $level > 3 ) { return ''; } $view_model = self::build_view_model( $adapter, $table, $current, $post_id ); if ( null === $view_model ) { return ''; } $title_enabled = ! empty( $settings['title_enabled'] ); $title_level = isset( $settings['title_level'] ) ? (string) $settings['title_level'] : 'h2'; $title_level = in_array( $title_level, array( 'h2', 'h3', 'h4' ), true ) ? $title_level : 'h2'; $title_text = isset( $settings['title_text'] ) && is_string( $settings['title_text'] ) && '' !== trim( $settings['title_text'] ) ? $settings['title_text'] : __( 'Featured topics', 'airygen-seo' ); $item_style = isset( $settings['style']['item_list_style'] ) ? (string) $settings['style']['item_list_style'] : 'none'; $item_style = in_array( $item_style, array( 'none', 'disc', 'decimal' ), true ) ? $item_style : 'none'; ob_start(); ?>