From 32ce5c542c90be348895328078e392dde2052957 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 04 Sep 2026 19:15:16 +0000
Subject: [PATCH] =Working at adding defined fields to a dedicated panel in the gutenberg editor. Registrar now has AddCustomFields.php, which currently only supports post fields. Added a @wordpress/plugins base _meta/fields in /build and /src that successfully creates a panel. Next steps: determine sections and fields, group fields by section (each section to a panel), and save output
---
inc/managers/SEO/render/SchemaOutput.php | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 155 insertions(+), 24 deletions(-)
diff --git a/inc/managers/SEO/render/SchemaOutput.php b/inc/managers/SEO/render/SchemaOutput.php
index 4619d94..87c2e7c 100644
--- a/inc/managers/SEO/render/SchemaOutput.php
+++ b/inc/managers/SEO/render/SchemaOutput.php
@@ -1,17 +1,30 @@
<?php
namespace JVBase\managers\SEO\render;
+use JVBase\base\SchemaHelper;
use JVBase\inc\managers\SEO\render\Thing\Intangible\ItemList\OfferCatalog;
+use JVBase\Instance;
use JVBase\managers\Cache;
use JVBase\managers\SEO\BreadcrumbManager;
+use JVBase\managers\SEO\render\Thing\CreativeWork\Menu;
+use JVBase\managers\SEO\render\Thing\CreativeWork\MenuSection;
+use JVBase\managers\SEO\render\Thing\Intangible\MenuItem;
+use JVBase\managers\SEO\render\Thing\Intangible\Offer;
use JVBase\managers\SEO\render\Thing\Intangible\Service;
use JVBase\managers\SEO\render\Thing\Organization\LocalBusiness\LocalBusiness;
+use JVBase\managers\SEO\render\Thing\Thing;
+use JVBase\meta\Meta;
use JVBase\registrar\config\seo\Resolver;
use JVBase\registrar\Registrar;
+use WP_Query;
+if (!defined('ABSPATH')) {
+ exit;
+}
class SchemaOutput {
+ use Instance;
protected array $types;
- public function __construct() {
+ protected function __construct() {
add_action('wp_head', [$this, 'outputSchema'], 0);
$this->init();
}
@@ -23,23 +36,28 @@
{
$schema = [];
-
+ $registrar = false;
if (is_front_page()) {
- $schema[] = $this->buildWebsiteSchema(true);
+ $schema[] = $this->buildWebsiteSchema();
$test = $this->buildOrganizationSchema();
if (!empty($test)) {
$schema[] = $test;
}
}
+
if (is_singular($this->types)) {
$type = get_post_type();
$registrar = Registrar::getInstance($type);
- if ($registrar) {
+
+ $function = BASE.'build_singular_'.jvbNoBase($type).'_schema';
+ if (function_exists($function)) {
+ $schema = $function(get_the_ID());
+ } else if ($registrar) {
$seo = $registrar->getSEO();
$schema[] = $seo->schema()->outputSingularSchema();
}
}elseif (is_post_type_archive($this->types)) {
- error_log('It is a post type archive');
+
$type = get_queried_object();
$type = $type->name;
$registrar = Registrar::getInstance($type);
@@ -54,17 +72,19 @@
$registrar = Registrar::getInstance($type);
if ($registrar ) {
$seo = $registrar->getSEO();
- error_log('SEO: '.print_r($seo->schema(), true));
+// error_log('SEO: '.print_r($seo->schema(), true));
$schema[] = $seo->schema()->outputArchiveSchema();
}
+ } elseif (is_post_type_archive('product')) {
+ $schema[] = $this->buildProductSchema();
}
$isContent = array_values(array_filter(array_map(function($item) {
return intval(get_option(BASE.$item.'_archive', false));
- },Registrar::getFeatured('is_content', 'term'))));
+ },Registrar::withFeature('is_content', 'term'))));
- if (is_page($isContent)){
+ if (!empty($isContent) && is_page($isContent)){
$type = get_post_meta(get_the_id(), BASE.'for_type', true);
- error_log('Type: '.print_r($type, true));
+// error_log('Type: '.print_r($type, true));
if (!empty($type)) {
$registrar = Registrar::getInstance($type);
if ($registrar) {
@@ -74,6 +94,10 @@
}
+ if ($registrar && !empty($registrar->getSEO()->schema()->extra())) {
+ $schema = array_merge($schema, $registrar->getSEO()->schema()->extra());
+ }
+
$breadcrumbs = $this->buildBreadcrumbs();
@@ -83,11 +107,9 @@
if (!empty($schema)) {
if (!is_front_page()) {
- $website = JVB()->schemaHelper()::schema('website');
+ $website = SchemaHelper::getInstance()::schema('website');
if (!empty($website)) {
- if (JVB_TESTING) {
- Cache::for('websiteSchema')->flush();
- }
+
$website = Cache::for('websiteSchema')->remember(
'schema',
function () {
@@ -103,13 +125,14 @@
'@graph' => $schema
];
}
+
return $schema;
}
protected function websiteSchema():array
{
- $stored = JVB()->schemaHelper()::schema('website');
- $website = JVB()->schemaHelper()::classFromConfig($stored);
+ $stored = SchemaHelper::getInstance()::schema('website');
+ $website = SchemaHelper::getInstance()::classFromConfig($stored);
if (!$website->getUrl() || empty($website->getUrl())){
$website->setUrl(get_home_url());
@@ -132,7 +155,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, 2048);
if ($encoded === false) {
error_log('wp_json_encode failed: ' . json_last_error_msg());
return;
@@ -155,7 +178,7 @@
if (JVB_TESTING){
Cache::for('websiteSchema')->flush();
}
- $storedWebsite = JVB()->schemaHelper()::schema('website');
+ $storedWebsite = SchemaHelper::getInstance()::schema('website');
if (!$full) {
return Cache::for('websiteSchema')->remember(
@@ -166,7 +189,7 @@
return in_array($key, $allowed);
}, ARRAY_FILTER_USE_KEY);
- $website = JVB()->schemaHelper()::classFromConfig($storedWebsite);
+ $website = SchemaHelper::getInstance()::classFromConfig($storedWebsite);
if (!$website->getName() || empty($website->getName())) {
$website->setName(get_bloginfo('name'));
}
@@ -198,7 +221,7 @@
return Cache::for('websiteSchema')->remember(
'full',
function () use ($storedWebsite) {
- $website = JVB()->schemaHelper()::classFromConfig($storedWebsite);
+ $website = SchemaHelper::getInstance()::classFromConfig($storedWebsite);
if (!$website->getName() || empty($website->getName())) {
$website->setName(get_bloginfo('name'));
}
@@ -298,9 +321,9 @@
if ($reference) {
return $this->getOptionSchemaReference('organization');
}
- $config = JVB()->schemaHelper()::schema('organization');
+ $config = SchemaHelper::getInstance()::schema('organization');
- return JVB()->schemaHelper()::classFromConfig($config);
+ return SchemaHelper::getInstance()::classFromConfig($config);
}
public function getOptionSchemaReference(string $option):mixed
@@ -314,7 +337,7 @@
return null;
}
- $stored = JVB()->schemaHelper()::reference($option);
+ $stored = SchemaHelper::getInstance()::reference($option);
if (empty($stored)){
error_log('Attempted to get schema reference for: '.$option.', but defaults not set.');
@@ -345,10 +368,118 @@
public function buildOrganizationSchema():array
{
- $config = JVB()->schemaHelper()::schema('organization');
+ $config = SchemaHelper::getInstance()::schema('organization');
- $class = JVB()->schemaHelper()::classFromConfig($config);
+ $class = SchemaHelper::getInstance()::classFromConfig($config);
return ($class)? $class->outputSchema() : [];
}
+
+ public function buildProductSchema():array
+ {
+ $sections = aneb_menu_sections();
+ if (empty($sections)) {
+ $sections = [];
+ }
+
+ $menuSections = [];
+
+ foreach ($sections as $s) {
+ if (empty($s['id'])) {
+ continue;
+ }
+ $items = new WP_Query([
+ 'post_type' => 'product',
+ 'order' => 'ASC',
+ 'posts_per_page' => -1,
+ 'post_status' => 'publish',
+ 'tax_query' => [
+ [
+ 'taxonomy' => 'product_cat',
+ 'terms' => (int)$s['id']
+ ]
+ ],
+ 'fields' => 'ids',
+ ]);
+ if (!$items->have_posts()) {
+ continue;
+ }
+
+ $section = new MenuSection();
+
+ $section->setName($s['name']);
+ $section->setId(get_post_type_archive_link('product').'#'.sanitize_title($s['name']));
+ if (!empty($s['description'])) {
+ $section->setDescription($s['description']);
+ }
+
+ $menuItems = [];
+ foreach ($items->posts as $ID) {
+ $meta = Meta::forPost($ID);
+ $fields = $meta->getAll();
+ if (empty($fields['variations'])) {
+ $item = $this->buildMenuItem($ID, $fields);
+ if ($item) {
+ $menuItems[] = $item;
+ }
+ } else {
+ foreach ($fields['variations'] as $variation) {
+ $item = $this->buildMenuItem($ID, $variation);
+ if ($item) {
+ $menuItems[] = $item;
+ }
+ }
+ }
+ }
+
+ if (!empty($menuItems)) {
+ $section->setHasMenuItem($menuItems);
+ $menuSections[] = $section;
+ }
+
+
+ }
+
+ if (!empty($menuSections)) {
+ $schema = new Menu();
+ $schema->setName(get_bloginfo('name') . ' | Alberta\'s Best Food Truck Menu');
+ $schema->setId(get_post_type_archive_link('product').'#menu');
+ $schema->setDescription('Southern style barbeque with Northern flair from Meeting Creek, Alberta');
+ $schema->setUrl(get_post_type_archive_link('product'));
+
+ $schema->setHasMenuSection($menuSections);
+
+ return $schema->outputSchema();
+ }
+
+ return [];
+ }
+
+ protected function buildMenuItem(int $ID, array $fields):MenuItem|false
+ {
+ $item = new MenuItem();
+ $item->setUrl(get_the_permalink($ID));
+ $base = get_post_type_archive_link('product').'#'.$ID.'-'.sanitize_title($fields['post_title']);
+ $item->setId($base);
+ $doit = false;
+ if (!empty($fields['post_thumbnail']??'')) {
+ $doit = true;
+ $item->setImage(Thing::createImageFromID($fields['post_thumbnail']));
+ }
+
+ if (!empty($fields['post_excerpt']??'')) {
+ $doit = true;
+ $item->setDescription(wp_strip_all_tags($fields['post_excerpt']));
+ }
+
+ if (!empty($fields['price']??'')) {
+ $doit = true;
+ $offer = new Offer();
+ $offer->setId($base.'-price');
+ $offer->setPrice($fields['price']);
+ $offer->setPriceCurrency('CAD');
+ $item->setOffers($offer);
+ }
+ return $doit ? $item : false;
+ }
}
--
Gitblit v1.10.0