From ed57c386db34d8693ca75311972d0929ebe5f488 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 01 Jun 2026 22:23:19 +0000
Subject: [PATCH] =Added some more Schema classes, allowed for override of  array in outputSchema for complex schema, as for timeline post types

---
 inc/managers/SEO/render/Traits/_Properties/followupTrait.php        |   21 +++
 inc/managers/SEO/render/SchemaOutput.php                            |    2 
 inc/managers/SEO/render/Thing/MedicalEntity/_setup.php              |    4 
 inc/managers/SEO/render/Traits/_Properties/preparationTrait.php     |   23 +++
 inc/registrar/config/seo/Resolver.php                               |   11 +
 inc/managers/SEO/render/Thing/MedicalEntity/MedicalEntity.php       |   13 +
 inc/managers/SEO/render/Thing/_setup.php                            |    1 
 inc/managers/SEO/render/Thing/Intangible/_setup.php                 |    1 
 inc/registrar/config/seo/Meta.php                                   |    2 
 inc/managers/SEO/render/Thing/CreativeWork/Article/Article.php      |    9 +
 inc/managers/SEO/render/Traits/_Properties/articleSectionTrait.php  |   21 +++
 inc/managers/SEO/render/Traits/_Properties/bodyLocationTrait.php    |   21 +++
 inc/managers/SEO/render/Traits/_Properties/paginationTrait.php      |   21 +++
 inc/managers/SEO/render/Traits/_Properties/pageStartTrait.php       |   21 +++
 inc/managers/SEO/render/Thing/CreativeWork/Article/_setup.php       |    4 
 inc/managers/SEO/render/Traits/_Properties/backstoryTrait.php       |   23 +++
 inc/managers/SEO/render/Thing/CreativeWork/Article/Report.php       |   14 ++
 inc/managers/SEO/render/Traits/_Properties/_setup.php               |   13 +
 inc/managers/SEO/render/Traits/_Properties/pageEndTrait.php         |   21 +++
 inc/managers/SEO/render/Traits/_Properties/reportNumberTrait.php    |   21 +++
 inc/managers/SEO/render/Traits/ThingSchema.php                      |   15 +
 inc/managers/SEO/render/Traits/_Properties/marginOfErrorTrait.php   |   23 +++
 inc/managers/SEO/render/Thing/Intangible/Observation.php            |   17 ++
 inc/managers/SEO/render/Traits/_Properties/howPerformedTrait.php    |   21 +++
 inc/managers/SEO/render/Traits/_Properties/observationDateTrait.php |   27 +++
 inc/managers/SEO/render/Thing/MedicalEntity/MedicalProcedure.php    |   18 ++
 26 files changed, 380 insertions(+), 8 deletions(-)

diff --git a/inc/managers/SEO/render/SchemaOutput.php b/inc/managers/SEO/render/SchemaOutput.php
index 8bd5a35..a6cdc55 100644
--- a/inc/managers/SEO/render/SchemaOutput.php
+++ b/inc/managers/SEO/render/SchemaOutput.php
@@ -141,7 +141,7 @@
 		}
 //		$encoded =  wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
 //		$encoded =  wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT, 1024);
