Step 2.5: Build Property archive template with filters and results
This commit is contained in:
@@ -407,4 +407,4 @@ UNLOCK TABLES;
|
|||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
-- Dump completed on 2025-11-28 16:34:33
|
-- Dump completed on 2025-11-28 16:36:00
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Property Archive Template
|
||||||
|
*
|
||||||
|
* Displays the properties listing page
|
||||||
|
*
|
||||||
|
* @package HomeProz
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prevent direct access
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<main id="primary" class="site-main">
|
||||||
|
<!-- Archive Hero -->
|
||||||
|
<section class="archive-hero">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="archive-hero-title">Find Your Perfect Property</h1>
|
||||||
|
<p class="archive-hero-subtitle">Browse our selection of homes, land, and commercial properties in southern Minnesota.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<!-- Filters -->
|
||||||
|
<?php get_template_part('template-parts/property/property-filters'); ?>
|
||||||
|
|
||||||
|
<!-- Results -->
|
||||||
|
<div id="property-results">
|
||||||
|
<?php get_template_part('template-parts/property/property-results'); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -15,6 +15,7 @@
|
|||||||
@import '../template-parts/content/content-single.scss';
|
@import '../template-parts/content/content-single.scss';
|
||||||
@import '../template-parts/content/content-404.scss';
|
@import '../template-parts/content/content-404.scss';
|
||||||
@import '../template-parts/property/property-card.scss';
|
@import '../template-parts/property/property-card.scss';
|
||||||
|
@import '../template-parts/property/property-filters.scss';
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// CSS Custom Properties (Design Tokens)
|
// CSS Custom Properties (Design Tokens)
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Property Filters Template Part
|
||||||
|
*
|
||||||
|
* @package HomeProz
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prevent direct access
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current filter values from URL
|
||||||
|
$current_type = isset($_GET['property_type']) ? sanitize_text_field($_GET['property_type']) : '';
|
||||||
|
$current_status = isset($_GET['property_status']) ? sanitize_text_field($_GET['property_status']) : '';
|
||||||
|
$current_location = isset($_GET['property_location']) ? sanitize_text_field($_GET['property_location']) : '';
|
||||||
|
$current_min_price = isset($_GET['min_price']) ? intval($_GET['min_price']) : '';
|
||||||
|
$current_max_price = isset($_GET['max_price']) ? intval($_GET['max_price']) : '';
|
||||||
|
$current_beds = isset($_GET['beds']) ? intval($_GET['beds']) : '';
|
||||||
|
$current_sort = isset($_GET['sort']) ? sanitize_text_field($_GET['sort']) : 'newest';
|
||||||
|
|
||||||
|
// Get taxonomy terms
|
||||||
|
$property_types = get_terms(array('taxonomy' => 'property_type', 'hide_empty' => false));
|
||||||
|
$property_statuses = get_terms(array('taxonomy' => 'property_status', 'hide_empty' => false));
|
||||||
|
$property_locations = get_terms(array('taxonomy' => 'property_location', 'hide_empty' => false));
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="property-filters" id="property-filters" data-ajax-url="<?php echo esc_url(admin_url('admin-ajax.php')); ?>">
|
||||||
|
<form class="filters-form" method="get" action="<?php echo esc_url(get_post_type_archive_link('property')); ?>">
|
||||||
|
<div class="filters-row">
|
||||||
|
<!-- Property Type -->
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="filter-type" class="filter-label">Property Type</label>
|
||||||
|
<select name="property_type" id="filter-type" class="filter-select">
|
||||||
|
<option value="">All Types</option>
|
||||||
|
<?php foreach ($property_types as $type) : ?>
|
||||||
|
<option value="<?php echo esc_attr($type->slug); ?>" <?php selected($current_type, $type->slug); ?>>
|
||||||
|
<?php echo esc_html($type->name); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Property Status -->
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="filter-status" class="filter-label">Status</label>
|
||||||
|
<select name="property_status" id="filter-status" class="filter-select">
|
||||||
|
<option value="">All Statuses</option>
|
||||||
|
<?php foreach ($property_statuses as $status) : ?>
|
||||||
|
<option value="<?php echo esc_attr($status->slug); ?>" <?php selected($current_status, $status->slug); ?>>
|
||||||
|
<?php echo esc_html($status->name); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Location -->
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="filter-location" class="filter-label">Location</label>
|
||||||
|
<select name="property_location" id="filter-location" class="filter-select">
|
||||||
|
<option value="">All Locations</option>
|
||||||
|
<?php foreach ($property_locations as $location) : ?>
|
||||||
|
<option value="<?php echo esc_attr($location->slug); ?>" <?php selected($current_location, $location->slug); ?>>
|
||||||
|
<?php echo esc_html($location->name); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bedrooms -->
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="filter-beds" class="filter-label">Bedrooms</label>
|
||||||
|
<select name="beds" id="filter-beds" class="filter-select">
|
||||||
|
<option value="">Any</option>
|
||||||
|
<option value="1" <?php selected($current_beds, 1); ?>>1+</option>
|
||||||
|
<option value="2" <?php selected($current_beds, 2); ?>>2+</option>
|
||||||
|
<option value="3" <?php selected($current_beds, 3); ?>>3+</option>
|
||||||
|
<option value="4" <?php selected($current_beds, 4); ?>>4+</option>
|
||||||
|
<option value="5" <?php selected($current_beds, 5); ?>>5+</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Price Range -->
|
||||||
|
<div class="filter-group filter-group-price">
|
||||||
|
<label class="filter-label">Price Range</label>
|
||||||
|
<div class="price-inputs">
|
||||||
|
<select name="min_price" id="filter-min-price" class="filter-select">
|
||||||
|
<option value="">Min Price</option>
|
||||||
|
<option value="50000" <?php selected($current_min_price, 50000); ?>>$50,000</option>
|
||||||
|
<option value="100000" <?php selected($current_min_price, 100000); ?>>$100,000</option>
|
||||||
|
<option value="150000" <?php selected($current_min_price, 150000); ?>>$150,000</option>
|
||||||
|
<option value="200000" <?php selected($current_min_price, 200000); ?>>$200,000</option>
|
||||||
|
<option value="250000" <?php selected($current_min_price, 250000); ?>>$250,000</option>
|
||||||
|
<option value="300000" <?php selected($current_min_price, 300000); ?>>$300,000</option>
|
||||||
|
<option value="400000" <?php selected($current_min_price, 400000); ?>>$400,000</option>
|
||||||
|
<option value="500000" <?php selected($current_min_price, 500000); ?>>$500,000</option>
|
||||||
|
</select>
|
||||||
|
<span class="price-separator">-</span>
|
||||||
|
<select name="max_price" id="filter-max-price" class="filter-select">
|
||||||
|
<option value="">Max Price</option>
|
||||||
|
<option value="100000" <?php selected($current_max_price, 100000); ?>>$100,000</option>
|
||||||
|
<option value="150000" <?php selected($current_max_price, 150000); ?>>$150,000</option>
|
||||||
|
<option value="200000" <?php selected($current_max_price, 200000); ?>>$200,000</option>
|
||||||
|
<option value="250000" <?php selected($current_max_price, 250000); ?>>$250,000</option>
|
||||||
|
<option value="300000" <?php selected($current_max_price, 300000); ?>>$300,000</option>
|
||||||
|
<option value="400000" <?php selected($current_max_price, 400000); ?>>$400,000</option>
|
||||||
|
<option value="500000" <?php selected($current_max_price, 500000); ?>>$500,000</option>
|
||||||
|
<option value="750000" <?php selected($current_max_price, 750000); ?>>$750,000</option>
|
||||||
|
<option value="1000000" <?php selected($current_max_price, 1000000); ?>>$1,000,000+</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="filters-actions">
|
||||||
|
<!-- Sort -->
|
||||||
|
<div class="filter-group filter-group-sort">
|
||||||
|
<label for="filter-sort" class="filter-label">Sort By</label>
|
||||||
|
<select name="sort" id="filter-sort" class="filter-select">
|
||||||
|
<option value="newest" <?php selected($current_sort, 'newest'); ?>>Newest First</option>
|
||||||
|
<option value="oldest" <?php selected($current_sort, 'oldest'); ?>>Oldest First</option>
|
||||||
|
<option value="price_low" <?php selected($current_sort, 'price_low'); ?>>Price: Low to High</option>
|
||||||
|
<option value="price_high" <?php selected($current_sort, 'price_high'); ?>>Price: High to Low</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary filters-submit">Search</button>
|
||||||
|
<a href="<?php echo esc_url(get_post_type_archive_link('property')); ?>" class="btn btn-secondary filters-reset">Reset</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* Property Filters Styles
|
||||||
|
*
|
||||||
|
* @package HomeProz
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Archive Hero
|
||||||
|
.archive-hero {
|
||||||
|
background-color: var(--color-bg-card);
|
||||||
|
padding: 3rem 0;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.archive-hero-title {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.archive-hero-subtitle {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
margin-bottom: 0;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters Container
|
||||||
|
.property-filters {
|
||||||
|
background-color: var(--color-bg-card);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
grid-template-columns: repeat(3, 1fr) 2fr;
|
||||||
|
gap: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter Groups
|
||||||
|
.filter-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-label {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.625rem 2rem 0.625rem 0.75rem;
|
||||||
|
background-color: var(--color-bg-dark);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: none;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23B0B0B0' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right 0.75rem center;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Price Input Group
|
||||||
|
.filter-group-price {
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
grid-column: span 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-inputs {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
.filter-select {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-separator {
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters Actions
|
||||||
|
.filters-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 1rem;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-group-sort {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 150px;
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 180px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters-submit,
|
||||||
|
.filters-reset {
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loading State
|
||||||
|
.property-filters.is-loading {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Results loading spinner (only for first load)
|
||||||
|
.property-results-loading {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 4rem 0;
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 3px solid var(--color-border);
|
||||||
|
border-top-color: var(--color-accent);
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Property Results Template Part
|
||||||
|
*
|
||||||
|
* Displays property results for archive/search
|
||||||
|
*
|
||||||
|
* @package HomeProz
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Prevent direct access
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get filter values
|
||||||
|
$current_type = isset($_GET['property_type']) ? sanitize_text_field($_GET['property_type']) : '';
|
||||||
|
$current_status = isset($_GET['property_status']) ? sanitize_text_field($_GET['property_status']) : '';
|
||||||
|
$current_location = isset($_GET['property_location']) ? sanitize_text_field($_GET['property_location']) : '';
|
||||||
|
$current_min_price = isset($_GET['min_price']) ? intval($_GET['min_price']) : '';
|
||||||
|
$current_max_price = isset($_GET['max_price']) ? intval($_GET['max_price']) : '';
|
||||||
|
$current_beds = isset($_GET['beds']) ? intval($_GET['beds']) : '';
|
||||||
|
$current_sort = isset($_GET['sort']) ? sanitize_text_field($_GET['sort']) : 'newest';
|
||||||
|
|
||||||
|
// Build query args
|
||||||
|
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
|
||||||
|
$args = array(
|
||||||
|
'post_type' => 'property',
|
||||||
|
'posts_per_page' => 12,
|
||||||
|
'paged' => $paged,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Taxonomy filters
|
||||||
|
$tax_query = array();
|
||||||
|
|
||||||
|
if ($current_type) {
|
||||||
|
$tax_query[] = array(
|
||||||
|
'taxonomy' => 'property_type',
|
||||||
|
'field' => 'slug',
|
||||||
|
'terms' => $current_type,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($current_status) {
|
||||||
|
$tax_query[] = array(
|
||||||
|
'taxonomy' => 'property_status',
|
||||||
|
'field' => 'slug',
|
||||||
|
'terms' => $current_status,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($current_location) {
|
||||||
|
$tax_query[] = array(
|
||||||
|
'taxonomy' => 'property_location',
|
||||||
|
'field' => 'slug',
|
||||||
|
'terms' => $current_location,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($tax_query)) {
|
||||||
|
$args['tax_query'] = $tax_query;
|
||||||
|
if (count($tax_query) > 1) {
|
||||||
|
$args['tax_query']['relation'] = 'AND';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meta query for price and bedrooms
|
||||||
|
$meta_query = array();
|
||||||
|
|
||||||
|
if ($current_min_price) {
|
||||||
|
$meta_query[] = array(
|
||||||
|
'key' => 'property_price',
|
||||||
|
'value' => $current_min_price,
|
||||||
|
'type' => 'NUMERIC',
|
||||||
|
'compare' => '>=',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($current_max_price) {
|
||||||
|
$meta_query[] = array(
|
||||||
|
'key' => 'property_price',
|
||||||
|
'value' => $current_max_price,
|
||||||
|
'type' => 'NUMERIC',
|
||||||
|
'compare' => '<=',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($current_beds) {
|
||||||
|
$meta_query[] = array(
|
||||||
|
'key' => 'bedrooms',
|
||||||
|
'value' => $current_beds,
|
||||||
|
'type' => 'NUMERIC',
|
||||||
|
'compare' => '>=',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($meta_query)) {
|
||||||
|
$args['meta_query'] = $meta_query;
|
||||||
|
if (count($meta_query) > 1) {
|
||||||
|
$args['meta_query']['relation'] = 'AND';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting
|
||||||
|
switch ($current_sort) {
|
||||||
|
case 'oldest':
|
||||||
|
$args['orderby'] = 'date';
|
||||||
|
$args['order'] = 'ASC';
|
||||||
|
break;
|
||||||
|
case 'price_low':
|
||||||
|
$args['meta_key'] = 'property_price';
|
||||||
|
$args['orderby'] = 'meta_value_num';
|
||||||
|
$args['order'] = 'ASC';
|
||||||
|
break;
|
||||||
|
case 'price_high':
|
||||||
|
$args['meta_key'] = 'property_price';
|
||||||
|
$args['orderby'] = 'meta_value_num';
|
||||||
|
$args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
case 'newest':
|
||||||
|
default:
|
||||||
|
$args['orderby'] = 'date';
|
||||||
|
$args['order'] = 'DESC';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$properties = new WP_Query($args);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- Results Meta -->
|
||||||
|
<div class="properties-meta">
|
||||||
|
<p class="properties-count">
|
||||||
|
<?php if ($properties->found_posts > 0) : ?>
|
||||||
|
Showing <strong><?php echo esc_html($properties->found_posts); ?></strong>
|
||||||
|
<?php echo $properties->found_posts === 1 ? 'property' : 'properties'; ?>
|
||||||
|
<?php else : ?>
|
||||||
|
No properties found
|
||||||
|
<?php endif; ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($properties->have_posts()) : ?>
|
||||||
|
<div class="properties-grid">
|
||||||
|
<?php
|
||||||
|
while ($properties->have_posts()) :
|
||||||
|
$properties->the_post();
|
||||||
|
get_template_part('template-parts/property/property-card');
|
||||||
|
endwhile;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Pagination
|
||||||
|
$big = 999999999;
|
||||||
|
$pagination = paginate_links(array(
|
||||||
|
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
|
||||||
|
'format' => '?paged=%#%',
|
||||||
|
'current' => max(1, $paged),
|
||||||
|
'total' => $properties->max_num_pages,
|
||||||
|
'prev_text' => '← Previous',
|
||||||
|
'next_text' => 'Next →',
|
||||||
|
'type' => 'array',
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($pagination) :
|
||||||
|
?>
|
||||||
|
<nav class="pagination" aria-label="Property pagination">
|
||||||
|
<div class="nav-links">
|
||||||
|
<?php foreach ($pagination as $link) : ?>
|
||||||
|
<?php echo $link; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php else : ?>
|
||||||
|
<div class="no-properties">
|
||||||
|
<h3>No Properties Found</h3>
|
||||||
|
<p>We couldn't find any properties matching your criteria. Try adjusting your filters or browse all properties.</p>
|
||||||
|
<a href="<?php echo esc_url(get_post_type_archive_link('property')); ?>" class="btn btn-primary">View All Properties</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php wp_reset_postdata(); ?>
|
||||||
Reference in New Issue
Block a user