From 46d681c6b825d21b3f698d793c4e630c687d90ad Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 21 May 2026 21:41:53 +0000
Subject: [PATCH] =Major CustomBlocks.php overhaul, expanding block support and customization from the editor. theme.json should now be updated on new themes to set brand colours, etc. Also note: major change to .col vs .row alignment: simplifying it to .top .bottom vs the confusion of the differences for .col/.row .start and .a-start
---
inc/helpers/renderFields.php | 445 ++++++++++++++++++++++++++++++-------------------------
1 files changed, 244 insertions(+), 201 deletions(-)
diff --git a/inc/helpers/renderFields.php b/inc/helpers/renderFields.php
index 44cf5cd..150af0e 100644
--- a/inc/helpers/renderFields.php
+++ b/inc/helpers/renderFields.php
@@ -4,7 +4,10 @@
exit;
}
-use JVBase\meta\MetaManager;
+use JVBase\forms\TaxonomySelector;
+use JVBase\managers\Cache;
+use JVBase\meta\Form;
+use JVBase\meta\Meta;
/**
* Outputs a toggle text that visually changes based on selection, like a switch
@@ -23,12 +26,16 @@
string $labelAfter,
string $on,
string $off,
- bool $hidden = false
+ bool $hidden = false,
+ array $data = []
):string {
$hidden = ($hidden) ? ' hidden' : '';
+ $dataset = (!empty($data)) ? implode('', array_map(function ($key, $value) {
+ return ' data-'.$key.'="'.$value.'"';
+ }, array_keys($data), array_values($data))) : '';
return sprintf(
- '<div class="toggle-text" %s>
- <input value="all" name="%s" id="%s" type="checkbox">
+ '<div class="toggle-text"%s>
+ <input value="all" name="%s" id="%s" type="checkbox"%s>
<label for="%s" class="row">
%s
<span class="text row">
@@ -41,6 +48,7 @@
$hidden,
$name,
$name,
+ $dataset,
$name,
$labelBefore,
$off,
@@ -51,24 +59,31 @@
/**
* @param int $ID
- * @param MetaManager|null $meta
- *
+ * @param string $type
* @return string
*/
-function jvbRenderLinks(int $ID, MetaManager|null $meta = null):string
+function jvbRenderLinks(int $ID, string $type =''):string
{
- $cache = new JVBase\managers\CacheManager('bio-'.$ID, WEEK_IN_SECONDS);
- $key = 'links';
- $cached = $cache->get($key);
+ $cache = Cache::for('user_links', WEEK_IN_SECONDS)->connect('post')->connect('taxonomy')->connect('user');
+ $cached = $cache->get($ID);
if ($cached) {
return $cached;
}
- if (!$meta) {
- $meta = jvbGetMeta($ID);
- }
+ $meta = match($type){
+ 'post' => Meta::forPost($ID),
+ 'term' => Meta::forTerm($ID),
+ 'user' => Meta::forUser($ID),
+ default => false
+ };
+ if (!$meta) {
+ $meta = jvbGetMeta($ID);
+ }
+ if (!$meta) {
+ return '';
+ }
- $links = $meta->getValue('links');
+ $links = $meta->get('links');
$out = '';
if (!empty($links)) {
@@ -77,41 +92,41 @@
$url = $link['url'];
switch (true) {
case strpos($url, 'facebook'):
- $i = jvbIcon('facebook');
+ $i = jvbIcon('facebook-logo');
break;
case strpos($url, 'instagram'):
- $i = jvbIcon('instagram');
+ $i = jvbIcon('instagram-logo');
break;
case strpos($url, 'tiktok'):
- $i = jvbIcon('tiktok');
+ $i = jvbIcon('tiktok-logo');
break;
case strpos($url, 'x.com'):
$i = jvbIcon('x');
break;
case strpos($url, 'youtube'):
- $i = jvbIcon('youtube');
+ $i = jvbIcon('youtube-logo');
break;
case strpos($url, 'mastadon'):
- $i = jvbIcon('mastadon');
+ $i = jvbIcon('mastadon-logo');
break;
case strpos($url, 'fediverse'):
case strpos($url, 'bluesky'):
- $i = jvbIcon('fediverse');
+ $i = jvbIcon('fediverse-logo');
break;
case strpos($url, 'linktree'):
- $i = jvbIcon('linktree');
+ $i = jvbIcon('linktree-logo');
break;
case strpos($url, 'snapchat'):
- $i = jvbIcon('snapchat');
+ $i = jvbIcon('snapchat-logo');
break;
case strpos($url, 'twitch'):
- $i = jvbIcon('twitch');
+ $i = jvbIcon('twitch-logo');
break;
case strpos($url, 'threads'):
- $i = jvbIcon('threads');
+ $i = jvbIcon('threads-logo');
break;
case strpos($url, 'twitter'):
- $i = jvbIcon('twitter');
+ $i = jvbIcon('twitter-logo');
break;
default:
$i = jvbIcon('link');
@@ -122,50 +137,59 @@
}
$out .= '</ul>';
}
- $cache->set($key, $out);
+ $cache->set($ID, $out);
return $out;
}
/**
* @param int $ID
- * @param MetaManager|null $meta
+ * @param string $type
*
* @return string
*/
-function jvbRenderContactInfo(int $ID, MetaManager|null $meta = null):string
+function jvbRenderContactInfo(int $ID, string $type = ''):string
{
- $cache = new JVBase\managers\CacheManager('bio-'.$ID, WEEK_IN_SECONDS);
- $key = 'contact';
-// $cached = $cache->get($key);
-// if($cached){
-// return $cached;
-// }
- if (!$meta) {
- $meta = jvbGetMeta($ID);
- }
+ $cache = Cache::for('contact', WEEK_IN_SECONDS)->connect('post')->connect('taxonomy');
- $preference = $meta->getValue('public_contact');
+ $cached = $cache->get($ID);
+ if($cached){
+ return $cached;
+ }
+ $meta = match($type){
+ 'post' => Meta::forPost($ID),
+ 'term' => Meta::forTerm($ID),
+ 'user' => Meta::forUser($ID),
+ default => false
+ };
+ if (!$meta) {
+ $meta = jvbGetMeta($ID);
+ }
+ if (!$meta) {
+ return '';
+ }
+
+ $preference = $meta->get('public_contact');
$preference = (is_array($preference)) ? $preference : explode(',', $preference);
$out = '';
if (!empty($preference)) {
$out = '<ul class="contact">';
- $phone = $meta->getValue('phone');
+ $phone = $meta->get('phone');
foreach ($preference as $p) {
$link = $label = false;
switch ($p) {
case 'text':
$link = 'sms:+1'.$phone.';?body='.rawurlencode('Hey! I found you on edmonton.ink, and I wanted to reach out.');
- $label = jvbIcon('text').'<span>Text</span>';
+ $label = jvbIcon('chat').'<span>Text</span>';
break;
case 'call':
$link = 'tel:+1'.$phone;
$label = jvbIcon('phone').'<span>Call</span>';
break;
case 'email':
- $link = 'mailto:'.$meta->getValue('email').'?subject='.rawurlencode('Contact from edmonton.ink').'&body='.rawurlencode('Hey,
+ $link = 'mailto:'.$meta->get('email').'?subject='.rawurlencode('Contact from edmonton.ink').'&body='.rawurlencode('Hey,
I found you on edmonton.ink, and I wanted to reach out!');
- $label = jvbIcon('email').'<span>Email</span>';
+ $label = jvbIcon('envelope').'<span>Email</span>';
break;
}
if ($link) {
@@ -176,29 +200,38 @@
$out .= '</ul>';
}
- $cache->set($key, $out);
+ $cache->set($ID, $out);
return $out;
}
/**
* @param int $ID
- * @param MetaManager|null $meta
+ * @param string $type
* @return string
*/
-function jvbRenderSpecialtyField(int $ID, MetaManager|null $meta = null):string
+function jvbRenderSpecialtyField(int $ID, string $type = ''):string
{
- if (!$meta) {
- $meta = jvbGetMeta($ID);
- }
+ $meta = match($type){
+ 'post' => Meta::forPost($ID),
+ 'term' => Meta::forTerm($ID),
+ 'user' => Meta::forUser($ID),
+ default => false
+ };
+ if (!$meta) {
+ $meta = jvbGetMeta($ID);
+ }
+ if (!$meta) {
+ return '';
+ }
$out = '';
- $specialties = $meta->getValue('specialties');
+ $specialties = $meta->get('specialties');
if (!empty($specialties)) {
foreach ($specialties as $specialty) {
$out .= '<li><b>'.$specialty['specialty'].'</b>';
if ($specialty['description'] !== '') {
- $out .= apply_filters('the_content', $specialty['description']);
+ $out .= jvb_filter_content( $specialty['description']);
}
$out .= '</li>';
}
@@ -213,17 +246,26 @@
/**
* @param int $ID
- * @param MetaManager|null $meta
+ * @param string $type = ''
* @return string
*/
-function jvbRenderAwardsField(int $ID, MetaManager|null $meta = null):string
+function jvbRenderAwardsField(int $ID, string $type = ''):string
{
- if (!$meta) {
- $meta = jvbGetMeta($ID);
- }
+ $meta = match($type){
+ 'post' => Meta::forPost($ID),
+ 'term' => Meta::forTerm($ID),
+ 'user' => Meta::forUser($ID),
+ default => false
+ };
+ if (!$meta) {
+ $meta = jvbGetMeta($ID);
+ }
+ if (!$meta) {
+ return '';
+ }
$out = '';
- $awards = $meta->getValue('awards');
+ $awards = $meta->get('awards');
if (!empty($awards)) {
foreach ($awards as $award) {
$out .= '<li><b>'.$award['name'].'</b>';
@@ -241,23 +283,32 @@
/**
* @param int $ID
- * @param MetaManager|null $meta
+ * @param string $type
* @return string
*/
-function jvbRenderReviewsField(int $ID, MetaManager|null $meta = null):string
+function jvbRenderReviewsField(int $ID, string $type = ''):string
{
- if (!$meta) {
- $meta = jvbGetMeta($ID);
- }
+ $meta = match($type){
+ 'post' => Meta::forPost($ID),
+ 'term' => Meta::forTerm($ID),
+ 'user' => Meta::forUser($ID),
+ default => false
+ };
+ if (!$meta) {
+ $meta = jvbGetMeta($ID);
+ }
+ if (!$meta) {
+ return '';
+ }
$out = '';
- $reviews = $meta->getValue('reviews');
+ $reviews = $meta->get('reviews');
if (!empty($reviews)) {
foreach ($reviews as $review) {
if ($review['review'] === '') {
continue;
}
- $out .= '<li><blockquote>'.apply_filters('the_content', $review['review']);
+ $out .= '<li><blockquote>'.jvb_filter_content( $review['review']);
if ($review['name'] !== '' || $review['rating'] !== 'none') {
$date = $aOpen = $aClose = '';
if ($review['url']) {
@@ -268,7 +319,7 @@
$date = new Date('M j, Y', strtotime($review['date']));
}
- $out .= '<cite class="row btw">';
+ $out .= '<cite class="row x-btw">';
if ($review['rating'] !== 'none') {
$out .= jvbFormatStarRating($review['rating']);
}
@@ -291,75 +342,128 @@
return $out;
}
-function jvbGetMeta(int $ID) {
- if (is_tax()) {
- $type = 'term';
- } elseif (is_singular()) {
- $type = 'post';
+function jvbGetMeta(int $ID):Meta|false {
+ if (term_exists($ID)) {
+ return Meta::forTerm($ID);
+ } elseif (get_post_status($ID)) {
+ return Meta::forPost($ID);
+ } elseif (get_userdata($ID)) {
+ return Meta::forUser($ID);
} else {
- $type = 'user';
- }
- return new JVBase\meta\MetaManager($ID, $type);
+ return false;
+ }
}
-
-function jvbRenderTermList(array|bool|WP_Error $terms, string $label = '') {
+function jvbRenderTermList(array|bool|WP_Error $terms, string $label = ''):string {
if (!$terms || is_wp_error($terms) || empty($terms)) {
return '';
}
$out = ($label === '') ? '' : '<h2 class="inline">'.$label.'</h2>';
$out .= '<ul class="term-list '.jvbNoBase($terms[array_key_first($terms)]->taxonomy).'">';
foreach ($terms as $term) {
- $out .= '<li>
- <a href="'.get_term_link($term->term_id, $term->taxonomy).'" title="'.$term->name.'">'.
- $term->name.
- '</a>
- </li>';
+ $out .= '<li>'.jvbGetTermLink($term).'</li>';
}
$out .= '</ul>';
return $out;
}
+function jvbGetTermLink(int|WP_Term $term, string $taxonomy = ''):string
+{
+ if (is_int($term)){
+ $term = get_term($term, jvbCheckBase($taxonomy));
+ if (is_wp_error($term)) {
+ return '';
+ }
+ }
+ $cache = Cache::for($term->taxonomy.'_link')->connect('taxonomy');
+ $key = $term->term_id;
+ return $cache->remember(
+ $key,
+ function() use ($term) {
+ return '<a href="'.get_term_link($term->term_id, $term->taxonomy).'" title="'.html_entity_decode($term->name).'">'.
+ html_entity_decode($term->name).
+ '</a>';
+ }
+ );
+}
+
+
add_action('wp_footer', 'jvbOutputImageTemplates');
function jvbOutputImageTemplates() {
+ if (wp_script_is('jvb-form')) {
+ jvbInlineStyles('forms');
+ ?>
+ <template class="formSummary">
+ <div class="form-summary">
+ <h2>Success!</h2>
+ <div class="message">
+ <p>We're picking up what you're laying down.</p>
+ <p>You'll get an email with your response. If you can't find it, check your spam.</p>
+ <p>If you need to make any changes, respond to that email.</p>
+ <p>You can see a summary of what you wrote below:</p>
+ </div>
+ <div class="summary">
+ <div class="result">
+ <h3></h3>
+ <p></p>
+ </div>
+ </div>
+ </div>
+ </template>
+ <?php
+ }
if (wp_script_is('jvb-uploader')) {
?>
<template class="emptyGroup">
- <div class="empty-group">
+ <div class="empty-group row">
<p>Drag here to create new group!</p>
</div>
</template>
<template class="uploadMeta">
- <?= jvbImageMeta() ?>
+ <?= Form::renderImagePreview() ?>
</template>
<template class="imageGroup">
- <details class="upload-group">
- <summary class="row btw">
- <div class="group-header">
- <div class="group-actions">
- <button type="button" class="add-selection-to-group" title="Add selected images to this group">
- <?= jvbIcon('add') ?>
- Add to Group
- </button>
- <button type="button" class="remove-group" title="Delete group">
- <?= jvbIcon('delete') ?>
- Delete Group
- </button>
+ <div class="upload-group">
+ <div class="group-header">
+ <div class="selected">
+ <div class="field checkbox">
+ <input type="checkbox" id="select-all" name="select-all" data-selects="item-grid" data-select-all>
+ <label for="select-all">
+ Select All In Group
+ </label>
+ </div>
+ <div class="info" hidden>
</div>
</div>
- <div class="group-content col">
- <div class="item-grid group"></div>
- <p class="hint group-count"></p>
+ <div class="selection-actions">
+ <button type="button" data-action="add-to-group" title="Add selected uploads to this group">
+ <?= jvbIcon('plus-square') ?>
+ Add Here
+ </button>
+ <button type="button" data-action="delete-group" title="Delete group">
+ <?= jvbIcon('trash') ?>
+ Delete Group
+ </button>
</div>
- </summary>
- <div class="fields"></div>
- </details>
+ </div>
+ <details>
+ <summary class="row x-btw">
+ Extra Fields
+ </summary>
+ <div class="fields"></div>
+ </details>
+ <div class="group-content col">
+ <p class="hint count"></p>
+ <div class="item-grid group"></div>
+ </div>
+ </div>
+
</template>
<template class="groupActions">
<div class="item-actions">
- <div class="radio-button">
+ <div class="btn">
<input type="radio" class="featured btn" name="featured" id="featured">
<label for="featured">
<?=jvbIcon('star')?>
@@ -368,8 +472,8 @@
</label>
</div>
- <button type="button" class="remove" title="Remove from Group">
- <?=jvbIcon('delete')?>
+ <button type="button" data-action="remove-from-group" title="Remove from Group">
+ <?=jvbIcon('trash')?>
</button>
</div>
</template>
@@ -379,14 +483,10 @@
<span class="selection-count">0</span> items selected
</div>
<div class="selection-controls">
- <button type="button" class="create-from-selection">
- <?= jvbIcon('add') ?>
+ <button type="button" data-action="add-to-group">
+ <?= jvbIcon('plus-square') ?>
New Group
</button>
- <button type="button" class="deselect-all">
- <?= jvbIcon('close') ?>
- Deselect All
- </button>
</div>
</div>
</template>
@@ -412,89 +512,50 @@
</div>
</template>
<template class="uploadItem">
- <div class="upload-item">
- <div class="preview">
- <img>
- <?php jvbRenderProgressBar('<span class="icon"></span><span class="details"></span>') ?>
- <div class="actions">
- <input type="checkbox" class="upload-select" name="select-item" id="select-item">
- <label for="select-item" aria-label="Select image"></label>
- <div class="item-actions">
- <div class="radio-button">
- <input type="radio" class="featured btn" name="featured" id="featured" hidden>
- <label for="featured">
- <?=jvbIcon('star')?>
- <?=jvbIcon('star', ['style' => 'fill'])?>
- <span class="screen-reader-text">Set as featured image</span>
- </label>
- </div>
-
- <button type="button" class="remove" title="Remove from Group">
- <?=jvbIcon('delete')?>
- </button>
- </div>
-
- </div>
- </div>
- <details>
- <summary class="row btw"><?=jvbIcon('edit')?><span>Edit Image Info</span></summary>
- </details>
- </div>
+ <?= Form::renderImagePreview() ?>
</template>
<template class="restoreNotification">
- <div class="restore-notification">
- <div class="restore-content">
+ <dialog class="restore-uploads">
+ <div class="wrap">
<div class="restore-message">
<h4>Looks like we left things hanging</h4>
- <p class="restore-details"></p>
+ <p class="details"></p>
<p class="hint">If you'd rather start over, you can clear this information.</p>
</div>
- <div class="restore-actions">
- <div class="selection-controls">
- <button type="button" class="select-all-restore">Select All</button>
- <button type="button" class="select-none-restore">Select None</button>
+ <div class="selection-actions">
+ <div class="selected">
+ <div class="field checkbox">
+ <input type="checkbox" id="select-all-restore" name="select-all-restore">
+ <label for="select-all-restore">
+ Select All
+ </label>
+ </div>
+ <div class="info" hidden>
+ </div>
</div>
- <div class="action-buttons">
- <button type="button" class="restore-selected">
- <?= jvbIcon('restore') ?>
+ <div class="m-actions row nowrap">
+ <button type="button" data-action="restore-all">
+ <?= jvbIcon('infinity') ?>
+ Restore All
+ </button>
+ <button type="button" data-action="restore">
+ <?= jvbIcon('arrow-counter-clockwise') ?>
Restore Selected
</button>
- <button type="button" class="restart-uploads">
- <?= jvbIcon('delete') ?>
- Scrap Cache
- </button>
- <button type="button" class="dismiss-cache-check" title="Dismiss notification">
- <?= jvbIcon('close') ?>
- Dismiss
+ <button type="button" data-action="clear-cache" title="Clear cache and close window">
+ <?= jvbIcon('x') ?>
+ Clear Cache
</button>
</div>
</div>
</div>
- </div>
+ </dialog>
</template>
<template class="restoreField">
- <div class="restore-field">
- <h3></h3>
+ <details class="restore-field">
+ <summary><h3><a></a></h3></summary>
<div class="item-grid restore"></div>
- </div>
- </template>
- <template class="restoreItem">
- <label class="restore-item">
- <div class="preview">
- <img>
- <div class="image-placeholder"><svg width="40" height="40" fill="currentColor" viewBox="0 0 256 256">
- <path d="M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40ZM56,56H200V158.75l-26.07-26.06a16,16,0,0,0-22.63,0l-20,20-44-44a16,16,0,0,0-22.62,0L56,117.37V56Zm144,144H56V141.67l36.7-36.7,44,44a8,8,0,0,0,11.31,0l20-20L200,161.67V200ZM148,100a12,12,0,1,1,12,12A12,12,0,0,1,148,100Z"/>
- </svg></div>
- </div>
- <div class="restore-item-info">
- <div class="name"></div>
- <div class="restore-item-meta">
- </div>
- </div>
- <div class="restore-item-controls">
- <input type="checkbox" id="restore-" class="restore-checkbox" checked>
- </div>
- </label>
+ </details>
</template>
<template class="startOverConfirmation">
@@ -519,44 +580,26 @@
</div>
</dialog>
</template>
+ <template class="dragPreview">
+ <div class="drag-preview">
+ <div class="drag-items"><div class="drag-item"></div></div>
+ <div class="drag-count" hidden></div>
+ </div>
+ </template>
<?php
}
if (wp_script_is('jvb-selector')) {
- \JVBase\forms\TaxonomySelector::class::outputSelector();
+ TaxonomySelector::class::outputSelectorModal();
}
}
-function jvbImageMeta(int|null $ID = null, string $title = '', string $alt = '', string $caption = ''):string
-{
-
- $dataID = ($ID) ? ' data-image-id="'.$ID.'"' : '';
- $ID = ($ID) ? '-'.$ID : '';
-
- return '<div class="upload-meta"'.$dataID.'>
- <div class="field">
- <label for="image-title'.$ID.'">Image Title</label>
- <input type="text" id="image-title'.$ID.'" name="image-title'.$ID.'" value="'.$title.'">
- </div>
- <div class="field">
- <label for="image-alt-text'.$ID.'">Image Alt Text</label>
- <input type="text" id="image-alt-text'.$ID.'" name="image-alt-text'.$ID.'" value="'.$alt.'">
- <p class="hint">Alt text helps the visually impaired, as well as some benefits for SEO.</p>
- </div>
- <div class="field">
- <label for="image-caption'.$ID.'">Image Caption</label>
- <textarea id="image-caption'.$ID.'" name="image-caption'.$ID.'">'.$caption.'</textarea>
- </div>
- <p class="hint">These will be automatically generated if left blank.</p>
- </div>';
-}
-
function jvbLocationLinks(array $location): string {
if (empty($location['address'])) {
return '';
}
- $cache = new \JVBase\managers\CacheManager('location');
+ $cache = Cache::for('locations')->connect('taxonomy');
$key = $cache->generateKey($location);
$cached = false;
--
Gitblit v1.10.0