While SEO plugins are capable of recognizing the Motors theme "Listings" page types, most do not do very well with actually parsing the information from the listing.
The listings themselves may not have consistent naming conventions from one deployment to the next -- and so the code below is provided as an example only. Just ask if you need a hand generating custom schema for every listing on your site automatically!
The end result? Product snippets of type "vehicle" to get your listings front and center on search and generative engines.
function generate_vehicle_schema() { global $post; // Fetch custom fields or metadata $manufacturer = get_post_meta($post->ID, 'make', true); $model = get_post_meta($post->ID, 'serie', true); $condition = get_post_meta($post->ID, 'condition', true); $sale_price = get_post_meta($post->ID, 'sale_price', true); $regular_price = get_post_meta($post->ID, 'regular_price', true); $mileage = get_post_meta($post->ID, 'mileage', true); $fuel_type = get_post_meta($post->ID, 'fuel', true); $color = get_post_meta($post->ID, 'exterior-color', true); $year = get_post_meta($post->ID, 'ca-year', true); $horsepower = get_post_meta($post->ID, 'horsepower', true); $vin = get_post_meta($post->ID, 'vin', true); $city = get_post_meta($post->ID, 'city', true); $state = get_post_meta($post->ID, 'state', true); // Transform the state: remove hyphens and capitalize the first letter of each word $state = $state ? ucwords(str_replace('-', ' ', strtolower($state))) : ''; // Construct the title dynamically and exclude "in" from capitalization $title = trim(sprintf( '%s %s %s in %s, %s', 'Used', $manufacturer ?: '', $model ?: '', $city ?: '', $state )); $title = preg_replace_callback('/\b(in)\b/i', function($matches) { return strtolower($matches[0]); }, ucwords(strtolower($title))); // Get the featured image URL $image = get_the_post_thumbnail_url($post->ID, 'full') ?: null; // Generate the description dynamically $description = "Used commercial truck available at yoursite.com: $title"; if ($mileage || $manufacturer || $model || $sale_price) { $description .= ". "; $description .= $mileage ? "$mileage miles on this " : ''; $description .= $manufacturer ? "$manufacturer " : ''; $description .= $model ? "$model, " : ''; $description .= $sale_price ? "current price is \$$sale_price. " : ''; $description .= "Financing available."; } // Determine the last day of the current month for priceValidUntil $price_valid_until = date('Y-m-t'); // Format: YYYY-MM-DD // Build the Schema.org JSON-LD structure $schema = [ '@context' => 'https://schema.org', '@type' => 'Vehicle', 'name' => $title ?: 'Unknown', 'manufacturer' => $manufacturer ?: 'Unknown', 'model' => $model ?: 'Unknown', 'vehicleCondition' => 'Used', 'price' => $sale_price ?: null, 'priceCurrency' => 'USD', 'mileageFromOdometer' => $mileage ?: null, 'fuelType' => $fuel_type ?: null, 'color' => $color ?: null, 'year' => $year ?: null, 'horsepower' => $horsepower ?: null, 'vehicleIdentificationNumber' => $vin ?: null, 'image' => $image, // Add image field 'description' => $description, // Add description field 'offers' => [ '@type' => 'Offer', 'price' => $sale_price ?: null, 'priceCurrency' => 'USD', 'priceValidUntil' => $price_valid_until, 'availability' => 'LimitedAvailability', ], 'location' => $city && $state ? "$city, $state" : null, ]; // Remove null or empty values $schema = array_filter($schema, function ($value) { return $value !== null && $value !== ''; }); // Output JSON-LD as a <script> tag echo '<script type="application/ld+json">' . json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . '</script>'; } // Call this function directly in the template or hook it to a specific action. generate_vehicle_schema();
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article