-		$encoded = wp_json_encode($schema, JSON_UNESCAPED_SLASHES, 512);
+		$encoded = wp_json_encode($schema, JSON_UNESCAPED_SLASHES, 1024);
 		if ($encoded === false) {
 			error_log('wp_json_encode failed: ' . json_last_error_msg());
 			return;
diff --git a/inc/managers/SEO/render/Thing/CreativeWork/Article/Article.php b/inc/managers/SEO/render/Thing/CreativeWork/Article/Article.php
index 01968e8..f4f091f 100644
--- a/inc/managers/SEO/render/Thing/CreativeWork/Article/Article.php
+++ b/inc/managers/SEO/render/Thing/CreativeWork/Article/Article.php
@@ -1,7 +1,14 @@
 <?php
 namespace JVBase\managers\SEO\render\Thing\CreativeWork\Article;
 
+use JVBase\inc\managers\SEO\render\Traits\_Properties\articleBodyTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\articleSectionTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\backstoryTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\pageEndTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\pageStartTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\paginationTrait;
 use JVBase\managers\SEO\render\Thing\CreativeWork\CreativeWork;
+use JVBase\managers\SEO\render\Traits\_Properties\wordCountTrait;
 
 if (!defined('ABSPATH')) {
 	exit;
@@ -9,5 +16,5 @@
 
 
 class Article extends CreativeWork {
-
+	use articleBodyTrait, articleSectionTrait, backstoryTrait, pageEndTrait, pageStartTrait, paginationTrait, wordCountTrait;
 }
diff --git a/inc/managers/SEO/render/Thing/CreativeWork/Article/Report.php b/inc/managers/SEO/render/Thing/CreativeWork/Article/Report.php
new file mode 100644
index 0000000..369be44
--- /dev/null
+++ b/inc/managers/SEO/render/Thing/CreativeWork/Article/Report.php
@@ -0,0 +1,14 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Thing\CreativeWork\Article;
+
+use JVBase\inc\managers\SEO\render\Traits\_Properties\reportNumberTrait;
+use JVBase\managers\SEO\render\Thing\CreativeWork\Article\Article;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+
+
+class Report extends Article {
+	use reportNumberTrait;
+}
diff --git a/inc/managers/SEO/render/Thing/CreativeWork/Article/_setup.php b/inc/managers/SEO/render/Thing/CreativeWork/Article/_setup.php
index e69de29..3abef7e 100644
--- a/inc/managers/SEO/render/Thing/CreativeWork/Article/_setup.php
+++ b/inc/managers/SEO/render/Thing/CreativeWork/Article/_setup.php
@@ -0,0 +1,4 @@
+<?php
+$base = JVB_DIR . '/inc/managers/SEO/render/Thing/CreativeWork/Article/';
+require ($base.'Article.php');
+require ($base.'Report.php');
diff --git a/inc/managers/SEO/render/Thing/Intangible/Observation.php b/inc/managers/SEO/render/Thing/Intangible/Observation.php
new file mode 100644
index 0000000..64d26a6
--- /dev/null
+++ b/inc/managers/SEO/render/Thing/Intangible/Observation.php
@@ -0,0 +1,17 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Thing\Intangible;
+
+
+use JVBase\inc\managers\SEO\render\Traits\_Properties\marginOfErrorTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\observationDateTrait;
+use JVBase\managers\SEO\render\Thing\Intangible\StructuredValue\QuantitativeValue;
+use JVBase\managers\SEO\render\Traits\_Properties\associatedMediaTrait;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+
+class Observation extends QuantitativeValue {
+	use marginOfErrorTrait, observationDateTrait, associatedMediaTrait;
+	//TODO also has measuredProperty, measurementDenominator, measurementMethod, measurementQualifier, measurementTechnique, observationAbout, observationPeriod, and variableMeasured
+}
diff --git a/inc/managers/SEO/render/Thing/Intangible/_setup.php b/inc/managers/SEO/render/Thing/Intangible/_setup.php
index 0869361..56cc70e 100644
--- a/inc/managers/SEO/render/Thing/Intangible/_setup.php
+++ b/inc/managers/SEO/render/Thing/Intangible/_setup.php
@@ -20,6 +20,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/ListItem.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/MenuItem.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/MerchantReturnPolicy.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/Observation.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/Occupation.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/OccupationalExperienceRequirements.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/Offer.php');
diff --git a/inc/managers/SEO/render/Thing/MedicalEntity/MedicalEntity.php b/inc/managers/SEO/render/Thing/MedicalEntity/MedicalEntity.php
new file mode 100644
index 0000000..1850c99
--- /dev/null
+++ b/inc/managers/SEO/render/Thing/MedicalEntity/MedicalEntity.php
@@ -0,0 +1,13 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Thing\MedicalEntity;
+
+use JVBase\managers\SEO\render\Thing\Thing;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+
+
+class MedicalEntity extends Thing {
+	//TODO: has code, funding, guideline, legalStatus, medicineSystem, recognizingAuthority, relevantSpecialty, and study
+}
diff --git a/inc/managers/SEO/render/Thing/MedicalEntity/MedicalProcedure.php b/inc/managers/SEO/render/Thing/MedicalEntity/MedicalProcedure.php
new file mode 100644
index 0000000..7ca79a2
--- /dev/null
+++ b/inc/managers/SEO/render/Thing/MedicalEntity/MedicalProcedure.php
@@ -0,0 +1,18 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Thing\MedicalEntity;
+
+
+use JVBase\inc\managers\SEO\render\Traits\_Properties\bodyLocationTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\followupTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\howPerformedTrait;
+use JVBase\inc\managers\SEO\render\Traits\_Properties\preparationTrait;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+
+
+class MedicalProcedure extends MedicalEntity {
+	use bodyLocationTrait, followupTrait, howPerformedTrait, preparationTrait;
+	//TODO: Also has procedureType and status
+}
diff --git a/inc/managers/SEO/render/Thing/MedicalEntity/_setup.php b/inc/managers/SEO/render/Thing/MedicalEntity/_setup.php
new file mode 100644
index 0000000..4180661
--- /dev/null
+++ b/inc/managers/SEO/render/Thing/MedicalEntity/_setup.php
@@ -0,0 +1,4 @@
+<?php
+$base = JVB_DIR . '/inc/managers/SEO/render/Thing/MedicalEntity/';
+require ($base.'MedicalEntity.php');
+require ($base.'MedicalProcedure.php');
diff --git a/inc/managers/SEO/render/Thing/_setup.php b/inc/managers/SEO/render/Thing/_setup.php
index e1f0ca8..029dadd 100644
--- a/inc/managers/SEO/render/Thing/_setup.php
+++ b/inc/managers/SEO/render/Thing/_setup.php
@@ -5,6 +5,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/CreativeWork/_setup.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Event/_setup.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Intangible/_setup.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Thing/MedicalEntity/_setup.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Organization/_setup.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Person/_setup.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Thing/Place/_setup.php');
diff --git a/inc/managers/SEO/render/Traits/ThingSchema.php b/inc/managers/SEO/render/Traits/ThingSchema.php
index 43ec460..d41ad97 100644
--- a/inc/managers/SEO/render/Traits/ThingSchema.php
+++ b/inc/managers/SEO/render/Traits/ThingSchema.php
@@ -31,11 +31,12 @@
 		nameTrait, ownerTrait, potentialActionTrait, sameAsTrait, subjectOfTrait, urlTrait;
 
 	protected string $id;
-
+	protected bool $showID = true;
 	protected array $ignore = [
 		'mappedMethods',
 		'ignore',
-		'id'
+		'id',
+		'showID',
 	];
 	public function outputSchema():array
 	{
@@ -76,9 +77,10 @@
 			}, ARRAY_FILTER_USE_KEY)
 		);
 
