AUTO WP CATEGORIZATION

Hierarchical Taxonomy Creation with URL Structures

Process Overview

The auto categorization system creates hierarchical WordPress taxonomy structures for properties based on RETS data. It generates area/subarea categories, property type categories, and SEO-friendly URL slug structures for organized property browsing.

Taxonomy Registration

// Property Category Taxonomy (hierarchical)
register_taxonomy('property_category', 'property', [
    'hierarchical' => true,
    'labels' => [
        'name' => __('Category', 'es-plugin'),
        'singular_name' => __('Category', 'es-plugin'),
    ],
    'public' => true,
    'show_ui' => true,
    'show_in_rest' => true,
    'rewrite' => [
        'slug' => 'mls',
        'with_front' => false,
    ],
]);

// Property Tag Taxonomy (non-hierarchical)
register_taxonomy('property_tag', 'property', [
    'hierarchical' => false,
    'label' => __('Tags', 'esh'),
    'rewrite' => [
        'slug' => 'mls/tag',
        'with_front' => false,
    ],
]);

URL Structure Examples

Category URLs

/mls/toronto/
/mls/toronto-condos/
/mls/toronto-downtown-condos/

Tag URLs

/mls/tag/3-bedrooms/
/mls/tag/2-baths/
/mls/tag/in-suite-laundry/

Category Hierarchy Creation

Property Type Logic

// Bridge API property class mapping
if ($property_type == 'Residential' && 
    strpos($structure_type, 'Residential Detached') !== false) {
    $property_class = 'RD_1';
} elseif ($property_type == 'Residential' && 
          strpos($structure_type, 'Residential Attached') !== false) {
    $property_class = 'RA_2';
} elseif ($property_type == 'Residential Income') {
    $property_class = 'MF_3';
} elseif ($property_type == 'Land') {
    $property_class = 'LD_4';
}

// Type determination based on dwelling
if (($property_class == 'RD_1' || $property_class == 'RA_2')) {
    if ($type_of_dwelling == 'Townhouse') {
        $type = 'Townhouses';
    } elseif ($type_of_dwelling == 'Apartment/Condo') {
        $type = 'Condos';
    } else {
        $type = 'House';
    }
}

Hierarchy Example

Toronto (area)
├── Toronto Condos (area+type)
│ └── Toronto Downtown Condos (subarea+type)
├── Toronto Houses (area+type)
│ └── Toronto North Houses (subarea+type)
└── Toronto Townhouses (area+type)
└── Toronto East Townhouses (subarea+type)

Area-Based Category Creation

// Create area categories without types for autocomplete
if (!empty($area)) {
    $term_parent = wp_set_object_terms($this->_entity->getID(), $area, 'property_category', true);
    
    if (!is_wp_error($term_parent)) {
        $term_parent_tid = reset($term_parent);
        update_term_meta($term_parent_tid, 'autocomplete', 1);
        update_term_meta($term_parent_tid, 'breadcrumb_name', $area);
        update_term_meta($term_parent_tid, 'area', $area);
        update_term_meta($term_parent_tid, 'category_type', 'area');
        
        // Create subarea if exists
        if (!empty($sub_area)) {
            $term = wp_set_object_terms($this->_entity->getID(), 
                                      $area . ' ' . $sub_area, 
                                      'property_category', true);
            
            if (!is_wp_error($term)) {
                $term_tid = reset($term);
                update_term_meta($term_tid, 'autocomplete', 1);
                update_term_meta($term_tid, 'breadcrumb_name', $area . ' ' . $sub_area);
                update_term_meta($term_tid, 'area', $area);
                update_term_meta($term_tid, 'category_type', 'subarea');
                
                wp_update_term($term_tid, 'property_category', [
                    'parent' => $term_parent_tid,
                ]);
            }
        }
    }
}

Data Field Mapping

Bridge API vs Legacy RETS

Data Component Bridge API Fields Legacy RETS Fields Usage
Area MLSAreaMajor L_Area Main geographic region
Sub Area MLSAreaMinor LM_Char10_5 Subdivision within area
Property Type PropertyType, StructureType LM_char1_36 Property classification
Dwelling Type PropertySubType LM_Char10_11 Specific property style

Data Extraction Logic

// Extract categorization data
$property_class = $this->_class;
$prop_type = $this->_data['LM_char1_36'];
$type_of_dwelling = $this->_data['LM_Char10_11'];
$area = $this->_data['L_Area'];
$sub_area = $this->_data['LM_Char10_5'];

// Bridge API adjustments
if ($is_bridge_api) {
    $property_type = $this->_data['PropertyType'];
    $property_sub_type = $this->_data['PropertySubType'];
    $structure_type = $this->_data['StructureType'];
    
    $prop_type = $structure_type;
    $type_of_dwelling = $property_sub_type;
    $area = $this->_data['MLSAreaMajor'];
    $sub_area = $this->_data['MLSAreaMinor'];
}

