Add 6 reusable page templates with ACF integration

Introduces layout-focused templates for marketing pages:
- Content with Sidebar: 70/30 grid with callout boxes
- Alternating Blocks: Zigzag image/text sections
- Service Detail: Hero + features grid + FAQ accordion
- Card Grid: Configurable 2/3/4 column card layouts
- Long-Form Article: Clean reading layout with related links
- Landing Page: Conversion-focused with benefits and testimonial

Each template has corresponding ACF field groups for content
management. Sample pages created under /page-template-examples/.

🤖 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-18 00:50:33 -06:00
parent d11e8bfd4c
commit 183e1b92c9
10 changed files with 1759 additions and 1 deletions
File diff suppressed because one or more lines are too long
@@ -407,6 +407,117 @@ function homeproz_register_acf_fields() {
'name' => 'theme_youtube', 'name' => 'theme_youtube',
'type' => 'url', 'type' => 'url',
), ),
// Footer & Branding
array(
'key' => 'field_theme_tab_footer',
'label' => 'Footer & Branding',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_theme_footer_tagline',
'label' => 'Footer Tagline',
'name' => 'theme_footer_tagline',
'type' => 'textarea',
'instructions' => 'Short description shown in footer about section',
'rows' => 2,
'default_value' => 'Your trusted partner in Minnesota and Iowa real estate. Finding homes, building futures.',
),
array(
'key' => 'field_theme_broker_info',
'label' => 'Broker Information',
'name' => 'theme_broker_info',
'type' => 'textarea',
'instructions' => 'Legal broker disclosure text shown in footer',
'rows' => 3,
'default_value' => 'HomeProz Real Estate LLC DBA LandProz Real Estate, LLC',
),
array(
'key' => 'field_theme_org_description',
'label' => 'Organization Description',
'name' => 'theme_org_description',
'type' => 'textarea',
'instructions' => 'Used for SEO/schema markup. Describe your business in 1-2 sentences.',
'rows' => 2,
'default_value' => 'Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.',
),
// Office Hours
array(
'key' => 'field_theme_tab_hours',
'label' => 'Office Hours',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_theme_office_hours',
'label' => 'Office Hours',
'name' => 'theme_office_hours',
'type' => 'repeater',
'instructions' => 'Set your business hours for each day or day range',
'min' => 1,
'max' => 7,
'layout' => 'table',
'button_label' => 'Add Hours',
'sub_fields' => array(
array(
'key' => 'field_hours_day',
'label' => 'Day(s)',
'name' => 'day',
'type' => 'text',
'instructions' => 'e.g., "Monday - Friday" or "Saturday"',
'required' => 1,
'wrapper' => array('width' => '40'),
),
array(
'key' => 'field_hours_time',
'label' => 'Hours',
'name' => 'time',
'type' => 'text',
'instructions' => 'e.g., "9:00 AM - 5:00 PM" or "By Appointment"',
'required' => 1,
'wrapper' => array('width' => '60'),
),
),
),
// Location/Map
array(
'key' => 'field_theme_tab_location',
'label' => 'Location',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_theme_latitude',
'label' => 'Latitude',
'name' => 'theme_latitude',
'type' => 'number',
'instructions' => 'Office location latitude for maps and schema',
'default_value' => '43.6477',
'step' => 'any',
),
array(
'key' => 'field_theme_longitude',
'label' => 'Longitude',
'name' => 'theme_longitude',
'type' => 'number',
'instructions' => 'Office location longitude for maps and schema',
'default_value' => '-93.3683',
'step' => 'any',
),
array(
'key' => 'field_theme_map_embed',
'label' => 'Google Maps Embed Code',
'name' => 'theme_map_embed',
'type' => 'textarea',
'instructions' => 'Paste the full iframe embed code from Google Maps. Get this from maps.google.com > Share > Embed a map.',
'rows' => 4,
),
), ),
'location' => array( 'location' => array(
array( array(
@@ -480,6 +591,270 @@ function homeproz_register_acf_fields() {
'active' => true, 'active' => true,
)); ));
// Homepage Content Field Group
acf_add_local_field_group(array(
'key' => 'group_homepage_content',
'title' => 'Homepage Content',
'fields' => array(
// Hero Section Tab
array(
'key' => 'field_home_tab_hero',
'label' => 'Hero Section',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_home_hero_title',
'label' => 'Hero Title',
'name' => 'home_hero_title',
'type' => 'text',
'default_value' => 'Find Your Dream Home Today',
),
array(
'key' => 'field_home_hero_subtitle',
'label' => 'Hero Subtitle',
'name' => 'home_hero_subtitle',
'type' => 'textarea',
'rows' => 2,
'default_value' => 'Expert real estate services for buyers and sellers in Albert Lea and the surrounding Minnesota communities.',
),
array(
'key' => 'field_home_hero_primary_cta_text',
'label' => 'Primary Button Text',
'name' => 'home_hero_primary_cta_text',
'type' => 'text',
'default_value' => 'View All Properties',
),
array(
'key' => 'field_home_hero_primary_cta_url',
'label' => 'Primary Button URL',
'name' => 'home_hero_primary_cta_url',
'type' => 'url',
'instructions' => 'Leave empty to use /properties/',
),
array(
'key' => 'field_home_hero_secondary_cta_text',
'label' => 'Secondary Button Text',
'name' => 'home_hero_secondary_cta_text',
'type' => 'text',
'default_value' => 'Contact Us',
),
array(
'key' => 'field_home_hero_secondary_cta_url',
'label' => 'Secondary Button URL',
'name' => 'home_hero_secondary_cta_url',
'type' => 'url',
'instructions' => 'Leave empty to use /contact/',
),
array(
'key' => 'field_home_hero_background',
'label' => 'Hero Background Image',
'name' => 'home_hero_background',
'type' => 'image',
'instructions' => 'Recommended size: 1920x800 or larger.',
'return_format' => 'url',
'preview_size' => 'medium',
),
// Service Cards Tab
array(
'key' => 'field_home_tab_services',
'label' => 'Service Cards',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_home_services_title',
'label' => 'Section Title',
'name' => 'home_services_title',
'type' => 'text',
'default_value' => 'Go With The Proz',
),
array(
'key' => 'field_home_services_subtitle',
'label' => 'Section Subtitle',
'name' => 'home_services_subtitle',
'type' => 'textarea',
'rows' => 2,
'default_value' => 'Whether you\'re buying or selling, we\'re here to guide you every step of the way.',
),
array(
'key' => 'field_home_service_cards',
'label' => 'Service Cards',
'name' => 'home_service_cards',
'type' => 'repeater',
'min' => 1,
'max' => 6,
'layout' => 'block',
'button_label' => 'Add Service Card',
'sub_fields' => array(
array(
'key' => 'field_service_icon',
'label' => 'Icon',
'name' => 'icon',
'type' => 'select',
'choices' => array(
'home' => 'Home',
'dollar-sign' => 'Dollar Sign',
'users' => 'Users/Team',
'map-pin' => 'Map Pin',
'key' => 'Key',
'building' => 'Building',
'search' => 'Search',
'handshake' => 'Handshake',
),
'default_value' => 'home',
),
array(
'key' => 'field_service_title',
'label' => 'Title',
'name' => 'title',
'type' => 'text',
'required' => 1,
),
array(
'key' => 'field_service_description',
'label' => 'Description',
'name' => 'description',
'type' => 'textarea',
'rows' => 3,
'required' => 1,
),
array(
'key' => 'field_service_button_text',
'label' => 'Button Text',
'name' => 'button_text',
'type' => 'text',
),
array(
'key' => 'field_service_button_url',
'label' => 'Button URL',
'name' => 'button_url',
'type' => 'url',
),
),
),
// Featured Sections Tab
array(
'key' => 'field_home_tab_featured',
'label' => 'Featured Sections',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_home_featured_homes_title',
'label' => 'Featured Homes Title',
'name' => 'home_featured_homes_title',
'type' => 'text',
'default_value' => 'Featured Homes',
),
array(
'key' => 'field_home_featured_homes_subtitle',
'label' => 'Featured Homes Subtitle',
'name' => 'home_featured_homes_subtitle',
'type' => 'textarea',
'rows' => 2,
'default_value' => 'Browse our residential properties for sale',
),
array(
'key' => 'field_home_commercial_title',
'label' => 'Commercial Section Title',
'name' => 'home_commercial_title',
'type' => 'text',
'default_value' => 'Commercial & Land',
),
array(
'key' => 'field_home_commercial_subtitle',
'label' => 'Commercial Section Subtitle',
'name' => 'home_commercial_subtitle',
'type' => 'textarea',
'rows' => 2,
'default_value' => 'Explore commercial properties and land for sale',
),
// CTA Section Tab
array(
'key' => 'field_home_tab_cta',
'label' => 'CTA Section',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_home_cta_title',
'label' => 'CTA Title',
'name' => 'home_cta_title',
'type' => 'text',
'default_value' => 'Ready to Find Your Dream Home?',
),
array(
'key' => 'field_home_cta_text',
'label' => 'CTA Text',
'name' => 'home_cta_text',
'type' => 'textarea',
'rows' => 2,
'default_value' => 'Whether you\'re buying or selling, our team is here to help you every step of the way.',
),
array(
'key' => 'field_home_cta_button_text',
'label' => 'CTA Button Text',
'name' => 'home_cta_button_text',
'type' => 'text',
'default_value' => 'Contact Us Today',
),
array(
'key' => 'field_home_cta_button_url',
'label' => 'CTA Button URL',
'name' => 'home_cta_button_url',
'type' => 'url',
'instructions' => 'Leave empty to use /contact/',
),
// Property Type Boxes Tab
array(
'key' => 'field_home_tab_property_types',
'label' => 'Property Types',
'name' => '',
'type' => 'tab',
'placement' => 'left',
),
array(
'key' => 'field_home_property_types_title',
'label' => 'Section Title',
'name' => 'home_property_types_title',
'type' => 'text',
'default_value' => 'Browse by Property Type',
),
array(
'key' => 'field_home_property_types_subtitle',
'label' => 'Section Subtitle',
'name' => 'home_property_types_subtitle',
'type' => 'textarea',
'rows' => 2,
'default_value' => 'Find the perfect property for your needs',
),
),
'location' => array(
array(
array(
'param' => 'page_type',
'operator' => '==',
'value' => 'front_page',
),
),
),
'menu_order' => -1,
'position' => 'acf_after_title',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'active' => true,
));
// Agent Details Field Group // Agent Details Field Group
acf_add_local_field_group(array( acf_add_local_field_group(array(
'key' => 'group_agent_details', 'key' => 'group_agent_details',
@@ -669,6 +1044,225 @@ function homeproz_register_acf_fields() {
'instruction_placement' => 'label', 'instruction_placement' => 'label',
'active' => true, 'active' => true,
)); ));
// ===========================================
// PAGE TEMPLATE FIELD GROUPS
// ===========================================
// 1. Content with Sidebar Template
acf_add_local_field_group(array(
'key' => 'group_template_sidebar',
'title' => 'Content with Sidebar Settings',
'fields' => array(
array(
'key' => 'field_sidebar_callouts',
'label' => 'Sidebar Callouts',
'name' => 'sidebar_callouts',
'type' => 'repeater',
'instructions' => 'Add callout boxes for the sidebar',
'max' => 5,
'layout' => 'block',
'button_label' => 'Add Callout',
'sub_fields' => array(
array('key' => 'field_callout_title', 'label' => 'Title', 'name' => 'callout_title', 'type' => 'text', 'required' => 1),
array('key' => 'field_callout_content', 'label' => 'Content', 'name' => 'callout_content', 'type' => 'textarea', 'rows' => 3),
array('key' => 'field_callout_button_text', 'label' => 'Button Text', 'name' => 'callout_button_text', 'type' => 'text'),
array('key' => 'field_callout_button_url', 'label' => 'Button URL', 'name' => 'callout_button_url', 'type' => 'url'),
),
),
array('key' => 'field_sidebar_cta_title', 'label' => 'CTA Title', 'name' => 'page_cta_title', 'type' => 'text', 'default_value' => 'Ready to Get Started?'),
array('key' => 'field_sidebar_cta_text', 'label' => 'CTA Text', 'name' => 'page_cta_text', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_sidebar_cta_btn_text', 'label' => 'CTA Button Text', 'name' => 'page_cta_button_text', 'type' => 'text', 'default_value' => 'Contact Us'),
array('key' => 'field_sidebar_cta_btn_url', 'label' => 'CTA Button URL', 'name' => 'page_cta_button_url', 'type' => 'url'),
),
'location' => array(array(array('param' => 'page_template', 'operator' => '==', 'value' => 'page-templates/content-sidebar.php'))),
'menu_order' => 0,
'position' => 'normal',
'active' => true,
));
// 2. Alternating Blocks Template
acf_add_local_field_group(array(
'key' => 'group_template_alternating',
'title' => 'Alternating Blocks Settings',
'fields' => array(
array('key' => 'field_alt_hero_title', 'label' => 'Hero Title', 'name' => 'alt_hero_title', 'type' => 'text'),
array('key' => 'field_alt_hero_subtitle', 'label' => 'Hero Subtitle', 'name' => 'alt_hero_subtitle', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_alt_hero_bg', 'label' => 'Hero Background', 'name' => 'alt_hero_background', 'type' => 'image', 'return_format' => 'url'),
array(
'key' => 'field_content_blocks',
'label' => 'Content Blocks',
'name' => 'content_blocks',
'type' => 'repeater',
'instructions' => 'Add alternating image/text blocks. Odd rows show image left, even rows show image right.',
'min' => 1,
'max' => 10,
'layout' => 'block',
'button_label' => 'Add Block',
'sub_fields' => array(
array('key' => 'field_block_image', 'label' => 'Image', 'name' => 'block_image', 'type' => 'image', 'return_format' => 'url'),
array('key' => 'field_block_title', 'label' => 'Title', 'name' => 'block_title', 'type' => 'text', 'required' => 1),
array('key' => 'field_block_content', 'label' => 'Content', 'name' => 'block_content', 'type' => 'wysiwyg', 'tabs' => 'all', 'toolbar' => 'full', 'media_upload' => 0),
array('key' => 'field_block_btn_text', 'label' => 'Button Text', 'name' => 'block_button_text', 'type' => 'text'),
array('key' => 'field_block_btn_url', 'label' => 'Button URL', 'name' => 'block_button_url', 'type' => 'url'),
),
),
array('key' => 'field_alt_cta_title', 'label' => 'CTA Title', 'name' => 'alt_cta_title', 'type' => 'text'),
array('key' => 'field_alt_cta_text', 'label' => 'CTA Text', 'name' => 'alt_cta_text', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_alt_cta_btn_text', 'label' => 'CTA Button Text', 'name' => 'alt_cta_button_text', 'type' => 'text', 'default_value' => 'Contact Us'),
array('key' => 'field_alt_cta_btn_url', 'label' => 'CTA Button URL', 'name' => 'alt_cta_button_url', 'type' => 'url'),
),
'location' => array(array(array('param' => 'page_template', 'operator' => '==', 'value' => 'page-templates/alternating-blocks.php'))),
'menu_order' => 0,
'position' => 'normal',
'active' => true,
));
// 3. Service Detail Template
acf_add_local_field_group(array(
'key' => 'group_template_service',
'title' => 'Service Detail Settings',
'fields' => array(
array('key' => 'field_svc_hero_title', 'label' => 'Hero Title', 'name' => 'service_hero_title', 'type' => 'text'),
array('key' => 'field_svc_hero_subtitle', 'label' => 'Hero Subtitle', 'name' => 'service_hero_subtitle', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_svc_hero_bg', 'label' => 'Hero Background', 'name' => 'service_hero_background', 'type' => 'image', 'return_format' => 'url'),
array('key' => 'field_svc_intro', 'label' => 'Introduction', 'name' => 'service_intro', 'type' => 'wysiwyg', 'tabs' => 'all', 'toolbar' => 'full'),
array(
'key' => 'field_svc_features',
'label' => 'Feature Cards',
'name' => 'service_features',
'type' => 'repeater',
'max' => 6,
'layout' => 'block',
'button_label' => 'Add Feature',
'sub_fields' => array(
array('key' => 'field_feature_icon', 'label' => 'Icon', 'name' => 'feature_icon', 'type' => 'select', 'choices' => array('check' => 'Check', 'star' => 'Star', 'shield' => 'Shield', 'home' => 'Home', 'dollar-sign' => 'Dollar', 'users' => 'Users', 'map-pin' => 'Map Pin', 'key' => 'Key', 'building' => 'Building', 'search' => 'Search')),
array('key' => 'field_feature_title', 'label' => 'Title', 'name' => 'feature_title', 'type' => 'text', 'required' => 1),
array('key' => 'field_feature_desc', 'label' => 'Description', 'name' => 'feature_description', 'type' => 'textarea', 'rows' => 2),
),
),
array(
'key' => 'field_svc_faq',
'label' => 'FAQ Items',
'name' => 'service_faq',
'type' => 'repeater',
'max' => 10,
'layout' => 'block',
'button_label' => 'Add FAQ',
'sub_fields' => array(
array('key' => 'field_faq_q', 'label' => 'Question', 'name' => 'faq_question', 'type' => 'text', 'required' => 1),
array('key' => 'field_faq_a', 'label' => 'Answer', 'name' => 'faq_answer', 'type' => 'wysiwyg', 'tabs' => 'all', 'toolbar' => 'basic', 'media_upload' => 0),
),
),
array('key' => 'field_svc_cta_title', 'label' => 'CTA Title', 'name' => 'service_cta_title', 'type' => 'text'),
array('key' => 'field_svc_cta_btn_text', 'label' => 'CTA Button Text', 'name' => 'service_cta_button_text', 'type' => 'text', 'default_value' => 'Contact Us'),
array('key' => 'field_svc_cta_btn_url', 'label' => 'CTA Button URL', 'name' => 'service_cta_button_url', 'type' => 'url'),
),
'location' => array(array(array('param' => 'page_template', 'operator' => '==', 'value' => 'page-templates/service-detail.php'))),
'menu_order' => 0,
'position' => 'normal',
'active' => true,
));
// 4. Card Grid Template
acf_add_local_field_group(array(
'key' => 'group_template_card_grid',
'title' => 'Card Grid Settings',
'fields' => array(
array('key' => 'field_grid_title', 'label' => 'Section Title', 'name' => 'grid_title', 'type' => 'text'),
array('key' => 'field_grid_subtitle', 'label' => 'Section Subtitle', 'name' => 'grid_subtitle', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_grid_intro', 'label' => 'Introduction', 'name' => 'grid_intro', 'type' => 'wysiwyg', 'tabs' => 'all', 'toolbar' => 'basic'),
array('key' => 'field_grid_columns', 'label' => 'Columns', 'name' => 'grid_columns', 'type' => 'select', 'choices' => array('2' => '2 Columns', '3' => '3 Columns', '4' => '4 Columns'), 'default_value' => '3'),
array(
'key' => 'field_grid_cards',
'label' => 'Cards',
'name' => 'grid_cards',
'type' => 'repeater',
'max' => 12,
'layout' => 'block',
'button_label' => 'Add Card',
'sub_fields' => array(
array('key' => 'field_card_image', 'label' => 'Image', 'name' => 'card_image', 'type' => 'image', 'return_format' => 'url'),
array('key' => 'field_card_title', 'label' => 'Title', 'name' => 'card_title', 'type' => 'text', 'required' => 1),
array('key' => 'field_card_desc', 'label' => 'Description', 'name' => 'card_description', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_card_link_text', 'label' => 'Link Text', 'name' => 'card_link_text', 'type' => 'text'),
array('key' => 'field_card_link_url', 'label' => 'Link URL', 'name' => 'card_link_url', 'type' => 'url'),
),
),
array('key' => 'field_grid_cta_title', 'label' => 'CTA Title', 'name' => 'grid_cta_title', 'type' => 'text'),
array('key' => 'field_grid_cta_btn_text', 'label' => 'CTA Button Text', 'name' => 'grid_cta_button_text', 'type' => 'text', 'default_value' => 'Contact Us'),
array('key' => 'field_grid_cta_btn_url', 'label' => 'CTA Button URL', 'name' => 'grid_cta_button_url', 'type' => 'url'),
),
'location' => array(array(array('param' => 'page_template', 'operator' => '==', 'value' => 'page-templates/card-grid.php'))),
'menu_order' => 0,
'position' => 'normal',
'active' => true,
));
// 5. Long-Form Article Template
acf_add_local_field_group(array(
'key' => 'group_template_article',
'title' => 'Long-Form Article Settings',
'fields' => array(
array('key' => 'field_article_subtitle', 'label' => 'Subtitle', 'name' => 'article_subtitle', 'type' => 'text', 'instructions' => 'Optional subtitle under the title'),
array('key' => 'field_show_breadcrumbs', 'label' => 'Show Breadcrumbs', 'name' => 'show_breadcrumbs', 'type' => 'true_false', 'default_value' => 1, 'ui' => 1),
array(
'key' => 'field_related_links',
'label' => 'Related Links',
'name' => 'related_links',
'type' => 'repeater',
'max' => 5,
'layout' => 'table',
'button_label' => 'Add Link',
'sub_fields' => array(
array('key' => 'field_rel_link_title', 'label' => 'Title', 'name' => 'link_title', 'type' => 'text', 'required' => 1),
array('key' => 'field_rel_link_url', 'label' => 'URL', 'name' => 'link_url', 'type' => 'url', 'required' => 1),
),
),
),
'location' => array(array(array('param' => 'page_template', 'operator' => '==', 'value' => 'page-templates/long-form-article.php'))),
'menu_order' => 0,
'position' => 'normal',
'active' => true,
));
// 6. Landing Page Template
acf_add_local_field_group(array(
'key' => 'group_template_landing',
'title' => 'Landing Page Settings',
'fields' => array(
array('key' => 'field_land_hero_title', 'label' => 'Hero Title', 'name' => 'landing_hero_title', 'type' => 'text'),
array('key' => 'field_land_hero_subtitle', 'label' => 'Hero Subtitle', 'name' => 'landing_hero_subtitle', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_land_hero_bg', 'label' => 'Hero Background', 'name' => 'landing_hero_background', 'type' => 'image', 'return_format' => 'url'),
array('key' => 'field_land_hero_cta_text', 'label' => 'Hero CTA Text', 'name' => 'landing_hero_cta_text', 'type' => 'text', 'default_value' => 'Get Started'),
array('key' => 'field_land_hero_cta_url', 'label' => 'Hero CTA URL', 'name' => 'landing_hero_cta_url', 'type' => 'url'),
array(
'key' => 'field_land_benefits',
'label' => 'Benefits',
'name' => 'landing_benefits',
'type' => 'repeater',
'max' => 4,
'layout' => 'block',
'button_label' => 'Add Benefit',
'sub_fields' => array(
array('key' => 'field_benefit_icon', 'label' => 'Icon', 'name' => 'benefit_icon', 'type' => 'select', 'choices' => array('check' => 'Check', 'star' => 'Star', 'shield' => 'Shield', 'home' => 'Home', 'dollar-sign' => 'Dollar', 'users' => 'Users', 'clock' => 'Clock', 'thumbs-up' => 'Thumbs Up')),
array('key' => 'field_benefit_title', 'label' => 'Title', 'name' => 'benefit_title', 'type' => 'text', 'required' => 1),
array('key' => 'field_benefit_desc', 'label' => 'Description', 'name' => 'benefit_description', 'type' => 'textarea', 'rows' => 2),
),
),
array('key' => 'field_land_testimonial_quote', 'label' => 'Testimonial Quote', 'name' => 'landing_testimonial_quote', 'type' => 'textarea', 'rows' => 3),
array('key' => 'field_land_testimonial_author', 'label' => 'Testimonial Author', 'name' => 'landing_testimonial_author', 'type' => 'text'),
array('key' => 'field_land_testimonial_title', 'label' => 'Author Title', 'name' => 'landing_testimonial_title', 'type' => 'text'),
array('key' => 'field_land_final_cta_title', 'label' => 'Final CTA Title', 'name' => 'landing_final_cta_title', 'type' => 'text'),
array('key' => 'field_land_final_cta_text', 'label' => 'Final CTA Text', 'name' => 'landing_final_cta_text', 'type' => 'textarea', 'rows' => 2),
array('key' => 'field_land_final_cta_btn_text', 'label' => 'Final CTA Button Text', 'name' => 'landing_final_cta_button_text', 'type' => 'text', 'default_value' => 'Contact Us Today'),
array('key' => 'field_land_final_cta_btn_url', 'label' => 'Final CTA Button URL', 'name' => 'landing_final_cta_button_url', 'type' => 'url'),
),
'location' => array(array(array('param' => 'page_template', 'operator' => '==', 'value' => 'page-templates/landing-page.php'))),
'menu_order' => 0,
'position' => 'normal',
'active' => true,
));
} }
add_action('acf/init', 'homeproz_register_acf_fields'); add_action('acf/init', 'homeproz_register_acf_fields');
@@ -698,13 +1292,23 @@ add_action('acf/init', 'homeproz_register_acf_options_page');
function homeproz_get_acf_option($key, $default = '') { function homeproz_get_acf_option($key, $default = '') {
// ACF field mapping // ACF field mapping
$field_map = array( $field_map = array(
// Contact Information
'phone' => 'theme_phone', 'phone' => 'theme_phone',
'email' => 'theme_email', 'email' => 'theme_email',
'address' => 'theme_address', 'address' => 'theme_address',
// Social Media
'facebook' => 'theme_facebook', 'facebook' => 'theme_facebook',
'tiktok' => 'theme_tiktok', 'tiktok' => 'theme_tiktok',
'instagram' => 'theme_instagram', 'instagram' => 'theme_instagram',
'youtube' => 'theme_youtube', 'youtube' => 'theme_youtube',
// Footer & Branding
'footer_tagline' => 'theme_footer_tagline',
'broker_info' => 'theme_broker_info',
'org_description' => 'theme_org_description',
// Location
'latitude' => 'theme_latitude',
'longitude' => 'theme_longitude',
'map_embed' => 'theme_map_embed',
); );
// If ACF is active and we have an options page // If ACF is active and we have an options page
@@ -722,7 +1326,30 @@ function homeproz_get_acf_option($key, $default = '') {
'address' => '111 E Clark St, Albert Lea, MN 56007', 'address' => '111 E Clark St, Albert Lea, MN 56007',
'facebook' => 'https://www.facebook.com/profile.php?id=61578834743321', 'facebook' => 'https://www.facebook.com/profile.php?id=61578834743321',
'tiktok' => 'https://www.tiktok.com/@homeproz.real.est', 'tiktok' => 'https://www.tiktok.com/@homeproz.real.est',
'footer_tagline' => 'Your trusted partner in Minnesota and Iowa real estate. Finding homes, building futures.',
'broker_info' => 'HomeProz Real Estate LLC DBA LandProz Real Estate, LLC',
'org_description' => 'Your trusted partner for buying and selling homes in Albert Lea, Minnesota and surrounding areas.',
'latitude' => '43.6477',
'longitude' => '-93.3683',
); );
return isset($defaults[$key]) ? $defaults[$key] : $default; return isset($defaults[$key]) ? $defaults[$key] : $default;
} }
/**
* Get office hours from ACF or return default
*/
function homeproz_get_office_hours() {
if (function_exists('get_field')) {
$hours = get_field('theme_office_hours', 'option');
if ($hours && is_array($hours)) {
return $hours;
}
}
// Fallback defaults
return array(
array('day' => 'Monday - Friday', 'time' => '9:00 AM - 5:00 PM'),
array('day' => 'Saturday - Sunday', 'time' => 'By Appointment'),
);
}
@@ -0,0 +1,83 @@
<?php
/**
* Template Name: Alternating Blocks
* Template for displaying pages with alternating image/text blocks (zigzag pattern)
*
* @package HomeProz
*/
if (!defined('ABSPATH')) {
exit;
}
get_header();
$hero_title = get_field('alt_hero_title') ?: get_the_title();
$hero_subtitle = get_field('alt_hero_subtitle');
$hero_bg = get_field('alt_hero_background');
$blocks = get_field('content_blocks');
?>
<main id="primary" class="site-main Alternating_Blocks">
<section class="archive-hero <?php echo $hero_bg ? 'has-background' : ''; ?>" <?php echo $hero_bg ? 'style="background-image: url(' . esc_url($hero_bg) . ');"' : ''; ?>>
<?php if ($hero_bg) : ?><div class="archive-hero-overlay"></div><?php endif; ?>
<div class="container">
<h1 class="archive-hero-title"><?php echo esc_html($hero_title); ?></h1>
<?php if ($hero_subtitle) : ?>
<p class="archive-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
<?php endif; ?>
</div>
</section>
<?php if ($blocks) : ?>
<section class="alternating-blocks-section">
<?php foreach ($blocks as $index => $block) :
$is_reversed = ($index % 2 === 1);
?>
<div class="alternating-block <?php echo $is_reversed ? 'alternating-block--reverse' : ''; ?>">
<div class="container">
<div class="alternating-block-inner">
<?php if (!empty($block['block_image'])) : ?>
<div class="alternating-block-image">
<img src="<?php echo esc_url($block['block_image']); ?>" alt="<?php echo esc_attr($block['block_title']); ?>">
</div>
<?php endif; ?>
<div class="alternating-block-content">
<?php if (!empty($block['block_title'])) : ?>
<h2 class="alternating-block-title"><?php echo esc_html($block['block_title']); ?></h2>
<?php endif; ?>
<?php if (!empty($block['block_content'])) : ?>
<div class="alternating-block-text"><?php echo wp_kses_post($block['block_content']); ?></div>
<?php endif; ?>
<?php if (!empty($block['block_button_text']) && !empty($block['block_button_url'])) : ?>
<a href="<?php echo esc_url($block['block_button_url']); ?>" class="btn btn-primary"><?php echo esc_html($block['block_button_text']); ?></a>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</section>
<?php endif; ?>
<?php
$cta_title = get_field('alt_cta_title');
$cta_text = get_field('alt_cta_text');
$cta_btn_text = get_field('alt_cta_button_text') ?: 'Contact Us';
$cta_btn_url = get_field('alt_cta_button_url') ?: home_url('/contact/');
if ($cta_title) :
get_template_part('template-parts/components/cta-section', null, array(
'title' => $cta_title,
'text' => $cta_text,
'button_text' => $cta_btn_text,
'button_url' => $cta_btn_url,
'style' => 'accent',
));
endif;
?>
</main>
<?php get_footer();
@@ -0,0 +1,98 @@
<?php
/**
* Template Name: Card Grid
* Template for displaying pages with a grid of cards
*
* @package HomeProz
*/
if (!defined('ABSPATH')) {
exit;
}
get_header();
$hero_title = get_field('hero_title') ?: get_the_title();
$hero_subtitle = get_field('hero_subtitle');
$hero_bg = get_field('hero_background');
$grid_title = get_field('grid_title');
$grid_subtitle = get_field('grid_subtitle');
$grid_intro = get_field('grid_intro');
$grid_columns = get_field('grid_columns') ?: '3';
$cards = get_field('grid_cards');
?>
<main id="primary" class="site-main Card_Grid">
<section class="archive-hero <?php echo $hero_bg ? 'has-background' : ''; ?>" <?php echo $hero_bg ? 'style="background-image: url(' . esc_url($hero_bg) . ');"' : ''; ?>>
<?php if ($hero_bg) : ?><div class="archive-hero-overlay"></div><?php endif; ?>
<div class="container">
<h1 class="archive-hero-title"><?php echo esc_html($hero_title); ?></h1>
<?php if ($hero_subtitle) : ?>
<p class="archive-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
<?php endif; ?>
</div>
</section>
<section class="card-grid-section">
<div class="container">
<?php if ($grid_title || $grid_subtitle) : ?>
<header class="section-header">
<?php if ($grid_title) : ?>
<h2 class="section-title"><?php echo esc_html($grid_title); ?></h2>
<?php endif; ?>
<?php if ($grid_subtitle) : ?>
<p class="section-subtitle"><?php echo esc_html($grid_subtitle); ?></p>
<?php endif; ?>
</header>
<?php endif; ?>
<?php if ($grid_intro) : ?>
<div class="card-grid-intro"><?php echo wp_kses_post($grid_intro); ?></div>
<?php endif; ?>
<?php if ($cards) : ?>
<div class="card-grid card-grid--<?php echo esc_attr($grid_columns); ?>col">
<?php foreach ($cards as $card) : ?>
<div class="grid-card">
<?php if (!empty($card['card_image'])) : ?>
<div class="grid-card-image">
<img src="<?php echo esc_url($card['card_image']); ?>" alt="<?php echo esc_attr($card['card_title']); ?>">
</div>
<?php endif; ?>
<div class="grid-card-content">
<?php if (!empty($card['card_title'])) : ?>
<h3 class="grid-card-title"><?php echo esc_html($card['card_title']); ?></h3>
<?php endif; ?>
<?php if (!empty($card['card_description'])) : ?>
<p class="grid-card-desc"><?php echo esc_html($card['card_description']); ?></p>
<?php endif; ?>
<?php if (!empty($card['card_link_text']) && !empty($card['card_link_url'])) : ?>
<a href="<?php echo esc_url($card['card_link_url']); ?>" class="grid-card-link"><?php echo esc_html($card['card_link_text']); ?> &rarr;</a>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</section>
<?php
$cta_title = get_field('grid_cta_title');
$cta_btn_text = get_field('grid_cta_button_text') ?: 'Contact Us';
$cta_btn_url = get_field('grid_cta_button_url') ?: home_url('/contact/');
if ($cta_title) :
get_template_part('template-parts/components/cta-section', null, array(
'title' => $cta_title,
'button_text' => $cta_btn_text,
'button_url' => $cta_btn_url,
'style' => 'accent',
));
endif;
?>
</main>
<?php get_footer();
@@ -0,0 +1,81 @@
<?php
/**
* Template Name: Content with Sidebar
* Template for displaying pages with main content and sidebar callout boxes
*
* @package HomeProz
*/
if (!defined('ABSPATH')) {
exit;
}
get_header();
$hero_title = get_field('hero_title') ?: get_the_title();
$hero_subtitle = get_field('hero_subtitle');
$hero_bg = get_field('hero_background');
?>
<main id="primary" class="site-main Content_Sidebar">
<section class="archive-hero <?php echo $hero_bg ? 'has-background' : ''; ?>" <?php echo $hero_bg ? 'style="background-image: url(' . esc_url($hero_bg) . ');"' : ''; ?>>
<?php if ($hero_bg) : ?><div class="archive-hero-overlay"></div><?php endif; ?>
<div class="container">
<h1 class="archive-hero-title"><?php echo esc_html($hero_title); ?></h1>
<?php if ($hero_subtitle) : ?>
<p class="archive-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
<?php endif; ?>
</div>
</section>
<section class="content-sidebar-section">
<div class="container">
<div class="content-sidebar-layout">
<div class="content-sidebar-main">
<?php while (have_posts()) : the_post(); the_content(); endwhile; ?>
</div>
<aside class="content-sidebar-aside">
<?php
$callouts = get_field('sidebar_callouts');
if ($callouts) :
foreach ($callouts as $callout) :
?>
<div class="sidebar-callout-box">
<?php if (!empty($callout['callout_title'])) : ?>
<h3 class="sidebar-callout-title"><?php echo esc_html($callout['callout_title']); ?></h3>
<?php endif; ?>
<?php if (!empty($callout['callout_content'])) : ?>
<div class="sidebar-callout-content"><?php echo wp_kses_post(wpautop($callout['callout_content'])); ?></div>
<?php endif; ?>
<?php if (!empty($callout['callout_button_text']) && !empty($callout['callout_button_url'])) : ?>
<a href="<?php echo esc_url($callout['callout_button_url']); ?>" class="btn btn-secondary"><?php echo esc_html($callout['callout_button_text']); ?></a>
<?php endif; ?>
</div>
<?php endforeach; endif; ?>
</aside>
</div>
</div>
</section>
<?php
$cta_title = get_field('page_cta_title') ?: 'Ready to Get Started?';
$cta_text = get_field('page_cta_text');
$cta_btn_text = get_field('page_cta_button_text') ?: 'Contact Us';
$cta_btn_url = get_field('page_cta_button_url') ?: home_url('/contact/');
if ($cta_title) :
get_template_part('template-parts/components/cta-section', null, array(
'title' => $cta_title,
'text' => $cta_text,
'button_text' => $cta_btn_text,
'button_url' => $cta_btn_url,
'style' => 'accent',
));
endif;
?>
</main>
<?php get_footer();
@@ -0,0 +1,110 @@
<?php
/**
* Template Name: Landing Page
* Conversion-focused template with big hero, benefits, testimonial, and CTAs
*
* @package HomeProz
*/
if (!defined('ABSPATH')) {
exit;
}
get_header();
$hero_title = get_field('landing_hero_title') ?: get_the_title();
$hero_subtitle = get_field('landing_hero_subtitle');
$hero_bg = get_field('landing_hero_background');
$hero_cta_text = get_field('landing_hero_cta_text') ?: 'Get Started';
$hero_cta_url = get_field('landing_hero_cta_url') ?: home_url('/contact/');
$benefits = get_field('landing_benefits');
$testimonial_quote = get_field('landing_testimonial_quote');
$testimonial_author = get_field('landing_testimonial_author');
$testimonial_title = get_field('landing_testimonial_title');
$icon_map = array(
'check' => '<polyline points="20 6 9 17 4 12"/>',
'star' => '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',
'shield' => '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>',
'home' => '<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
'dollar-sign' => '<line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>',
'users' => '<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
'clock' => '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
'thumbs-up' => '<path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/>',
);
?>
<main id="primary" class="site-main Landing_Page">
<section class="landing-hero <?php echo $hero_bg ? 'has-background' : ''; ?>" <?php echo $hero_bg ? 'style="background-image: url(' . esc_url($hero_bg) . ');"' : ''; ?>>
<?php if ($hero_bg) : ?><div class="landing-hero-overlay"></div><?php endif; ?>
<div class="container">
<div class="landing-hero-content">
<h1 class="landing-hero-title"><?php echo esc_html($hero_title); ?></h1>
<?php if ($hero_subtitle) : ?>
<p class="landing-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
<?php endif; ?>
<a href="<?php echo esc_url($hero_cta_url); ?>" class="btn btn-primary btn-lg landing-hero-cta"><?php echo esc_html($hero_cta_text); ?></a>
</div>
</div>
</section>
<?php if ($benefits) : ?>
<section class="landing-benefits-section">
<div class="container">
<div class="landing-benefits-grid">
<?php foreach ($benefits as $benefit) :
$icon_key = $benefit['benefit_icon'] ?? 'check';
$icon_path = $icon_map[$icon_key] ?? $icon_map['check'];
?>
<div class="landing-benefit">
<div class="landing-benefit-icon">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><?php echo $icon_path; ?></svg>
</div>
<h3 class="landing-benefit-title"><?php echo esc_html($benefit['benefit_title']); ?></h3>
<p class="landing-benefit-desc"><?php echo esc_html($benefit['benefit_description']); ?></p>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php if ($testimonial_quote) : ?>
<section class="landing-testimonial-section">
<div class="container">
<blockquote class="landing-testimonial">
<p class="landing-testimonial-quote">&ldquo;<?php echo esc_html($testimonial_quote); ?>&rdquo;</p>
<?php if ($testimonial_author) : ?>
<footer class="landing-testimonial-footer">
<cite class="landing-testimonial-author"><?php echo esc_html($testimonial_author); ?></cite>
<?php if ($testimonial_title) : ?>
<span class="landing-testimonial-title"><?php echo esc_html($testimonial_title); ?></span>
<?php endif; ?>
</footer>
<?php endif; ?>
</blockquote>
</div>
</section>
<?php endif; ?>
<?php
$final_cta_title = get_field('landing_final_cta_title');
$final_cta_text = get_field('landing_final_cta_text');
$final_cta_btn_text = get_field('landing_final_cta_button_text') ?: 'Contact Us Today';
$final_cta_btn_url = get_field('landing_final_cta_button_url') ?: home_url('/contact/');
if ($final_cta_title) :
get_template_part('template-parts/components/cta-section', null, array(
'title' => $final_cta_title,
'text' => $final_cta_text,
'button_text' => $final_cta_btn_text,
'button_url' => $final_cta_btn_url,
'style' => 'accent',
));
endif;
?>
</main>
<?php get_footer();
@@ -0,0 +1,61 @@
<?php
/**
* Template Name: Long-Form Article
* Template for clean, readable long-form content pages
*
* @package HomeProz
*/
if (!defined('ABSPATH')) {
exit;
}
get_header();
$show_breadcrumbs = get_field('show_breadcrumbs');
$article_subtitle = get_field('article_subtitle');
$related_links = get_field('related_links');
?>
<main id="primary" class="site-main Long_Form_Article">
<?php if ($show_breadcrumbs) : ?>
<nav class="article-breadcrumbs" aria-label="Breadcrumb">
<div class="container">
<ol class="breadcrumb-list">
<li class="breadcrumb-item"><a href="<?php echo esc_url(home_url('/')); ?>">Home</a></li>
<li class="breadcrumb-item breadcrumb-current" aria-current="page"><?php the_title(); ?></li>
</ol>
</div>
</nav>
<?php endif; ?>
<article class="article-content-wrapper">
<div class="container">
<header class="article-header">
<h1 class="article-title"><?php the_title(); ?></h1>
<?php if ($article_subtitle) : ?>
<p class="article-subtitle"><?php echo esc_html($article_subtitle); ?></p>
<?php endif; ?>
</header>
<div class="article-body">
<?php while (have_posts()) : the_post(); the_content(); endwhile; ?>
</div>
<?php if ($related_links) : ?>
<aside class="article-related">
<h2 class="article-related-heading">Related Resources</h2>
<ul class="article-related-list">
<?php foreach ($related_links as $link) : ?>
<li><a href="<?php echo esc_url($link['link_url']); ?>"><?php echo esc_html($link['link_title']); ?></a></li>
<?php endforeach; ?>
</ul>
</aside>
<?php endif; ?>
</div>
</article>
</main>
<?php get_footer();
@@ -0,0 +1,585 @@
// ===========================================
// PAGE TEMPLATES STYLES
// ===========================================
// -----------------------------
// 1. Content with Sidebar
// -----------------------------
.Content_Sidebar {
.content-sidebar-section {
padding: 4rem 0;
}
.content-sidebar-layout {
display: grid;
grid-template-columns: 1fr;
gap: 3rem;
@media (min-width: 992px) {
grid-template-columns: 7fr 3fr;
}
}
.content-sidebar-main {
h2, h3, h4 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
}
p {
margin-bottom: 1rem;
line-height: 1.7;
}
ul, ol {
margin-bottom: 1rem;
padding-left: 1.5rem;
}
}
.content-sidebar-aside {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.sidebar-callout-box {
background: var(--color-surface, #1a1a1a);
border: 1px solid var(--color-border, #333);
border-radius: 8px;
padding: 1.5rem;
.sidebar-callout-title {
font-size: 1.125rem;
margin-bottom: 0.75rem;
color: var(--color-accent, #c45c26);
}
.sidebar-callout-content {
font-size: 0.9375rem;
color: var(--color-text-muted, #aaa);
margin-bottom: 1rem;
p:last-child {
margin-bottom: 0;
}
}
}
}
// -----------------------------
// 2. Alternating Blocks
// -----------------------------
.Alternating_Blocks {
.alternating-blocks-section {
padding: 2rem 0;
}
.alternating-block {
padding: 3rem 0;
&:nth-child(even) {
background: var(--color-surface, #1a1a1a);
}
}
.alternating-block-inner {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
align-items: center;
@media (min-width: 768px) {
grid-template-columns: 1fr 1fr;
gap: 4rem;
}
}
.alternating-block--reverse {
.alternating-block-inner {
@media (min-width: 768px) {
direction: rtl;
> * {
direction: ltr;
}
}
}
}
.alternating-block-image {
img {
width: 100%;
height: auto;
border-radius: 8px;
}
}
.alternating-block-title {
font-size: 1.75rem;
margin-bottom: 1rem;
}
.alternating-block-text {
color: var(--color-text-muted, #aaa);
margin-bottom: 1.5rem;
p {
margin-bottom: 1rem;
}
}
}
// -----------------------------
// 3. Service Detail
// -----------------------------
.Service_Detail {
.service-intro-section {
padding: 3rem 0;
max-width: 800px;
margin: 0 auto;
.service-intro-content {
font-size: 1.125rem;
line-height: 1.8;
}
}
.service-features-section {
padding: 3rem 0;
background: var(--color-surface, #1a1a1a);
}
.service-features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
}
.service-feature-card {
background: var(--color-bg, #0a0a0a);
border: 1px solid var(--color-border, #333);
border-radius: 8px;
padding: 2rem;
text-align: center;
}
.service-feature-icon {
color: var(--color-accent, #c45c26);
margin-bottom: 1rem;
}
.service-feature-title {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.service-feature-desc {
color: var(--color-text-muted, #aaa);
font-size: 0.9375rem;
}
.service-faq-section {
padding: 4rem 0;
max-width: 800px;
margin: 0 auto;
}
.service-faq-heading {
font-size: 2rem;
margin-bottom: 2rem;
text-align: center;
}
.service-faq-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.service-faq-item {
background: var(--color-surface, #1a1a1a);
border: 1px solid var(--color-border, #333);
border-radius: 8px;
overflow: hidden;
&[open] {
.service-faq-question::after {
transform: rotate(180deg);
}
}
}
.service-faq-question {
padding: 1.25rem 1.5rem;
font-weight: 600;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
list-style: none;
&::-webkit-details-marker {
display: none;
}
&::after {
content: '';
border: solid var(--color-accent, #c45c26);
border-width: 0 2px 2px 0;
padding: 4px;
transform: rotate(45deg);
transition: transform 0.2s;
}
}
.service-faq-answer {
padding: 0 1.5rem 1.25rem;
color: var(--color-text-muted, #aaa);
}
}
// -----------------------------
// 4. Card Grid
// -----------------------------
.Card_Grid {
.card-grid-section {
padding: 4rem 0;
}
.card-grid-intro {
max-width: 800px;
margin: 0 auto 3rem;
text-align: center;
}
.card-grid {
display: grid;
gap: 2rem;
&.card-grid--2col {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
@media (min-width: 768px) {
grid-template-columns: repeat(2, 1fr);
}
}
&.card-grid--3col {
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
@media (min-width: 992px) {
grid-template-columns: repeat(3, 1fr);
}
}
&.card-grid--4col {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
@media (min-width: 1200px) {
grid-template-columns: repeat(4, 1fr);
}
}
}
.grid-card {
background: var(--color-surface, #1a1a1a);
border: 1px solid var(--color-border, #333);
border-radius: 8px;
overflow: hidden;
transition: transform 0.2s, box-shadow 0.2s;
&:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
}
.grid-card-image {
aspect-ratio: 16 / 10;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.grid-card-content {
padding: 1.5rem;
}
.grid-card-title {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.grid-card-desc {
color: var(--color-text-muted, #aaa);
font-size: 0.9375rem;
margin-bottom: 1rem;
}
.grid-card-link {
color: var(--color-accent, #c45c26);
font-weight: 500;
&:hover {
text-decoration: underline;
}
}
}
// -----------------------------
// 5. Long-Form Article
// -----------------------------
.Long_Form_Article {
.article-breadcrumbs {
padding: 1rem 0;
background: var(--color-surface, #1a1a1a);
border-bottom: 1px solid var(--color-border, #333);
}
.breadcrumb-list {
display: flex;
align-items: center;
gap: 0.5rem;
list-style: none;
padding: 0;
margin: 0;
font-size: 0.875rem;
li:not(:last-child)::after {
content: '/';
margin-left: 0.5rem;
color: var(--color-text-muted, #666);
}
a {
color: var(--color-text-muted, #aaa);
&:hover {
color: var(--color-accent, #c45c26);
}
}
}
.breadcrumb-current {
color: var(--color-text, #fff);
}
.article-content-wrapper {
padding: 4rem 0;
}
.article-header {
max-width: 800px;
margin: 0 auto 3rem;
text-align: center;
}
.article-title {
font-size: 2.5rem;
margin-bottom: 1rem;
@media (min-width: 768px) {
font-size: 3rem;
}
}
.article-subtitle {
font-size: 1.25rem;
color: var(--color-text-muted, #aaa);
}
.article-body {
max-width: 800px;
margin: 0 auto;
font-size: 1.0625rem;
line-height: 1.8;
h2 {
font-size: 1.75rem;
margin: 2.5rem 0 1rem;
}
h3 {
font-size: 1.375rem;
margin: 2rem 0 0.75rem;
}
p {
margin-bottom: 1.25rem;
}
ul, ol {
margin-bottom: 1.25rem;
padding-left: 1.5rem;
}
li {
margin-bottom: 0.5rem;
}
blockquote {
border-left: 4px solid var(--color-accent, #c45c26);
padding-left: 1.5rem;
margin: 2rem 0;
font-style: italic;
color: var(--color-text-muted, #aaa);
}
}
.article-related {
max-width: 800px;
margin: 3rem auto 0;
padding-top: 2rem;
border-top: 1px solid var(--color-border, #333);
}
.article-related-heading {
font-size: 1.25rem;
margin-bottom: 1rem;
}
.article-related-list {
list-style: none;
padding: 0;
li {
margin-bottom: 0.5rem;
}
a {
color: var(--color-accent, #c45c26);
&:hover {
text-decoration: underline;
}
}
}
}
// -----------------------------
// 6. Landing Page
// -----------------------------
.Landing_Page {
.landing-hero {
min-height: 60vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
position: relative;
background-size: cover;
background-position: center;
background-color: var(--color-surface, #1a1a1a);
&.has-background {
color: #fff;
}
}
.landing-hero-overlay {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.6);
}
.landing-hero-content {
position: relative;
z-index: 1;
max-width: 800px;
padding: 3rem 1rem;
}
.landing-hero-title {
font-size: 2.5rem;
margin-bottom: 1rem;
@media (min-width: 768px) {
font-size: 3.5rem;
}
}
.landing-hero-subtitle {
font-size: 1.25rem;
margin-bottom: 2rem;
opacity: 0.9;
}
.landing-hero-cta {
font-size: 1.125rem;
padding: 1rem 2.5rem;
}
.landing-benefits-section {
padding: 4rem 0;
background: var(--color-bg, #0a0a0a);
}
.landing-benefits-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 2rem;
text-align: center;
}
.landing-benefit {
padding: 1.5rem;
}
.landing-benefit-icon {
color: var(--color-accent, #c45c26);
margin-bottom: 1rem;
}
.landing-benefit-title {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.landing-benefit-desc {
color: var(--color-text-muted, #aaa);
font-size: 0.9375rem;
}
.landing-testimonial-section {
padding: 4rem 0;
background: var(--color-surface, #1a1a1a);
}
.landing-testimonial {
max-width: 800px;
margin: 0 auto;
text-align: center;
}
.landing-testimonial-quote {
font-size: 1.5rem;
font-style: italic;
line-height: 1.6;
margin-bottom: 1.5rem;
@media (min-width: 768px) {
font-size: 1.75rem;
}
}
.landing-testimonial-footer {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.landing-testimonial-author {
font-weight: 600;
font-style: normal;
}
.landing-testimonial-title {
color: var(--color-text-muted, #aaa);
font-size: 0.875rem;
}
}
@@ -0,0 +1,110 @@
<?php
/**
* Template Name: Service Detail
* Template for service/product pages with intro, feature cards, and FAQ
*
* @package HomeProz
*/
if (!defined('ABSPATH')) {
exit;
}
get_header();
$hero_title = get_field('service_hero_title') ?: get_the_title();
$hero_subtitle = get_field('service_hero_subtitle');
$hero_bg = get_field('service_hero_background');
$intro = get_field('service_intro');
$features = get_field('service_features');
$faqs = get_field('service_faq');
$icon_map = array(
'home' => '<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
'dollar-sign' => '<line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>',
'users' => '<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
'check' => '<polyline points="20 6 9 17 4 12"/>',
'star' => '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',
'shield' => '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>',
'map-pin' => '<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>',
'key' => '<path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/>',
'building' => '<rect x="4" y="2" width="16" height="20" rx="2" ry="2"/><path d="M9 22v-4h6v4"/><path d="M8 6h.01"/><path d="M16 6h.01"/><path d="M12 6h.01"/><path d="M12 10h.01"/><path d="M12 14h.01"/><path d="M16 10h.01"/><path d="M16 14h.01"/><path d="M8 10h.01"/><path d="M8 14h.01"/>',
'search' => '<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>',
);
?>
<main id="primary" class="site-main Service_Detail">
<section class="archive-hero <?php echo $hero_bg ? 'has-background' : ''; ?>" <?php echo $hero_bg ? 'style="background-image: url(' . esc_url($hero_bg) . ');"' : ''; ?>>
<?php if ($hero_bg) : ?><div class="archive-hero-overlay"></div><?php endif; ?>
<div class="container">
<h1 class="archive-hero-title"><?php echo esc_html($hero_title); ?></h1>
<?php if ($hero_subtitle) : ?>
<p class="archive-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
<?php endif; ?>
</div>
</section>
<?php if ($intro) : ?>
<section class="service-intro-section">
<div class="container">
<div class="service-intro-content"><?php echo wp_kses_post($intro); ?></div>
</div>
</section>
<?php endif; ?>
<?php if ($features) : ?>
<section class="service-features-section">
<div class="container">
<div class="service-features-grid">
<?php foreach ($features as $feature) :
$icon_key = $feature['feature_icon'] ?? 'check';
$icon_path = $icon_map[$icon_key] ?? $icon_map['check'];
?>
<div class="service-feature-card">
<div class="service-feature-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><?php echo $icon_path; ?></svg>
</div>
<h3 class="service-feature-title"><?php echo esc_html($feature['feature_title']); ?></h3>
<p class="service-feature-desc"><?php echo esc_html($feature['feature_description']); ?></p>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php if ($faqs) : ?>
<section class="service-faq-section">
<div class="container">
<h2 class="service-faq-heading">Frequently Asked Questions</h2>
<div class="service-faq-list">
<?php foreach ($faqs as $faq) : ?>
<details class="service-faq-item">
<summary class="service-faq-question"><?php echo esc_html($faq['faq_question']); ?></summary>
<div class="service-faq-answer"><?php echo wp_kses_post($faq['faq_answer']); ?></div>
</details>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endif; ?>
<?php
$cta_title = get_field('service_cta_title');
$cta_btn_text = get_field('service_cta_button_text') ?: 'Contact Us';
$cta_btn_url = get_field('service_cta_button_url') ?: home_url('/contact/');
if ($cta_title) :
get_template_part('template-parts/components/cta-section', null, array(
'title' => $cta_title,
'button_text' => $cta_btn_text,
'button_url' => $cta_btn_url,
'style' => 'accent',
));
endif;
?>
</main>
<?php get_footer();
+3
View File
@@ -40,6 +40,9 @@
@import '../template-parts/components/service-cards.scss'; @import '../template-parts/components/service-cards.scss';
@import '../template-parts/components/property-type-boxes.scss'; @import '../template-parts/components/property-type-boxes.scss';
// Import page templates
@import '../page-templates/page-templates.scss';
// ============================================ // ============================================
// CSS Custom Properties (Design Tokens) // CSS Custom Properties (Design Tokens)
// ============================================ // ============================================