-		return  array_merge([
+		$id = $this->showID ? ['@id' => $id] : [];
+
+		return  array_merge($id, [
 			'@type'	=> $this->getTypeName(),
-			'@id'	=> $id,
 		], array_filter($elements));
 	}
 
@@ -161,4 +163,9 @@
 		);
 
 	}
+
+	public function showID(bool $showIt = true):void
+	{
+		$this->showID = $showIt;
+	}
 }
diff --git a/inc/managers/SEO/render/Traits/_Properties/_setup.php b/inc/managers/SEO/render/Traits/_Properties/_setup.php
index 9a463f9..7c08ef4 100644
--- a/inc/managers/SEO/render/Traits/_Properties/_setup.php
+++ b/inc/managers/SEO/render/Traits/_Properties/_setup.php
@@ -32,6 +32,8 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/applicableCountryTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/areaServedTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/artEditionTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/articleBodyTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/articleSectionTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/artistTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/artFormTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/artMediumTrait.php');
@@ -51,10 +53,12 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/availableDeliveryMethodTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/availableLanguageTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/awardTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/backstoryTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/bestRatingTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/birthDateTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/birthPlaceTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/bitrateTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/bodyLocationTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/bookingTimeTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/boxTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/branchCodeTrait.php');
@@ -165,6 +169,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/faxNumberTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/fiberContentTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/followsTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/followupTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/founderTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/foundingDateTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/foundingLocationTrait.php');
@@ -201,6 +206,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/honorificPrefixTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/honorificSuffixTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/hoursAvailableTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/howPerformedTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/httpMethodTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/imageTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/includesObjectTrait.php');
@@ -261,6 +267,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/manufacturerTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/materialExtentTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/materialTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/marginOfErrorTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/maximumAttendeeCapacityTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/maximumPhysicalAttendeeCapacityTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/maximumVirtualAttendeeCapacityTrait.php');
@@ -287,6 +294,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/numberOfItemsTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/nutritionTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/objectTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/observationDateTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/occupationalCategoryTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/occupationLocationTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/offerCountTrait.php');
@@ -299,6 +307,9 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/ownershipFundInfoTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/ownerTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/ownsTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/pageEndTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/pageStartTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/paginationTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/parentOrganizationTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/parentTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/parentItemTrait.php');
@@ -320,6 +331,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/postOfficeBoxNumberTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/potentialActionTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/predecessorOfTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/preparationTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/prepTimeTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/previousItemTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/previousStartDateTrait.php');
@@ -357,6 +369,7 @@
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/remainingAttendeeCapacityTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/repeatCountTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/repeatFrequencyTrait.php');
+require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/reportNumberTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/representativeOfPageTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/requiredQuantityTrait.php');
 require(JVB_DIR . '/inc/managers/SEO/render/Traits/_Properties/reservationForTrait.php');
