| @@ -86,8 +86,40 @@ | ||
| 86 | 86 | 'required' => ['@type', 'mainEntity'], |
| 87 | 87 | 'recommended' => ['about', 'author'], |
| 88 | 88 | 'optional' => ['name', 'description', 'url', 'dateModified'] |
| 89 | 89 | ], |
| 90 | + // The WebPage family. Schema_Builder has had a `case 'WebPage'` branch | |
| 91 | + // all along, but nothing here declared the type — so build_schema() | |
| 92 | + // rejected it before the switch was ever reached, and that branch was | |
| 93 | + // dead code. A customer asking for AboutPage and ContactPage is what | |
| 94 | + // surfaced it (#624). | |
| 95 | + // | |
| 96 | + // Only the four the output side can actually emit as themselves. | |
| 97 | + // ItemPage, QAPage and CollectionPage appear in | |
| 98 | + // Schema_Graph::PAGE_LEVEL_TYPES but have no branch in | |
| 99 | + // Global_SEO_Schema_Output::generate_schema(), so they fall to its | |
| 100 | + // `default` arm and publish plain WebPage — offering a type that | |
| 101 | + // silently emits a different one is worse than not offering it. | |
| 102 | + 'WebPage' => [ | |
| 103 | + 'required' => ['@type', 'name'], | |
| 104 | + 'recommended' => ['description', 'url', 'datePublished', 'dateModified'], | |
| 105 | + 'optional' => ['image', 'breadcrumb', 'primaryImageOfPage', 'about', 'mainEntity'] | |
| 106 | + ], | |
| 107 | + 'AboutPage' => [ | |
| 108 | + 'required' => ['@type', 'name'], | |
| 109 | + 'recommended' => ['description', 'url', 'datePublished', 'dateModified'], | |
| 110 | + 'optional' => ['image', 'breadcrumb', 'primaryImageOfPage', 'about', 'mainEntity'] | |
| 111 | + ], | |
| 112 | + 'ContactPage' => [ | |
| 113 | + 'required' => ['@type', 'name'], | |
| 114 | + 'recommended' => ['description', 'url', 'datePublished', 'dateModified'], | |
| 115 | + 'optional' => ['image', 'breadcrumb', 'primaryImageOfPage', 'about', 'mainEntity'] | |
| 116 | + ], | |
| 117 | + 'ProfilePage' => [ | |
| 118 | + 'required' => ['@type', 'name'], | |
| 119 | + 'recommended' => ['description', 'url', 'datePublished', 'dateModified'], | |
| 120 | + 'optional' => ['image', 'breadcrumb', 'primaryImageOfPage', 'about', 'mainEntity'] | |
| 121 | + ], | |
| 90 | 122 | 'LocalBusiness' => [ |
| 91 | 123 | 'required' => ['@type', 'name', 'address'], |
| 92 | 124 | 'recommended' => ['telephone', 'url', 'openingHours', 'geo', 'priceRange'], |
| 93 | 125 | 'optional' => ['description', 'logo', 'contactPoint', 'sameAs', 'paymentAccepted', 'currenciesAccepted'] |
| @@ -106,12 +138,22 @@ | ||
| 106 | 138 | 'required' => ['@type', 'name', 'startDate', 'location'], |
| 107 | 139 | 'recommended' => ['endDate', 'description', 'image', 'offers', 'performer'], |
| 108 | 140 | 'optional' => ['eventStatus', 'eventAttendanceMode', 'url', 'organizer'] |
| 109 | 141 | ], |
| 142 | + 'Review' => [ | |
| 143 | + 'required' => ['@type', 'itemReviewed', 'reviewRating', 'author'], | |
| 144 | + 'recommended' => ['reviewBody', 'datePublished', 'publisher'], | |
| 145 | + 'optional' => ['name', 'url'] | |
| 146 | + ], | |
| 110 | 147 | 'HowTo' => [ |
| 111 | 148 | 'required' => ['@type', 'name', 'step'], |
| 112 | 149 | 'recommended' => ['image', 'totalTime', 'estimatedCost', 'tool', 'supply'], |
| 113 | 150 | 'optional' => ['description', 'prepTime', 'difficulty', 'yield', 'video'] |
| 151 | + ], | |
| 152 | + 'VideoObject' => [ | |
| 153 | + 'required' => ['@type', 'name', 'description', 'thumbnailUrl', 'uploadDate'], | |
| 154 | + 'recommended' => ['contentUrl', 'embedUrl', 'duration'], | |
| 155 | + 'optional' => ['interactionStatistic', 'expires', 'regionsAllowed'] | |
| 114 | 156 | ] |
| 115 | 157 | ]; |
| 116 | 158 | |
| 117 | 159 | /** |
| @@ -178,9 +220,10 @@ | ||
| 178 | 220 | 'technicalarticle' => 'TechnicalArticle', |
| 179 | 221 | 'newsarticle' => 'NewsArticle', |
| 180 | 222 | 'scholarlyarticle' => 'ScholarlyArticle', |
| 181 | 223 | 'faqpage' => 'FAQPage', |
| 182 | - 'howto' => 'HowTo' | |
| 224 | + 'howto' => 'HowTo', | |
| 225 | + 'videoobject' => 'VideoObject' | |
| 183 | 226 | ]; |
| 184 | 227 | |
| 185 | 228 | $key = strtolower($schema_type); |
| 186 | 229 | return $schema_cases[$key] ?? ucfirst($schema_type); |