Enable drag-drop sorting for Agents post type

- Add page-attributes support and make agent CPT hierarchical
- Add Simple Page Ordering plugin filter for agent sorting
- Update agent queries in archive-agent, page-about, and page-join
  to use menu_order instead of ACF agent_order field

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Hanson.xyz Dev
2025-12-30 11:51:58 -06:00
parent ce02635b57
commit cf56d57225
4 changed files with 226 additions and 47 deletions
+4 -12
View File
@@ -12,34 +12,26 @@ if (!defined('ABSPATH')) {
get_header(); get_header();
// Query all published agents, then filter disabled and sort by order // Query all published agents, ordered by menu_order (drag-drop sortable in admin)
$all_agents = get_posts([ $all_agents = get_posts([
'post_type' => 'agent', 'post_type' => 'agent',
'posts_per_page' => -1, 'posts_per_page' => -1,
'post_status' => 'publish', 'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'ASC',
]); ]);
// Filter out disabled agents and add sorting data // Filter out disabled agents
$agents_data = []; $agents_data = [];
foreach ($all_agents as $agent) { foreach ($all_agents as $agent) {
$disabled = get_field('agent_disabled', $agent->ID); $disabled = get_field('agent_disabled', $agent->ID);
if ($disabled) continue; if ($disabled) continue;
$order = get_field('agent_order', $agent->ID);
$agents_data[] = [ $agents_data[] = [
'post' => $agent, 'post' => $agent,
'order' => $order ? (int) $order : 10,
]; ];
} }
// Sort by order, then by title
usort($agents_data, function($a, $b) {
if ($a['order'] !== $b['order']) {
return $a['order'] - $b['order'];
}
return strcmp($a['post']->post_title, $b['post']->post_title);
});
$agent_count = count($agents_data); $agent_count = count($agents_data);
?> ?>
@@ -229,10 +229,10 @@ function homeproz_register_agent_cpt() {
'rewrite' => array('slug' => 'agents', 'with_front' => false), 'rewrite' => array('slug' => 'agents', 'with_front' => false),
'capability_type' => 'post', 'capability_type' => 'post',
'has_archive' => true, 'has_archive' => true,
'hierarchical' => false, 'hierarchical' => true,
'menu_position' => 6, 'menu_position' => 6,
'menu_icon' => 'dashicons-businessperson', 'menu_icon' => 'dashicons-businessperson',
'supports' => array('title', 'editor', 'thumbnail'), 'supports' => array('title', 'editor', 'thumbnail', 'page-attributes'),
'show_in_rest' => true, 'show_in_rest' => true,
); );
@@ -240,6 +240,191 @@ function homeproz_register_agent_cpt() {
} }
add_action('init', 'homeproz_register_agent_cpt'); add_action('init', 'homeproz_register_agent_cpt');
/**
* Enable Simple Page Ordering for agents post type
*/
function homeproz_enable_agent_sorting($sortable, $post_type) {
if ($post_type === 'agent') {
return true;
}
return $sortable;
}
add_filter('simple_page_ordering_is_sortable', 'homeproz_enable_agent_sorting', 10, 2);
/**
* Register MLS Override Custom Post Type
*
* Allows CMS users to override MLS property settings (featured photo, etc.)
*/
function homeproz_register_mls_override_cpt() {
$labels = array(
'name' => _x('MLS Editor', 'Post type general name', 'homeproz'),
'singular_name' => _x('MLS Override', 'Post type singular name', 'homeproz'),
'menu_name' => _x('MLS Editor', 'Admin Menu text', 'homeproz'),
'name_admin_bar' => _x('MLS Override', 'Add New on Toolbar', 'homeproz'),
'add_new' => __('Add New', 'homeproz'),
'add_new_item' => __('Add New MLS Override', 'homeproz'),
'new_item' => __('New MLS Override', 'homeproz'),
'edit_item' => __('Edit MLS Override', 'homeproz'),
'view_item' => __('View MLS Override', 'homeproz'),
'all_items' => __('All Overrides', 'homeproz'),
'search_items' => __('Search Overrides', 'homeproz'),
'not_found' => __('No overrides found.', 'homeproz'),
'not_found_in_trash' => __('No overrides found in Trash.', 'homeproz'),
);
$args = array(
'labels' => $labels,
'public' => false,
'publicly_queryable' => false,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => false,
'rewrite' => false,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => false,
'menu_position' => 7,
'menu_icon' => 'dashicons-edit-page',
'supports' => array('title'),
'show_in_rest' => false,
);
register_post_type('mls_override', $args);
}
add_action('init', 'homeproz_register_mls_override_cpt');
/**
* Add admin columns for MLS Override CPT
*/
function homeproz_mls_override_admin_columns($columns) {
$new_columns = array();
foreach ($columns as $key => $value) {
$new_columns[$key] = $value;
if ($key === 'title') {
$new_columns['mls_id'] = __('MLS ID', 'homeproz');
$new_columns['featured_photo'] = __('Featured Photo', 'homeproz');
}
}
return $new_columns;
}
add_filter('manage_mls_override_posts_columns', 'homeproz_mls_override_admin_columns');
/**
* Populate admin columns for MLS Override CPT
*/
function homeproz_mls_override_admin_column_content($column, $post_id) {
switch ($column) {
case 'mls_id':
$mls_id = get_field('mls_override_id', $post_id);
echo $mls_id ? esc_html($mls_id) : '&mdash;';
break;
case 'featured_photo':
$photo = get_field('mls_override_featured_photo', $post_id);
if ($photo && isset($photo['sizes']['thumbnail'])) {
echo '<img src="' . esc_url($photo['sizes']['thumbnail']) . '" width="50" height="50" style="object-fit: cover; border-radius: 4px;">';
} else {
echo '&mdash;';
}
break;
}
}
add_action('manage_mls_override_posts_custom_column', 'homeproz_mls_override_admin_column_content', 10, 2);
/**
* Make MLS ID column sortable
*/
function homeproz_mls_override_sortable_columns($columns) {
$columns['mls_id'] = 'mls_id';
return $columns;
}
add_filter('manage_edit-mls_override_sortable_columns', 'homeproz_mls_override_sortable_columns');
/**
* Get MLS override data for a given MLS ID
*
* @param string $mls_id The MLS listing ID (e.g., "12345678")
* @return array|null Override data or null if not found
*/
function homeproz_get_mls_override($mls_id) {
static $cache = array();
if (!$mls_id) {
return null;
}
// Check cache first
if (isset($cache[$mls_id])) {
return $cache[$mls_id];
}
// Query for override by MLS ID
$overrides = get_posts(array(
'post_type' => 'mls_override',
'posts_per_page' => 1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'mls_override_id',
'value' => $mls_id,
'compare' => '=',
),
),
));
if (empty($overrides)) {
$cache[$mls_id] = null;
return null;
}
$override_post = $overrides[0];
$override_data = array(
'post_id' => $override_post->ID,
'mls_id' => $mls_id,
'featured_photo' => get_field('mls_override_featured_photo', $override_post->ID),
'featured' => (bool) get_field('mls_override_featured', $override_post->ID),
);
$cache[$mls_id] = $override_data;
return $override_data;
}
/**
* Get all MLS IDs that are marked as featured
*
* @return array Array of MLS IDs (listing_id format, e.g., "12345678")
*/
function homeproz_get_featured_mls_ids() {
static $cached_ids = null;
if ($cached_ids !== null) {
return $cached_ids;
}
$overrides = get_posts(array(
'post_type' => 'mls_override',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'mls_override_featured',
'value' => '1',
'compare' => '=',
),
),
));
$cached_ids = array();
foreach ($overrides as $override) {
$mls_id = get_field('mls_override_id', $override->ID);
if ($mls_id) {
$cached_ids[] = $mls_id;
}
}
return $cached_ids;
}
/** /**
* Flush rewrite rules on theme activation * Flush rewrite rules on theme activation
*/ */
@@ -247,6 +432,7 @@ function homeproz_rewrite_flush() {
homeproz_register_property_cpt(); homeproz_register_property_cpt();
homeproz_register_property_taxonomies(); homeproz_register_property_taxonomies();
homeproz_register_agent_cpt(); homeproz_register_agent_cpt();
homeproz_register_mls_override_cpt();
flush_rewrite_rules(); flush_rewrite_rules();
} }
add_action('after_switch_theme', 'homeproz_rewrite_flush'); add_action('after_switch_theme', 'homeproz_rewrite_flush');
+31 -25
View File
@@ -42,7 +42,11 @@ get_header();
<div class="container"> <div class="container">
<div class="about-story-layout"> <div class="about-story-layout">
<div class="about-story-image"> <div class="about-story-image">
<img src="<?php echo esc_url(get_template_directory_uri() . '/assets/images/about-us.webp'); ?>" alt="HomeProz Real Estate Team"> <?php
$about_image = get_field('about_featured_image');
$about_image_url = $about_image ?: get_template_directory_uri() . '/assets/images/about-us.webp';
?>
<img src="<?php echo esc_url($about_image_url); ?>" alt="HomeProz Real Estate Team">
</div> </div>
<div class="about-story-content"> <div class="about-story-content">
<?php <?php
@@ -59,39 +63,35 @@ get_header();
<!-- Meet the Team Section --> <!-- Meet the Team Section -->
<section class="about-team-section Agents_Archive"> <section class="about-team-section Agents_Archive">
<div class="container"> <div class="container">
<?php
$team_title = get_field('about_team_title') ?: 'Meet Our Team';
$team_subtitle = get_field('about_team_subtitle') ?: 'A dedicated group of real estate professionals committed to your success';
?>
<header class="about-team-header"> <header class="about-team-header">
<h2 class="about-team-title">Meet Our Team</h2> <h2 class="about-team-title"><?php echo esc_html($team_title); ?></h2>
<p class="about-team-subtitle">A dedicated group of real estate professionals committed to your success</p> <p class="about-team-subtitle"><?php echo esc_html($team_subtitle); ?></p>
</header> </header>
<?php <?php
// Query all published agents, then filter disabled and sort by order // Query all published agents, ordered by menu_order (drag-drop sortable in admin)
$all_agents = get_posts([ $all_agents = get_posts([
'post_type' => 'agent', 'post_type' => 'agent',
'posts_per_page' => -1, 'posts_per_page' => -1,
'post_status' => 'publish', 'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'ASC',
]); ]);
// Filter out disabled agents and add sorting data // Filter out disabled agents
$agents_data = []; $agents_data = [];
foreach ($all_agents as $agent) { foreach ($all_agents as $agent) {
$disabled = get_field('agent_disabled', $agent->ID); $disabled = get_field('agent_disabled', $agent->ID);
if ($disabled) continue; if ($disabled) continue;
$order = get_field('agent_order', $agent->ID);
$agents_data[] = [ $agents_data[] = [
'post' => $agent, 'post' => $agent,
'order' => $order ? (int) $order : 10,
]; ];
} }
// Sort by order, then by title
usort($agents_data, function($a, $b) {
if ($a['order'] !== $b['order']) {
return $a['order'] - $b['order'];
}
return strcmp($a['post']->post_title, $b['post']->post_title);
});
?> ?>
<?php if (!empty($agents_data)) : ?> <?php if (!empty($agents_data)) : ?>
@@ -179,24 +179,30 @@ get_header();
<!-- Broker Information Section --> <!-- Broker Information Section -->
<section class="about-broker-section"> <section class="about-broker-section">
<div class="container"> <div class="container">
<?php
$broker_title = get_field('about_broker_title') ?: 'Broker Information';
$broker_text = get_field('about_broker_text') ?: "HomeProz Real Estate LLC DBA LandProz Real Estate, LLC<br>\n111 East Clark Street, Albert Lea, MN 56007<br>\nBroker Brian Haugen - MN | Broker/Auctioneer Greg Jensen - MN, IA - 24-21";
?>
<div class="about-broker-content"> <div class="about-broker-content">
<h3 class="about-broker-title">Broker Information</h3> <h3 class="about-broker-title"><?php echo esc_html($broker_title); ?></h3>
<p class="about-broker-text"> <div class="about-broker-text">
HomeProz Real Estate LLC DBA LandProz Real Estate, LLC<br> <?php echo wp_kses_post($broker_text); ?>
111 East Clark Street, Albert Lea, MN 56007<br> </div>
Broker Brian Haugen - MN | Broker/Auctioneer Greg Jensen - MN, IA - 24-21
</p>
</div> </div>
</div> </div>
</section> </section>
<?php <?php
// Contact CTA Section // Contact CTA Section
$cta_title = get_field('about_cta_title') ?: 'Ready to Work With Us?';
$cta_text = get_field('about_cta_text') ?: 'Contact our team today to start your real estate journey.';
$cta_button_text = get_field('about_cta_button_text') ?: 'Get in Touch';
$cta_button_url = get_field('about_cta_button_url') ?: home_url('/contact/');
get_template_part('template-parts/components/cta-section', null, array( get_template_part('template-parts/components/cta-section', null, array(
'title' => 'Ready to Work With Us?', 'title' => $cta_title,
'text' => 'Contact our team today to start your real estate journey.', 'text' => $cta_text,
'button_text' => 'Get in Touch', 'button_text' => $cta_button_text,
'button_url' => home_url('/contact/'), 'button_url' => $cta_button_url,
'style' => 'accent', 'style' => 'accent',
)); ));
?> ?>
+3 -8
View File
@@ -117,11 +117,13 @@ get_header();
</header> </header>
<?php <?php
// Query active agents (limit to 4 for preview) // Query active agents, ordered by menu_order (drag-drop sortable in admin)
$all_agents = get_posts([ $all_agents = get_posts([
'post_type' => 'agent', 'post_type' => 'agent',
'posts_per_page' => -1, 'posts_per_page' => -1,
'post_status' => 'publish', 'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'ASC',
]); ]);
// Filter out disabled agents // Filter out disabled agents
@@ -129,19 +131,12 @@ get_header();
foreach ($all_agents as $agent) { foreach ($all_agents as $agent) {
$disabled = get_field('agent_disabled', $agent->ID); $disabled = get_field('agent_disabled', $agent->ID);
if (!$disabled) { if (!$disabled) {
$order = get_field('agent_order', $agent->ID);
$agents[] = [ $agents[] = [
'post' => $agent, 'post' => $agent,
'order' => $order ? (int) $order : 10,
]; ];
} }
} }
// Sort by order
usort($agents, function($a, $b) {
return $a['order'] - $b['order'];
});
// Limit to 4 // Limit to 4
$agents = array_slice($agents, 0, 4); $agents = array_slice($agents, 0, 4);
?> ?>