'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(); ?>
Before After

Started:

Last treated:

Total Treatments:

routes('content'); global $post; $data = $route->formatTimeline($post); $timeline = $data['fields']['timeline']; $total = count($timeline); if ($total === 1) { return $out; } $total--; $first = 'Before'.jvbFormatImage($timeline[0]['post_thumbnail'],'tiny','medium',false); $last = 'After '.$total.' Tx'.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 '
  • '.$item['name'].''.$extra.'
    '.$before.$after.'
  • '; } 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 = new Meta($ID, 'post'); $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); }