From d7dbe7fee362d587dfc334135d9581b6216a4295 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 23 Nov 2025 04:13:56 +0000
Subject: [PATCH] =Timeline block, and feed block updated. DataStore.js refactored to not block rendering
---
inc/blocks/CustomBlocks.php | 244 ++++++++++++++++++------------------------------
1 files changed, 90 insertions(+), 154 deletions(-)
diff --git a/inc/blocks/CustomBlocks.php b/inc/blocks/CustomBlocks.php
index 8e175b8..43831f2 100644
--- a/inc/blocks/CustomBlocks.php
+++ b/inc/blocks/CustomBlocks.php
@@ -14,13 +14,12 @@
class CustomBlocks
{
protected CacheManager $cache;
- protected CacheManager $imgCache;
public function __construct()
{
$this->cache = CacheManager::for('blocks', WEEK_IN_SECONDS);
- $this->imgCache = CacheManager::for('images', WEEK_IN_SECONDS);
+ add_filter('render_block', [$this, 'render'], 999, 3);
- add_action('render_block', [$this, 'render'], 10, 3);
+
add_action('init', [$this, 'registerBlockStyles']);
}
@@ -67,8 +66,10 @@
public function render(string $content, array $block, WP_Block $instance)
{
- $method = 'render_'.$this->sanitizeBlockName($block);
+ $blockName = $this->sanitizeBlockName($block);
+ $method = 'render_'.$blockName;
$function = BASE.$method;
+
if (function_exists($function)) {
// return $this->cache->remember(
// $block,
@@ -77,8 +78,7 @@
// }
// );
return $function($block, $content);
- }
- if (method_exists($this, $method)) {
+ } else if (method_exists($this, $method)) {
return $this->$method($block, $content);
//TODO: Recache it
// return $this->cache->remember(
@@ -94,9 +94,10 @@
'core/post-title',
'core/list-item',
'core/site-title',
+ 'jvb/forms'
];
if (!in_array($block['blockName'], $ignore)) {
- jvbDump('No method found for '.print_r($block['blockName'], true));
+// jvbDump('No method found for '.print_r($block['blockName'], true));
}
}
if ($block['blockName'] === 'jvb/feed') {
@@ -220,6 +221,7 @@
$attrs = $block['attrs'] ?? [];
$innerContent = $this->innerBlocks($block);
+ $position = 'object-position: center;';
if (array_key_exists('focalPoint', $attrs)) {
$x = (array_key_exists('x', $attrs['focalPoint'])) ? ($attrs['focalPoint']['x'] * 100).'%' : 'center';
$y = (array_key_exists('y', $attrs['focalPoint'])) ? ($attrs['focalPoint']['y'] * 100).'%' : 'center';
@@ -231,8 +233,16 @@
$backgroundType = $attrs['backgroundType'] ?? 'image';
$background = '';
- if ($backgroundType === 'image' && isset($attrs['id'])) {
- $background .= str_replace('<img', '<img style="'.$position.'"', $this->image($attrs['id']));
+ $ID = false;
+ if (array_key_exists('useFeaturedImage', $attrs)) {
+ global $post;
+ $ID = get_post_thumbnail_id($post->ID);
+ } else if (array_key_exists('id', $attrs)) {
+ $ID = (int)$attrs['id'];
+ }
+
+ if ($backgroundType === 'image' && $ID) {
+ $background .= str_replace('<img', '<img style="'.$position.'"', $this->image($ID));
} elseif ($backgroundType === 'video' && isset($attrs['url'])) {
$background .= '<video style="'.$position.'"autoplay muted loop playsinline src="' . esc_url($attrs['url']) . '"></video>';
}
@@ -471,8 +481,8 @@
aria-label="Open Menu"
aria-controls="navigation-' .$ID. '"
aria-expanded="false">'.
- jvbIcon('menu', ['title'=>'Toggle Menu']).
- jvbIcon('close', ['title'=>'Toggle Menu']).
+ jvbIcon('list', ['title'=>'Toggle Menu']).
+ jvbIcon('x', ['title'=>'Toggle Menu']).
'</button>';
$class = ($toggle === '') ?
$this->getClassesAndStyles($block['attrs'], ['mobile']) :
@@ -537,7 +547,7 @@
$linkOpen = $this->build_navigation_link($block['attrs'], $aria);
$content = '<li'.$classes.'>'.$linkOpen.$block['attrs']['label'].
'</a><button class="toggle" data-action="toggle-submenu" title="Toggle Submenu" aria-label="Open '.$block['attrs']['label'].' Submenu" aria-expanded="false" aria-controls="'.$id.'-submenu">'.
- jvbIcon('submenu', ['title'=>'Toggle Submenu']).
+ jvbIcon('caret-down', ['title'=>'Toggle Submenu']).
'</button><ul class="submenu" id='.$id.'-submenu">';
$content .= $this->innerBlocks($block);
@@ -607,8 +617,10 @@
//core_post_excerpt
protected function render_core_post_featured_image(array $block):string
{
+ global $post;
+ $ID = get_post_thumbnail_id($post->ID);
return '<figure'.$this->getClassesAndStyles($block['attrs']).'>'.
- $this->imageLink(true).
+ $this->image($ID).
'</figure>';
}
//core_post_navigation_link
@@ -765,18 +777,18 @@
protected function render_core_template_part(array $block, string $content):string
{
- $check = ['header', 'footer'];
$isHeaderTemplate = (
- (array_key_exists('slug', $block['attrs']) && str_contains($block['attrs']['slug'], 'header')) ||
- (array_key_exists('tagName', $block['attrs']) && str_contains($block['attrs']['tagName'], 'header'))
+ (array_key_exists('slug', $block['attrs']) && str_contains(strtolower($block['attrs']['slug']), 'header')) ||
+ (array_key_exists('tagName', $block['attrs']) && str_contains(strtolower($block['attrs']['tagName']), 'header'))
) ? 'header' : false;
$isFooterTemplate = (
- (array_key_exists('slug', $block['attrs']) && str_contains($block['attrs']['slug'], 'footer')) ||
- (array_key_exists('tagName', $block['attrs']) && str_contains($block['attrs']['tagName'], 'footer'))
+ (array_key_exists('slug', $block['attrs']) && str_contains(strtolower($block['attrs']['slug']), 'footer')) ||
+ (array_key_exists('tagName', $block['attrs']) && str_contains(strtolower($block['attrs']['tagName']), 'footer'))
) ? 'footer' : false;
- if ($isHeaderTemplate || $isFooterTemplate) {
+ if (($isHeaderTemplate || $isFooterTemplate)) {
+
$tag = $isHeaderTemplate ?: $isFooterTemplate ?: 'div';
$breadcrumbs = $themeSwitch = $afterHeader = $beforeHeader = $footerText= '';
@@ -788,11 +800,12 @@
}
$checked = (is_user_logged_in() && current_user_can('prefers_dark_theme', true)) ? ' checked' : '';
$title = ($checked == '') ? 'Toggle Dark Mode' : 'Toggle Light Mode';
- $themeSwitch = '<label title="'.$title.'" id="theme-switch" class="toggle-switch" for="theme-switcher">
+ $showThemeSwitch = (bool)apply_filters('jvb_show_theme_switch', true);
+ $themeSwitch = ($showThemeSwitch) ? '<label title="'.$title.'" id="theme-switch" class="toggle-switch" for="theme-switcher">
<input class="theme-switch row" id="theme-switcher" type="checkbox"'.$checked.' data-setting="theme" data-theme role="switch" name="dark-mode"><span class="slider">'.
- jvbIcon('light', ['title'=> 'Light Mode']).
- jvbIcon('dark', ['title'=>'Dark Mode']).
- '</span></label>';
+ jvbIcon('sun-dim', ['title'=> 'Light Mode']).
+ jvbIcon('moon', ['title'=>'Dark Mode']).
+ '</span></label>' : '';
$breadcrumbs = jvbBuildBreadcrumbs();
$afterHeader = apply_filters('jvbBelowHeader', $afterHeader);
if ($afterHeader !== '') {
@@ -804,12 +817,21 @@
$beforeHeader = '<section class="pre-footer">'.$beforeHeader.'</section>';
}
$footerText = jvbRandomFooterText();
- }
+ }
+// jvbDump($beforeHeader,'beforeHeader');
+// jvbDump('<'.$tag.$this->getClassesAndStyles($block['attrs']).'>','tag');
+// jvbDump($themeSwitch,'themeSwitch');
+// jvbDump($this->inside($block, $tag, $content),'inside');
+// jvbDump($footerText,'footerText');
+// jvbDump($afterHeader, 'afterheader');
+// jvbDump($breadcrumbs, 'breadcrumbs');
+
return $beforeHeader.'<'.$tag.$this->getClassesAndStyles($block['attrs']).'>'.
$themeSwitch .
- $this->inside($block, $tag, $content).
+ $this->inside($block, $tag, $content) .
$footerText.'</'.$tag.'>'.$afterHeader.$breadcrumbs;
}
+
return $content;
}
//core_term_description
@@ -853,14 +875,10 @@
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(),
-
]);
}
@@ -876,18 +894,22 @@
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;
+ $content = '';
+ foreach ($block['innerBlocks'] as $b) {
+ $method = 'render_'.$this->sanitizeBlockName($b);
+ $function = BASE.$method;
+
+ $content .= $before;
+ if (function_exists($function)) {
+ $content .= $function($b, '');
+ } else 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
@@ -902,7 +924,9 @@
$tag = (str_contains($tag, ' class')) ? strtok($tag, ' class') : $tag;
$tag = trim($tag);
}
-
+ if (!str_starts_with($o, '<'.$tag)) {
+ return $o;
+ }
$len = strlen('</'.$tag.'>');
@@ -946,8 +970,8 @@
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();
@@ -969,26 +993,16 @@
int $ID = 0,
string $start = 'tiny',
string $replace = 'large',
- string $postSlug = ''
+ ?string $postSlug = null
):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 = '<a class="open-gallery" target="_blank" rel="nofollow" data-opens="gallery-'.$postSlug.'" data-focus="'.$postSlug.'-'.$imgSlug.'">'.$image;
+ $image = jvbFormatImage($ID, $start, $replace, true, $postSlug);
+
if ($close) {
- $img .= '</a>';
+ return $image;
}
- return $img;
+ $len = strlen('</a>');
+ return substr_replace($image, '', -$len, $len);
}
public function image(string $ID = '', string $start = 'tiny', string $replace = 'large'):string
{
@@ -1000,41 +1014,7 @@
if ($ID === 0 || $ID === false) {
return '';
}
-
- $img = wp_get_attachment_image_src($ID, $start);
- if (!$img) return '';
- $img = $img[0];
-
- $data = $this->gallerySizes($ID, $replace);
-
- $alt = get_post_meta($ID, '_wp_attachment_image_alt', true);
- $alt = ($alt=='')? '' : ' alt="'.$alt.'" ';
-
- return '<img width="100%" height="auto" src="' .
- $img . '"' .$alt . $data . ' loading="lazy" decoding="async">';
- }
- 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 '';
+ return jvbFormatImage($ID, $start, $replace, false);
}
public function sanitizeBlockName(array $block):string
{
@@ -1167,7 +1147,6 @@
}
protected function getClass(string $key, string|bool|array|int $value, array $attrs):string|array
{
-
switch ($key) {
//Any additional classes the user adds
case 'className':
@@ -1177,6 +1156,7 @@
default => str_replace('is-style-', '', $value),
};
case 'contentPosition':
+
$classes = [];
$pos = explode(' ', $value);
foreach($pos as $p) {
@@ -1229,14 +1209,14 @@
//
// }
if (!array_key_exists('justifyContent', $value) && !array_key_exists('contentPosition', $attrs)) {
- $classes[] = 'start';
+ $classes[] = ($type === 'row') ? 'start' : 'a-start';
}
if (array_key_exists('justifyContent', $value) && !array_key_exists('contentPosition', $attrs)) {
if (in_array($value['justifyContent'], ['left', 'right','space-between'])) {
// jvbDump($type);
switch ($value['justifyContent']) {
case 'right':
- $classes[] = 'end';
+ $classes[] = ($type === 'row') ? 'end' : 'a-end';
break;
case 'space-between':
$classes[] = 'btw';
@@ -1412,6 +1392,7 @@
return '';
default:
$ignore = [
+ 'useFeaturedImage',
'opacity',
'borderColor',
'backgroundColor',
@@ -1453,8 +1434,8 @@
];
if (!is_admin() &&!in_array($key, $ignore)) {
// TESTING
- jvbDump($key, 'getClass');
- jvbDump($attrs);
+// jvbDump($key, 'getClass');
+// jvbDump($attrs);
}
return '';
@@ -1674,6 +1655,7 @@
// Any other attributes that need direct styling
default:
$ignore = [
+ 'useFeaturedImage',
'opacity',
'textAlign',
'minHeightUnit',
@@ -1718,8 +1700,8 @@
];
if (!is_admin() && !in_array($key, $ignore)) {
//TESTING
- jvbDump($key, 'getStyle');
- jvbDump($attrs);
+// jvbDump($key, 'getStyle');
+// jvbDump($attrs);
}
// No default inline styles
break;
@@ -1728,61 +1710,15 @@
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 '<img width="300px" height="300px" src="'.$img.'"'.$alt.$data.' loading="lazy" decoding="async">';
- }
- );
+ if ($ID === 0) {
+ $ID = $this->imageID($ID);
+ }
+ if ($ID === 0) {
+ return '';
+ }
+ return jvbFormatImage($ID, $start, $replace);
}
}
--
Gitblit v1.10.0