From 7213ae7358c86aa3ca7e416a22379b42ed0f4eac Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 12 May 2026 14:04:28 +0000
Subject: [PATCH] =minor css tweak
---
content/progress.php | 643 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 603 insertions(+), 40 deletions(-)
diff --git a/content/progress.php b/content/progress.php
index e06ef9b..ec84aee 100644
--- a/content/progress.php
+++ b/content/progress.php
@@ -1,46 +1,609 @@
<?php
-// /content/art.php
-function altr_progress():array
+// /content/progress.php
+
+use JVBase\meta\Meta;
+use JVBase\registrar\Registrar;
+if (!defined('ABSPATH')) {
+ exit;
+}
+
+add_action('jvbDefineRegistrar', 'altr_progress');
+add_action('jvbDefineRegistrarFields', 'altr_progress_fields');
+
+add_action('plugins_loaded', 'altr_progress',1);
+//Add fields later so we can verify taxonomies/post types exist
+add_action('plugins_loaded', 'altr_progress_fields', 2);
+
+add_filter('altr_ProgressSchemaDefault', 'altr_progress_schema');
+add_filter('altr_ProgressMetaDefault', 'altr_progress_meta');
+add_filter('altr_ProgressArchiveDefault', 'altr_progress_archive');
+
+function altr_progress(){
+ if (!class_exists('JVBase\registrar\Registrar')) {
+ return;
+ }
+ $progress = Registrar::forPost('progress', 'Before & After', 'Before & Afters')
+ ->setIcon('arrows-left-right')
+ ->make([
+ 'rewrite' => [
+ 'slug' => 'before-and-after',
+ 'with_front' => false,
+ ],
+ 'taxonomies' => [
+ 'age',
+ 'body_part',
+ 'goal',
+ 'number',
+ 'person',
+ 'skin_type',
+ 'style',
+ 'theme',
+ 'timeline',
+ ]
+ ])
+ ->setAll([
+ 'show_directory',
+ 'show_feed',
+ 'hide_children',
+ 'is_timeline',
+ 'add_image_column'
+ ]);
+
+ $breadcrumb = $progress->config('breadcrumbs');
+ $breadcrumb->setTitle('Before & Afters');
+//$directory = $progress->getConfig('directory');
+
+}
+
+function altr_progress_fields():void
+{
+ if (!class_exists('JVBase\registrar\Registrar')) {
+ return;
+ }
+ $progress = Registrar::getInstance('progress');
+ $breadcrumbs = $progress->config('breadcrumbs');
+ $breadcrumbs->setCrumb(['project', 'form']);
+
+ $fields = $progress->fields();
+ $fields->modifyField('post_title', 'for_all', true);
+ $fields->modifyField('post_status', 'for_all', true);
+ $fields->modifyField('post_date', 'for_all', true);
+ $fields->modifyField('post_thumbnail', 'for_all', true);
+ $fields->addField('person', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'person',
+ 'label' => 'Person',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ 'hint' => 'Not public, just to make it easier to find',
+ ]);
+ $fields->addField('body_part', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'body_part',
+ 'label' => 'Body Part',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('goal', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'goal',
+ 'label' => 'Goal',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('timeline', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'timeline',
+ 'label' => 'Timeline',
+ 'quickEdit' => true,
+ 'for_all' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('style', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'style',
+ 'label' => 'Tattoo Style',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('theme', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'theme',
+ 'label' => 'Tattoo Theme',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('skin_type', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'skin_type',
+ 'label' => 'Skin Type',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('age', [
+ 'type' => 'selector',
+ 'subtype' => 'taxonomy',
+ 'taxonomy' => 'age',
+ 'label' => 'Age of Tattoo',
+ 'quickEdit' => true,
+ 'createNew' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->addField('number', [
+ 'type' => 'text',
+ 'subtype' => 'number',
+ 'label' => 'Number of Treatments',
+ 'quickEdit' => true,
+ 'for_all' => true,
+ 'section' => 'progression',
+ ]);
+ $fields->modifyField('post_content', 'for_all', true);
+ $fields->modifyField('post_content', 'label', 'About this Timeline Point');
+ $fields->addField('last_date', [
+ 'type' => 'text',
+ 'subtype' => 'number',
+ 'label' => 'Last Date',
+ 'hidden' => true,
+ ]);
+ $fields->addField('is_update', [
+ 'type' => 'true_false',
+ 'label' => 'Is Update',
+ 'hint' => 'If this point is not another treatment, but just an update in the progress',
+ 'for_all' => true,
+ ]);
+
+ $feed = $progress->config('feed');
+ $feed->setCustomOrder([
+ 'number' => [
+ 'label' => 'Number of Treatments',
+ 'icon' => 'hash-straight',
+ 'for' => 'progress'
+ ]
+ ]
+ );
+
+ $directory = $progress->config('directory');
+ $directory->setDirectoryExtra([
+ 'goal',
+ 'skin_type',
+ 'age'
+ ]);
+}
+
+function altr_progress_schema():array
{
return [
- 'singular' => 'Before & After',
- 'plural' => 'Before & Afters',
- 'dash_title' => 'Before & Afters',
- 'dash_description' => 'Manage your before and after posts',
- 'breadcrumb' => 'Before & Afters',
- 'hide_single' => false,
- 'show_feed' => true,
- 'favouritable' => false,
- 'karma' => false,
- 'icon' => 'arrows-left-right',
- 'rewrite' => [
- 'slug' => 'before-and-after',
- 'with_front' => false,
+ 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\ImageGallery',
+ 'name' => '{{post_title}} | Before and After Laser Tattoo Removal',
+ 'description' => '{{post_excerpt}}',
+ 'temporalCoverage' => '{{post_date}}/{{last_date}}',
+ 'additionalProperty'=> [
+ ['id'=> 'number-of-sessions','name' => 'Number of sessions', 'value' => '{{number.name}}'],
+ ['id' => 'treatment-area','name' => 'Treatment area', 'value' => '{{body_part.name}}'],
+ ['id' => 'tattoo-style','name' => 'Tattoo style', 'value' => '{{style.name}}'],
+ ['id' => 'skin-type','name' => 'Skin type', 'value' => '{{skin_type.name}}'],
+ ['id' => 'goal','name' => 'Goal', 'value' => '{{goal.name}}'],
],
- 'fields' => [
- 'post_title' => [
- 'type' => 'text',
- 'label' => 'Title',
- ],
- 'featured_image' => [
- 'type' => 'image',
- 'label' => 'Image',
- ],
- 'gallery' => [
- 'type' => 'gallery',
- 'label' => 'Gallery',
- ],
- 'price' => [
- 'type' => 'number',
- 'label' => 'Price',
- ],
- 'post_content' => [
- 'type' => 'textarea',
- 'quill' => true,
- 'label' => 'Notes'
- ]
- ],
- 'single_image' => false,
- 'upload_title' => 'Upload Before & Afters',
+
];
}
+
+function altr_progress_meta():array
+{
+ return[
+ 'title' => '{{style.name}} {{theme.name}} Tattoo – Before & After {{number}} Laser Removal Sessions',
+ 'description' => 'See this {{style.name}} {{theme.name}} {{age.name}}-old tattoo before and after {{number}} laser tattoo removal treatments on the {{body_part.name}}.',
+ ];
+}
+
+function altr_progress_archive(array $defaults):array
+{
+ return array_merge($defaults, [
+ 'name' => 'Tattoos Before and After Laser Tattoo Removal',
+ ]);
+}
+
+function altr_progress_reference_schema(array $defaults):array
+{
+ return $defaults;
+}
+
+//function altr_progress():array
+//{
+// return [
+// 'singular' => 'Before & After',
+// 'plural' => 'Before & Afters',
+// 'dash_title' => 'Progress',
+// 'dash_description' => 'Manage your before and after posts',
+// 'breadcrumb' => 'Before & Afters',
+// 'capability_type' => ['progress', 'progress'],
+// 'hide_children' => true,
+// 'is_timeline' => true,
+// 'show_feed' => true,
+// 'show_directory'=> true,
+// 'directory_extra'=> ['goal', 'skin-type','age'],
+// 'hierarchical' => true,
+// 'icon' => 'arrows-left-right',
+// 'rewrite' => [
+// 'slug' => 'before-and-after',
+// 'with_front' => false,
+// ],
+// 'sections' => [
+// 'progression' => [
+// 'label' => 'Progression',
+// ]
+// ],
+// 'custom_order' => [
+// 'number' => [
+// 'label' => 'Number of Treatments',
+// 'icon' => 'hash-straight',
+// 'for' => 'progress',
+// ]
+// ],
+// 'seo' => [
+// 'schema' => [
+// 'type' => 'BeforeAfter',
+// 'name' => '{{post_title}}',
+// 'description' => '{{post_excerpt}}',
+// 'temporalCoverage' => '{{post_date}}/{{last_date}}',
+// 'additionalProperty' => [
+// ['name' => 'Number of sessions', 'value' => '{{number.name}}'],
+// ['name' => 'Treatment area', 'value' => '{{body-part.name}}'],
+// ['name' => 'Tattoo style', 'value' => '{{style.name}}'],
+// ['name' => 'Skin type', 'value' => '{{skin-type.name}}'],
+// ['name' => 'Goal', 'value' => '{{goal.name}}'],
+// ],
+// 'associatedMedia' => '{{timeline_photos}}',
+// ],
+// 'meta' => [
+// 'title' => '{{style.name}} {{theme.name}} Tattoo – Before & After {{number}} Laser Removal Sessions',
+// 'description' => 'See this {{style.name}} {{theme.name}} {{age.name}}-old tattoo before and after {{number}} laser tattoo removal treatments on the {{body_part.name}}.',
+// ],
+// 'archive' => [
+// 'type' => 'CollectionPage',
+// 'name' => 'Tattoos Before and After Laser Tattoo Removal',
+// ],
+// ],
+// 'feed' => [
+// 'single' => [
+// 'pre_title' => 'Before & After Laser Tattoo Removal',
+// ],
+// 'archive' => [
+//
+// ],
+// 'config' => [
+// 'is_gallery' => false,
+// 'content' => 'progress',
+// 'context' => 'progress',
+// 'id' => [],
+// 'class' => [],
+// ]
+// ],
+// 'fields' => [
+// 'post_title' => [
+// 'type' => 'text',
+// 'label' => 'Title',
+// 'quickEdit' => true,
+// 'section' => 'progression',
+// 'for_all' => true,
+// ],
+// 'post_status' => [
+// 'type' => 'radio',
+// 'label' => 'Status',
+// 'options' => [
+// 'publish' => 'Show',
+// 'draft' => 'Hide',
+// 'trash' => 'Scrap',
+// 'delete' => 'Permanently Delete'
+// ],
+// 'for_all' => true,
+// ],
+// 'post_date' => [
+// 'type' => 'date',
+// 'label' => 'Date',
+// 'for_all' => true,
+// ],
+// 'post_thumbnail' => [
+// 'type' => 'upload',
+// 'label' => 'Image',
+// 'quickEdit' => true,
+// 'section' => 'progression',
+// 'for_all' => true,
+// ],
+// 'person' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'person',
+// 'autocomplete' => true,
+// 'label' => 'Person',
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression',
+// 'hint' => 'Not public, just to make it easier to find'
+// ],
+// 'body-part' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'body-part',
+// 'label' => 'Body Part',
+// 'autocomplete' => true,
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression'
+// ],
+// 'goal' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'goal',
+// 'autocomplete' => true,
+// 'label' => 'Goal',
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression'
+// ],
+// 'timeline' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'timeline',
+// 'autocomplete' => true,
+// 'label' => 'Timeline',
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression',
+// 'for_all' => true,
+// 'hidden' => true,
+// ],
+// 'style' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'style',
+// 'autocomplete' => true,
+// 'label' => 'Tattoo Style',
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression'
+// ],
+// 'theme' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'theme',
+// 'autocomplete' => true,
+// 'label' => 'Tattoo Theme',
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression'
+// ],
+// 'skin-type' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'skin-type',
+// 'label' => 'Skin Type',
+// 'autocomplete' => true,
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression'
+// ],
+// 'age' => [
+// 'type' => 'taxonomy',
+// 'taxonomy' => 'age',
+// 'autocomplete' => true,
+// 'label' => 'Age of Tattoo',
+// 'quickEdit' => true,
+// 'createNew' => true,
+// 'section' => 'progression'
+// ],
+// 'number' => [
+// 'type' => 'text',
+// 'subtype' => 'number',
+// 'label' => 'Number of Treatments',
+// 'quickEdit' => true,
+// 'section' => 'progression',
+// 'for_all' => true,
+// 'hidden' => true, //auto calculated
+// ],
+// 'post_content' => [
+// 'type' => 'textarea',
+// 'quill' => true,
+// 'label' => 'Notes',
+// 'section' => 'progression',
+// 'for_all' => true,
+// ],
+// 'last_date' => [
+// 'type' => 'number',
+// 'label' => 'Last Date',
+// 'hidden' => true,
+// 'default' => 0,
+// 'for_all' => true,
+// ]
+// ],
+// 'upload_title' => 'Upload Before & Afters',
+// ];
+//}
+
+add_filter('jvbFeedItem', 'altr_progress_item', 10, 2);
+
+function altr_progress_item(string $out, string $content):string
+{
+ if ($content !== 'progress') {
+ return $out;
+ }
+
+ ob_start();
+ ?>
+ <div class="feed item col progress" data-timeline>
+ <div class="images">
+ <a>
+ <span class="before-text">Before</span>
+ <img data-field="before" width="300px" height="300px" sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px" loading="lazy" decoding="async" class="before">
+ <img data-field="after" width="300px" height="300px" sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px" loading="lazy" decoding="async" class="after">
+ <span class="after-text">After</span>
+ </a>
+ </div>
+ <details>
+ <summary>
+ <?= jvbIcon('dots-three')?>
+ </summary>
+ <div class="item-info">
+ <p data-field="started">Started: <time></time></p>
+ <p data-field="updated">Last treated: <time></time></p>
+ <p data-field="number">Total Treatments: <b></b></p>
+ <ul data-field="goal" class="term-list"><?= jvbIcon(Registrar::getInstance('goal')->getIcon()) ?><li><a></a></li></ul>
+ <ul data-field="body_part" class="term-list"><?= jvbIcon(Registrar::getInstance('body_part')->getIcon()) ?><li><a><i></i></a></li></ul>
+ <ul data-field="skin_type" class="term-list"><?= jvbIcon(Registrar::getInstance('skin_type')->getIcon()) ?><li><a><i></i></a></li></ul>
+ <ul data-field="age" class="term-list"><?= jvbIcon(Registrar::getInstance('age')->getIcon()) ?><li><a><i></i></a></li></ul>
+ <ul data-field="style" class="term-list"><?= jvbIcon(Registrar::getInstance('style')->getIcon()) ?><li><a><i></i></a></li></ul>
+ <ul data-field="theme" class="term-list"><?=jvbIcon(Registrar::getInstance('theme')->getIcon()) ?><li><a><i></i></a></li></ul>
+ </div>
+ </details>
+ </div>
+
+ <?php
+ return ob_get_clean();
+}
+
+
+add_filter('jvbCoreFeaturedImage', 'altr_progress_featured_image', 10, 2);
+function altr_progress_featured_image(string $out, string $postType):string
+{
+ if ($postType !== BASE.'progress') {
+ return $out;
+ }
+ $route = JVB()->routes('content');
+ global $post;
+ $data = $route->formatTimeline($post);
+ $timeline = $data['fields']['timeline'];
+ if (!is_array($timeline)) {
+ return $out;
+ }
+ $total = count($timeline);
+ if ($total === 1) {
+ return $out;
+ }
+
+ $total--;
+ $first = '<span class="before">Before</span>'.jvbFormatImage($timeline[0]['post_thumbnail'],'tiny','medium',false);
+ $last = '<span class="after">After '.$total.' Tx</span>'.jvbFormatImage($timeline[$total]['post_thumbnail'],'tiny','medium',false);
+ return $first.$last;
+}
+
+add_filter('jvb_directory_render_item', 'altr_progress_directory_item', 10, 4);
+
+function altr_progress_directory_item(string $out, array $item, string $content, string $extra):string
+{
+ if ($content !== 'progress') return $out;
+ $parent = (int)$item['id'];
+ $children = get_children($parent);
+ $before = jvbFormatImage(get_post_thumbnail_id($parent),'tiny','directory-preview',false);
+ $after = '';
+ if ($children) {
+ $last = array_key_last($children);
+ $after = jvbIcon('logo-triangle-fill').jvbFormatImage(get_post_thumbnail_id($last),'tiny','directory-preview',false);
+ }
+
+ return '<li class="row btw">
+
+ <a href="'.$item['url'].'" title="More about '.$item['name'].'">
+ '.$item['name'].'</a>'.$extra.'
+ <div class="image">'.$before.$after.'</div>
+ </li>';
+}
+
+
+add_filter('jvbSEOResolveVariable', 'altr_progress_variables', 10, 6);
+function altr_progress_variables(mixed $return, string $variable, ?int $ID, ?string $objectType, ?string $contentType, ?Meta $meta):mixed
+{
+ if ($contentType !== 'progress' || !in_array($variable, ['timeline_photos', 'last_date'])) {
+ return $return;
+ }
+
+ $children = get_children([
+ 'post_parent' => $ID,
+ 'post_status' => 'publish',
+ 'order_by' => 'date',
+ 'fields' => 'ids'
+ ]);
+ //Insert the parent to the beginning
+ array_unshift($children, $ID);
+ if ($variable === 'timeline_photos') {
+ return array_map(function ($item) {
+ return get_post_thumbnail_id($item);
+ }, $children);
+ }
+ // $variable === 'last_date'
+ return get_the_date('c', $children[array_key_last($children)]);
+}
+
+
+add_action('wp_after_insert_post', 'altr_update_progress_alt_text', 999, 3);
+
+function altr_update_progress_alt_text(int $ID, WP_Post $post, bool $update, ?WP_Post $before = null) {
+ if ($post->post_type !== 'altr_progress') {
+ return;
+ }
+ $thumbnail = get_post_thumbnail_id($ID);
+ if (!$thumbnail || $thumbnail === 0) {
+ return;
+ }
+ $meta = Meta::forPost($ID);
+ $number = $meta->get('number');
+ $terms = $meta->getAll(['style', 'body_part','goal', 'skin_type', 'age', 'timeline']);
+ foreach($terms as $slug => $value) {
+ $terms = array_filter(
+ array_map(function($term) use($slug) {
+ return get_term((int)$term, BASE.$slug);
+ },explode(',', $value)
+ ), function($term) {
+ return $term && !is_wp_error($term);
+ }
+ );
+
+ switch ($slug) {
+ case 'skin_type':
+ $slug = 'skinType';
+ break;
+ case 'body_part':
+ $slug = 'bodyPart';
+ break;
+ }
+
+ if (empty($terms)) {
+ $$slug = '';
+ } else {
+ $$slug = jvbCommaList(array_map(function($term){ return $term->name; }, $terms));
+ }
+ }
+ $title = sprintf(
+ "%s | %s Before & After Laser Tattoo Removal",
+ $post->post_title,
+ $style
+ );
+ $style = ($style === '') ? $style : ' '.$style;
+ $age = ($age === '') ? $age : ' '.$age.' old';
+ $bodyPart = ($bodyPart === '') ? $bodyPart : ' on the '.$bodyPart;
+ $skinType = ($skinType === '') ? $skinType : ' on a person with FitzPatrick Skin Type '.$skinType;
+ $timeline = ($timeline === '') ? $timeline : ' '.$timeline.' after their '.$number.' treatment';
+ $goal = ($goal === '') ? $goal : ' This client is hoping for '.$goal;
+
+ $alt = sprintf(
+ "A photo of a%s%s tattoo%s%s%s.%s",
+ $style,
+ $age,
+ $bodyPart, //on the ...
+ $skinType, //on a person with FitzPatrick Scale skin type ...
+ $timeline, //", x weeks after their %number% treatment"
+ $goal //"This client is hoping for %goal%."
+ );
+
+ wp_update_post([
+ 'ID' => $thumbnail,
+ 'post_title' => $title
+ ]);
+ update_post_meta($thumbnail, '_wp_attachment_image_alt', $alt);
+}
\ No newline at end of file
--
Gitblit v1.10.0