diff --git a/inc/managers/SEO/render/Traits/_Properties/articleSectionTrait.php b/inc/managers/SEO/render/Traits/_Properties/articleSectionTrait.php
new file mode 100644
index 0000000..b951714
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/articleSectionTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait articleSectionTrait {
+	/**
+	 * @var string Articles may belong to one or more 'sections' in a magazine or newspaper, such as Sports, Lifestyle, etc.
+	 */
+	protected string $articleSection;
+
+	public function getArticleSection():?string
+	{
+		return $this->articleSection??null;
+	}
+	public function setArticleSection(string $articleSection):void
+	{
+		$this->articleSection = $articleSection;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/backstoryTrait.php b/inc/managers/SEO/render/Traits/_Properties/backstoryTrait.php
new file mode 100644
index 0000000..8195c64
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/backstoryTrait.php
@@ -0,0 +1,23 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+use JVBase\managers\SEO\render\Thing\CreativeWork\CreativeWork;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait backstoryTrait {
+	/**
+	 * @var CreativeWork|string For an Article, typically a NewsArticle, the backstory property provides a textual summary giving a brief explanation of why and how an article was created. In a journalistic setting this could include information about reporting process, methods, interviews, data sources, etc.
+	 */
+	protected CreativeWork|string $backstory;
+
+	public function getBackstory():CreativeWork|string|null
+	{
+		return $this->backstory??null;
+	}
+	public function setBackstory(CreativeWork|string $backstory):void
+	{
+		$this->backstory = $backstory;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/bodyLocationTrait.php b/inc/managers/SEO/render/Traits/_Properties/bodyLocationTrait.php
new file mode 100644
index 0000000..9c92311
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/bodyLocationTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait bodyLocationTrait {
+	/**
+	 * @var string Location in the body of the anatomical structure.
+	 */
+	protected string $bodyLocation;
+
+	public function getBodyLocation():?string
+	{
+		return $this->bodyLocation??null;
+	}
+	public function setBodyLocation(string $bodyLocation):void
+	{
+		$this->bodyLocation = $bodyLocation;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/followupTrait.php b/inc/managers/SEO/render/Traits/_Properties/followupTrait.php
new file mode 100644
index 0000000..c87c310
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/followupTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait followupTrait {
+	/**
+	 * @var string Typical or recommended followup care after the procedure is performed.
+	 */
+	protected string $followup;
+
+	public function getFollowup():?string
+	{
+		return $this->followup??null;
+	}
+	public function setFollowup(string $followup):void
+	{
+		$this->followup = $followup;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/howPerformedTrait.php b/inc/managers/SEO/render/Traits/_Properties/howPerformedTrait.php
new file mode 100644
index 0000000..351f8dc
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/howPerformedTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait howPerformedTrait {
+	/**
+	 * @var string How the procedure is performed.
+	 */
+	protected string $howPerformed;
+
+	public function getHowPerformed():?string
+	{
+		return $this->howPerformed??null;
+	}
+	public function setHowPerformed(string $howPerformed):void
+	{
+		$this->howPerformed = $howPerformed;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/marginOfErrorTrait.php b/inc/managers/SEO/render/Traits/_Properties/marginOfErrorTrait.php
new file mode 100644
index 0000000..2d6cc1d
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/marginOfErrorTrait.php
@@ -0,0 +1,23 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+use JVBase\managers\SEO\render\Thing\Intangible\StructuredValue\QuantitativeValue;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait marginOfErrorTrait {
+	/**
+	 * @var QuantitativeValue A marginOfError for an Observation.
+	 */
+	protected QuantitativeValue $marginOfError;
+
+	public function getMarginOfError():?QuantitativeValue
+	{
+		return $this->marginOfError??null;
+	}
+	public function setMarginOfError(QuantitativeValue $marginOfError):void
+	{
+		$this->marginOfError = $marginOfError;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/observationDateTrait.php b/inc/managers/SEO/render/Traits/_Properties/observationDateTrait.php
new file mode 100644
index 0000000..045415c
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/observationDateTrait.php
@@ -0,0 +1,27 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+use JVBase\managers\SEO\render\DataType\Date;
+use JVBase\managers\SEO\render\DataType\DateTime;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait observationDateTrait {
+	/**
+	 * @var Date|DateTime A observationDate of the item
+	 */
+	protected Date|DateTime $observationDate;
+
+	public function getObservationDate():Date|DateTime|null
+	{
+		return $this->observationDate??null;
+	}
+	public function setObservationDate(Date|DateTime|string $observationDate):void
+	{
+		if (is_string($observationDate)) {
+			$observationDate = new Date($observationDate);
+		}
+		$this->observationDate = $observationDate;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/pageEndTrait.php b/inc/managers/SEO/render/Traits/_Properties/pageEndTrait.php
new file mode 100644
index 0000000..2493898
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/pageEndTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait pageEndTrait {
+	/**
+	 * @var string|int The page on which the work ends; for example "138" or "xvi".
+	 */
+	protected string|int $pageEnd;
+
+	public function getPageEnd():string|int|null
+	{
+		return $this->pageEnd??null;
+	}
+	public function setPageEnd(string|int $pageEnd):void
+	{
+		$this->pageEnd = $pageEnd;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/pageStartTrait.php b/inc/managers/SEO/render/Traits/_Properties/pageStartTrait.php
new file mode 100644
index 0000000..7bbb32a
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/pageStartTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait pageStartTrait {
+	/**
+	 * @var string|int The page on which the work starts; for example "138" or "xvi".
+	 */
+	protected string|int $pageStart;
+
+	public function getPageStart():string|int|null
+	{
+		return $this->pageStart??null;
+	}
+	public function setPageStart(string|int $pageStart):void
+	{
+		$this->pageStart = $pageStart;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/paginationTrait.php b/inc/managers/SEO/render/Traits/_Properties/paginationTrait.php
new file mode 100644
index 0000000..85047d4
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/paginationTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait paginationTrait {
+	/**
+	 * @var string Any description of pages that is not separated into pageStart and pageEnd; for example, "1-6, 9, 55" or "10-12, 46-49".
+	 */
+	protected string $pagination;
+
+	public function getPagination():?string
+	{
+		return $this->pagination??null;
+	}
+	public function setPagination(string $pagination):void
+	{
+		$this->pagination = $pagination;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/preparationTrait.php b/inc/managers/SEO/render/Traits/_Properties/preparationTrait.php
new file mode 100644
index 0000000..c1926c1
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/preparationTrait.php
@@ -0,0 +1,23 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+use JVBase\inc\managers\SEO\render\Thing\MedicalEntity\MedicalEntity;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait preparationTrait {
+	/**
+	 * @var MedicalEntity|string A preparation of the item
+	 */
+	protected MedicalEntity|string $preparation;
+
+	public function getPreparation():MedicalEntity|string|null
+	{
+		return $this->preparation??null;
+	}
+	public function setPreparation(MedicalEntity|string $preparation):void
+	{
+		$this->preparation = $preparation;
+	}
+}
diff --git a/inc/managers/SEO/render/Traits/_Properties/reportNumberTrait.php b/inc/managers/SEO/render/Traits/_Properties/reportNumberTrait.php
new file mode 100644
index 0000000..457bf22
--- /dev/null
+++ b/inc/managers/SEO/render/Traits/_Properties/reportNumberTrait.php
@@ -0,0 +1,21 @@
+<?php
+namespace JVBase\inc\managers\SEO\render\Traits\_Properties;
+
+if (!defined('ABSPATH')) {
+	exit;
+}
+trait reportNumberTrait {
+	/**
+	 * @var string The number or other unique designator assigned to a Report by the publishing organization.
+	 */
+	protected string $reportNumber;
+
+	public function getReportNumber():?string
+	{
+		return $this->reportNumber??null;
+	}
+	public function setReportNumber(string $reportNumber):void
+	{
+		$this->reportNumber = $reportNumber;
+	}
+}
diff --git a/inc/registrar/config/seo/Meta.php b/inc/registrar/config/seo/Meta.php
index f43cf15..26a4ac9 100644
--- a/inc/registrar/config/seo/Meta.php
+++ b/inc/registrar/config/seo/Meta.php
@@ -26,6 +26,8 @@
 
 	public function __construct(string $slug) {
 		$this->slug = $slug;
+
+		$this->titleConfig['alts'] = apply_filters(BASE.jvbNoBase($slug).'TitleAlts', []);
 		add_action('init', [$this, 'init']);
 	}
 
diff --git a/inc/registrar/config/seo/Resolver.php b/inc/registrar/config/seo/Resolver.php
index e9c681b..172e1c5 100644
--- a/inc/registrar/config/seo/Resolver.php
+++ b/inc/registrar/config/seo/Resolver.php
@@ -209,6 +209,12 @@
 			if (!$imgID || $imgID === '') {
 				return null;
 			}
+
+			return self::imgIDToSchema($imgID);
+
+		}
+		public static function imgIDToSchema(int $imgID):ImageObject|null
+		{
 			$img = wp_get_attachment_image_src($imgID,'full');
 			if (!$img) {
 				return null;
@@ -223,12 +229,14 @@
 					$imageObject = new ImageObject();
 					$imageObject->setContentUrl($img[0]);
 					$width = new QuantitativeValue();
+					$width->showID(false);
 					$width->setValue($img[1]);
 					$width->setUnitText('px');
 					$imageObject->setWidth($width);
 					$height = new QuantitativeValue();
+					$height->showID(false);
 					$height->setValue($img[2]);
-					$width->setUnitText('px');
+					$height->setUnitText('px');
 					$imageObject->setHeight($height);
 
 					$image_path = get_attached_file($imgID);
@@ -249,7 +257,6 @@
 					return $imageObject;
 				}
 			);
-
 		}
 
 		public static function resolveCreator(string $type, mixed $value, mixed $schema, ?Meta $meta):mixed

--
Gitblit v1.10.0