'srpp-edit' ), admin_url( 'admin.php' ) ); $active = 0; foreach ( $displays as $display ) { if ( $display->is_active() ) { $active++; } } echo '
'; SRPP_Admin::header( __( 'Related Content Displays', 'advanced-css3-related-posts-widget' ), __( 'From what you recommend to where it lands, in one smooth flow.', 'advanced-css3-related-posts-widget' ), sprintf( '%s', esc_url( $add_url ), esc_html__( '+ Add Related Content', 'advanced-css3-related-posts-widget' ) ), array( 'icon' => 'layers', 'highlights' => array( array( 'icon' => 'wand', 'tone' => 'amber', 'title' => __( 'What to show', 'advanced-css3-related-posts-widget' ), 'text' => __( 'Weighted relevance, not just same category.', 'advanced-css3-related-posts-widget' ), ), array( 'icon' => 'target', 'tone' => 'teal', 'title' => __( 'Where it appears', 'advanced-css3-related-posts-widget' ), 'text' => __( 'Inside content, WooCommerce hooks, anywhere.', 'advanced-css3-related-posts-widget' ), ), array( 'icon' => 'grid', 'tone' => 'violet', 'title' => __( 'How it looks', 'advanced-css3-related-posts-widget' ), 'text' => __( 'Twelve templates, responsive by column.', 'advanced-css3-related-posts-widget' ), ), ), ) ); SRPP_Admin::features( array( array( 'icon' => 'database', 'tone' => 'teal', 'title' => __( 'Cached Recommendation IDs', 'advanced-css3-related-posts-widget' ), 'text' => __( 'Relationships are resolved once and stored per post, then refreshed automatically when the post, its terms or the display change. Page views stay cheap.', 'advanced-css3-related-posts-widget' ), ), array( 'icon' => 'code', 'tone' => 'coral', 'title' => __( 'HTML-Aware Insertion', 'advanced-css3-related-posts-widget' ), 'text' => __( 'In-content placement runs through a DOM pass, so a block only ever lands between top-level elements. Lists, tables and shortcodes are never split.', 'advanced-css3-related-posts-widget' ), ), array( 'icon' => 'bolt', 'tone' => 'violet', 'title' => __( 'Nothing Loads Globally', 'advanced-css3-related-posts-widget' ), 'text' => __( 'Grid templates ship CSS only. The carousel script is enqueued on the pages that actually use a carousel, and nowhere else.', 'advanced-css3-related-posts-widget' ), ), ) ); if ( empty( $displays ) ) { echo '
'; echo SRPP_Admin::tile( 'wand', 'amber', true ); // phpcs:ignore WordPress.Security.EscapeOutput printf( '

%s

%s

%s', esc_html__( 'No displays yet', 'advanced-css3-related-posts-widget' ), esc_html__( 'Creating your first one takes four questions: what to recommend, where it appears, how many items, and which template.', 'advanced-css3-related-posts-widget' ), esc_url( $add_url ), esc_html__( 'Create a display', 'advanced-css3-related-posts-widget' ) ); echo '
'; return; } echo '
'; // Section header: icon, title, live search and status filters. ?>

'; echo '' . esc_html__( 'Display', 'advanced-css3-related-posts-widget' ) . ''; echo '' . esc_html__( 'Content', 'advanced-css3-related-posts-widget' ) . ''; echo '' . esc_html__( 'Placement', 'advanced-css3-related-posts-widget' ) . ''; echo '' . esc_html__( 'Layout', 'advanced-css3-related-posts-widget' ) . ''; echo '' . esc_html__( 'Template', 'advanced-css3-related-posts-widget' ) . ''; echo '' . esc_html__( 'Status', 'advanced-css3-related-posts-widget' ) . ''; echo '' . esc_html__( 'Shortcode', 'advanced-css3-related-posts-widget' ) . ''; echo ''; echo ''; $types = srpp_post_types(); $layouts = srpp_layouts(); $placements = array_merge( SRPP_Placement::content_placements(), srpp_is_woo_active() ? SRPP_Woo::placements() : array(), SRPP_Placement::manual_placements() ); foreach ( $displays as $display ) { $edit_url = add_query_arg( array( 'page' => 'srpp-edit', 'display' => $display->id ), admin_url( 'admin.php' ) ); $labels = array(); foreach ( (array) $display->opt( 'target_types' ) as $type ) { $labels[] = isset( $types[ $type ] ) ? $types[ $type ] : $type; } $template = SRPP_Templates::get( $display->opt( 'template' ) ); $placement = $display->opt( 'placement' ); $layout = $display->opt( 'layout' ); printf( '', $display->is_active() ? 'active' : 'inactive', esc_attr( strtolower( $display->title . ' ' . implode( ' ', $labels ) . ' ' . $template['name'] ) ) ); printf( '
%s
%s
%s
', SRPP_Admin::avatar( $display->title ), // phpcs:ignore WordPress.Security.EscapeOutput esc_url( $edit_url ), esc_html( $display->title ), wp_kses_post( $this->row_actions( $display, $edit_url ) ) ); printf( '%s%s', esc_html( implode( ', ', $labels ) ), esc_html( $this->relation_summary( $display ) ) ); printf( '%s%s', esc_html( isset( $placements[ $placement ] ) ? $placements[ $placement ] : $placement ), esc_html( $this->placement_detail( $display ) ) ); printf( '%s%s', esc_html( isset( $layouts[ $layout ] ) ? $layouts[ $layout ] : $layout ), esc_html( sprintf( /* translators: 1: items, 2: desktop cols, 3: tablet cols, 4: mobile cols */ __( '%1$d items · %2$d/%3$d/%4$d cols', 'advanced-css3-related-posts-widget' ), (int) $display->opt( 'items' ), (int) $display->opt( 'cols_d' ), (int) $display->opt( 'cols_t' ), (int) $display->opt( 'cols_m' ) ) ) ); printf( '%s', esc_html( $template['name'] ) ); printf( '%s', $display->is_active() ? 'is-active' : 'is-paused', $display->is_active() ? esc_html__( 'Active', 'advanced-css3-related-posts-widget' ) : esc_html__( 'Inactive', 'advanced-css3-related-posts-widget' ) ); printf( '[smart_related id="%d"]', esc_attr__( 'Click to copy', 'advanced-css3-related-posts-widget' ), absint( $display->id ) ); printf( '%s', esc_url( $edit_url ), esc_attr__( 'Edit display', 'advanced-css3-related-posts-widget' ), SRPP_Admin::icon( 'chevron' ) // phpcs:ignore WordPress.Security.EscapeOutput ); echo ''; } echo ''; printf( '

