Changeset 3492628
- Timestamp:
- 03/27/2026 12:07:05 PM (6 days ago)
- Location:
- firetap-knowledge-panel-schema
- Files:
-
- 24 added
- 2 edited
-
tags/2.7 (added)
-
tags/2.7/firetap-knowledge-panel-schema.php (added)
-
tags/2.7/includes (added)
-
tags/2.7/includes/class-kpsp-faq-display.php (added)
-
tags/2.7/includes/class-kpsp-pro.php (added)
-
tags/2.7/includes/class-kpsp-review-manager.php (added)
-
tags/2.7/includes/class-kpsp-video-manager.php (added)
-
tags/2.7/index.php (added)
-
tags/2.7/languages (added)
-
tags/2.7/languages/firetap-knowledge-panel-schema-en_GB.po (added)
-
tags/2.7/languages/index.php (added)
-
tags/2.7/readme.txt (added)
-
tags/2.7/templates (added)
-
tags/2.7/templates/index.php (added)
-
tags/2.7/templates/single-video.php (added)
-
trunk/firetap-knowledge-panel-schema.php (modified) (10 diffs)
-
trunk/includes (added)
-
trunk/includes/class-kpsp-faq-display.php (added)
-
trunk/includes/class-kpsp-pro.php (added)
-
trunk/includes/class-kpsp-review-manager.php (added)
-
trunk/includes/class-kpsp-video-manager.php (added)
-
trunk/languages/firetap-knowledge-panel-schema-en_GB.po (added)
-
trunk/readme.txt (modified) (5 diffs)
-
trunk/templates (added)
-
trunk/templates/index.php (added)
-
trunk/templates/single-video.php (added)
Legend:
- Unmodified
- Added
- Removed
-
firetap-knowledge-panel-schema/trunk/firetap-knowledge-panel-schema.php
r3490689 r3492628 3 3 Plugin Name: Firetap Knowledge Panel Schema 4 4 Plugin URI: https://firetap.co.uk/ 5 Description: Adds Organization + LocalBusiness JSON-LD (type selector, single PostalAddress, multi-location via hasPart, social, optional reviews, FAQ UI with URL targeting, Services CSV, Products UI with image upload + logo fallback, Courses UI) with modern admin UI.6 Version: 2. 65 Description: Adds Organization + LocalBusiness JSON-LD (type selector, single PostalAddress, multi-location via hasPart, social, optional reviews, FAQ UI with URL targeting, Services CSV, Products UI with image upload + logo fallback, Courses UI) with templates, entity linking, conditions, validation, reviews, FAQ groups, and per-post overrides. 6 Version: 2.7 7 7 Author: Rakshak Mathur (FireTap Ltd) 8 8 Author URI: https://firetap.co.uk … … 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html 11 11 Text Domain: firetap-knowledge-panel-schema 12 Domain Path: /languages 12 13 Requires at least: 6.0 13 14 Requires PHP: 7.4 … … 17 18 exit; 18 19 } 20 21 define( 'KPSP_VERSION', '2.7' ); 22 define( 'KPSP_PLUGIN_FILE', __FILE__ ); 23 define( 'KPSP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 24 define( 'KPSP_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 25 26 add_action( 27 'plugins_loaded', 28 static function() { 29 load_plugin_textdomain( 'firetap-knowledge-panel-schema', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); 30 } 31 ); 32 33 if ( file_exists( KPSP_PLUGIN_DIR . 'includes/class-kpsp-pro.php' ) ) { 34 require_once KPSP_PLUGIN_DIR . 'includes/class-kpsp-pro.php'; 35 } 36 37 if ( file_exists( KPSP_PLUGIN_DIR . 'includes/class-kpsp-faq-display.php' ) ) { 38 require_once KPSP_PLUGIN_DIR . 'includes/class-kpsp-faq-display.php'; 39 } 40 41 if ( file_exists( KPSP_PLUGIN_DIR . 'includes/class-kpsp-review-manager.php' ) ) { 42 require_once KPSP_PLUGIN_DIR . 'includes/class-kpsp-review-manager.php'; 43 } 44 45 if ( file_exists( KPSP_PLUGIN_DIR . 'includes/class-kpsp-video-manager.php' ) ) { 46 require_once KPSP_PLUGIN_DIR . 'includes/class-kpsp-video-manager.php'; 47 } 48 49 register_activation_hook( 50 __FILE__, 51 static function() { 52 if ( class_exists( 'KPSP_Video_Manager' ) ) { 53 KPSP_Video_Manager::activate(); 54 } 55 } 56 ); 57 58 register_deactivation_hook( 59 __FILE__, 60 static function() { 61 if ( class_exists( 'KPSP_Video_Manager' ) ) { 62 KPSP_Video_Manager::deactivate(); 63 } 64 } 65 ); 19 66 20 67 /** … … 50 97 } 51 98 add_action( 'admin_init', 'kpsp_maybe_migrate_legacy_options', 1 ); 99 100 /** 101 * Refresh rewrite rules after plugin updates so video URLs and sitemap routes work. 102 */ 103 function kpsp_maybe_refresh_rewrites() { 104 $stored_version = get_option( 'kpsp_rewrite_version', '' ); 105 106 if ( KPSP_VERSION === $stored_version ) { 107 return; 108 } 109 110 if ( class_exists( 'KPSP_Video_Manager' ) ) { 111 KPSP_Video_Manager::boot(); 112 } 113 114 flush_rewrite_rules( false ); 115 update_option( 'kpsp_rewrite_version', KPSP_VERSION ); 116 } 117 add_action( 'init', 'kpsp_maybe_refresh_rewrites', 99 ); 52 118 53 119 /** ========================================================= … … 733 799 function kpsp_admin_css() { 734 800 return ' 735 .kpsp-tab-content{background:#fff;padding:20px;border:1px solid #ddd;margin-top:10px;border-radius:8px;} 736 .kpsp-location-row{display:flex;gap:10px;margin-bottom:8px;flex-wrap:wrap;} 737 .kpsp-location-row input{flex:1;min-width:180px;padding:5px;border:1px solid #ccc;border-radius:4px;} 738 .kpsp-location-row button.kpsp-remove-location{background:#e74c3c;color:#fff;border:none;padding:5px 10px;border-radius:4px;cursor:pointer;} 739 .kpsp-location-row button.kpsp-remove-location:hover{background:#c0392b;} 740 .nav-tab-wrapper .nav-tab{padding:10px 15px;margin-right:5px;border-radius:5px 5px 0 0;} 741 .nav-tab-wrapper .nav-tab.nav-tab-active{background:#d22e33;color:#fff;} 742 #kpsp-json-preview{font-family:monospace;white-space:pre-wrap;max-height:420px;overflow:auto;} 743 .kpsp-faq-item{border:1px solid #e5e5e5;border-radius:8px;padding:12px;margin:12px 0;background:#fafafa;} 744 .kpsp-faq-head{display:flex;gap:10px;align-items:center;margin-bottom:8px;} 801 .nav-tab-wrapper{border-bottom:1px solid #d3e6ea;padding-bottom:0;} 802 .nav-tab-wrapper .nav-tab{padding:10px 16px;margin-right:6px;border:1px solid #c8d8de;border-bottom:none;border-radius:8px 8px 0 0;background:#f4fbfc;color:#264653;font-weight:600;box-shadow:none;} 803 .nav-tab-wrapper .nav-tab:hover{background:#dff7f8;color:#15345d;} 804 .nav-tab-wrapper .nav-tab.nav-tab-active{background:#264653;color:#fff;border-color:#264653;box-shadow:0 10px 20px rgba(38,70,83,.14);} 805 .kpsp-tab-content{background:linear-gradient(180deg,#ffffff 0%,#f5fbfc 100%);padding:24px;border:1px solid #d3e6ea;margin-top:10px;border-radius:16px;box-shadow:0 16px 32px rgba(38,70,83,.08);} 806 .kpsp-tab-content h2,.kpsp-tab-content h3{color:#15345d;} 807 .kpsp-tab-content p.description{color:#4f6671;} 808 .kpsp-tab-content input[type=\"text\"],.kpsp-tab-content input[type=\"url\"],.kpsp-tab-content input[type=\"number\"],.kpsp-tab-content input[type=\"time\"],.kpsp-tab-content input[type=\"date\"],.kpsp-tab-content select,.kpsp-tab-content textarea{border:1px solid #bdd7dd;border-radius:10px;padding:9px 12px;box-shadow:none;} 809 .kpsp-tab-content input[type=\"text\"]:focus,.kpsp-tab-content input[type=\"url\"]:focus,.kpsp-tab-content input[type=\"number\"]:focus,.kpsp-tab-content input[type=\"time\"]:focus,.kpsp-tab-content input[type=\"date\"]:focus,.kpsp-tab-content select:focus,.kpsp-tab-content textarea:focus{border-color:#2bb8c4;box-shadow:0 0 0 1px #2bb8c4;} 810 .kpsp-tab-content .button,.kpsp-tab-content .button-secondary{border-color:#264653;color:#264653;border-radius:10px;padding:6px 14px;} 811 .kpsp-tab-content .button:hover,.kpsp-tab-content .button-secondary:hover{border-color:#1b3240;color:#1b3240;background:#dff7f8;} 812 .kpsp-tab-content .button-primary{background:#264653;border-color:#264653;color:#fff;border-radius:10px;box-shadow:none;} 813 .kpsp-tab-content .button-primary:hover,.kpsp-tab-content .button-primary:focus{background:#15345d;border-color:#15345d;color:#fff;} 814 .kpsp-location-row{display:flex;gap:10px;margin-bottom:10px;flex-wrap:wrap;padding:12px;border:1px solid #d3e6ea;border-radius:14px;background:#f8fcfd;} 815 .kpsp-location-row input{flex:1;min-width:180px;padding:9px 12px;border:1px solid #bdd7dd;border-radius:10px;} 816 .kpsp-location-row button.kpsp-remove-location,.kpsp-faq-remove{background:#264653!important;color:#fff!important;border:none!important;padding:9px 14px;border-radius:10px!important;cursor:pointer;box-shadow:none!important;} 817 .kpsp-location-row button.kpsp-remove-location:hover,.kpsp-faq-remove:hover{background:#15345d!important;} 818 #kpsp-json-preview{font-family:monospace;white-space:pre-wrap;max-height:420px;overflow:auto;background:#102a43;color:#dff7f8;border-radius:14px;padding:18px;border:1px solid #264653;} 819 .kpsp-faq-item{border:1px solid #d3e6ea;border-radius:14px;padding:14px;margin:12px 0;background:#f8fcfd;box-shadow:0 10px 24px rgba(38,70,83,.05);} 820 .kpsp-faq-head{display:flex;gap:10px;align-items:center;margin-bottom:10px;} 745 821 .kpsp-faq-head input{flex:1;min-width:280px;} 746 .kpsp-faq-remove{background:#e74c3c!important;color:#fff!important;border:none!important;} 747 .kpsp-faq-remove:hover{background:#c0392b!important;} 748 .kpsp-hours-table{width:100%;max-width:720px;border-collapse:collapse;} 749 .kpsp-hours-table th,.kpsp-hours-table td{padding:8px;border-bottom:1px solid #eee;vertical-align:middle;} 750 .kpsp-hours-table input[type="time"]{min-width:120px;} 751 .kpsp-special-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:10px 0;padding:10px;border:1px solid #eee;border-radius:8px;background:#fafafa;} 822 .kpsp-hours-table{width:100%;max-width:720px;border-collapse:collapse;background:#fff;border:1px solid #d3e6ea;border-radius:14px;overflow:hidden;} 823 .kpsp-hours-table th,.kpsp-hours-table td{padding:10px 12px;border-bottom:1px solid #e7f1f4;vertical-align:middle;} 824 .kpsp-hours-table th{background:#f2fbfc;color:#15345d;} 825 .kpsp-hours-table input[type=\"time\"]{min-width:120px;} 826 .kpsp-special-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:10px 0;padding:12px;border:1px solid #d3e6ea;border-radius:14px;background:#f8fcfd;} 752 827 .kpsp-special-row input{min-width:160px;} 753 .kpsp-product-row,.kpsp-course-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;margin:10px 0;padding:1 0px;border:1px solid #eee;border-radius:8px;background:#fafafa;}754 .kpsp-product-row label,.kpsp-course-row label{display:flex;flex-direction:column;font-size:12px;gap:4px; }828 .kpsp-product-row,.kpsp-course-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;margin:10px 0;padding:12px;border:1px solid #d3e6ea;border-radius:14px;background:#f8fcfd;box-shadow:0 10px 24px rgba(38,70,83,.05);} 829 .kpsp-product-row label,.kpsp-course-row label{display:flex;flex-direction:column;font-size:12px;gap:4px;color:#264653;font-weight:600;} 755 830 .kpsp-product-row input,.kpsp-course-row input{min-width:180px;} 756 831 .kpsp-media-btn{margin-top:4px;} 832 .kpsp-accent-note{color:#9f8a11;} 757 833 '; 758 834 } … … 1237 1313 wp_enqueue_media(); 1238 1314 1239 wp_register_style( 'kpsp-admin-style', false, array(), '2.6');1315 wp_register_style( 'kpsp-admin-style', false, array(), KPSP_VERSION ); 1240 1316 wp_enqueue_style( 'kpsp-admin-style' ); 1241 1317 wp_add_inline_style( 'kpsp-admin-style', kpsp_admin_css() ); 1242 1318 1243 wp_register_script( 'kpsp-admin-script', false, array( 'jquery' ), '2.6', true );1319 wp_register_script( 'kpsp-admin-script', false, array( 'jquery' ), KPSP_VERSION, true ); 1244 1320 wp_enqueue_script( 'kpsp-admin-script' ); 1245 1321 wp_add_inline_script( 'kpsp-admin-script', kpsp_admin_js() ); … … 1448 1524 ?> 1449 1525 <div class="wrap"> 1450 <h1><?php echo esc_html__( 'Knowledge Panel Schema Pro - Modern', 'firetap-knowledge-panel-schema' ); ?></h1>1526 <h1><?php echo esc_html__( 'Knowledge Panel Schema', 'firetap-knowledge-panel-schema' ); ?></h1> 1451 1527 1452 1528 <h2 class="nav-tab-wrapper"> … … 1750 1826 <div class="kpsp-tab-content" id="preview-tab" style="display:none"> 1751 1827 <h2><?php echo esc_html__( 'Live JSON-LD Preview', 'firetap-knowledge-panel-schema' ); ?></h2> 1752 <pre id="kpsp-json-preview" style="background:# f5f5f5;padding:10px;border:1px solid #ccc;"></pre>1828 <pre id="kpsp-json-preview" style="background:#102a43;color:#dff7f8;padding:18px;border:1px solid #264653;border-radius:14px;"></pre> 1753 1829 </div> 1754 1830 … … 1953 2029 } 1954 2030 2031 $graph = apply_filters( 2032 'kpsp_schema_graph', 2033 $graph, 2034 array( 2035 'org_id' => $org_id, 2036 'local_id' => $lb_id, 2037 'org_name' => $org_name, 2038 'org_url' => $org_url, 2039 'business_type' => $business_type, 2040 'social' => $social, 2041 'phone' => $phone, 2042 'logo' => $logo, 2043 'locations' => $locations, 2044 ) 2045 ); 2046 1955 2047 $schema = array( 1956 2048 '@context' => 'https://schema.org', … … 2025 2117 ); 2026 2118 } 2119 -
firetap-knowledge-panel-schema/trunk/readme.txt
r3490666 r3492628 1 1 === Firetap Knowledge Panel Schema === 2 2 Contributors: firetapltd, rakshakmathur 3 Tags: schema, json-ld, knowledge panel, localbusiness, structured data 3 Tags: schema, json-ld, knowledge panel, localbusiness, structured data, faq, review, video 4 4 Requires at least: 6.0 5 5 Tested up to: 6.9 6 Stable tag: 2. 66 Stable tag: 2.7 7 7 Requires PHP: 7.4 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 Generate clean JSON-LD schema for Organization, LocalBusiness, FAQs, Products and Courses with full control and no duplicates.11 Generate clean JSON-LD schema for business, content, FAQ, review, and video pages with templates, entities, validation, reusable styling, and post-level overrides. 12 12 13 13 == Description == 14 14 15 Firetap Knowledge Panel Schema is a lightweight yet powerful structured data plugin designed for **SEO professionals, agencies, and local businesses** who want **accurate, error-free schema markup**without complexity.15 Firetap Knowledge Panel Schema is a lightweight yet powerful structured data plugin designed for SEO professionals, agencies, and local businesses who want accurate, error-free schema markup without complexity. 16 16 17 17 Unlike many schema plugins, this plugin focuses on: 18 18 19 ✔Clean JSON-LD output20 ✔No duplicate structured data issues21 ✔Full control over where schema appears22 ✔ Compliance with Google Rich Results guidelines 19 * Clean JSON-LD output 20 * No duplicate structured data issues 21 * Full control over where schema appears 22 * Compliance with Google rich result guidance 23 23 24 It helps you build a complete **Google Knowledge Panel-ready schema setup**including:24 It helps you build a complete Google Knowledge Panel-ready schema setup including: 25 25 26 26 * Organization and LocalBusiness schema 27 * Multi-location support (primary + additional locations via `hasPart`)28 * Opening hours and special /holiday hours29 * FAQ schema with URL targeting (prevents duplicate FAQ warnings)27 * Multi-location support with primary and additional locations via `hasPart` 28 * Opening hours and special or holiday hours 29 * FAQ schema with reusable FAQ Groups, multiple display layouts, and sitewide style controls 30 30 * Product schema with valid `Offer` markup and image fallback 31 * Course schema using correct `Course` type (not misused Product schema) 32 * Optional Google Reviews integration (via Google Places API) 31 * Course schema using the correct `Course` type 32 * Review Groups for manual or imported review collections 33 * Optional Google Reviews integration via Google Places API 34 * Public video pages with VideoObject schema and a dedicated video sitemap 35 * Templates, entities, conditions, validation, and post-level overrides 33 36 34 Developed by **FireTap Ltd**, a UK-based digital marketing agency focused on technical SEO.37 Developed by FireTap Ltd, a UK-based digital marketing agency focused on technical SEO. 35 38 36 39 == Why This Plugin? == … … 40 43 * Output unnecessary or bloated markup 41 44 * Cause duplicate FAQ or Product schema issues 42 * Misuse schema types (especially Courses)45 * Misuse schema types 43 46 44 This plugin is built to **avoid those problems completely**. 45 46 ✔ No shortcodes 47 ✔ No frontend rendering 48 ✔ No unnecessary scripts 49 ✔ Only clean JSON-LD output 47 This plugin is built to avoid those problems with clean output, focused admin tools, and purpose-built display modules only where needed. 50 48 51 49 == Features == 52 50 53 * Business type selector (ProfessionalService, LegalService, Store, etc.) 54 * Primary location + multiple additional locations 55 * FAQ schema with page-level targeting 56 * Product schema: 51 * Business type selector such as ProfessionalService, LegalService, and Store 52 * Primary location plus multiple additional locations 53 * Classic main settings screen with live JSON-LD preview 54 * Templates, entities, conditions, validation, and per-post schema overrides 55 * FAQ Groups with: 56 57 * Accordion, boxed, minimal, grid cards, and question-and-answer layouts 58 * Website color, global FAQ style, or manual color modes 59 * Reusable global FAQ colors and sizing 60 * Hex color entry plus color pickers 61 * WYSIWYG answer editing 62 * Shortcode output 63 * Review Groups with: 64 65 * Manual review entry 66 * Paste import support 67 * Source labels for Google, Trustpilot, Review Solicitors, Facebook, Yelp, and other review sites 68 * Review schema output 69 * Product schema with: 57 70 58 71 * Price 59 72 * Availability 60 * Image (with automatic logo fallback)73 * Image with automatic logo fallback 61 74 * Course schema for training and education 62 * URL targeting for:75 * Public Videos post type with: 63 76 64 * FAQs 65 * Products 66 * Courses 67 * Opening hours + special hours support 68 * Google Rich Results compatible output 69 * Live JSON-LD preview in admin panel 70 * Lightweight and fast (no frontend assets) 77 * Metadata fields for video URL, upload date, duration, thumbnail, description, transcript, content URL, and embed URL 78 * Best-effort metadata detection for YouTube and Vimeo URLs 79 * Dedicated single video pages for indexing 80 * VideoObject schema 81 * Video sitemap output at `/video-sitemap.xml` 82 * URL targeting for FAQs, Products, and Courses 83 * Opening hours and special hours support 84 * Google rich result compatible output 85 * Lightweight front-end output with assets only on dedicated feature pages 71 86 72 87 == External Services == 73 88 74 This plugin can optionally connect to the **Google Places API (Google Maps Platform)**to fetch public review and rating data.89 This plugin can optionally connect to the Google Places API (Google Maps Platform) to fetch public review and rating data. 75 90 76 91 * What is sent: 77 92 78 * Your configured **Place ID**79 * Your **API key**93 * Your configured Place ID 94 * Your API key 80 95 * When: 81 96 … … 94 109 1. Upload the plugin folder to `/wp-content/plugins/` 95 110 2. Activate the plugin 96 3. Go to **KPSP Schema**in the WordPress admin menu97 4. Configure your schema settings111 3. Go to `KPSP Schema` in the WordPress admin menu 112 4. Configure your schema, FAQ, review, and video settings 98 113 5. Save changes 114 6. If video pages were just enabled, save Permalinks once to refresh rewrites 99 115 100 116 == Frequently Asked Questions == 101 117 102 118 = Will this cause duplicate FAQ errors? = 103 No. FAQ schema can be restricted to specific URLs to prevent duplication issues .119 No. FAQ schema can be restricted to specific URLs to prevent duplication issues, and FAQ Groups can output FAQPage schema only when needed. 104 120 105 121 = Can I use this for courses instead of products? = 106 122 Yes. Courses use proper `Course` schema instead of incorrectly using Product schema. 123 124 = Can I reuse FAQ styling across the whole website? = 125 Yes. Save a reusable FAQ style once in the plugin Settings page, then select `Use Global FAQ Style` inside any FAQ Group. 126 127 = Does it support video indexing? = 128 Yes. The plugin includes public video pages, VideoObject markup, and a dedicated `/video-sitemap.xml` feed. 107 129 108 130 = Does schema output on every page? = … … 110 132 111 133 = Does this slow down my website? = 112 No. The plugin o nly outputs lightweight JSON-LD in the `<head>` with no frontend scripts.134 No. The plugin outputs lightweight JSON-LD in the `<head>` and only loads dedicated display assets where they are needed. 113 135 114 136 == Changelog == 137 138 = 2.7 = 139 140 * Added templates, entities, conditions, validation, and post-level overrides while keeping existing KPSP settings and output intact 141 * Added reusable schema templates with mapping, conditions, preview, and validation 142 * Added advanced schema support for Person, Brand, Article, Service, Review, Recipe, VideoObject, Event, JobPosting, Book, SoftwareApplication, Podcast, Movie, and VehicleListing 143 * Added FAQ Groups with multiple display styles, WYSIWYG answers, color controls, hex inputs, and reusable global FAQ styling 144 * Added Review Groups with manual entry, import support, source tracking, and review schema output 145 * Added public Videos post type with metadata detection, custom video details editing, standalone video pages, VideoObject schema, SEO schema integration, and `/video-sitemap.xml` output 146 * Added entity linking for Organization, Person, and Brand using reusable `@id` nodes 147 * Added per-post schema override metabox for disabling templates or injecting custom JSON-LD 148 * Added duplicate protection for appended schema nodes 149 * Updated plugin admin styling and kept the original main settings experience available for safe upgrades 150 * Preserved legacy `kpsp_*` options and existing 2.6 schema output for safe upgrades 115 151 116 152 = 2.6 = 117 153 118 154 * Fixed location fields not saving correctly in admin 119 * Fixed locations option mismatch ( locations → kpsp_locations)155 * Fixed locations option mismatch (`locations` to `kpsp_locations`) 120 156 * Improved location sanitisation and reliability 121 157 * Improved live JSON preview accuracy … … 126 162 * Added Course schema support 127 163 * Added Product image upload with logo fallback 128 * Added URL targeting for FAQs, Products &Courses164 * Added URL targeting for FAQs, Products, and Courses 129 165 * Fixed Product rich results validation 130 166 * Improved schema output consistency
Note: See TracChangeset
for help on using the changeset viewer.