Dashboard
PHP:
8.4.22
OS:
Linux
User:
provencez
/
/
home
/
provencez
/
www
/
wp-content
/
plugins
/
flexa-block
/
build
/
blocks
/
team-member
📤 Upload
📝 New File
📁 New Folder
Close
Editing: render.php
<?php /** * Team Member block — server-side render. * * CSS is generated at save time by Team_Member_CSS and printed inline on the * front end. This file outputs the photo plus the content column — name, role, * bio and a row of linked social icons. All text is escaped (wp_kses with a * small inline whitelist); icons run through HTML_Helpers::svg_kses. The card * inherits the theme's typography unless the user overrode it. * * @package Flexa\Block * * @var array $attributes Block attributes. * @var string $content Save content (unused — dynamic block). * @var WP_Block $block Block instance. */ if ( ! defined( 'ABSPATH' ) ) { exit; } // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- $attributes provided by WP block API. use Flexa\Block\HTML_Helpers; $block_id = $attributes['blockId'] ?? ''; $anchor = $attributes['anchor'] ?? ''; $html_tag = HTML_Helpers::get_html_tag( $attributes ); $image_position = in_array( $attributes['imagePosition'] ?? 'top', [ 'top', 'left', 'right' ], true ) ? $attributes['imagePosition'] : 'top'; $image_shape = in_array( $attributes['imageShape'] ?? 'circle', [ 'circle', 'rounded', 'square' ], true ) ? $attributes['imageShape'] : 'circle'; $stack_on = in_array( $attributes['stackOn'] ?? 'none', [ 'tablet', 'mobile' ], true ) ? $attributes['stackOn'] : 'none'; // Name element tag — whitelist so only a known tag reaches the markup. $text_tags = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'div' ]; $name_tag = in_array( $attributes['nameTag'] ?? 'h3', $text_tags, true ) ? $attributes['nameTag'] : 'h3'; $name = (string) ( $attributes['name'] ?? '' ); $role = (string) ( $attributes['role'] ?? '' ); $bio = (string) ( $attributes['bio'] ?? '' ); $show_social = false !== ( $attributes['showSocial'] ?? true ); // Inline formatting allowed inside each text field. $inline_allowed = [ 'strong' => [], 'em' => [], 'b' => [], 'i' => [], 'br' => [], 'span' => [], ]; $bio_allowed = $inline_allowed + [ 'a' => [ 'href' => true, 'target' => true, 'rel' => true ] ]; // --- Photo ----------------------------------------------------------------- $photo_html = ''; $image = $attributes['image'] ?? []; $image_url = (string) ( $image['url'] ?? '' ); if ( '' !== $image_url ) { $photo_html = '<div class="flexa-team-member__photo"><img class="flexa-team-member__image" src="' . esc_url( $image_url ) . '" alt="' . esc_attr( (string) ( $image['alt'] ?? '' ) ) . '" loading="lazy" decoding="async" /></div>'; } // --- Text pieces ----------------------------------------------------------- $name_html = '' !== trim( $name ) ? '<' . $name_tag . ' class="flexa-team-member__name">' . wp_kses( $name, $inline_allowed ) . '</' . $name_tag . '>' : ''; $role_html = '' !== trim( $role ) ? '<span class="flexa-team-member__role">' . wp_kses( $role, $inline_allowed ) . '</span>' : ''; $bio_html = '' !== trim( $bio ) ? '<p class="flexa-team-member__bio">' . wp_kses( $bio, $bio_allowed ) . '</p>' : ''; // --- Social links ---------------------------------------------------------- $social_html = ''; if ( $show_social ) { $items = is_array( $attributes['items'] ?? null ) ? $attributes['items'] : []; $links_html = ''; foreach ( $items as $item ) { if ( ! is_array( $item ) ) { continue; } // Resolve the icon to inline SVG (builtin/library) or an <img> (upload). $icon_cfg = is_array( $item['icon'] ?? null ) ? $item['icon'] : []; $source = (string) ( $icon_cfg['source'] ?? 'none' ); $markup = (string) ( $icon_cfg['markup'] ?? '' ); $icon_url = (string) ( $icon_cfg['url'] ?? '' ); if ( 'upload' === $source && '' !== $icon_url ) { $icon_svg = '<img class="flexa-icon" src="' . esc_url( $icon_url ) . '" alt="" width="24" height="24" loading="lazy" />'; } elseif ( 'none' !== $source && '' !== $markup ) { $icon_svg = HTML_Helpers::svg_kses( $markup ); if ( '' === $icon_svg ) { continue; } } else { continue; } $label = '' !== (string) ( $icon_cfg['name'] ?? '' ) ? (string) $icon_cfg['name'] : __( 'Social link', 'flexa-block' ); $inner = '<span class="flexa-icon-slot">' . $icon_svg . '</span>'; $link = is_array( $item['link'] ?? null ) ? $item['link'] : []; $url = (string) ( $link['url'] ?? '' ); if ( '' !== $url ) { $link_attrs = 'class="flexa-team-member__social-link" href="' . esc_url( $url ) . '" aria-label="' . esc_attr( $label ) . '"'; if ( '_blank' === ( $link['target'] ?? '' ) ) { $rel = trim( (string) ( $link['rel'] ?? '' ) ); if ( '' === $rel ) { $rel = 'noopener noreferrer'; } $rel = trim( (string) preg_replace( '/[^a-z0-9 _-]/i', '', $rel ) ); $link_attrs .= ' target="_blank" rel="' . esc_attr( $rel ) . '"'; } $links_html .= '<a ' . $link_attrs . '>' . $inner . '</a>'; } else { $links_html .= '<span class="flexa-team-member__social-link">' . $inner . '</span>'; } } if ( '' !== $links_html ) { $social_html = '<div class="flexa-team-member__social">' . $links_html . '</div>'; } } $content_inner = $name_html . $role_html . $bio_html . $social_html; if ( '' === $photo_html && '' === $content_inner ) { return; } $content_html = '' !== $content_inner ? '<div class="flexa-team-member__content">' . $content_inner . '</div>' : ''; // --- Wrapper --------------------------------------------------------------- $classes = [ 'flexa-team-member', 'flexa-team-member--pos-' . $image_position, 'flexa-team-member--shape-' . $image_shape, ]; if ( 'top' !== $image_position && 'none' !== $stack_on ) { $classes[] = 'flexa-team-member--stack-' . $stack_on; } if ( '' !== $block_id ) { $classes[] = 'flexa-team-member-' . sanitize_html_class( $block_id ); } $classes = HTML_Helpers::build_wrapper_classes( $classes, $attributes ); $wrapper_args = [ 'class' => implode( ' ', $classes ) ]; if ( $anchor ) { $wrapper_args['id'] = sanitize_html_class( $anchor ); } $wrapper_attributes = get_block_wrapper_attributes( $wrapper_args ); $data_attrs = HTML_Helpers::build_data_attrs( $attributes ); // Lazy background: mark the wrapper so view.js reveals the image near the viewport. $background = $attributes['background'] ?? []; $is_lazy_bg = ! empty( $background['lazyLoad'] ) && 'image' === ( $background['type'] ?? 'none' ) && '' !== ( $background['image']['url'] ?? '' ); $lazy_marker = $is_lazy_bg ? ' data-flexa-lazy-bg' : ''; printf( '<%1$s %2$s%3$s%4$s>%5$s%6$s</%1$s>', esc_html( $html_tag ), $wrapper_attributes, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built via get_block_wrapper_attributes. $data_attrs, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- keys sanitized, values escaped in helper. $lazy_marker, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static literal. $photo_html, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- image src/alt escaped above. $content_html // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- text wp_kses'd, icons via svg_kses, link url/rel escaped above. );
Save
Cancel