60, 'width' => 200, 'flex-height' => true, 'flex-width' => true, ] ); register_nav_menus( [ 'primary' => __( 'Primary Menu', 'ots-signs' ), 'footer' => __( 'Footer Menu', 'ots-signs' ), ] ); } add_action( 'after_setup_theme', 'ots_setup' ); // ─── Fallback Menu ──────────────────────────────────────────────────────────── if ( ! function_exists( 'ots_fallback_menu' ) ) { function ots_fallback_menu() { echo ''; } } // ─── Enqueue Assets ─────────────────────────────────────────────────────────── function ots_enqueue_assets() { // Google Fonts wp_enqueue_style( 'ots-fonts', 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap', [], null ); // Main stylesheet — use filemtime for cache-busting during development wp_enqueue_style( 'ots-main', OTS_THEME_URI . '/assets/css/main.css', [ 'ots-fonts' ], filemtime( OTS_THEME_DIR . '/assets/css/main.css' ) ); // Main JS — use filemtime for cache-busting during development wp_enqueue_script( 'ots-main', OTS_THEME_URI . '/assets/js/main.js', [], filemtime( OTS_THEME_DIR . '/assets/js/main.js' ), true ); // Pass ajaxurl and nonce to JS wp_localize_script( 'ots-main', 'otsAjax', [ 'url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'ots_contact_nonce' ), ] ); } add_action( 'wp_enqueue_scripts', 'ots_enqueue_assets' ); // ─── Constrain Custom Logo Output ───────────────────────────────────────── /** * Force the custom logo image to have inline size constraints and use a * smaller image size so the browser never paints the full-resolution upload. */ add_filter( 'get_custom_logo', 'ots_constrain_custom_logo' ); function ots_constrain_custom_logo( $html ) { if ( empty( $html ) ) { return $html; } // Swap the full-size src for the 'medium' version (much smaller file) $custom_logo_id = get_theme_mod( 'custom_logo' ); if ( $custom_logo_id ) { $medium = wp_get_attachment_image_url( $custom_logo_id, 'medium' ); $full = wp_get_attachment_image_url( $custom_logo_id, 'full' ); if ( $medium && $full && $medium !== $full ) { $html = str_replace( esc_url( $full ), esc_url( $medium ), $html ); } } // Inject inline max-height directly on the tag $html = preg_replace( '/ 'Please fill in all required fields.' ] ); } if ( ! is_email( $email ) ) { wp_send_json_error( [ 'message' => 'Please enter a valid email address.' ] ); } $to = get_option( 'admin_email' ); $subject = 'New Contact Form Submission from ' . $name; $body = "Name: {$name}\n"; $body .= "Email: {$email}\n"; if ( $phone ) $body .= "Phone: {$phone}\n"; if ( $company ) $body .= "Company: {$company}\n"; $body .= "\nMessage:\n{$message}"; $headers = [ 'Content-Type: text/plain; charset=UTF-8', 'Reply-To: ' . $name . ' <' . $email . '>', ]; $sent = wp_mail( $to, $subject, $body, $headers ); if ( $sent ) { wp_send_json_success( [ 'message' => 'Thanks! We\'ll be in touch shortly.' ] ); } else { wp_send_json_error( [ 'message' => 'Sorry, there was a problem sending your message. Please try again.' ] ); } } add_action( 'wp_ajax_ots_contact', 'ots_handle_contact' ); add_action( 'wp_ajax_nopriv_ots_contact', 'ots_handle_contact' ); // ─── Custom Page Templates ───────────────────────────────────────────────── function ots_body_classes( $classes ) { $classes[] = 'ots-theme'; return $classes; } add_filter( 'body_class', 'ots_body_classes' ); // ─── Excerpt length ──────────────────────────────────────────────────────── function ots_excerpt_length( $length ) { return 25; } add_filter( 'excerpt_length', 'ots_excerpt_length' ); // ─── Meta Boxes ──────────────────────────────────────────────────────────── /** * Each page template gets its own meta box with the key * marketing copy fields. All fields fall back to sensible * defaults so the site works without any editing. */ add_action( 'add_meta_boxes', 'ots_register_meta_boxes' ); function ots_register_meta_boxes() { $screens = [ 'page' ]; add_meta_box( 'ots_page_hero', 'Page Hero Content', 'ots_render_hero_meta_box', $screens, 'normal', 'high' ); } function ots_render_hero_meta_box( $post ) { wp_nonce_field( 'ots_save_meta', 'ots_meta_nonce' ); $template = get_page_template_slug( $post->ID ); $fields = ots_get_meta_fields_for_template( $template ); if ( empty( $fields ) ) { echo '

No editable fields for this page template.

'; return; } echo ''; echo ''; foreach ( $fields as $field ) { if ( $field['type'] === 'section' ) { echo ''; continue; } $value = get_post_meta( $post->ID, $field['key'], true ); if ( $value === '' ) $value = $field['default'] ?? ''; echo ''; echo ''; echo ''; } echo '
' . esc_html( $field['label'] ) . '
'; if ( $field['type'] === 'textarea' ) { echo ''; } else { echo ''; } if ( ! empty( $field['hint'] ) ) { echo '
' . esc_html( $field['hint'] ) . '
'; } echo '
'; echo '

