Jake Vanderwerf
2026-05-11 aa974bf5954d0cca2506003a3cd9ec4eb89ed0bc
content/progress.php
@@ -1,212 +1,432 @@
<?php
// /content/progress.php
use JVBase\meta\Meta;
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',
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',
            ]
        ],
        'custom_order' => [
        ])
        ->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',
                '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'         => [],
            ]
    $directory = $progress->config('directory');
    $directory->setDirectoryExtra([
         'goal',
        'skin_type',
        'age'
    ]);
}
function altr_progress_schema():array
{
    return [
        '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',
                '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',
    ];
}
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
@@ -234,12 +454,12 @@
                <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"><?= array_key_exists('icon', JVB_TAXONOMY['goal']) ? jvbIcon(JVB_TAXONOMY['goal']['icon']) : '' ?><li><a></a></li></ul>
                <ul data-field="body-part" class="term-list"><?= array_key_exists('icon', JVB_TAXONOMY['body-part']) ? jvbIcon(JVB_TAXONOMY['body-part']['icon']) : '' ?><li><a><i></i></a></li></ul>
                <ul data-field="skin-type" class="term-list"><?= array_key_exists('icon', JVB_TAXONOMY['skin-type']) ? jvbIcon(JVB_TAXONOMY['skin-type']['icon']) : '' ?><li><a><i></i></a></li></ul>
                <ul data-field="age" class="term-list"><?= array_key_exists('icon', JVB_TAXONOMY['age']) ? jvbIcon(JVB_TAXONOMY['age']['icon']) : '' ?><li><a><i></i></a></li></ul>
                <ul data-field="style" class="term-list"><?= array_key_exists('icon', JVB_TAXONOMY['style']) ? jvbIcon(JVB_TAXONOMY['style']['icon']) : '' ?><li><a><i></i></a></li></ul>
                <ul data-field="theme" class="term-list"><?= array_key_exists('icon', JVB_TAXONOMY['theme']) ? jvbIcon(JVB_TAXONOMY['theme']['icon']) : '' ?><li><a><i></i></a></li></ul>
                <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>
@@ -256,10 +476,12 @@
        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;
@@ -329,9 +551,9 @@
    if (!$thumbnail || $thumbnail === 0) {
        return;
    }
    $meta = new Meta($ID, 'post');
    $meta = Meta::forPost($ID);
    $number = $meta->get('number');
    $terms = $meta->getAll(['style', 'body-part','goal', 'skin-type', 'age', 'timeline']);
    $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) {
@@ -343,10 +565,10 @@
        );
        switch ($slug) {
            case 'skin-type':
            case 'skin_type':
                $slug = 'skinType';
                break;
            case 'body-part':
            case 'body_part':
                $slug = 'bodyPart';
                break;
        }