cache = new CacheManager('blocks', DAY_IN_SECONDS); $this->imgCache = new CacheManager('images', DAY_IN_SECONDS); add_action('render_block', [$this, 'render'], 10, 3); add_action('init', [$this, 'registerBlockStyles']); } public function registerBlockStyles():void { //Register extra block styles register_block_style( 'core/navigation', [ 'name'=>'condensed', 'label' => __('Condensed', 'jvb') ] ); register_block_style( 'core/navigation', [ 'name'=>'floating', 'label' => __('Floating', 'jvb') ] ); register_block_style( 'core/navigation', [ 'name'=>'fixed', 'label' => __('Fixed', 'jvb') ] ); } public function render(string $content, array $block, WP_Block $instance) { $method = 'render_'.$this->sanitizeBlockName($block); if (method_exists($this, $method)) { return $this->$method($block, $content); //TODO: Recache it // return $this->cache->remember( // $block, // function () use ($method, $block, $content) { // return $this->$method($block, $content); // } // ); } if ($block['blockName'] === 'jvb/feed') { // Enqueue the feed block script (it will automatically load dependencies) $this->localize_feedblock(); } return $content; } /*********************************** * Blocks **********************************/ /** * Common Blocks */ //core_form //core_form_input //core_form_submission_notification //core_form_submit_button /** * Design blocks */ protected function render_core_button($block):string { $link = explode('href="', $block['innerHTML']); $url = explode('">', $link[1]); $label = explode('', $url[1])[0]; $url = $url[0]; return 'getClassesAndStyles($block['attrs'],['row']).'> '.$label.' '; } protected function render_core_buttons($block):string { return 'getClassesAndStyles($block['attrs'], ['buttons row']).'">'. $this->innerBlocks($block).''; } protected function render_core_column($block):string { $styles = (array_key_exists('attrs', $block) && array_key_exists('width', $block['attrs'])) ? ['flex-basis:'.$block['attrs']['width']] : []; return 'getClassesAndStyles($block['attrs'], ['col'], $styles).'>'. $this->innerBlocks($block).''; } protected function render_core_columns($block):string { return 'getClassesAndStyles($block['attrs'], ['columns']).'>'. $this->innerBlocks($block).''; } //core_comment_template protected function render_core_group($block):string { $tag = (array_key_exists('tagName', $block['attrs'])) ? $block['attrs']['tagName'] : 'div'; $classes = ($tag === 'main') ? $this->getClassesAndStyles($block['attrs']) : $this->getClassesAndStyles($block['attrs'], ['group row']); return '<'.$tag.$classes.'>'.$this->innerBlocks($block).''; } //core_home_link //core_more //core_nextpage protected function render_core_separator($block):string { return 'getClassesAndStyles($block['attrs']).'>'; } protected function render_core_spacer($block):string { return 'getClassesAndStyles($block['attrs'], ['spacer'], ['height:2rem']). ' aria-hidden="true">'; } //core_table_of_contents //core_text_columns /** * Embed Block */ //core_embed /** * Media Blocks */ //core_audio protected function render_core_cover($block):string { // Extract block attributes $attrs = $block['attrs'] ?? []; $innerContent = $this->innerBlocks($block); // Handle overlay opacity $dimRatio = $attrs['dimRatio'] ?? 50; $overlayClass = 'overlay-' . (ceil($dimRatio / 25) * 25); // Build classes and styles $classes = $this->getClassesAndStyles($attrs, ['cover', $overlayClass]); // Check for background type $backgroundType = $attrs['backgroundType'] ?? 'image'; $background = ''; if ($backgroundType === 'image' && isset($attrs['url'])) { // Image background $background = ''; } elseif ($backgroundType === 'video' && isset($attrs['url'])) { // Video background $background = ''; $background .= ''; } return '' . $background . '
' . $innerContent . '
'; } //core_file protected function render_core_gallery($block):string { return 'getClassesAndStyles($block['attrs'], ['gallery']).'>'. $this->innerBlocks($block,'
  • ', '
  • '). ''; } protected function render_core_image($block):string { $ID = $this->imageID('', $block); if (!$ID) { return ''; } $title = (get_the_title($ID) !== '') ? ''.get_the_title($ID).'' : ''; $caption = (wp_get_attachment_caption($ID)) ? '
    ' . $title . wp_get_attachment_caption($ID) . '
    ' : '
    ' . $title . '
    '; return 'getClassesAndStyles($block['attrs']).'>'. $this->imageLink(true, $ID) . $caption.''; } protected function render_core_media_text($block):string { $ID = $this->imageID('', $block); $img = ($ID) ? $this->image($ID, $block) : ''; $imgLink = ($ID) ? $this->imageLink(true, $ID) : ''; $inner = $this->innerBlocks($block); $content = 'getClassesAndStyles($block['attrs'], ['media-text']).'>'; $content .= (array_key_exists( 'mediaPosition', $block['attrs'] ) && $block['attrs']['mediaPosition'] == 'right') ? '
    '.$inner.'
    '.$imgLink.'
    ' : '
    '.$imgLink.'
    '.$inner.'
    '; $content .= ''; return $content; } //core_video /** * Reusable blocks */ //core_pattern /** * Text Blocks */ //render_core_code //render_core_details //render_core_footnotes //render_core_classic protected function render_core_heading(array $block):string { $level = (array_key_exists('level', $block['attrs'])) ? $block['attrs']['level'] : '2'; $id = sanitize_title(wp_strip_all_tags($block['innerHTML'])); return 'getClassesAndStyles($block['attrs']).'>'. $this->inside($block). ''; } //render_core_list //render_core_list_item //render_core_missing protected function render_core_paragraph(array $block):string { return 'getClassesAndStyles($block['attrs'], ['paragraph']).'>'. $this->inside($block, 'p'). '

    '; } //render_core_quote //render_core_table //render_core_verse /** * Theme Blocks */ //core_avatar //core_loginout //core_pattern protected function render_core_site_logo(array $block, string $content):string { $open = $close = ''; if ($block['attrs']['isLink']) { $open = ''; $close = ''; } $img = get_theme_mod('custom_logo'); $img = $this->image($img); $img = str_replace('getClassesAndStyles($block['attrs']), $img); return $open.$img.$close; } //core_site_title_tagline protected function render_core_site_title(array $block, string $content):string { $tag = (array_key_exists('level', $block['attrs'])) ? $block['attrs']['level'] : 1; $tag = ($tag == 0) ? 'p' : 'h'.$tag; $open = $close = ''; if (!is_front_page()) { $open = ''; $close = ''; } $class = ($tag === 'p') ? $this->getClassesAndStyles($block['attrs'], ['title']) : $this->getClassesAndStyles($block['attrs']); return '<'.$tag.$class.'>'. $open. jvbIcon('logo-basic'). ''. get_bloginfo('name'). ''. $close. ''; } /** * Theme Comments Blocks */ //core_avatar //core_comment_author_name //core_comment_content //core_comment_date //core_comment_edit_link //core_comment_reply_link //core_comments //core_comments_pagination //core_comments_pagination_next //core_comments_pagination_number //core_comments_pagination_previous //core_comments_title //core_post_comments_form /** * Theme Navigation Blocks */ protected function render_core_navigation(array $block, string $content):string { $ID = $block['attrs']['ref']; if (empty($block['innerBlocks']) && get_post($ID)) { $block['innerBlocks'] = parse_blocks(get_post($ID)->post_content); } $toggle = (array_key_exists('overlayMenu', $block['attrs']) && $block['attrs']['overlayMenu'] == 'never') ? '': ''; $class = ($toggle === '') ? $this->getClassesAndStyles($block['attrs'], ['mobile']) : $this->getClassesAndStyles($block['attrs']); $helpmenu = (get_the_title($ID) === 'Main') ? '' : ''; //Allows to add custom items to a menu, based on the menu name $helpmenu = apply_filters('jvbMenuExtraAfter', $helpmenu, get_the_title($ID)); return ' Skip to Content ' . $toggle . '
      '. apply_filters('jvbMenuExtra', $this->innerBlocks($block), get_the_title($ID)). '
    '.$helpmenu; } protected function render_core_navigation_link($block):string { global $wp; $url = (str_starts_with($block['attrs']['url'],'/')) ? home_url($block['attrs']['url']) : $block['attrs']['url']; $current = (home_url($wp->request.'/') == $url); $classes = ($current) ? $this->getClassesAndStyles($block['attrs'], ['current']): $this->getClassesAndStyles($block['attrs']); $aria = ''; if ($current) { $aria = ' aria-current="page"'; } $linkOpen = $this->build_navigation_link($block['attrs'], $aria); return ''.$linkOpen.$block['attrs']['label'].''; } protected function render_core_navigation_submenu(array $block):string { global $wp; $url = (str_starts_with($block['attrs']['url'],'/')) ? home_url($block['attrs']['url']) : $block['attrs']['url']; $current = (home_url($wp->request) == $url); $classes = ($current) ? $this->getClassesAndStyles($block['attrs'], ['has-submenu', 'current']): $this->getClassesAndStyles($block['attrs'], ['has-submenu']); $aria = ''; if ($current) { $aria = ' aria-current="page"'; } $id = sanitize_title($block['attrs']['label']); $linkOpen = $this->build_navigation_link($block['attrs'], $aria); $content = ''.$linkOpen.$block['attrs']['label']. ''; return $content; } protected function build_navigation_link(array $attrs, string $aria):string { global $wp; $url =(str_starts_with($attrs['url'],'/')) ? home_url($attrs['url']) : $attrs['url']; $type = $id = $label = $desc = $rel = $title = $kind = ''; foreach ($attrs as $k => $v) { switch ($k) { case 'description': $desc = $v; break; case 'rel': $rel = ' rel="'.$v.'"'; break; case 'title': $title = ' title="'.$v.'"'; break; case 'kind': $kind = $v; break; case 'type': $type = $v; break; } } return ''; } /** * Theme Query Blocks */ //core_post_author //core_post_author_biography //core_post_author_name protected function render_core_post_content(array $block, string $content = ''):string { $tag = (array_key_exists('tagName', $block['attrs'])) ? $block['attrs']['tagName'] : 'div'; if ($content == '') { return do_blocks(get_the_content(get_the_ID())); } else { return $this->inside($block, $tag, $content); } } //core_post_date //core_post_excerpt protected function render_core_post_featured_image(array $block):string { return 'getClassesAndStyles($block['attrs']).'>'. $this->imageLink(true). ''; } //core_post_navigation_link //core_post_template //core_post_terms //core_post_time_to_read protected function render_core_post_title(array $block):string { $open = $close = ''; if (array_key_exists('isLink', $block['attrs'])) { $rel = (array_key_exists('rel', $block['attrs'])) ? ' rel="'.$block['attrs']['rel'].'"' : ''; $target = (array_key_exists('linkTarget', $block['attrs'])) ? ' target="'.$block['attrs']['linkTarget'].'"' : ''; $open = ''; $close = ''; } if (is_singular(BASE.'partner')) { $open .= 'edmonton.ink partner: '; } $level = (array_key_exists('attrs', $block) && array_key_exists('level', $block['attrs'])) ? $block['attrs']['level'] : 2; return 'getClassesAndStyles($block['attrs']).'>'. $open.get_the_title().$close. ''; } //core_query //core_query_no_results //core_query_pagination //core_query_pagination_next //core_query_pagination_numbers //core_query_pagination_previous //core_query_title //core_read_more protected function render_core_template_part(array $block, string $content):string { if (array_key_exists('attrs', $block) && array_key_exists('slug', $block['attrs']) && in_array($block['attrs']['slug'], array('header', 'footer'))) { $tag = (array_key_exists('slug', $block['attrs'])) ? $block['attrs']['slug'] : 'div'; $breadcrumbs = $themeSwitch = $afterHeader = $footerText= ''; if ($block['attrs']['slug'] == 'header') { $checked = (is_user_logged_in() && current_user_can('prefers_dark_theme', true)) ? ' checked' : ''; $title = ($checked == '') ? 'Toggle Dark Mode' : 'Toggle Light Mode'; $themeSwitch = ''; $breadcrumbs = jvbBuildBreadcrumbs(); $afterHeader = apply_filters('jvbBelowHeader', $afterHeader); } elseif ($block['attrs']['slug'] == 'footer') { $footerText = jvbRandomFooterText(); } return '<'.$tag.$this->getClassesAndStyles($block['attrs']).'>'. $themeSwitch . $this->inside($block, $tag, $content). $footerText.''.$afterHeader.$breadcrumbs; } return $content; } //core_term_description /** * Widgets Blocks */ //core_archives //core_calendar //core_categories //core_html //core_latest_comments //core_latest_posts //core_page_list //core_page_list_item //core_rss //core_search //core_shortcode //core_social_link //core_social_links //core_tag_cloud /** * Extra feed block localization */ protected function localize_feedblock():void { wp_localize_script('jvb-feed-view-script', 'feedSettings', [ 'apiUrl' => rest_url('jvb/v1/'), 'nonce' => wp_create_nonce('wp_rest'), 'currentUser' => is_user_logged_in() ? [ 'id' => get_current_user_id() ] : null, 'from' => get_the_ID(), 'icons' => jvbFeedBlockIcons(), ]); } /*********************************** * Helpers **********************************/ public function innerBlocks(array $block, string $before = '', string $after = ''):string { $content = ''; foreach ($block['innerBlocks'] as $b) { $method = 'render_'.$this->sanitizeBlockName($b); $content .= $before; if (method_exists($this, $method)) { $content .= $this->$method($b, ''); } else { $content .= render_block($b); } $content .= $after; } return $content; } public function inside(array $block, mixed $tag = false, mixed $o = false):string { if (!$o) { $o = trim($block['innerHTML']); } if (!$tag) { //check to see if there was one dynamically set first $tag = (array_key_exists('tagName', $block['attrs'])) ? $block['attrs']['tagName'] : ''; $tag = ($tag == '') ? str_replace('<', '', strtok($o, '>')) : ''; $tag = (str_contains($tag, ' class')) ? strtok($tag, ' class') : $tag; $tag = trim($tag); } $len = strlen(''); return substr_replace( str_replace( strtok($o, '>').'>', ' ', $o ), '', -$len, $len ); } public function imageID(int|string $ID, array $block = []):int|false { if ($ID === '' && !empty($block)) { if (($block['blockName'] === 'core/post-featured-image' || (!array_key_exists('attrs', $block) && !array_key_exists('id', $block['attrs'])))) { $ID = get_post_thumbnail_id(); } else { if (array_key_exists('id', $block['attrs'])) { $ID = $block['attrs']['id']; } elseif (array_key_exists('mediaId', $block['attrs'])) { $ID = $block['attrs']['mediaId']; } } } if ($ID == '' || is_null(get_post($ID))) { return false; } return $ID; } public function imageLink( bool $close = false, int $ID = 0, string $start = 'tiny', string $replace = 'large', string $postSlug = '' ):string { $image = $this->image($ID, $start, $replace); if ($ID === 0) { $ID = $this->imageID($ID); } if ($postSlug==='') { global $post; $postSlug = $post->post_name; } if (!$ID) { return ''; } $imgSlug = get_post($ID)->post_name; $img = ''.$image; if ($close) { $img .= ''; } return $img; } public function image($ID = '', $start = 'tiny', $replace = 'large'):string { if ($ID == '') { $ID = $this->imageID($ID); } if ($ID === 0 || $ID === false) { return ''; } $img = wp_get_attachment_image_src($ID, $start)[0]; $data = $this->gallerySizes($ID, $replace); $alt = get_post_meta($ID, '_wp_attachment_image_alt', true); $alt = ($alt=='')? '' : ' alt="'.$alt.'" '; return ''; } public function gallerySizes(int $ID, string $replace = 'medium'):string { if (!wp_get_attachment_image_src($ID)) { return ''; } if ($replace == 'large') { return 'data-small="'. wp_get_attachment_image_src($ID, 'large')[0].'" data-medium="'. wp_get_attachment_image_src($ID, 'full')[0].'" data-full="'. wp_get_attachment_image_src($ID, 'full')[0].'"'; } elseif ($replace == 'medium') { return 'data-small="'. wp_get_attachment_image_src($ID, 'large')[0].'" data-medium="'. wp_get_attachment_image_src($ID, 'large')[0].'" data-full="'. wp_get_attachment_image_src($ID, 'large')[0].'"'; } elseif ($replace == 'thumbnail') { return 'data-small="'. wp_get_attachment_image_src($ID, 'medium')[0].'" data-medium="'. wp_get_attachment_image_src($ID, 'medium')[0].'" data-full="'. wp_get_attachment_image_src($ID, 'medium')[0].'"'; } return ''; } public function sanitizeBlockName(array $block):string { if (!array_key_exists('blockName', $block) || is_null($block['blockName'])) { return ''; } return str_replace( '/', '_', str_replace( '-', '_', $block['blockName'] ) ); } /** * Replaces the outside tag of an HTML string * @param string $content * @param bool|string $tagName * @param string $classes * @param string $styles * * @return string */ public function replaceOutsideTag( string $content, bool|string $tagName = false, string $classes = '', string $styles = '' ):string { if ($tagName && !in_array($tagName, ['div', 'section', 'article', 'aside', 'main'])) { return $content; } $content = explode('>', $content); if ($classes !== '') { if (!str_contains($classes, 'class="')) { $classes = ' class="'.$classes.'"'; } } if ($styles !== '') { if (!str_contains($styles, 'style="')) { $styles = ' style="'.$styles.'"'; } } if ($tagName) { $content[0] = '<'.str_replace( '<', '', str_replace( '>', '', $tagName ) ).$classes.$styles; } else { unset($content[0]); } unset($content[array_key_last($content)]); $out = ''; foreach ($content as $c) { $out .= $c.'>'; } return $out; } protected function getClassesAndStyles( array $attrs, array $classes = [], array $styles = [] ):string { // Get styles and classes from attributes $attr_styles = $this->getInlineStyles($attrs); $attr_classes = $this->getClasses($attrs); if(array_key_exists('slug', $attrs) && $attrs['slug'] === 'footer') { $classes[] = 'col'; } // Merge with passed classes and styles $styles = array_merge($attr_styles, $styles); $classes = array_merge($attr_classes, $classes); // Build attribute strings $class_string = !empty($classes) ? ' class="' . implode(' ', $classes) . '"' : ''; $style_string = !empty($styles) ? ' style="' . implode(';', $styles) . '"' : ''; $return = trim($class_string . $style_string); return ($return=='')? '' : ' '.$return; } /** * @param string $spacing * * @return string */ protected function getPresetSpacing(string $spacing):string { return match ($spacing) { 'var:preset|spacing|20' => '0.5rem', // 1 'var:preset|spacing|30' => '1rem', // 2 'var:preset|spacing|40' => '1.5rem', // 3 'var:preset|spacing|50' => '3rem', // 4 'var:preset|spacing|60' => '4rem', // 5 'var:preset|spacing|70' => '5rem', // 6 'var:preset|spacing|80' => '6rem', // 7 default => $spacing, }; } protected function getClasses(array $attrs):array { if (empty($attrs)) { return []; } $classes = []; foreach ($attrs as $key => $value) { $class = $this->getClass($key, $value); if (is_array($class)) { $classes = array_merge($classes, $class); } else { $classes[] = $class; } } $classes = array_filter($classes, function ($class) { return $class!=='' && !str_starts_with($class, 'wp'); }); return $classes; } protected function getClass(string $key, string|bool|array|int $value):string|array { switch ($key) { //Any additional classes the user adds case 'className': return match ($value) { 'is-style-floating' => 'always mobile fixed', 'is-style-fixed' => 'fixed bottom', default => $value, }; //Layout attributes case 'layout': $classes = []; if (array_key_exists('type', $value)) { if ($value['type'] === 'constrained') { $classes[] = 'container'; } } if (array_key_exists('justifyContent', $value)) { if (in_array($value['justifyContent'], ['left', 'right','space-between'])) { $classes[] = 'j-'.$value['justifyContent']; } } if (array_key_exists('orientation', $value)) { if ($value['orientation'] === 'vertical') { $classes[] = 'col'; if (in_array('row', $classes)) { $index = array_search('row', $classes); unset($classes[$index]); } } } if (array_key_exists('flexWrap', $value)) { if ($value['flexWrap'] === 'nowrap') { $classes[] = 'nowrap'; } } return implode(' ', $classes); case 'align': return !empty($value) ? 'align-'.$value : ''; case 'verticalAlignment': return !empty($value) ? 'v-align-'.$value : ''; case 'isStackedMobile': return ($value === true) ? 'stack-small' : ''; case 'justifyContent': return !empty($value) ? 'j-'.$value : ''; case 'orientation': return $value==='column' ? 'column' : ''; case 'width': case 'dimRatio': if (is_numeric($value)) { $width = match (true) { $value < 25 => 'one-fourth', $value < 33 => 'one-third', $value < 50 => 'half', $value < 66 => 'two-third', $value < 75 => 'three-fourth', default => 'full', }; switch ($key) { case 'width': return 'width-'.$width; case 'dimRatio': return 'overlay-'.$width; } } return ''; //Typography case 'textAlign': return !empty($value) ? 'text-'.$value : ''; case 'dropCap': return $value === true ? 'drop-cap' : ''; //Media case 'hasParallax': return $value === true ? 'bg-parallax' : ''; case 'isRepeated': return $value === true ? 'bg-repeat' : ''; //Style base: case 'style': $classes = []; //Margin and Padding if (array_key_exists('spacing', $value)) { foreach (['margin' => 'm', 'padding'=>'p'] as $search => $c) { if (array_key_exists($search, $value['spacing'])) { foreach ($value['spacing'][$search] as $direction => $size) { $size = $this->getPresetSpacing($size); if ($size) { $classes[] = $c.'-'.$direction.'-'.$size; } } } } } if (array_key_exists('fontSize', $value)) { if (in_array($value['fontSize'], ['small', 'large', 'extra-large', 'huge'])) { $classes[] = 'text-'.$value['fontSize']; } if (in_array('fontWeight', $value)) { $classes[] = 'text-'.$value['fontWeight']; } if (in_array('textTransform', $value)) { if (in_array($value['textTransform'], ['uppercase', 'capitalize', 'lowercase'])) { $classes[] = $value['textTransform']; } } } return implode(' ', $classes); default: return ''; } } protected function getInlineStyles(array $attrs):array { if (empty($attrs)) { return []; } $styles = []; foreach ($attrs as $key => $value) { $style = $this->getStyle($key, $value, $attrs); $styles = array_merge($styles, $style); } return $styles; } protected function getStyle(string $key, string|bool|array|int $value, array $attrs):array { $styles = []; switch ($key) { // Font family settings case 'fontFamily': if ($value === 'body') { $styles[] = 'font-family: "Open Sans", system-ui, -apple-system, sans-serif'; } elseif ($value === 'heading') { $styles[] = 'font-family: "Josefin Sans", system-ui, -apple-system, sans-serif'; } elseif (!empty($value)) { $styles[] = 'font-family: '.$value; } break; // Icon color (for icon blocks) case 'iconColorValue': if (!empty($value)) { $styles[] = 'color: '.$value; } break; // Minimum height settings case 'minHeight': if (!empty($value) && isset($attrs['minHeightUnit'])) { $styles[] = 'min-height: '.$value.$attrs['minHeightUnit']; } elseif (!empty($value)) { $styles[] = 'min-height: '.$value.'px'; // Default to px if no unit specified } break; // Background URL (for cover, media blocks) case 'url': if (!empty($value) && str_starts_with($value, 'http')) { $styles[] = 'background-image: url('.$value.')'; } break; // Focal point for background images case 'focalPoint': if (isset($value['x']) && isset($value['y'])) { $styles[] = 'background-position: '.($value['x'] * 100).'% '.($value['y'] * 100).'%'; } break; // Complex style object case 'style': // Border styles if (isset($value['border'])) { $border = $value['border']; if (isset($border['radius'])) { $styles[] = 'border-radius: '.$border['radius']; } if (isset($border['width'])) { $styles[] = 'border-width: '.$border['width']; } if (isset($border['style']) && isset($border['width']) && !empty($border['style'])) { $styles[] = 'border-style: '.$border['style']; } if (isset($border['color'])) { $styles[] = 'border-color: '.$border['color']; } } // Color styles if (isset($value['color'])) { $color = $value['color']; if (isset($color['background'])) { $styles[] = 'background-color: '.$color['background']; } if (isset($color['text'])) { $styles[] = 'color: '.$color['text']; } if (isset($color['gradient'])) { $styles[] = 'background: '.$color['gradient']; } } // Layout styles if (isset($value['layout'])) { foreach ($value['layout'] as $layout => $option) { switch ($layout) { case 'selfStretch': if ($option === 'fixed' && isset($value['layout']['selfStretchValue'])) { $styles[] = 'width: '.$value['layout']['selfStretchValue']; } break; } } } // Typography styles if (isset($value['typography'])) { $typography = $value['typography']; if (isset($typography['fontSize'])) { $styles[] = 'font-size: '.$typography['fontSize']; } if (isset($typography['fontWeight'])) { $styles[] = 'font-weight: '.$typography['fontWeight']; } if (isset($typography['textDecoration'])) { $styles[] = 'text-decoration: '.$typography['textDecoration']; } if (isset($typography['textTransform'])) { $styles[] = 'text-transform: '.$typography['textTransform']; } if (isset($typography['letterSpacing'])) { $styles[] = 'letter-spacing: '.$typography['letterSpacing']; } if (isset($typography['lineHeight'])) { $styles[] = 'line-height: '.$typography['lineHeight']; } } // Spacing styles if (isset($value['spacing'])) { $spacing = $value['spacing']; // Don't duplicate margin/padding that's handled by classes // Only add specific CSS values here that wouldn't work well as classes if (isset($spacing['margin'])) { foreach ($spacing['margin'] as $direction => $size) { // If not a preset value, add as inline style if (!str_contains($size, 'var:preset')) { $styles[] = 'margin-'.$direction.': '.$size; } } } if (isset($spacing['padding'])) { foreach ($spacing['padding'] as $direction => $size) { // If not a preset value, add as inline style if (!str_contains($size, 'var:preset')) { $styles[] = 'padding-'.$direction.': '.$size; } } } } break; // Custom styles (any other attributes that need inline styling) case 'backgroundType': if ($value === 'video' && isset($attrs['backgroundUrl'])) { // Don't set a background image for videos - it will be handled by the video element } elseif (isset($attrs['backgroundUrl'])) { $styles[] = 'background-image: url('.$attrs['backgroundUrl'].')'; } break; // Any other attributes that need direct styling default: // No default inline styles break; } return $styles; } public function getGallerySizes(int $ID, string $replace):string { if (!wp_get_attachment_image_src($ID)) { return ''; } if (!has_image_size($replace)) { $replace = 'large'; } if ($replace == 'large') { return 'data-small="' . wp_get_attachment_image_src($ID)[0] . '" data-medium="' . wp_get_attachment_image_src($ID, 'large')[0] . '" data-full="' . wp_get_attachment_image_src($ID, 'full')[0] . '"'; } elseif ($replace == 'medium') { return 'data-small="'. wp_get_attachment_image_src($ID, 'large')[0].'" data-medium="'. wp_get_attachment_image_src($ID, 'large')[0].'" data-full="'. wp_get_attachment_image_src($ID, 'large')[0].'"'; } elseif ($replace == 'thumbnail') { return 'data-small="'. wp_get_attachment_image_src($ID, 'medium')[0].'" data-medium="'. wp_get_attachment_image_src($ID, 'medium')[0].'" data-full="'. wp_get_attachment_image_src($ID, 'medium')[0].'"'; } return ''; } public function formatImage(int $ID = 0, string $start = 'tiny', string $replace = 'large'):string { if ($ID === 0) { $ID = $this->imageID($ID); } if ($ID === 0) { return ''; } return $this->imgCache->remember( ['ID' => $ID, 'start' => $start, 'replace' => $replace], function() use ($ID, $start, $replace) { $img = wp_get_attachment_image_src($ID, $start); if (!$img) { return''; } $img = $img[0]; $data = $this->getGallerySizes($ID, $replace); $alt = get_post_meta($ID, '_wp_attachment_image_alt', true); $alt = ($alt=='')? '' : ' alt="'.$alt.'" '; return ''; } ); } } new CustomBlocks();