Files
repa-woocommerce/theme/functions.php
FrontendDev de8d1b8bef Fix products, search, and newsletter form per REPA-17
- Search: replace static <a href="/?s="> with togglable search overlay
  form that submits post_type=product for proper WooCommerce results
- Newsletter: remove mc4wp shortcode (plugin not installed), replace
  with self-contained HTML form + JS confirmation handler
- Shop by Design: link each design card to real product_tag pages
  (passive-aggressive, email-signatures, meeting-recovery, etc.)
  and show live tag.count instead of hardcoded numbers
- Category slugs: update $cat_meta mapping to match actual WC slugs
  (drinkware, wall-decor, stationery, apparel, stickers, accessories)
  in both front-page.php and archive-product.php
- Footer dept links updated to real WC category slugs

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-02 21:25:45 -04:00

336 lines
17 KiB
PHP

<?php
/**
* RAR Storefront — Theme functions
* Reply All Regrets™ WooCommerce theme
*/
defined('ABSPATH') || exit;
// ─── Theme Setup ────────────────────────────────────────────────────────────
function rar_setup() {
add_theme_support('title-tag');
add_theme_support('post-thumbnails');
add_theme_support('html5', ['search-form','comment-form','comment-list','gallery','caption','style','script']);
add_theme_support('woocommerce');
add_theme_support('wc-product-gallery-zoom');
add_theme_support('wc-product-gallery-lightbox');
add_theme_support('wc-product-gallery-slider');
add_theme_support('custom-logo');
add_theme_support('automatic-feed-links');
add_theme_support('align-wide');
register_nav_menus([
'primary' => __('Primary Navigation', 'rar-storefront'),
'footer' => __('Footer Navigation', 'rar-storefront'),
]);
}
add_action('after_setup_theme', 'rar_setup');
// ─── Enqueue Assets ─────────────────────────────────────────────────────────
function rar_enqueue_assets() {
// Google Fonts
wp_enqueue_style(
'rar-fonts',
'https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,600;1,9..144,400;1,9..144,500&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;600&display=swap',
[],
null
);
// Theme stylesheet
wp_enqueue_style('rar-style', get_stylesheet_uri(), ['rar-fonts'], '1.0.0');
// Theme JS
wp_enqueue_script('rar-main', get_template_directory_uri() . '/js/rar.js', [], '1.0.0', true);
// Pass data to JS
wp_localize_script('rar-main', 'rarData', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('rar-nonce'),
'cartUrl' => wc_get_cart_url(),
'shopUrl' => get_permalink(wc_get_page_id('shop')),
]);
}
add_action('wp_enqueue_scripts', 'rar_enqueue_assets');
// ─── Remove default WC styles we override ───────────────────────────────────
add_filter('woocommerce_enqueue_styles', function($styles) {
// Keep WooCommerce core but remove some defaults we fully override
return $styles;
});
// ─── Widget Areas ────────────────────────────────────────────────────────────
function rar_register_sidebars() {
register_sidebar([
'name' => 'Shop Filter Sidebar',
'id' => 'shop-filter',
'before_widget' => '<div class="rar-filter-widget">',
'after_widget' => '</div>',
'before_title' => '<h4 class="rar-filter-widget__title">',
'after_title' => '</h4>',
]);
}
add_action('widgets_init', 'rar_register_sidebars');
// ─── WooCommerce: remove default wrappers ───────────────────────────────────
remove_action('woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10);
remove_action('woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10);
add_action('woocommerce_before_main_content', function() {
echo '<div class="rar-wc-wrap">';
});
add_action('woocommerce_after_main_content', function() {
echo '</div>';
});
// ─── Remove WC breadcrumb (we build our own) ────────────────────────────────
remove_action('woocommerce_before_main_content', 'woocommerce_breadcrumb', 20);
// ─── Product loop: 3 columns ────────────────────────────────────────────────
add_filter('loop_shop_columns', fn() => 3);
add_filter('loop_shop_per_page', fn() => 12, 20);
// ─── Custom product loop template ───────────────────────────────────────────
add_filter('woocommerce_product_loop_start', function($html) {
return '<ul class="rar-product-grid products">';
});
add_filter('woocommerce_product_loop_end', function($html) {
return '</ul>';
});
// ─── Helper: announcement bar ───────────────────────────────────────────────
function rar_announcement_bar() {
$msg = get_option('rar_announcement', 'FREE DESK-CHAIR DELIVERY ON ORDERS OVER $40 · CIRCULATE TO YOUR TEAM · DOC. REV. 04.26');
if ($msg) {
echo '<div class="rar-bar">' . esc_html($msg) . '</div>';
}
}
// ─── Helper: nav ────────────────────────────────────────────────────────────
function rar_nav() {
$cart_count = WC()->cart ? WC()->cart->get_cart_contents_count() : 0;
$cart_url = wc_get_cart_url();
$shop_url = get_permalink(wc_get_page_id('shop'));
?>
<nav class="rar-nav" id="rar-nav">
<div class="rar-nav__logo">
<a href="<?php echo esc_url(home_url('/')); ?>" class="rar-nav__logo-mark">Reply All Regrets™</a>
<span class="rar-nav__logo-sub">EST. 2024 · INTERNAL USE ONLY</span>
</div>
<div class="rar-nav__links">
<?php
wp_nav_menu([
'theme_location' => 'primary',
'container' => false,
'items_wrap' => '%3$s',
'fallback_cb' => function() use ($shop_url) {
$links = [
['Shop', $shop_url],
['Designs', home_url('/designs/')],
['Mugs', home_url('/product-category/mugs/')],
['Canvas', home_url('/product-category/canvas/')],
['Planners', home_url('/product-category/planners/')],
['Apparel', home_url('/product-category/apparel/')],
['The Memo', home_url('/blog/')],
['About', home_url('/about/')],
];
foreach ($links as [$label, $url]) {
echo '<a href="' . esc_url($url) . '">' . esc_html($label) . '</a>';
}
},
]);
?>
</div>
<div class="rar-nav__icons">
<button class="rar-nav__search-btn" id="rar-search-toggle" type="button"
onclick="rarToggleSearch()" aria-label="Search" aria-expanded="false">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="7"></circle><path d="m20 20-3.5-3.5"></path>
</svg>
Search
</button>
<a href="<?php echo esc_url(get_permalink(wc_get_page_id('myaccount'))); ?>" aria-label="Account">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="8" r="4"></circle>
<path d="M4 21c1.5-4.5 5-7 8-7s6.5 2.5 8 7"></path>
</svg>
Account
</a>
<a href="<?php echo esc_url($cart_url); ?>" class="rar-nav__cart">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 4h2l2.5 12h11l2-8H6"></path>
<circle cx="9" cy="20" r="1.5"></circle><circle cx="17" cy="20" r="1.5"></circle>
</svg>
Cart (<?php echo esc_html($cart_count); ?>)
</a>
</div>
</nav>
<div class="rar-search-overlay" id="rar-search-overlay" hidden>
<form class="rar-search-form" action="<?php echo esc_url(home_url('/')); ?>" method="get">
<input type="hidden" name="post_type" value="product" />
<input class="rar-search-input" type="search" name="s" placeholder="Search products…"
aria-label="Search products" autocomplete="off" />
<button type="submit" class="rar-btn rar-btn--stamp">Search</button>
<button type="button" class="rar-search-close" onclick="rarToggleSearch()" aria-label="Close search">✕</button>
</form>
</div>
<?php
}
// ─── Helper: footer ─────────────────────────────────────────────────────────
function rar_footer_content() {
$shop_url = get_permalink(wc_get_page_id('shop'));
?>
<footer class="rar-footer">
<div class="rar-footer__grid">
<div>
<div style="font-family:var(--serif);font-size:28px;margin-bottom:8px;">Reply All Regrets™</div>
<p style="font-family:var(--mono);font-size:11px;line-height:1.7;color:rgba(245,241,232,0.7);max-width:280px;margin:0;">
Deliverables for the chronically employed. Filed quarterly,<br>
shipped from a warehouse in Cleveland.
</p>
<div class="rar-footer__newsletter">
<form class="rar-newsletter-form" onsubmit="return rarNewsletterSubmit(event, this)">
<input type="email" name="EMAIL" placeholder="your.name@workplace.com"
aria-label="Email for newsletter" required />
<button type="submit" class="rar-btn rar-btn--stamp" style="padding:10px 16px;">CC: ME →</button>
</form>
</div>
</div>
<div class="rar-footer__col">
<div class="rar-footer__col-title">Departments</div>
<ul>
<li><a href="<?php echo esc_url(home_url('/product-category/drinkware/')); ?>">Drinkware</a></li>
<li><a href="<?php echo esc_url(home_url('/product-category/apparel/')); ?>">Apparel</a></li>
<li><a href="<?php echo esc_url(home_url('/product-category/wall-decor/')); ?>">Wall Decor</a></li>
<li><a href="<?php echo esc_url(home_url('/product-category/stationery/')); ?>">Stationery</a></li>
<li><a href="<?php echo esc_url(home_url('/bulk/')); ?>">Bulk / HR</a></li>
</ul>
</div>
<div class="rar-footer__col">
<div class="rar-footer__col-title">Company</div>
<ul>
<li><a href="<?php echo esc_url(home_url('/about/')); ?>">About</a></li>
<li><a href="<?php echo esc_url(home_url('/blog/')); ?>">The Memo (blog)</a></li>
<li><a href="<?php echo esc_url(home_url('/press/')); ?>">Press</a></li>
<li><a href="<?php echo esc_url(home_url('/careers/')); ?>">Careers</a></li>
<li><a href="<?php echo esc_url(home_url('/wholesale/')); ?>">Wholesale</a></li>
</ul>
</div>
<div class="rar-footer__col">
<div class="rar-footer__col-title">Form 9-A: Help</div>
<ul>
<li><a href="<?php echo esc_url(home_url('/shipping/')); ?>">Shipping</a></li>
<li><a href="<?php echo esc_url(home_url('/returns/')); ?>">Returns &amp; Grievances</a></li>
<li><a href="<?php echo esc_url(home_url('/order-status/')); ?>">Order Status</a></li>
<li><a href="<?php echo esc_url(home_url('/contact/')); ?>">Contact (no calls)</a></li>
<li><a href="<?php echo esc_url(home_url('/faq/')); ?>">FAQ</a></li>
</ul>
</div>
</div>
<div class="rar-footer__legal">
<span>© <?php echo date('Y'); ?> RAR HOLDINGS LLC · ALL RIGHTS RESERVED</span>
<span>
<a href="<?php echo esc_url(home_url('/terms/')); ?>">TERMS</a> ·
<a href="<?php echo esc_url(get_privacy_policy_url()); ?>">PRIVACY</a> ·
<a href="<?php echo esc_url(home_url('/accessibility/')); ?>">ACCESSIBILITY</a>
</span>
</div>
</footer>
<?php
}
// ─── Helper: breadcrumb ─────────────────────────────────────────────────────
function rar_breadcrumb() {
echo '<div class="rar-breadcrumb">';
if (function_exists('woocommerce_breadcrumb')) {
woocommerce_breadcrumb(['wrap_before' => '', 'wrap_after' => '', 'before' => '', 'after' => '', 'delimiter' => ' / ']);
} else {
echo '<a href="' . esc_url(home_url('/')) . '">Home</a> / ';
if (is_singular()) {
echo '<span>' . get_the_title() . '</span>';
} elseif (is_archive()) {
echo '<span>' . get_the_archive_title() . '</span>';
}
}
echo '</div>';
}
// ─── Helper: section header ──────────────────────────────────────────────────
function rar_section_head($form, $title, $meta = '') {
echo '<div class="rar-section-head">';
echo '<div>';
echo '<div class="rar-form-tag" style="margin-bottom:10px;">' . esc_html($form) . '</div>';
echo '<h2>' . esc_html($title) . '</h2>';
echo '</div>';
if ($meta) {
echo '<div class="rar-section-head__meta">' . wp_kses_post($meta) . '</div>';
}
echo '</div>';
}
// ─── Add WooCommerce cart fragment support ───────────────────────────────────
add_filter('woocommerce_add_to_cart_fragments', function($fragments) {
$cart_count = WC()->cart->get_cart_contents_count();
$fragments['.rar-nav__cart'] = '<a href="' . esc_url(wc_get_cart_url()) . '" class="rar-nav__cart">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 4h2l2.5 12h11l2-8H6"></path>
<circle cx="9" cy="20" r="1.5"></circle><circle cx="17" cy="20" r="1.5"></circle>
</svg>
Cart (' . $cart_count . ')
</a>';
return $fragments;
});
// ─── Custom image sizes ──────────────────────────────────────────────────────
add_image_size('rar-product-card', 600, 600, true);
add_image_size('rar-blog-thumb', 800, 450, true);
add_image_size('rar-hero', 900, 1125, true);
// ─── Page templates ──────────────────────────────────────────────────────────
add_filter('theme_page_templates', function($templates) {
$templates['page-designs.php'] = 'Designs Index';
$templates['page-design-detail.php'] = 'Design Detail';
$templates['page-about.php'] = 'About';
return $templates;
});
// ─── AJAX: add to cart from homepage ────────────────────────────────────────
add_action('wp_ajax_rar_add_to_cart', 'rar_ajax_add_to_cart');
add_action('wp_ajax_nopriv_rar_add_to_cart', 'rar_ajax_add_to_cart');
function rar_ajax_add_to_cart() {
check_ajax_referer('rar-nonce', 'nonce');
$product_id = absint($_POST['product_id'] ?? 0);
$qty = absint($_POST['qty'] ?? 1);
if ($product_id) {
WC()->cart->add_to_cart($product_id, $qty);
wp_send_json_success(['count' => WC()->cart->get_cart_contents_count()]);
}
wp_send_json_error();
}
// ─── Customizer settings ─────────────────────────────────────────────────────
add_action('customize_register', function($wp_customize) {
$wp_customize->add_section('rar_options', [
'title' => __('Reply All Regrets Settings', 'rar-storefront'),
'priority' => 30,
]);
$wp_customize->add_setting('rar_announcement', [
'default' => 'FREE DESK-CHAIR DELIVERY ON ORDERS OVER $40 · CIRCULATE TO YOUR TEAM · DOC. REV. 04.26',
'transport' => 'refresh',
]);
$wp_customize->add_control('rar_announcement', [
'label' => __('Announcement Bar Text', 'rar-storefront'),
'section' => 'rar_options',
'type' => 'text',
]);
$wp_customize->add_setting('rar_hero_tagline', [
'default' => 'Office supplies for people who hate the office.',
'transport' => 'postMessage',
]);
$wp_customize->add_control('rar_hero_tagline', [
'label' => __('Hero Tagline', 'rar-storefront'),
'section' => 'rar_options',
'type' => 'textarea',
]);
});