%s

', esc_html__( 'No displays match that search.', 'advanced-css3-related-posts-widget' ) ); echo '
'; SRPP_Admin::footnote( __( 'Several displays can run on the same article.', 'advanced-css3-related-posts-widget' ), __( 'A short "Read next" after paragraph four, a three-card block at 65%, a six-item grid at the end — each one independent, and never repeating the same item twice.', 'advanced-css3-related-posts-widget' ), sprintf( '%s', esc_url( $add_url ), esc_html__( 'Add another display', 'advanced-css3-related-posts-widget' ) ), 'sparkle', 'amber' ); $this->cheatsheet(); echo ''; } /** * Row action links. * * @param SRPP_Display $display Display. * @param string $edit_url Edit URL. * @return string */ protected function row_actions( $display, $edit_url ) { $base = add_query_arg( array( 'page' => 'srpp-displays', 'display' => $display->id ), admin_url( 'admin.php' ) ); $link = function ( $action, $label, $class = '' ) use ( $base, $display ) { $url = wp_nonce_url( add_query_arg( 'srpp_action', $action, $base ), 'srpp_row_' . $display->id ); return sprintf( '%s', esc_attr( $class ), esc_url( $url ), esc_html( $label ) ); }; $parts = array( sprintf( '%s', esc_url( $edit_url ), esc_html__( 'Edit', 'advanced-css3-related-posts-widget' ) ), $link( 'toggle', $display->is_active() ? __( 'Deactivate', 'advanced-css3-related-posts-widget' ) : __( 'Activate', 'advanced-css3-related-posts-widget' ) ), $link( 'duplicate', __( 'Duplicate', 'advanced-css3-related-posts-widget' ) ), $link( 'delete', __( 'Delete', 'advanced-css3-related-posts-widget' ), 'srpp-delete' ), ); return implode( ' · ', $parts ); } /** * Short human summary of the relation setup. * * @param SRPP_Display $display Display. * @return string */ protected function relation_summary( $display ) { $modes = array( 'auto' => __( 'Automatic', 'advanced-css3-related-posts-widget' ), 'manual' => __( 'Manual', 'advanced-css3-related-posts-widget' ), 'auto_manual' => __( 'Manual first, then automatic', 'advanced-css3-related-posts-widget' ), ); $mode = $display->opt( 'selection_mode' ); $out = isset( $modes[ $mode ] ) ? $modes[ $mode ] : $mode; $taxonomies = srpp_taxonomies(); $names = array(); foreach ( (array) $display->opt( 'relate_by' ) as $taxonomy ) { $names[] = isset( $taxonomies[ $taxonomy ] ) ? $taxonomies[ $taxonomy ] : $taxonomy; } if ( $names && 'manual' !== $mode ) { $out .= ' · ' . implode( ' + ', $names ); } return $out; } /** * Placement detail line. * * @param SRPP_Display $display Display. * @return string */ protected function placement_detail( $display ) { $placement = $display->opt( 'placement' ); $value = (int) $display->opt( 'placement_value' ); switch ( $placement ) { case 'after_paragraph': case 'before_paragraph': /* translators: %d: paragraph number */ return sprintf( __( 'Paragraph %d', 'advanced-css3-related-posts-widget' ), $value ); case 'after_percent': /* translators: %d: percentage */ return sprintf( __( '%d%% of the article', 'advanced-css3-related-posts-widget' ), $value ); case 'every_paragraphs': return sprintf( /* translators: 1: interval, 2: max blocks */ __( 'Every %1$d paragraphs, max %2$d', 'advanced-css3-related-posts-widget' ), (int) $display->opt( 'repeat_every' ), (int) $display->opt( 'repeat_max' ) ); case 'every_words': return sprintf( /* translators: 1: interval, 2: max blocks */ __( 'Every %1$d words, max %2$d', 'advanced-css3-related-posts-widget' ), (int) $display->opt( 'repeat_every' ), (int) $display->opt( 'repeat_max' ) ); } $types = srpp_post_types(); $labels = array(); foreach ( (array) $display->opt( 'cond_types' ) as $type ) { $labels[] = isset( $types[ $type ] ) ? $types[ $type ] : $type; } return $labels ? implode( ', ', $labels ) : ''; } /** * Integration cheat sheet. */ protected function cheatsheet() { ?>

[smart_related id="5"]

<?php srpp_the_related_content( 5 ); ?>