<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>wordpress development Archives - Developry Themes</title>
	<atom:link href="https://developrythemes.com/tag/wordpress-development/feed/" rel="self" type="application/rss+xml" />
	<link>https://developrythemes.com/tag/wordpress-development/</link>
	<description>Nexus Pro — Engineered for AI Search &#38; SEO Performance</description>
	<lastBuildDate>Mon, 24 Nov 2025 08:05:04 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://developrythemes.com/wp-content/uploads/sites/9/2025/11/cropped-favicon-32x32.png</url>
	<title>wordpress development Archives - Developry Themes</title>
	<link>https://developrythemes.com/tag/wordpress-development/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Extending Nexus Pro: Add Custom Fields to Entity Templates</title>
		<link>https://developrythemes.com/extending-nexus-pro-add-custom-fields-to-entity-templates/</link>
					<comments>https://developrythemes.com/extending-nexus-pro-add-custom-fields-to-entity-templates/#respond</comments>
		
		<dc:creator><![CDATA[Krasen Slavov]]></dc:creator>
		<pubDate>Fri, 20 Feb 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Developer Guides]]></category>
		<category><![CDATA[custom fields]]></category>
		<category><![CDATA[entity templates]]></category>
		<category><![CDATA[nexus pro]]></category>
		<category><![CDATA[plugin extension]]></category>
		<category><![CDATA[wordpress development]]></category>
		<guid isPermaLink="false">https://developrythemes.com/?p=519</guid>

					<description><![CDATA[<p>Nexus Pro provides Person, Product, and Place entity templates with essential schema fields out of the box.</p>
<p>The post <a href="https://developrythemes.com/extending-nexus-pro-add-custom-fields-to-entity-templates/">Extending Nexus Pro: Add Custom Fields to Entity Templates</a> appeared first on <a href="https://developrythemes.com">Developry Themes</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Nexus Pro provides Person, Product, and Place entity templates with essential schema fields out of the box. However, many projects require additional custom fields—industry-specific data, extra properties, or specialized metadata. Extending Nexus Pro through hooks and filters allows adding custom fields while maintaining plugin compatibility and update safety.</p>



<p>This developer guide shows you how to extend Nexus Pro&#8217;s entity templates, add custom meta fields, integrate with schema output, and create admin interfaces for your custom data.</p>



<h2 class="wp-block-heading" id="understanding-nexus-pro-architecture">Understanding Nexus Pro Architecture</h2>



<p>Foundation for safe extensions.</p>



<h3 class="wp-block-heading" id="entity-template-structure">Entity Template Structure</h3>



<p><strong>Three Custom Post Types:</strong></p>



<p><strong>1. Person (nexus_person):</strong></p>



<ul class="wp-block-list">
<li>Name, job title, bio</li>



<li>Social profiles</li>



<li>Contact information</li>



<li>Person schema markup</li>
</ul>



<p><strong>2. Product (nexus_product):</strong></p>



<ul class="wp-block-list">
<li>Product name, description</li>



<li>Price, availability</li>



<li>Images, SKU</li>



<li>Product schema markup</li>
</ul>



<p><strong>3. Place (nexus_place):</strong></p>



<ul class="wp-block-list">
<li>Business name, type</li>



<li>Address, coordinates</li>



<li>Hours, contact</li>



<li>LocalBusiness schema markup</li>
</ul>



<h3 class="wp-block-heading" id="hook-system">Hook System</h3>



<p><strong>Nexus Pro provides hooks for:</strong></p>



<ul class="wp-block-list">
<li>Adding meta fields to admin</li>



<li>Saving custom meta data</li>



<li>Filtering schema output</li>



<li>Modifying entity queries</li>



<li>Extending admin interfaces</li>
</ul>



<p><strong>Hook Naming Convention:</strong></p>



<pre class="wp-block-code"><code>nexus_pro_{entity}_{action}
</code></pre>



<p>Examples:</p>



<ul class="wp-block-list">
<li><code>nexus_pro_person_meta_fields</code></li>



<li><code>nexus_pro_product_schema</code></li>



<li><code>nexus_pro_place_save_meta</code></li>
</ul>



<h2 class="wp-block-heading" id="adding-custom-fields-to-person-entity">Adding Custom Fields to Person Entity</h2>



<p>Extend Person template with additional fields.</p>



<h3 class="wp-block-heading" id="register-custom-meta-fields">Register Custom Meta Fields</h3>



<p><strong>Add Fields to Admin:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Add custom fields to Person entity edit screen.
 */</em>
function add_custom_person_fields($post) {
    <em>// Get current values</em>
    $linkedin = get_post_meta($post-&gt;ID, 'linkedin_url', true);
    $github = get_post_meta($post-&gt;ID, 'github_url', true);
    $expertise = get_post_meta($post-&gt;ID, 'expertise_areas', true);
    ?&gt;
    &lt;div class="nexus-pro-custom-fields"&gt;
        &lt;h3&gt;Additional Professional Information&lt;/h3&gt;

        &lt;p&gt;
            &lt;label for="linkedin_url"&gt;LinkedIn Profile:&lt;/label&gt;&lt;br&gt;
            &lt;input type="url" id="linkedin_url" name="linkedin_url"
                   value="&lt;?php echo esc_attr($linkedin); ?&gt;"
                   class="widefat" placeholder="https://linkedin.com/in/username"&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for="github_url"&gt;GitHub Profile:&lt;/label&gt;&lt;br&gt;
            &lt;input type="url" id="github_url" name="github_url"
                   value="&lt;?php echo esc_attr($github); ?&gt;"
                   class="widefat" placeholder="https://github.com/username"&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for="expertise_areas"&gt;Expertise Areas (comma-separated):&lt;/label&gt;&lt;br&gt;
            &lt;input type="text" id="expertise_areas" name="expertise_areas"
                   value="&lt;?php echo esc_attr($expertise); ?&gt;"
                   class="widefat" placeholder="WordPress, PHP, JavaScript"&gt;
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;?php
}
add_action('nexus_pro_person_meta_fields', 'add_custom_person_fields');
</code></pre>



<h3 class="wp-block-heading" id="save-custom-meta-data">Save Custom Meta Data</h3>



<p><strong>Hook Into Save Process:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Save custom Person meta fields.
 */</em>
function save_custom_person_meta($post_id) {
    <em>// Security checks</em>
    if (defined('DOING_AUTOSAVE') &amp;&amp; DOING_AUTOSAVE) {
        return;
    }

    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    <em>// Verify post type</em>
    if (get_post_type($post_id) !== 'nexus_person') {
        return;
    }

    <em>// Save LinkedIn URL</em>
    if (isset($_POST&#91;'linkedin_url'])) {
        update_post_meta(
            $post_id,
            'linkedin_url',
            esc_url_raw($_POST&#91;'linkedin_url'])
        );
    }

    <em>// Save GitHub URL</em>
    if (isset($_POST&#91;'github_url'])) {
        update_post_meta(
            $post_id,
            'github_url',
            esc_url_raw($_POST&#91;'github_url'])
        );
    }

    <em>// Save expertise areas</em>
    if (isset($_POST&#91;'expertise_areas'])) {
        $expertise = sanitize_text_field($_POST&#91;'expertise_areas']);
        update_post_meta($post_id, 'expertise_areas', $expertise);
    }
}
add_action('save_post_nexus_person', 'save_custom_person_meta');
</code></pre>



<h3 class="wp-block-heading" id="add-to-person-schema">Add to Person Schema</h3>



<p><strong>Extend Schema Output:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Add custom fields to Person schema.
 */</em>
function extend_person_schema($schema, $post_id) {
    <em>// Add LinkedIn to sameAs</em>
    $linkedin = get_post_meta($post_id, 'linkedin_url', true);
    if ($linkedin) {
        if (!isset($schema&#91;'sameAs'])) {
            $schema&#91;'sameAs'] = &#91;];
        }
        $schema&#91;'sameAs']&#91;] = $linkedin;
    }

    <em>// Add GitHub to sameAs</em>
    $github = get_post_meta($post_id, 'github_url', true);
    if ($github) {
        if (!isset($schema&#91;'sameAs'])) {
            $schema&#91;'sameAs'] = &#91;];
        }
        $schema&#91;'sameAs']&#91;] = $github;
    }

    <em>// Add expertise as knowsAbout</em>
    $expertise = get_post_meta($post_id, 'expertise_areas', true);
    if ($expertise) {
        $areas = array_map('trim', explode(',', $expertise));
        $schema&#91;'knowsAbout'] = $areas;
    }

    return $schema;
}
add_filter('nexus_pro_person_schema', 'extend_person_schema', 10, 2);
</code></pre>



<h2 class="wp-block-heading" id="adding-custom-fields-to-product-entity">Adding Custom Fields to Product Entity</h2>



<p>Extend Product template.</p>



<h3 class="wp-block-heading" id="product-meta-fields">Product Meta Fields</h3>



<p><strong>Additional Product Data:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Add custom fields to Product entity.
 */</em>
function add_custom_product_fields($post) {
    $dimensions = get_post_meta($post-&gt;ID, 'product_dimensions', true);
    $weight = get_post_meta($post-&gt;ID, 'product_weight', true);
    $material = get_post_meta($post-&gt;ID, 'product_material', true);
    $warranty = get_post_meta($post-&gt;ID, 'warranty_period', true);
    ?&gt;
    &lt;div class="nexus-pro-product-specs"&gt;
        &lt;h3&gt;Product Specifications&lt;/h3&gt;

        &lt;p&gt;
            &lt;label for="product_dimensions"&gt;Dimensions (L x W x H in cm):&lt;/label&gt;&lt;br&gt;
            &lt;input type="text" id="product_dimensions" name="product_dimensions"
                   value="&lt;?php echo esc_attr($dimensions); ?&gt;"
                   placeholder="30 x 20 x 15"&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for="product_weight"&gt;Weight (kg):&lt;/label&gt;&lt;br&gt;
            &lt;input type="number" id="product_weight" name="product_weight"
                   value="&lt;?php echo esc_attr($weight); ?&gt;"
                   step="0.01" min="0"&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for="product_material"&gt;Material:&lt;/label&gt;&lt;br&gt;
            &lt;input type="text" id="product_material" name="product_material"
                   value="&lt;?php echo esc_attr($material); ?&gt;"
                   placeholder="Stainless Steel"&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for="warranty_period"&gt;Warranty Period (months):&lt;/label&gt;&lt;br&gt;
            &lt;input type="number" id="warranty_period" name="warranty_period"
                   value="&lt;?php echo esc_attr($warranty); ?&gt;"
                   min="0"&gt;
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;?php
}
add_action('nexus_pro_product_meta_fields', 'add_custom_product_fields');
</code></pre>



<h3 class="wp-block-heading" id="save-product-meta">Save Product Meta</h3>



<pre class="wp-block-code"><code><em>/**
 * Save custom Product meta fields.
 */</em>
function save_custom_product_meta($post_id) {
    if (get_post_type($post_id) !== 'nexus_product') {
        return;
    }

    $fields = &#91;
        'product_dimensions' =&gt; 'sanitize_text_field',
        'product_weight' =&gt; 'floatval',
        'product_material' =&gt; 'sanitize_text_field',
        'warranty_period' =&gt; 'absint'
    ];

    foreach ($fields as $field =&gt; $sanitize_callback) {
        if (isset($_POST&#91;$field])) {
            $value = call_user_func($sanitize_callback, $_POST&#91;$field]);
            update_post_meta($post_id, $field, $value);
        }
    }
}
add_action('save_post_nexus_product', 'save_custom_product_meta');
</code></pre>



<h3 class="wp-block-heading" id="extend-product-schema">Extend Product Schema</h3>



<pre class="wp-block-code"><code><em>/**
 * Add specifications to Product schema.
 */</em>
function extend_product_schema($schema, $post_id) {
    <em>// Add dimensions</em>
    $dimensions = get_post_meta($post_id, 'product_dimensions', true);
    if ($dimensions) {
        $schema&#91;'depth'] = &#91;
            '@type' =&gt; 'QuantitativeValue',
            'value' =&gt; $dimensions
        ];
    }

    <em>// Add weight</em>
    $weight = get_post_meta($post_id, 'product_weight', true);
    if ($weight) {
        $schema&#91;'weight'] = &#91;
            '@type' =&gt; 'QuantitativeValue',
            'value' =&gt; $weight,
            'unitCode' =&gt; 'KGM' <em>// Kilograms</em>
        ];
    }

    <em>// Add material</em>
    $material = get_post_meta($post_id, 'product_material', true);
    if ($material) {
        $schema&#91;'material'] = $material;
    }

    <em>// Add warranty</em>
    $warranty = get_post_meta($post_id, 'warranty_period', true);
    if ($warranty) {
        $schema&#91;'warranty'] = &#91;
            '@type' =&gt; 'WarrantyPromise',
            'durationOfWarranty' =&gt; &#91;
                '@type' =&gt; 'QuantitativeValue',
                'value' =&gt; $warranty,
                'unitCode' =&gt; 'MON' <em>// Months</em>
            ]
        ];
    }

    return $schema;
}
add_filter('nexus_pro_product_schema', 'extend_product_schema', 10, 2);
</code></pre>



<h2 class="wp-block-heading" id="adding-custom-fields-to-place-entity">Adding Custom Fields to Place Entity</h2>



<p>Extend LocalBusiness template.</p>



<h3 class="wp-block-heading" id="place-meta-fields">Place Meta Fields</h3>



<p><strong>Business-Specific Data:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Add custom fields to Place entity.
 */</em>
function add_custom_place_fields($post) {
    $parking = get_post_meta($post-&gt;ID, 'parking_available', true);
    $accessibility = get_post_meta($post-&gt;ID, 'wheelchair_accessible', true);
    $payment_methods = get_post_meta($post-&gt;ID, 'payment_methods', true);
    $languages = get_post_meta($post-&gt;ID, 'languages_spoken', true);
    ?&gt;
    &lt;div class="nexus-pro-place-amenities"&gt;
        &lt;h3&gt;Business Amenities&lt;/h3&gt;

        &lt;p&gt;
            &lt;label&gt;
                &lt;input type="checkbox" name="parking_available" value="1"
                       &lt;?php checked($parking, '1'); ?&gt;&gt;
                Parking Available
            &lt;/label&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label&gt;
                &lt;input type="checkbox" name="wheelchair_accessible" value="1"
                       &lt;?php checked($accessibility, '1'); ?&gt;&gt;
                Wheelchair Accessible
            &lt;/label&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label&gt;Payment Methods Accepted:&lt;/label&gt;&lt;br&gt;
            &lt;select name="payment_methods&#91;]" multiple size="5" class="widefat"&gt;
                &lt;?php
                $methods = &#91;'Cash', 'Credit Card', 'Debit Card', 'PayPal', 'Apple Pay', 'Google Pay'];
                $selected = is_array($payment_methods) ? $payment_methods : &#91;];
                foreach ($methods as $method) {
                    $is_selected = in_array($method, $selected) ? 'selected' : '';
                    echo "&lt;option value='" . esc_attr($method) . "' $is_selected&gt;$method&lt;/option&gt;";
                }
                ?&gt;
            &lt;/select&gt;
            &lt;small&gt;Hold Ctrl/Cmd to select multiple&lt;/small&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label&gt;Languages Spoken:&lt;/label&gt;&lt;br&gt;
            &lt;input type="text" name="languages_spoken"
                   value="&lt;?php echo esc_attr($languages); ?&gt;"
                   class="widefat" placeholder="English, Spanish, French"&gt;
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;?php
}
add_action('nexus_pro_place_meta_fields', 'add_custom_place_fields');
</code></pre>



<h3 class="wp-block-heading" id="save-place-meta">Save Place Meta</h3>



<pre class="wp-block-code"><code><em>/**
 * Save custom Place meta fields.
 */</em>
function save_custom_place_meta($post_id) {
    if (get_post_type($post_id) !== 'nexus_place') {
        return;
    }

    <em>// Save checkboxes</em>
    update_post_meta($post_id, 'parking_available',
        isset($_POST&#91;'parking_available']) ? '1' : '0');

    update_post_meta($post_id, 'wheelchair_accessible',
        isset($_POST&#91;'wheelchair_accessible']) ? '1' : '0');

    <em>// Save payment methods array</em>
    if (isset($_POST&#91;'payment_methods'])) {
        $methods = array_map('sanitize_text_field', $_POST&#91;'payment_methods']);
        update_post_meta($post_id, 'payment_methods', $methods);
    } else {
        delete_post_meta($post_id, 'payment_methods');
    }

    <em>// Save languages</em>
    if (isset($_POST&#91;'languages_spoken'])) {
        update_post_meta($post_id, 'languages_spoken',
            sanitize_text_field($_POST&#91;'languages_spoken']));
    }
}
add_action('save_post_nexus_place', 'save_custom_place_meta');
</code></pre>



<h3 class="wp-block-heading" id="extend-localbusiness-schema">Extend LocalBusiness Schema</h3>



<pre class="wp-block-code"><code><em>/**
 * Add amenities to LocalBusiness schema.
 */</em>
function extend_place_schema($schema, $post_id) {
    <em>// Add parking</em>
    $parking = get_post_meta($post_id, 'parking_available', true);
    if ($parking === '1') {
        $schema&#91;'amenityFeature']&#91;] = &#91;
            '@type' =&gt; 'LocationFeatureSpecification',
            'name' =&gt; 'Parking',
            'value' =&gt; true
        ];
    }

    <em>// Add accessibility</em>
    $accessibility = get_post_meta($post_id, 'wheelchair_accessible', true);
    if ($accessibility === '1') {
        $schema&#91;'amenityFeature']&#91;] = &#91;
            '@type' =&gt; 'LocationFeatureSpecification',
            'name' =&gt; 'Wheelchair Accessible',
            'value' =&gt; true
        ];
    }

    <em>// Add payment methods</em>
    $payment_methods = get_post_meta($post_id, 'payment_methods', true);
    if (is_array($payment_methods) &amp;&amp; !empty($payment_methods)) {
        $schema&#91;'paymentAccepted'] = implode(', ', $payment_methods);
    }

    <em>// Add languages</em>
    $languages = get_post_meta($post_id, 'languages_spoken', true);
    if ($languages) {
        $lang_array = array_map('trim', explode(',', $languages));
        $schema&#91;'availableLanguage'] = $lang_array;
    }

    return $schema;
}
add_filter('nexus_pro_place_schema', 'extend_place_schema', 10, 2);
</code></pre>



<h2 class="wp-block-heading" id="creating-custom-meta-boxes">Creating Custom Meta Boxes</h2>



<p>Professional admin interfaces.</p>



<h3 class="wp-block-heading" id="meta-box-with-tabs">Meta Box with Tabs</h3>



<p><strong>Organized Field Groups:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Register tabbed meta box.
 */</em>
function register_tabbed_meta_box() {
    add_meta_box(
        'nexus_pro_extended_meta',
        'Extended Information',
        'render_tabbed_meta_box',
        &#91;'nexus_person', 'nexus_product', 'nexus_place'],
        'normal',
        'high'
    );
}
add_action('add_meta_boxes', 'register_tabbed_meta_box');

<em>/**
 * Render tabbed interface.
 */</em>
function render_tabbed_meta_box($post) {
    wp_nonce_field('save_extended_meta', 'extended_meta_nonce');
    ?&gt;
    &lt;div class="nexus-pro-tabs"&gt;
        &lt;ul class="tab-nav"&gt;
            &lt;li&gt;&lt;a href="#tab-basic" class="active"&gt;Basic Info&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#tab-advanced"&gt;Advanced&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href="#tab-schema"&gt;Schema Data&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;

        &lt;div id="tab-basic" class="tab-content active"&gt;
            &lt;?php render_basic_fields($post); ?&gt;
        &lt;/div&gt;

        &lt;div id="tab-advanced" class="tab-content"&gt;
            &lt;?php render_advanced_fields($post); ?&gt;
        &lt;/div&gt;

        &lt;div id="tab-schema" class="tab-content"&gt;
            &lt;?php render_schema_fields($post); ?&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;style&gt;
        .tab-nav { list-style: none; margin: 0; padding: 0; border-bottom: 1px solid <em>#ccc; }</em>
        .tab-nav li { display: inline-block; margin: 0; }
        .tab-nav a { display: block; padding: 10px 15px; text-decoration: none; border: 1px solid <em>#ccc; border-bottom: none; background: #f1f1f1; }</em>
        .tab-nav a.active { background: <em>#fff; }</em>
        .tab-content { display: none; padding: 20px; border: 1px solid <em>#ccc; border-top: none; }</em>
        .tab-content.active { display: block; }
    &lt;/style&gt;

    &lt;script&gt;
    jQuery(document).ready(function($) {
        $('.tab-nav a').click(function(e) {
            e.preventDefault();
            $('.tab-nav a, .tab-content').removeClass('active');
            $(this).addClass('active');
            $($(this).attr('href')).addClass('active');
        });
    });
    &lt;/script&gt;
    &lt;?php
}
</code></pre>



<h3 class="wp-block-heading" id="repeatable-fields">Repeatable Fields</h3>



<p><strong>Dynamic Field Groups:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * Render repeatable fields (e.g., certifications).
 */</em>
function render_repeatable_certifications($post) {
    $certifications = get_post_meta($post-&gt;ID, 'certifications', true);
    if (!is_array($certifications)) {
        $certifications = &#91;];
    }
    ?&gt;
    &lt;div id="certifications-container"&gt;
        &lt;h4&gt;Certifications&lt;/h4&gt;
        &lt;div class="certifications-list"&gt;
            &lt;?php
            if (empty($certifications)) {
                $certifications = &#91;&#91;'name' =&gt; '', 'issuer' =&gt; '', 'date' =&gt; '']];
            }
            foreach ($certifications as $index =&gt; $cert) {
                ?&gt;
                &lt;div class="certification-item" data-index="&lt;?php echo $index; ?&gt;"&gt;
                    &lt;input type="text" name="certifications&#91;&lt;?php echo $index; ?&gt;]&#91;name]"
                           value="&lt;?php echo esc_attr($cert&#91;'name'] ?? ''); ?&gt;"
                           placeholder="Certification Name"&gt;
                    &lt;input type="text" name="certifications&#91;&lt;?php echo $index; ?&gt;]&#91;issuer]"
                           value="&lt;?php echo esc_attr($cert&#91;'issuer'] ?? ''); ?&gt;"
                           placeholder="Issuing Organization"&gt;
                    &lt;input type="date" name="certifications&#91;&lt;?php echo $index; ?&gt;]&#91;date]"
                           value="&lt;?php echo esc_attr($cert&#91;'date'] ?? ''); ?&gt;"&gt;
                    &lt;button type="button" class="remove-certification"&gt;Remove&lt;/button&gt;
                &lt;/div&gt;
                &lt;?php
            }
            ?&gt;
        &lt;/div&gt;
        &lt;button type="button" id="add-certification"&gt;Add Certification&lt;/button&gt;
    &lt;/div&gt;

    &lt;script&gt;
    jQuery(document).ready(function($) {
        var certIndex = &lt;?php echo count($certifications); ?&gt;;

        $('#add-certification').click(function() {
            var html = '&lt;div class="certification-item" data-index="' + certIndex + '"&gt;' +
                '&lt;input type="text" name="certifications&#91;' + certIndex + ']&#91;name]" placeholder="Certification Name"&gt;' +
                '&lt;input type="text" name="certifications&#91;' + certIndex + ']&#91;issuer]" placeholder="Issuing Organization"&gt;' +
                '&lt;input type="date" name="certifications&#91;' + certIndex + ']&#91;date]"&gt;' +
                '&lt;button type="button" class="remove-certification"&gt;Remove&lt;/button&gt;' +
                '&lt;/div&gt;';
            $('.certifications-list').append(html);
            certIndex++;
        });

        $(document).on('click', '.remove-certification', function() {
            $(this).closest('.certification-item').remove();
        });
    });
    &lt;/script&gt;
    &lt;?php
}
</code></pre>



<h2 class="wp-block-heading" id="best-practices">Best Practices</h2>



<p>Professional extension guidelines.</p>



<h3 class="wp-block-heading" id="use-proper-hook-priorities">Use Proper Hook Priorities</h3>



<pre class="wp-block-code"><code><em>// Default priority (10)</em>
add_filter('nexus_pro_person_schema', 'extend_person_schema', 10, 2);

<em>// Run late to ensure all other modifications are done</em>
add_filter('nexus_pro_person_schema', 'final_person_adjustments', 999, 2);
</code></pre>



<h3 class="wp-block-heading" id="validate-and-sanitize">Validate and Sanitize</h3>



<pre class="wp-block-code"><code><em>// Always validate and sanitize user input</em>
function save_custom_meta($post_id) {
    <em>// URL validation</em>
    if (isset($_POST&#91;'website'])) {
        $url = esc_url_raw($_POST&#91;'website']);
        if (filter_var($url, FILTER_VALIDATE_URL)) {
            update_post_meta($post_id, 'website', $url);
        }
    }

    <em>// Email validation</em>
    if (isset($_POST&#91;'email'])) {
        $email = sanitize_email($_POST&#91;'email']);
        if (is_email($email)) {
            update_post_meta($post_id, 'email', $email);
        }
    }

    <em>// Number validation</em>
    if (isset($_POST&#91;'price'])) {
        $price = floatval($_POST&#91;'price']);
        if ($price &gt;= 0) {
            update_post_meta($post_id, 'price', $price);
        }
    }
}
</code></pre>



<h3 class="wp-block-heading" id="check-for-empty-values">Check for Empty Values</h3>



<pre class="wp-block-code"><code><em>// Don't add empty fields to schema</em>
function extend_schema_safely($schema, $post_id) {
    $custom_field = get_post_meta($post_id, 'custom_field', true);

    if (!empty($custom_field)) {
        $schema&#91;'customProperty'] = $custom_field;
    }

    return $schema;
}
</code></pre>



<h3 class="wp-block-heading" id="use-nonces-for-security">Use Nonces for Security</h3>



<pre class="wp-block-code"><code><em>// Add nonce to form</em>
wp_nonce_field('save_custom_meta', 'custom_meta_nonce');

<em>// Verify nonce when saving</em>
function save_custom_meta($post_id) {
    if (!isset($_POST&#91;'custom_meta_nonce']) ||
        !wp_verify_nonce($_POST&#91;'custom_meta_nonce'], 'save_custom_meta')) {
        return;
    }

    <em>// Proceed with saving</em>
}
</code></pre>



<h3 class="wp-block-heading" id="document-your-extensions">Document Your Extensions</h3>



<pre class="wp-block-code"><code><em>/**
 * Extend Nexus Pro Person entity with professional certifications.
 *
 * Adds repeatable certification fields to Person entity admin interface
 * and includes them in Person schema output as credentials.
 *
 * @since 1.0.0
 * @param WP_Post $post The post object.
 */</em>
function add_certification_fields($post) {
    <em>// Implementation</em>
}
</code></pre>



<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>



<p>Extending Nexus Pro through hooks and filters allows adding custom fields to entity templates while maintaining plugin compatibility. By understanding the hook system, implementing proper validation, and following WordPress development best practices, you can customize Nexus Pro for any project requirements.</p>



<p><strong>Extension Checklist:</strong></p>



<ol class="wp-block-list">
<li>✓ Use Nexus Pro hooks (not core files)</li>



<li>✓ Add meta fields with action hooks</li>



<li>✓ Save data securely with nonces</li>



<li>✓ Validate and sanitize all input</li>



<li>✓ Extend schema with filter hooks</li>



<li>✓ Check for empty values</li>



<li>✓ Test schema with validators</li>



<li>✓ Document custom code</li>



<li>✓ Prefix function names</li>



<li>✓ Test with plugin updates</li>
</ol>



<p><strong>Available Hooks:</strong></p>



<ul class="wp-block-list">
<li><code>nexus_pro_{entity}_meta_fields</code> &#8211; Add fields to admin</li>



<li><code>nexus_pro_{entity}_schema</code> &#8211; Filter schema output</li>



<li><code>save_post_nexus_{entity}</code> &#8211; Save custom meta</li>



<li><code>nexus_pro_{entity}_query</code> &#8211; Modify entity queries</li>
</ul>



<p>Start with simple single-field additions to understand the hook system, then progress to complex meta boxes, repeatable fields, and advanced schema integrations. Always test extensions after Nexus Pro updates to ensure compatibility.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Related Articles:</strong></p>



<ul class="wp-block-list">
<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-03-extending-nexus-pro-custom-fields.md#">WordPress Hooks and Filters Guide</a></li>



<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-03-extending-nexus-pro-custom-fields.md#">Custom Schema Types Tutorial</a></li>



<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-03-extending-nexus-pro-custom-fields.md#">Schema Markup: 7 Essential Types</a></li>



<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-03-extending-nexus-pro-custom-fields.md#">WordPress Plugin Development Best Practices</a></li>
</ul>
<p>The post <a href="https://developrythemes.com/extending-nexus-pro-add-custom-fields-to-entity-templates/">Extending Nexus Pro: Add Custom Fields to Entity Templates</a> appeared first on <a href="https://developrythemes.com">Developry Themes</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://developrythemes.com/extending-nexus-pro-add-custom-fields-to-entity-templates/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Create Custom Schema Types in WordPress (Advanced Tutorial)</title>
		<link>https://developrythemes.com/how-to-create-custom-schema-types-in-wordpress-advanced-tutorial/</link>
					<comments>https://developrythemes.com/how-to-create-custom-schema-types-in-wordpress-advanced-tutorial/#respond</comments>
		
		<dc:creator><![CDATA[Krasen Slavov]]></dc:creator>
		<pubDate>Fri, 30 Jan 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Developer Guides]]></category>
		<category><![CDATA[custom schema]]></category>
		<category><![CDATA[json-ld]]></category>
		<category><![CDATA[schema development]]></category>
		<category><![CDATA[structured data]]></category>
		<category><![CDATA[wordpress development]]></category>
		<guid isPermaLink="false">https://developrythemes.com/?p=517</guid>

					<description><![CDATA[<p>While Nexus Pro provides seven essential schema types out of the box, some projects require custom schema implementations—industry-specific types, additional properties, or nested schema structures.</p>
<p>The post <a href="https://developrythemes.com/how-to-create-custom-schema-types-in-wordpress-advanced-tutorial/">How to Create Custom Schema Types in WordPress (Advanced Tutorial)</a> appeared first on <a href="https://developrythemes.com">Developry Themes</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>While Nexus Pro provides seven essential schema types out of the box, some projects require custom schema implementations—industry-specific types, additional properties, or nested schema structures. Creating custom schema types in WordPress requires understanding Schema.org vocabulary, JSON-LD format, and WordPress hooks for proper implementation.</p>



<p>This advanced guide shows you how to create custom schema types, extend existing schemas, implement complex nested structures, and validate your structured data for Google compatibility.</p>



<h2 class="wp-block-heading" id="understanding-schemaorg-structure">Understanding Schema.org Structure</h2>



<p>Foundation knowledge for custom implementations.</p>



<h3 class="wp-block-heading" id="schemaorg-hierarchy">Schema.org Hierarchy</h3>



<p><strong>Core Concept:</strong>&nbsp;Schema.org uses hierarchical types where specific types inherit properties from parent types.</p>



<p><strong>Example Hierarchy:</strong></p>



<pre class="wp-block-code"><code>Thing
└── CreativeWork
    └── Article
        └── NewsArticle
        └── BlogPosting
        └── TechArticle
</code></pre>



<p><strong>Inheritance:</strong>&nbsp;NewsArticle inherits all properties from Article, CreativeWork, and Thing.</p>



<h3 class="wp-block-heading" id="json-ld-format">JSON-LD Format</h3>



<p><strong>Structure:</strong></p>



<pre class="wp-block-code"><code>{
  "@context": "https://schema.org",
  "@type": "TypeName",
  "property1": "value1",
  "property2": "value2",
  "nestedObject": {
    "@type": "NestedType",
    "nestedProperty": "value"
  }
}
</code></pre>



<p><strong>Key Elements:</strong></p>



<ul class="wp-block-list">
<li><code>@context</code>: Schema.org vocabulary</li>



<li><code>@type</code>: Schema type</li>



<li>Properties: Type-specific attributes</li>



<li>Values: Strings, numbers, objects, arrays</li>
</ul>



<h3 class="wp-block-heading" id="common-schema-types">Common Schema Types</h3>



<p><strong>Available on Schema.org:</strong></p>



<p><strong>Organizations:</strong></p>



<ul class="wp-block-list">
<li>Organization</li>



<li>LocalBusiness</li>



<li>Corporation</li>



<li>EducationalOrganization</li>
</ul>



<p><strong>Creative Works:</strong></p>



<ul class="wp-block-list">
<li>Article</li>



<li>BlogPosting</li>



<li>Book</li>



<li>Movie</li>



<li>MusicAlbum</li>
</ul>



<p><strong>Events:</strong></p>



<ul class="wp-block-list">
<li>Event</li>



<li>BusinessEvent</li>



<li>SocialEvent</li>
</ul>



<p><strong>Products:</strong></p>



<ul class="wp-block-list">
<li>Product</li>



<li>SoftwareApplication</li>



<li>Vehicle</li>
</ul>



<p><strong>People:</strong></p>



<ul class="wp-block-list">
<li>Person</li>
</ul>



<p><strong>200+ types available:</strong>&nbsp;Check Schema.org for complete list.</p>



<h2 class="wp-block-heading" id="creating-basic-custom-schema">Creating Basic Custom Schema</h2>



<p>Implement custom schema from scratch.</p>



<h3 class="wp-block-heading" id="step-1-choose-schema-type">Step 1: Choose Schema Type</h3>



<p><strong>Determine Type:</strong>&nbsp;Browse Schema.org to find appropriate type for your content.</p>



<p><strong>Example:</strong>&nbsp;Creating SoftwareApplication schema for plugin documentation.</p>



<h3 class="wp-block-heading" id="step-2-define-schema-structure">Step 2: Define Schema Structure</h3>



<p><strong>Plan Properties:</strong></p>



<pre class="wp-block-code"><code><em>/**
 * SoftwareApplication schema properties:
 * - name: Application name
 * - applicationCategory: Category (e.g., "DeveloperApplication")
 * - operatingSystem: "WordPress"
 * - offers: Price/availability
 * - aggregateRating: User ratings
 */</em>
</code></pre>



<h3 class="wp-block-heading" id="step-3-create-schema-function">Step 3: Create Schema Function</h3>



<p><strong>Implementation:</strong></p>



<pre class="wp-block-code"><code>function custom_software_schema($post_id) {
    <em>// Get post data</em>
    $post = get_post($post_id);

    <em>// Build schema array</em>
    $schema = &#91;
        '@context' =&gt; 'https://schema.org',
        '@type' =&gt; 'SoftwareApplication',
        'name' =&gt; get_the_title($post_id),
        'description' =&gt; get_the_excerpt($post_id),
        'applicationCategory' =&gt; 'DeveloperApplication',
        'operatingSystem' =&gt; 'WordPress',
        'offers' =&gt; &#91;
            '@type' =&gt; 'Offer',
            'price' =&gt; get_post_meta($post_id, 'price', true),
            'priceCurrency' =&gt; 'USD',
            'availability' =&gt; 'https://schema.org/InStock'
        ],
        'aggregateRating' =&gt; &#91;
            '@type' =&gt; 'AggregateRating',
            'ratingValue' =&gt; get_post_meta($post_id, 'rating', true),
            'reviewCount' =&gt; get_post_meta($post_id, 'review_count', true)
        ]
    ];

    return $schema;
}
</code></pre>



<h3 class="wp-block-heading" id="step-4-output-schema">Step 4: Output Schema</h3>



<p><strong>Add to WordPress:</strong></p>



<pre class="wp-block-code"><code>function output_software_schema() {
    if (is_singular('plugin')) {
        $schema = custom_software_schema(get_the_ID());
        echo '&lt;script type="application/ld+json"&gt;' .
             wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) .
             '&lt;/script&gt;';
    }
}
add_action('wp_head', 'output_software_schema');
</code></pre>



<p><strong>Output:</strong></p>



<pre class="wp-block-code"><code>&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "Nexus Pro",
  ...
}
&lt;/script&gt;
</code></pre>



<h2 class="wp-block-heading" id="extending-existing-schema">Extending Existing Schema</h2>



<p>Add properties to Nexus Pro schemas.</p>



<h3 class="wp-block-heading" id="filter-nexus-pro-schema">Filter Nexus Pro Schema</h3>



<p><strong>Hook Into Schema Output:</strong></p>



<pre class="wp-block-code"><code><em>// Add custom properties to Article schema</em>
add_filter('nexus_pro_article_schema', 'extend_article_schema', 10, 2);

function extend_article_schema($schema, $post_id) {
    <em>// Add wordCount property</em>
    $content = get_post_field('post_content', $post_id);
    $word_count = str_word_count(strip_tags($content));
    $schema&#91;'wordCount'] = $word_count;

    <em>// Add timeRequired for reading</em>
    $minutes = ceil($word_count / 200); <em>// 200 words per minute</em>
    $schema&#91;'timeRequired'] = 'PT' . $minutes . 'M'; <em>// ISO 8601 duration</em>

    <em>// Add inLanguage</em>
    $schema&#91;'inLanguage'] = get_locale();

    <em>// Add audience</em>
    $difficulty = get_post_meta($post_id, 'difficulty_level', true);
    if ($difficulty) {
        $schema&#91;'audience'] = &#91;
            '@type' =&gt; 'EducationalAudience',
            'educationalRole' =&gt; $difficulty <em>// Beginner, Intermediate, Advanced</em>
        ];
    }

    return $schema;
}
</code></pre>



<h3 class="wp-block-heading" id="add-nested-schemas">Add Nested Schemas</h3>



<p><strong>Complex Structures:</strong></p>



<pre class="wp-block-code"><code>add_filter('nexus_pro_article_schema', 'add_citation_schema', 10, 2);

function add_citation_schema($schema, $post_id) {
    <em>// Get cited sources from custom field</em>
    $citations = get_post_meta($post_id, 'citations', true);

    if (!empty($citations)) {
        $schema&#91;'citation'] = &#91;];

        foreach ($citations as $citation) {
            $schema&#91;'citation']&#91;] = &#91;
                '@type' =&gt; 'CreativeWork',
                'name' =&gt; $citation&#91;'title'],
                'url' =&gt; $citation&#91;'url'],
                'author' =&gt; &#91;
                    '@type' =&gt; 'Person',
                    'name' =&gt; $citation&#91;'author']
                ]
            ];
        }
    }

    return $schema;
}
</code></pre>



<h2 class="wp-block-heading" id="advanced-schema-patterns">Advanced Schema Patterns</h2>



<p>Complex implementations.</p>



<h3 class="wp-block-heading" id="breadcrumb-schema">Breadcrumb Schema</h3>



<p><strong>Navigation Structure:</strong></p>



<pre class="wp-block-code"><code>function generate_breadcrumb_schema() {
    if (!is_singular()) {
        return;
    }

    $breadcrumbs = &#91;];
    $position = 1;

    <em>// Home</em>
    $breadcrumbs&#91;] = &#91;
        '@type' =&gt; 'ListItem',
        'position' =&gt; $position++,
        'name' =&gt; 'Home',
        'item' =&gt; home_url('/')
    ];

    <em>// Categories</em>
    $categories = get_the_category();
    if ($categories) {
        $category = $categories&#91;0];
        $breadcrumbs&#91;] = &#91;
            '@type' =&gt; 'ListItem',
            'position' =&gt; $position++,
            'name' =&gt; $category-&gt;name,
            'item' =&gt; get_category_link($category-&gt;term_id)
        ];
    }

    <em>// Current post</em>
    $breadcrumbs&#91;] = &#91;
        '@type' =&gt; 'ListItem',
        'position' =&gt; $position,
        'name' =&gt; get_the_title(),
        'item' =&gt; get_permalink()
    ];

    $schema = &#91;
        '@context' =&gt; 'https://schema.org',
        '@type' =&gt; 'BreadcrumbList',
        'itemListElement' =&gt; $breadcrumbs
    ];

    return $schema;
}
</code></pre>



<h3 class="wp-block-heading" id="recipe-schema">Recipe Schema</h3>



<p><strong>Detailed Cooking Instructions:</strong></p>



<pre class="wp-block-code"><code>function create_recipe_schema($post_id) {
    $schema = &#91;
        '@context' =&gt; 'https://schema.org',
        '@type' =&gt; 'Recipe',
        'name' =&gt; get_the_title($post_id),
        'image' =&gt; get_the_post_thumbnail_url($post_id, 'large'),
        'author' =&gt; &#91;
            '@type' =&gt; 'Person',
            'name' =&gt; get_the_author_meta('display_name')
        ],
        'datePublished' =&gt; get_the_date('c', $post_id),
        'description' =&gt; get_the_excerpt($post_id),
        'prepTime' =&gt; 'PT' . get_post_meta($post_id, 'prep_time', true) . 'M',
        'cookTime' =&gt; 'PT' . get_post_meta($post_id, 'cook_time', true) . 'M',
        'totalTime' =&gt; 'PT' . get_post_meta($post_id, 'total_time', true) . 'M',
        'recipeYield' =&gt; get_post_meta($post_id, 'servings', true),
        'recipeCategory' =&gt; get_post_meta($post_id, 'category', true),
        'recipeCuisine' =&gt; get_post_meta($post_id, 'cuisine', true),
        'nutrition' =&gt; &#91;
            '@type' =&gt; 'NutritionInformation',
            'calories' =&gt; get_post_meta($post_id, 'calories', true) . ' calories'
        ],
        'recipeIngredient' =&gt; get_post_meta($post_id, 'ingredients', true), <em>// Array</em>
        'recipeInstructions' =&gt; &#91;]
    ];

    <em>// Build instructions</em>
    $steps = get_post_meta($post_id, 'instructions', true);
    foreach ($steps as $index =&gt; $step) {
        $schema&#91;'recipeInstructions']&#91;] = &#91;
            '@type' =&gt; 'HowToStep',
            'name' =&gt; 'Step ' . ($index + 1),
            'text' =&gt; $step,
            'url' =&gt; get_permalink($post_id) . '#step-' . ($index + 1)
        ];
    }

    <em>// Aggregate rating</em>
    $rating = get_post_meta($post_id, 'rating', true);
    if ($rating) {
        $schema&#91;'aggregateRating'] = &#91;
            '@type' =&gt; 'AggregateRating',
            'ratingValue' =&gt; $rating,
            'reviewCount' =&gt; get_post_meta($post_id, 'review_count', true)
        ];
    }

    return $schema;
}
</code></pre>



<h3 class="wp-block-heading" id="video-object-schema">Video Object Schema</h3>



<p><strong>YouTube/Vimeo Integration:</strong></p>



<pre class="wp-block-code"><code>function create_video_schema($post_id) {
    $video_url = get_post_meta($post_id, 'video_url', true);

    if (empty($video_url)) {
        return null;
    }

    $schema = &#91;
        '@context' =&gt; 'https://schema.org',
        '@type' =&gt; 'VideoObject',
        'name' =&gt; get_the_title($post_id),
        'description' =&gt; get_the_excerpt($post_id),
        'thumbnailUrl' =&gt; get_the_post_thumbnail_url($post_id, 'large'),
        'uploadDate' =&gt; get_the_date('c', $post_id),
        'duration' =&gt; 'PT' . get_post_meta($post_id, 'duration', true) . 'S', <em>// seconds</em>
        'contentUrl' =&gt; $video_url,
        'embedUrl' =&gt; $video_url,
        'publisher' =&gt; &#91;
            '@type' =&gt; 'Organization',
            'name' =&gt; get_bloginfo('name'),
            'logo' =&gt; &#91;
                '@type' =&gt; 'ImageObject',
                'url' =&gt; get_site_icon_url()
            ]
        ]
    ];

    return $schema;
}
</code></pre>



<h2 class="wp-block-heading" id="multiple-schemas-per-page">Multiple Schemas Per Page</h2>



<p>Implement graph structure.</p>



<h3 class="wp-block-heading" id="schema-graph">Schema Graph</h3>



<p><strong>Multiple Related Schemas:</strong></p>



<pre class="wp-block-code"><code>function output_schema_graph() {
    $graph = &#91;
        '@context' =&gt; 'https://schema.org',
        '@graph' =&gt; &#91;]
    ];

    <em>// Add Organization schema</em>
    $graph&#91;'@graph']&#91;] = &#91;
        '@type' =&gt; 'Organization',
        '@id' =&gt; home_url('/#organization'),
        'name' =&gt; get_bloginfo('name'),
        'url' =&gt; home_url('/'),
        'logo' =&gt; get_site_icon_url()
    ];

    <em>// Add WebSite schema</em>
    $graph&#91;'@graph']&#91;] = &#91;
        '@type' =&gt; 'WebSite',
        '@id' =&gt; home_url('/#website'),
        'url' =&gt; home_url('/'),
        'name' =&gt; get_bloginfo('name'),
        'publisher' =&gt; &#91;
            '@id' =&gt; home_url('/#organization')
        ],
        'potentialAction' =&gt; &#91;
            '@type' =&gt; 'SearchAction',
            'target' =&gt; home_url('/?s={search_term_string}'),
            'query-input' =&gt; 'required name=search_term_string'
        ]
    ];

    <em>// Add Article schema (if single post)</em>
    if (is_singular('post')) {
        $graph&#91;'@graph']&#91;] = create_article_schema(get_the_ID());
    }

    <em>// Add Breadcrumb schema</em>
    $graph&#91;'@graph']&#91;] = generate_breadcrumb_schema();

    <em>// Output</em>
    echo '&lt;script type="application/ld+json"&gt;' .
         wp_json_encode($graph, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) .
         '&lt;/script&gt;';
}
add_action('wp_head', 'output_schema_graph');
</code></pre>



<p><strong>Benefits:</strong></p>



<ul class="wp-block-list">
<li>All schemas in one script tag</li>



<li>Clear entity relationships</li>



<li>Efficient for Google parsing</li>
</ul>



<h2 class="wp-block-heading" id="custom-meta-boxes-for-schema">Custom Meta Boxes for Schema</h2>



<p>Admin interface for schema data.</p>



<h3 class="wp-block-heading" id="register-meta-box">Register Meta Box</h3>



<pre class="wp-block-code"><code>function register_schema_meta_box() {
    add_meta_box(
        'custom_schema_meta',
        'Schema Markup Data',
        'render_schema_meta_box',
        'post',
        'side',
        'default'
    );
}
add_action('add_meta_boxes', 'register_schema_meta_box');
</code></pre>



<h3 class="wp-block-heading" id="render-fields">Render Fields</h3>



<pre class="wp-block-code"><code>function render_schema_meta_box($post) {
    wp_nonce_field('save_schema_meta', 'schema_meta_nonce');

    $rating = get_post_meta($post-&gt;ID, 'rating', true);
    $review_count = get_post_meta($post-&gt;ID, 'review_count', true);
    $price = get_post_meta($post-&gt;ID, 'price', true);
    ?&gt;
    &lt;p&gt;
        &lt;label&gt;Rating (1-5):&lt;/label&gt;&lt;br&gt;
        &lt;input type="number" name="rating" value="&lt;?php echo esc_attr($rating); ?&gt;"
               min="1" max="5" step="0.1"&gt;
    &lt;/p&gt;
    &lt;p&gt;
        &lt;label&gt;Review Count:&lt;/label&gt;&lt;br&gt;
        &lt;input type="number" name="review_count" value="&lt;?php echo esc_attr($review_count); ?&gt;"&gt;
    &lt;/p&gt;
    &lt;p&gt;
        &lt;label&gt;Price ($):&lt;/label&gt;&lt;br&gt;
        &lt;input type="number" name="price" value="&lt;?php echo esc_attr($price); ?&gt;"
               min="0" step="0.01"&gt;
    &lt;/p&gt;
    &lt;?php
}
</code></pre>



<h3 class="wp-block-heading" id="save-meta-data">Save Meta Data</h3>



<pre class="wp-block-code"><code>function save_schema_meta($post_id) {
    <em>// Security checks</em>
    if (!isset($_POST&#91;'schema_meta_nonce']) ||
        !wp_verify_nonce($_POST&#91;'schema_meta_nonce'], 'save_schema_meta')) {
        return;
    }

    if (defined('DOING_AUTOSAVE') &amp;&amp; DOING_AUTOSAVE) {
        return;
    }

    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    <em>// Save fields</em>
    if (isset($_POST&#91;'rating'])) {
        update_post_meta($post_id, 'rating', sanitize_text_field($_POST&#91;'rating']));
    }

    if (isset($_POST&#91;'review_count'])) {
        update_post_meta($post_id, 'review_count', absint($_POST&#91;'review_count']));
    }

    if (isset($_POST&#91;'price'])) {
        update_post_meta($post_id, 'price', sanitize_text_field($_POST&#91;'price']));
    }
}
add_action('save_post', 'save_schema_meta');
</code></pre>



<h2 class="wp-block-heading" id="validation-and-testing">Validation and Testing</h2>



<p>Ensure schema correctness.</p>



<h3 class="wp-block-heading" id="google-rich-results-test">Google Rich Results Test</h3>



<p><strong>Test URL:</strong>&nbsp;<a href="https://search.google.com/test/rich-results">https://search.google.com/test/rich-results</a></p>



<p><strong>Process:</strong></p>



<ol class="wp-block-list">
<li>Enter your URL or paste schema code</li>



<li>Click &#8220;Test URL&#8221; or &#8220;Test Code&#8221;</li>



<li>Review validation results</li>



<li>Fix any errors or warnings</li>
</ol>



<h3 class="wp-block-heading" id="schema-markup-validator">Schema Markup Validator</h3>



<p><strong>Official Tool:</strong>&nbsp;<a href="https://validator.schema.org/">https://validator.schema.org/</a></p>



<p><strong>Features:</strong></p>



<ul class="wp-block-list">
<li>Validates JSON-LD syntax</li>



<li>Checks property compatibility</li>



<li>Identifies schema errors</li>



<li>Suggests improvements</li>
</ul>



<h3 class="wp-block-heading" id="common-validation-errors">Common Validation Errors</h3>



<p><strong>Missing Required Properties:</strong></p>



<pre class="wp-block-code"><code><em>// ERROR - missing required 'name'</em>
$schema = &#91;
    '@type' =&gt; 'Person'
    <em>// Missing 'name' property</em>
];

<em>// CORRECT</em>
$schema = &#91;
    '@type' =&gt; 'Person',
    'name' =&gt; 'John Doe' <em>// Required</em>
];
</code></pre>



<p><strong>Incorrect Data Types:</strong></p>



<pre class="wp-block-code"><code><em>// ERROR - price should be number</em>
'price' =&gt; '$99'

<em>// CORRECT</em>
'price' =&gt; '99.00',
'priceCurrency' =&gt; 'USD'
</code></pre>



<p><strong>Invalid URLs:</strong></p>



<pre class="wp-block-code"><code><em>// ERROR - not a valid URL</em>
'url' =&gt; 'example.com'

<em>// CORRECT</em>
'url' =&gt; 'https://example.com'
</code></pre>



<h2 class="wp-block-heading" id="best-practices">Best Practices</h2>



<p>Professional schema implementation.</p>



<h3 class="wp-block-heading" id="use-constants-for-context">Use Constants for @context</h3>



<pre class="wp-block-code"><code>const SCHEMA_CONTEXT = 'https://schema.org';

$schema = &#91;
    '@context' =&gt; SCHEMA_CONTEXT,
    '@type' =&gt; 'Article'
];
</code></pre>



<h3 class="wp-block-heading" id="sanitize-all-data">Sanitize All Data</h3>



<pre class="wp-block-code"><code>$schema = &#91;
    '@type' =&gt; 'Article',
    'headline' =&gt; esc_html(get_the_title()),
    'description' =&gt; esc_html(get_the_excerpt()),
    'url' =&gt; esc_url(get_permalink())
];
</code></pre>



<h3 class="wp-block-heading" id="check-for-empty-values">Check for Empty Values</h3>



<pre class="wp-block-code"><code>$rating = get_post_meta($post_id, 'rating', true);

if (!empty($rating)) {
    $schema&#91;'aggregateRating'] = &#91;
        '@type' =&gt; 'AggregateRating',
        'ratingValue' =&gt; $rating
    ];
}
</code></pre>



<h3 class="wp-block-heading" id="use-iso-8601-for-dates">Use ISO 8601 for Dates</h3>



<pre class="wp-block-code"><code><em>// Correct format</em>
'datePublished' =&gt; get_the_date('c', $post_id), <em>// 2025-01-15T10:30:00+00:00</em>

<em>// Wrong</em>
'datePublished' =&gt; get_the_date('F j, Y') <em>// January 15, 2025</em>
</code></pre>



<h3 class="wp-block-heading" id="document-custom-schemas">Document Custom Schemas</h3>



<pre class="wp-block-code"><code><em>/**
 * Generate SoftwareApplication schema for plugin posts.
 *
 * @param int $post_id Post ID.
 * @return array Schema markup array.
 */</em>
function custom_software_schema($post_id) {
    <em>// Implementation</em>
}
</code></pre>



<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>



<p>Creating custom schema types in WordPress extends structured data beyond standard implementations. By understanding Schema.org vocabulary, JSON-LD format, and WordPress development practices, you can implement any schema type for your specific needs.</p>



<p><strong>Key Implementation Steps:</strong></p>



<ol class="wp-block-list">
<li>Choose appropriate Schema.org type</li>



<li>Define required and recommended properties</li>



<li>Create PHP function to build schema array</li>



<li>Output JSON-LD in wp_head</li>



<li>Create admin interface for data input</li>



<li>Validate with Google Rich Results Test</li>



<li>Test with Schema.org validator</li>



<li>Monitor Search Console for enhancements</li>
</ol>



<p><strong>Development Checklist:</strong></p>



<ul class="wp-block-list">
<li>✓ Use proper @context and @type</li>



<li>✓ Include all required properties</li>



<li>✓ Sanitize and escape data</li>



<li>✓ Use correct data types</li>



<li>✓ Validate before deployment</li>



<li>✓ Check for empty values</li>



<li>✓ Use ISO 8601 for dates</li>



<li>✓ Test in multiple validators</li>
</ul>



<p>Start by extending Nexus Pro&#8217;s existing schemas with custom properties, then progress to creating completely custom schema types for specialized content. Always validate implementations before deployment to ensure Google compatibility.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Related Articles:</strong></p>



<ul class="wp-block-list">
<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-02-custom-schema-types-tutorial.md#">WordPress Hooks and Filters Guide</a></li>



<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-02-custom-schema-types-tutorial.md#">Extending Nexus Pro: Custom Fields</a></li>



<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-02-custom-schema-types-tutorial.md#">Schema Markup: 7 Essential Types</a></li>



<li><a href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/krasenslavov/Desktop/DESKTOP%20-%20EXTENDED/DEVELOPRY%20NEXUS/CONTENT/BLOG/blog-posts/blog-developer-02-custom-schema-types-tutorial.md#">FAQ Schema Guide for Rich Results</a></li>
</ul>
<p>The post <a href="https://developrythemes.com/how-to-create-custom-schema-types-in-wordpress-advanced-tutorial/">How to Create Custom Schema Types in WordPress (Advanced Tutorial)</a> appeared first on <a href="https://developrythemes.com">Developry Themes</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://developrythemes.com/how-to-create-custom-schema-types-in-wordpress-advanced-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPress Hooks and Filters: Complete Developer Reference Guide</title>
		<link>https://developrythemes.com/wordpress-hooks-and-filters-complete-developer-reference-guide/</link>
					<comments>https://developrythemes.com/wordpress-hooks-and-filters-complete-developer-reference-guide/#respond</comments>
		
		<dc:creator><![CDATA[Krasen Slavov]]></dc:creator>
		<pubDate>Mon, 20 Oct 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[Developer Guides]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin development]]></category>
		<category><![CDATA[wordpress development]]></category>
		<category><![CDATA[wordpress filters]]></category>
		<category><![CDATA[wordpress hooks]]></category>
		<guid isPermaLink="false">https://developrythemes.com/?p=515</guid>

					<description><![CDATA[<p>The post <a href="https://developrythemes.com/wordpress-hooks-and-filters-complete-developer-reference-guide/">WordPress Hooks and Filters: Complete Developer Reference Guide</a> appeared first on <a href="https://developrythemes.com">Developry Themes</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The post <a href="https://developrythemes.com/wordpress-hooks-and-filters-complete-developer-reference-guide/">WordPress Hooks and Filters: Complete Developer Reference Guide</a> appeared first on <a href="https://developrythemes.com">Developry Themes</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://developrythemes.com/wordpress-hooks-and-filters-complete-developer-reference-guide/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