Property Class Mapping

RD_1 - Residential Detached

Single-family houses, houses with acreage

RA_2 - Residential Attached

Condos, townhouses, attached units

MF_3 - Multi-Family

Residential income properties

LD_4 - Land

Lots, land only properties

Term Meta Fields & Management

Meta Field Structure

// Term meta fields for enhanced functionality
update_term_meta($term_id, 'autocomplete', 1);
update_term_meta($term_id, 'breadcrumb_name', $display_name);
update_term_meta($term_id, 'area', $area_value);
update_term_meta($term_id, 'type', $property_type);
update_term_meta($term_id, 'category_type', $classification);

// Category type classifications:
// 'area' - Geographic area only
// 'subarea' - Geographic subarea only  
// 'area+type' - Area combined with property type
// 'subarea+type' - Subarea combined with property type

Meta Field Usage

autocomplete

Enables category in search autocomplete functionality

breadcrumb_name

Display name used in breadcrumb navigation

category_type

Classification for different category hierarchy levels

Category Type Implementation

// Area + Type combination creation
if (!empty($type)) {
    $term = $area . ' ' . $type;
    $t = wp_set_object_terms($this->_entity->getID(), $term, 'property_category', true);
    
    if (!is_wp_error($t) && $t) {
        $t = reset($t);
        update_term_meta($t, 'breadcrumb_name', $area);
        update_term_meta($t, 'area', $area);
        update_term_meta($t, 'type', $type);
        update_term_meta($t, 'category_type', 'area+type');
        
        if (!empty($term_parent)) {
            wp_update_term($t, 'property_category', [
                'parent' => $term_parent,
            ]);
        }
    }
}

Search Integration & Keywords

Keyword Generation

$keywords = '';

// Add MLS number
if ($mls = get_post_meta($post_id, 'fave_mls_no', true)) {
    $keywords .= $mls . ' ';
}

// Add address
if ($address = get_post_meta($post_id, 'fave_property_map_address', true)) {
    $keywords .= $address . ' ';
}

// Add categories
if ($categories = wp_get_object_terms($post_id, 'property_category', ['fields' => 'names'])) {
    $keywords .= implode(', ', $categories) . ' ';
}

// Add cities
if ($cities = wp_get_object_terms($post_id, 'property_city', ['fields' => 'names'])) {
    $keywords .= implode(', ', $cities);
}

// Save as custom keyword meta
update_post_meta($post_id, 'fave_custom_keyword', $keywords);

Property Type Assignment

// Assign property type taxonomy
if (!empty($type)) {
    wp_set_object_terms($this->_entity->getID(), 
                       $type, 
                       'property_type', 
                       true);
    
    // Also add to property_tag for tagging
    wp_set_object_terms($this->_entity->getID(), 
                       $type, 
                       'property_tag', 
                       true);
}

Search Features

Autocomplete Search

Categories with autocomplete=1 appear in search suggestions

Filtered Browsing

Hierarchical categories enable drill-down property browsing

SEO Optimization

Custom keywords enhance search engine visibility

URL Structure & SEO Benefits

URL Rewrite Structure

Category Base

Slug: 'mls' with with_front: false

/mls/category-name/
/mls/parent-category/child-category/

Tag Base

Slug: 'mls/tag'

/mls/tag/tag-name/
/mls/tag/3-bedrooms/

SEO Benefits

Semantic URLs

Descriptive URLs that clearly indicate content hierarchy

Breadcrumb Navigation

Enhanced user experience with clear navigation paths

Search Engine Friendly

Clean URL structure improves search engine crawling

URL Examples by Category Type

Category Type Example Category Generated URL Purpose
area Toronto /mls/toronto/ Geographic browsing
area+type Toronto Condos /mls/toronto-condos/ Filtered by type
subarea+type Toronto Downtown Condos /mls/toronto-downtown-condos/ Specific location + type
tag 3 Bedrooms /mls/tag/3-bedrooms/ Feature-based filtering

Implementation Notes for Developers

🔧 Technical Requirements

  • • WordPress wp_set_object_terms() function for taxonomy assignment
  • • update_term_meta() for enhanced category functionality
  • • wp_update_term() for parent-child relationships
  • • Custom rewrite rules for SEO-friendly URLs

⚡ Performance Considerations

  • • Cache term meta queries for frequent lookups
  • • Batch term creation to reduce database calls
  • • Index term meta fields for search performance
  • • Monitor taxonomy term count growth

⚠️ Critical Implementation Points

  • • Always check wp_set_object_terms() return for errors
  • • Validate term parent relationships before assignment
  • • Handle duplicate category names with unique slugs
  • • Implement term cleanup for deleted properties
← Return to Main Documentation