Fields left blank will use the default content shown above as placeholder text.

'; } function ots_get_meta_fields_for_template( $template ) { $templates = [ 'page-home.php' => [ [ 'type' => 'section', 'label' => 'Hero Section' ], [ 'key' => 'hero_title', 'label' => 'Hero Title', 'type' => 'textarea', 'default' => 'Turn any screen into a dynamic communication tool for your business.', 'hint' => 'Wrap a keyword in to colour it teal.' ], [ 'key' => 'hero_description', 'label' => 'Hero Description', 'type' => 'textarea', 'default' => 'The complete package for engaging digital signage. From eye-catching retail displays to dynamic informational screens, we craft tailored solutions that capture attention and deliver your message.' ], [ 'key' => 'hero_cta_primary_label', 'label' => 'Primary CTA Label', 'type' => 'text', 'default' => 'Get in Touch' ], [ 'key' => 'hero_cta_secondary_label', 'label' => 'Secondary CTA Label', 'type' => 'text', 'default' => 'View Demo' ], [ 'type' => 'section', 'label' => 'Hero Stats' ], [ 'key' => 'stat_1_value', 'label' => 'Stat 1 Value', 'type' => 'text', 'default' => '500+' ], [ 'key' => 'stat_1_label', 'label' => 'Stat 1 Label', 'type' => 'text', 'default' => 'Screens Managed' ], [ 'key' => 'stat_2_value', 'label' => 'Stat 2 Value', 'type' => 'text', 'default' => '6' ], [ 'key' => 'stat_2_label', 'label' => 'Stat 2 Label', 'type' => 'text', 'default' => 'Industry Verticals' ], [ 'key' => 'stat_3_value', 'label' => 'Stat 3 Value', 'type' => 'text', 'default' => '99.9%' ], [ 'key' => 'stat_3_label', 'label' => 'Stat 3 Label', 'type' => 'text', 'default' => 'Uptime SLA' ], [ 'type' => 'section', 'label' => 'Features Section' ], [ 'key' => 'features_heading', 'label' => 'Features Heading', 'type' => 'text', 'default' => 'Everything You Need for Engaging Digital Signage' ], [ 'key' => 'features_subheading', 'label' => 'Features Subheading', 'type' => 'textarea', 'default' => 'We provide a complete, end-to-end digital signage solution — from hardware to content management to live data integrations.' ], [ 'type' => 'section', 'label' => 'Industries Section' ], [ 'key' => 'industries_heading', 'label' => 'Industries Heading', 'type' => 'text', 'default' => 'Our Services Empower Your Brand' ], [ 'key' => 'industries_subheading', 'label' => 'Industries Subheading', 'type' => 'textarea', 'default' => 'Modern businesses need real-time communication. Digital signage helps you connect with your audience where it matters most.' ], [ 'type' => 'section', 'label' => 'Pricing Section' ], [ 'key' => 'pricing_heading', 'label' => 'Pricing Heading', 'type' => 'text', 'default' => 'Affordable Solutions, Scalable Options' ], [ 'key' => 'pricing_subheading', 'label' => 'Pricing Subheading', 'type' => 'textarea', 'default' => 'All plans include content scheduling/day-parting, live data integrations, unlimited user seats, and the ability to publish content to your signs in minutes.' ], [ 'type' => 'section', 'label' => 'CTA Banner' ], [ 'key' => 'cta_heading', 'label' => 'CTA Heading', 'type' => 'text', 'default' => 'Ready to Transform Your Screens?' ], [ 'key' => 'cta_description', 'label' => 'CTA Description', 'type' => 'textarea', 'default' => 'Get in touch today and discover how OTS Signs can revolutionize the way you communicate with your audience.' ], ], 'page-about.php' => [ [ 'type' => 'section', 'label' => 'Page Hero' ], [ 'key' => 'hero_title', 'label' => 'Page Title', 'type' => 'text', 'default' => 'The Complete Digital Signage Solution' ], [ 'key' => 'hero_description', 'label' => 'Page Subtitle', 'type' => 'textarea', 'default' => 'We help businesses of all sizes connect with their audiences through powerful, easy-to-manage digital signage.' ], [ 'type' => 'section', 'label' => 'Who We Are Section' ], [ 'key' => 'about_heading', 'label' => 'Section Heading', 'type' => 'text', 'default' => 'Bringing Your Message to Life on Every Screen' ], [ 'key' => 'about_intro', 'label' => 'Intro Paragraph', 'type' => 'textarea', 'default' => 'OTS Signs is a digital signage company dedicated to transforming how businesses communicate with their audiences. We offer a complete, end-to-end solution — from the hardware players to our cloud management platform to custom content creation.' ], [ 'key' => 'about_body', 'label' => 'Body Paragraph', 'type' => 'textarea', 'default' => 'Digital signage is the modern way to connect with your audience, transforming any screen into a way to communicate and engage. Whether you need an eye-catching retail display, a dynamic menu board, or enterprise-grade live data dashboards, we deliver solutions that capture attention and get results.' ], [ 'type' => 'section', 'label' => 'CTA Banner' ], [ 'key' => 'cta_heading', 'label' => 'CTA Heading', 'type' => 'text', 'default' => "Let's Build Something Great Together" ], [ 'key' => 'cta_description', 'label' => 'CTA Description', 'type' => 'textarea', 'default' => 'Ready to see what OTS Signs can do for your business? Get in touch or explore our demo platform.' ], ], 'page-services.php' => [ [ 'type' => 'section', 'label' => 'Page Hero' ], [ 'key' => 'hero_title', 'label' => 'Page Title', 'type' => 'text', 'default' => 'Services & Solutions' ], [ 'key' => 'hero_description', 'label' => 'Page Subtitle', 'type' => 'textarea', 'default' => 'From content creation to cloud management to live data integrations — we deliver everything you need for a complete digital signage deployment.' ], [ 'type' => 'section', 'label' => 'Core Services Section' ], [ 'key' => 'services_heading', 'label' => 'Section Heading', 'type' => 'text', 'default' => 'The Complete Package for Engaging Digital Signage' ], [ 'key' => 'services_subheading', 'label' => 'Section Subheading', 'type' => 'textarea', 'default' => 'Every service we offer is designed to make your digital signage as impactful, reliable, and easy to manage as possible.' ], [ 'type' => 'section', 'label' => 'Pricing Section' ], [ 'key' => 'pricing_heading', 'label' => 'Pricing Heading', 'type' => 'text', 'default' => 'Affordable Solutions, Scalable Options' ], [ 'key' => 'pricing_subheading', 'label' => 'Pricing Subheading', 'type' => 'textarea', 'default' => 'Simple, transparent pricing with no hidden fees. Choose the plan that fits your business size.' ], [ 'type' => 'section', 'label' => 'CTA Banner' ], [ 'key' => 'cta_heading', 'label' => 'CTA Heading', 'type' => 'text', 'default' => 'Want to See How Our Platform Works?' ], [ 'key' => 'cta_description', 'label' => 'CTA Description', 'type' => 'textarea', 'default' => 'Request access to our demo instance and explore the OTS Signs platform hands-on.' ], ], 'page-contact.php' => [ [ 'type' => 'section', 'label' => 'Page Hero' ], [ 'key' => 'hero_title', 'label' => 'Page Title', 'type' => 'text', 'default' => 'Get in Touch' ], [ 'key' => 'hero_description', 'label' => 'Page Subtitle', 'type' => 'textarea', 'default' => "Ready to transform your screens? We'd love to hear about your project. Drop us a message and we'll get back to you promptly." ], [ 'type' => 'section', 'label' => 'Contact Info' ], [ 'key' => 'contact_heading', 'label' => 'Section Heading', 'type' => 'text', 'default' => "Let's Start the Conversation" ], [ 'key' => 'contact_subheading', 'label' => 'Section Subheading', 'type' => 'textarea', 'default' => "Whether you're looking for a quote, want to see a demo, or just have questions — we're here to help." ], [ 'key' => 'contact_email', 'label' => 'Contact Email', 'type' => 'text', 'default' => 'info@ots-signs.com' ], [ 'type' => 'section', 'label' => 'Demo CTA Section' ], [ 'key' => 'demo_heading', 'label' => 'Demo Heading', 'type' => 'text', 'default' => 'Explore Our Demo Platform' ], [ 'key' => 'demo_description', 'label' => 'Demo Description', 'type' => 'textarea', 'default' => 'See the OTS Signs CMS in action. Request access to our live demo instance and experience the platform for yourself before making any commitment.' ], ], ]; return $templates[ $template ] ?? []; } // Save meta fields add_action( 'save_post_page', 'ots_save_meta_fields' ); function ots_save_meta_fields( $post_id ) { if ( ! isset( $_POST['ots_meta_nonce'] ) ) return; if ( ! wp_verify_nonce( $_POST['ots_meta_nonce'], 'ots_save_meta' ) ) return; if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( ! current_user_can( 'edit_page', $post_id ) ) return; if ( ! isset( $_POST['ots_meta'] ) || ! is_array( $_POST['ots_meta'] ) ) return; foreach ( $_POST['ots_meta'] as $key => $value ) { $key = sanitize_key( $key ); // Allow basic HTML (spans, br, strong, em) for rich text fields $allowed = array_merge( wp_kses_allowed_html( 'post' ), [] ); update_post_meta( $post_id, $key, wp_kses_post( $value ) ); } } /** * Helper: get a meta value with a default fallback. */ function ots_meta( $post_id, $key, $default = '' ) { $value = get_post_meta( $post_id, $key, true ); return ( $value !== '' && $value !== false ) ? $value : $default; }