diff --git a/acf-json/group_6824d74596f5f.json b/acf-json/group_6824d74596f5f.json index 07208a9..48d9b1d 100644 --- a/acf-json/group_6824d74596f5f.json +++ b/acf-json/group_6824d74596f5f.json @@ -358,11 +358,11 @@ "sub_fields": [ { "key": "field_6824e06c13d95", - "label": "Block", - "name": "block", + "label": "Blocks", + "name": "blocks", "aria-label": "", "type": "repeater", - "instructions": "", + "instructions": "Choose either a page\/product OR a product category. If you choose both, the page\/product on the left is the one that is chosen", "required": 0, "conditional_logic": 0, "wrapper": { @@ -371,16 +371,16 @@ "id": "" }, "layout": "table", - "min": 0, - "max": 0, + "min": 1, + "max": 4, "collapsed": "", - "button_label": "Add Row", + "button_label": "Add Block", "rows_per_page": 20, "sub_fields": [ { "key": "field_6824e07913d96", - "label": "Target", - "name": "target", + "label": "Page\/Product", + "name": "page_product", "aria-label": "", "type": "post_object", "instructions": "", @@ -391,7 +391,10 @@ "class": "", "id": "" }, - "post_type": "", + "post_type": [ + "page", + "product" + ], "post_status": "", "taxonomy": "", "return_format": "object", @@ -402,6 +405,143 @@ "ui": 1, "bidirectional_target": [], "parent_repeater": "field_6824e06c13d95" + }, + { + "key": "field_682d15cc48cf3", + "label": "Product Category", + "name": "product_category", + "aria-label": "", + "type": "taxonomy", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "taxonomy": "product_cat", + "add_term": 0, + "save_terms": 0, + "load_terms": 0, + "return_format": "id", + "field_type": "select", + "allow_null": 1, + "allow_in_bindings": 0, + "bidirectional": 0, + "multiple": 0, + "bidirectional_target": [], + "parent_repeater": "field_6824e06c13d95" + } + ] + } + ], + "min": "", + "max": "" + }, + "layout_682d09e6b11a2": { + "key": "layout_682d09e6b11a2", + "name": "vertical_callouts", + "label": "Vertical Callouts", + "display": "block", + "sub_fields": [ + { + "key": "field_683777b154db8", + "label": "Headline", + "name": "headline", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "placeholder": "", + "prepend": "", + "append": "" + }, + { + "key": "field_682d09e6b11a7", + "label": "Blocks", + "name": "blocks", + "aria-label": "", + "type": "repeater", + "instructions": "Choose either a page\/product OR a product category. If you choose both, the page\/product on the left is the one that is chosen", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "layout": "table", + "min": 1, + "max": 4, + "collapsed": "", + "button_label": "Add Block", + "rows_per_page": 20, + "sub_fields": [ + { + "key": "field_682d167848cf4", + "label": "Page\/Product", + "name": "page_product", + "aria-label": "", + "type": "post_object", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "post_type": [ + "page", + "product" + ], + "post_status": "", + "taxonomy": "", + "return_format": "object", + "multiple": 0, + "allow_null": 0, + "allow_in_bindings": 0, + "bidirectional": 0, + "ui": 1, + "bidirectional_target": [], + "parent_repeater": "field_682d09e6b11a7" + }, + { + "key": "field_682d09e6b11a8", + "label": "Category", + "name": "category", + "aria-label": "", + "type": "taxonomy", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "taxonomy": "product_cat", + "add_term": 0, + "save_terms": 0, + "load_terms": 0, + "return_format": "object", + "field_type": "select", + "allow_null": 1, + "allow_in_bindings": 0, + "bidirectional": 0, + "multiple": 0, + "bidirectional_target": [], + "parent_repeater": "field_682d09e6b11a7" } ] } @@ -550,6 +690,184 @@ ], "min": "", "max": "" + }, + "layout_6837a5ddc8328": { + "key": "layout_6837a5ddc8328", + "name": "callout_text", + "label": "Callout Text", + "display": "block", + "sub_fields": [ + { + "key": "field_6837a5e3c832e", + "label": "Headline 1", + "name": "headline_1", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "placeholder": "", + "prepend": "", + "append": "" + }, + { + "key": "field_6837a5ebc832f", + "label": "Headline 2", + "name": "headline_2", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "placeholder": "", + "prepend": "", + "append": "" + }, + { + "key": "field_6837a5f2c8330", + "label": "Descriptive Text", + "name": "descriptive_text", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "placeholder": "", + "prepend": "", + "append": "" + } + ], + "min": "", + "max": "" + }, + "layout_683a43e4c858e": { + "key": "layout_683a43e4c858e", + "name": "accordian_text", + "label": "Accordian Text", + "display": "block", + "sub_fields": [ + { + "key": "field_683a43f0c8590", + "label": "Text Blocks", + "name": "text_blocks", + "aria-label": "", + "type": "repeater", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "layout": "table", + "min": 0, + "max": 0, + "collapsed": "", + "button_label": "Add Row", + "rows_per_page": 20, + "sub_fields": [ + { + "key": "field_683a4417c8591", + "label": "Headline", + "name": "headline", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "placeholder": "", + "prepend": "", + "append": "", + "parent_repeater": "field_683a43f0c8590" + }, + { + "key": "field_683a4420c8592", + "label": "Content", + "name": "content", + "aria-label": "", + "type": "textarea", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "rows": "", + "placeholder": "", + "new_lines": "br", + "parent_repeater": "field_683a43f0c8590" + } + ] + } + ], + "min": "", + "max": "" + }, + "layout_683cb88438a58": { + "key": "layout_683cb88438a58", + "name": "4_column_business_blocks", + "label": "4 Column Business Blocks", + "display": "block", + "sub_fields": [ + { + "key": "field_683cb89138a5a", + "label": "You don't edit this here", + "name": "", + "aria-label": "", + "type": "message", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "message": "This could be shown on many pages, so click here<\/a> to manage this content.", + "new_lines": "wpautop", + "esc_html": 0 + } + ], + "min": "", + "max": "" } }, "min": "", @@ -577,5 +895,5 @@ "active": true, "description": "", "show_in_rest": 0, - "modified": 1747418238 + "modified": 1748810024 } diff --git a/acf-json/group_682cf199a3483.json b/acf-json/group_682cf199a3483.json new file mode 100644 index 0000000..97887b9 --- /dev/null +++ b/acf-json/group_682cf199a3483.json @@ -0,0 +1,93 @@ +{ + "key": "group_682cf199a3483", + "title": "Shop Category Fields", + "fields": [ + { + "key": "field_682cf19966afb", + "label": "Top Image", + "name": "top_image", + "aria-label": "", + "type": "image", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "return_format": "url", + "library": "all", + "min_width": "", + "min_height": "", + "min_size": "", + "max_width": "", + "max_height": "", + "max_size": "", + "mime_types": "", + "allow_in_bindings": 0, + "preview_size": "medium" + }, + { + "key": "field_682cf27e6b5c7", + "label": "Intro Headline", + "name": "intro_headline", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "allow_in_bindings": 0, + "placeholder": "", + "prepend": "", + "append": "" + }, + { + "key": "field_682cf2906b5c8", + "label": "Intro Content", + "name": "intro_content", + "aria-label": "", + "type": "wysiwyg", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "allow_in_bindings": 0, + "tabs": "all", + "toolbar": "full", + "media_upload": 1, + "delay": 0 + } + ], + "location": [ + [ + { + "param": "taxonomy", + "operator": "==", + "value": "product_cat" + } + ] + ], + "menu_order": 0, + "position": "normal", + "style": "default", + "label_placement": "top", + "instruction_placement": "label", + "hide_on_screen": "", + "active": true, + "description": "", + "show_in_rest": 0, + "modified": 1747776169 +} diff --git a/assets/arrow-right.svg b/assets/arrow-right.svg new file mode 100644 index 0000000..2362904 --- /dev/null +++ b/assets/arrow-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/megaphone-fill.svg b/assets/megaphone-fill.svg new file mode 100644 index 0000000..9f44f2e --- /dev/null +++ b/assets/megaphone-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/composer.lock b/composer.lock index 5e77c23..b6029e4 100644 --- a/composer.lock +++ b/composer.lock @@ -57,28 +57,28 @@ }, { "name": "open-function-computers-llc/rad-theme-engine", - "version": "v1.0.34", + "version": "v1.0.38", "source": { "type": "git", "url": "https://github.com/open-function-computers-llc/rad-theme-engine.git", - "reference": "c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e" + "reference": "90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/open-function-computers-llc/rad-theme-engine/zipball/c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e", - "reference": "c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e", + "url": "https://api.github.com/repos/open-function-computers-llc/rad-theme-engine/zipball/90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4", + "reference": "90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4", "shasum": "" }, "require": { "jjgrainger/posttypes": "^2.1", - "php": ">=7.4", + "php": ">=8.1", "salesforce/handlebars-php": "^2.3" }, "require-dev": { "phpunit/phpunit": "^9.5" }, "bin": [ - "bin/getIcon" + "bin/rad" ], "type": "library", "autoload": { @@ -98,9 +98,9 @@ ], "support": { "issues": "https://github.com/open-function-computers-llc/rad-theme-engine/issues", - "source": "https://github.com/open-function-computers-llc/rad-theme-engine/tree/v1.0.34" + "source": "https://github.com/open-function-computers-llc/rad-theme-engine/tree/v1.0.38" }, - "time": "2025-05-20T21:03:45+00:00" + "time": "2025-06-13T18:23:21+00:00" }, { "name": "salesforce/handlebars-php", diff --git a/config.php b/config.php index e1bc882..e990515 100644 --- a/config.php +++ b/config.php @@ -1,5 +1,7 @@ true, "flex-file-prefix" => "flex", @@ -73,6 +75,11 @@ return [ "testimonial" => \Helpers\McCansHelpers::testimonial(), "locationTile" => \Helpers\McCansHelpers::locationTile(), "productTile" => \Helpers\McCansHelpers::productTile(), + "renderBlock" => \Helpers\McCansHelpers::renderBlock(), + "renderCallout" => \Helpers\McCansHelpers::renderCallout(), + "productBox" => \Helpers\McCansHelpers::searchResultBox('product'), + "pageBox" => \Helpers\McCansHelpers::searchResultBox('page'), + "usd" => \Helpers\McCansHelpers::usd(), ], ], @@ -86,6 +93,7 @@ return [ "post-thumbnails", "menus", "woocommerce", + "excerpts", ], @@ -100,34 +108,107 @@ return [ "gutenberg", "patterns", "emojis", + "revisions", "meta-generator", "woocommerce.breadcrumb", "woocommerce.sidebar", "woocommerce.result_count", "woocommerce.page_title", + "woocommerce.archive_description", + "woocommerce.reviews", ], - "hooks" => [ - "woocommerce_before_main_content" => function () { + "actions" => [ + "woocommerce_before_single_product_summary" => [function () { + echo site()->render('woocommerce-before-content', [ + "additionalTopLevelClass" => "single-product-top", + ]); + }, 0], + "woocommerce_single_product_summary" => function () { + echo site()->render('woocommerce-after-content'); + }, + [ + "hook" => "woocommerce_after_single_product_summary", + "priority" => 0, + "callback" => function () { + echo site()->render('woocommerce-before-content'); + }, + ], + "woocommerce_after_single_product" => function () { + echo site()->render('woocommerce-after-content'); + }, + [ + "hook" => "woocommerce_after_single_product_summary", + "priority" => 18, + "callback" => function () { + echo site()->render('woocommerce-after-content'); + } + ], + [ + "hook" => "woocommerce_after_single_product_summary", + "priority" => 19, + "callback" => function () { + echo site()->render('flex_callout_text', [ + "headline_1" => "Shop", + "headline_2" => "Related Products", + ]); + echo site()->render('woocommerce-before-content', [ + "additionalTopLevelClass" => "related-wrapper" + ]); + } + ], + + "woocommerce_before_main_content" => [function () { + // skip this for individual products + if (is_product()) { + return; + } + // shop page if (is_shop()) { - echo site()->render("shop-top", site()->getPost(wc_get_page_id('shop'), ["headline", "intro_text", 'thumbnail'])); + echo site()->render("shop-top", site()->getPost(wc_get_page_id('shop'), [ + "headline", + "intro_text", + "thumbnail", + ])); + echo site()->render('woocommerce-before-content'); + return; + } + + if (is_product_category()) { + echo site()->render("shop-category-slice", site()->getQueriedObject(null, [ + "title", + "description", + "thumbnail", + "url", + "acf.intro_headline", + "acf.intro_content", + ])); echo site()->render('woocommerce-before-content'); return; } echo site()->render('woocommerce-before-content'); - }, - "woocommerce_after_main_content" => function () { - echo site()->render('woocommerce-after-content'); - }, - "init" => function() { - remove_all_actions( 'woocommerce_before_shop_loop_item' ); - remove_all_actions( 'woocommerce_before_shop_loop_item_title' ); - remove_all_actions( 'woocommerce_shop_loop_item_title' ); - remove_all_actions( 'woocommerce_after_shop_loop_item_title' ); - remove_all_actions( 'woocommerce_after_shop_loop_item' ); - add_action( 'woocommerce_shop_loop_item_title', function() { + }, 5], + [ + "hook" => "woocommerce_after_main_content", + "callback" => function () { + // skip this for individual products + if (is_product()) { + return; + } + + echo site()->render('woocommerce-after-content'); + }, + "priority" => 50, + ], + "init" => function () { + remove_all_actions('woocommerce_before_shop_loop_item'); + remove_all_actions('woocommerce_before_shop_loop_item_title'); + remove_all_actions('woocommerce_shop_loop_item_title'); + remove_all_actions('woocommerce_after_shop_loop_item_title'); + remove_all_actions('woocommerce_after_shop_loop_item'); + add_action('woocommerce_shop_loop_item_title', function () { global $product; $data = site()->getPost($product->id, [ @@ -141,13 +222,7 @@ return [ "woocommerce.sku", ]); - if ($data["price"] && $data["msrp"]) { - $difference = $data["msrp"] - $data["price"]; - - if ($difference > 0) { - $data["savings"] = round(($difference / $data["msrp"]) * 100); - } - } + $data["savings"] = McCansHelpers::calcDifference($data["price"], $data["msrp"]); echo site()->render("product-tile", $data); }); diff --git a/dist/app.css b/dist/app.css index 2bcc0b0..de3bf72 100644 --- a/dist/app.css +++ b/dist/app.css @@ -12214,22 +12214,48 @@ img { max-width: 100%; } -.montserrat, div.product-tile a.added_to_cart, footer.sub-footer, footer.site-footer .logo-col, footer.site-footer h2, footer.site-footer .h2, .cta-button a, .single-location .form-wrapper p:has(input[type=submit]) a, .cta-button input, .single-location .form-wrapper p:has(input[type=submit]) input, .headline-xl, section.intro-slide h1, section.intro-slide .h1, .background-image-cta h1, .background-image-cta .h1, .background-image-cta h2, .background-image-cta .h2, .background-image-cta h3, .background-image-cta .h3, .headline-lg, .single-location h1, .single-location .h1, .post-type-archive-location .intro h1, .post-type-archive-location .intro .h1, .testimonials-section h1, .testimonials-section .h1, .testimonials-section h2, .testimonials-section .h2, .testimonials-section h3, .testimonials-section .h3, .plain-text h1, .plain-text .h1, .plain-text h2, .plain-text .h2, .plain-text h3, .plain-text .h3 { +.montserrat, .single-product .wc-tabs li, .category-slice h2, .category-slice .h2, .page-tile h2, .page-tile .h2, div.product-tile a.learn-more, div.page-tile a.learn-more, div.product-tile a.added_to_cart, div.page-tile a.added_to_cart, section.intro-header h1, section.intro-header .h1, section.accordian-content a, footer.sub-footer, footer.site-footer .logo-col, footer.site-footer h2, footer.site-footer .h2, .cta-button a, .single-location .form-wrapper p:has(input[type=submit]) a, .cta-button input, .single-location .form-wrapper p:has(input[type=submit]) input, .headline-xl, section.intro-slide h1, section.intro-slide .h1, .background-image-cta h1, .background-image-cta .h1, .background-image-cta h2, .background-image-cta .h2, .background-image-cta h3, .background-image-cta .h3, .headline-lg, .single-location h1, .single-location .h1, .post-type-archive-location .intro h1, .post-type-archive-location .intro .h1, .category-slice-top h1, .category-slice-top .h1, .callout-text h2, .callout-text .h2, section.vertical-callouts h2, section.vertical-callouts .h2, .testimonials-section h1, .testimonials-section .h1, .testimonials-section h2, .testimonials-section .h2, .testimonials-section h3, .testimonials-section .h3, .plain-text h1, .plain-text .h1, .plain-text h2, .plain-text .h2, .plain-text h3, .plain-text .h3, .headline-md, .callout-page h3, .callout-page .h3, .callout-category h3, .callout-category .h3, section.intro-header h1, .headline-sm { font-family: "Montserrat", sans-serif; } -.change-black-to-red, div.product-tile a.added_to_cart::after, .testimonials-section .testimonials .slick-arrow img { +.change-black-to-red, div.product-tile a.added_to_cart::after, div.page-tile a.added_to_cart::after, .testimonials-section .testimonials .slick-arrow img { filter: invert(10%) sepia(79%) saturate(7388%) hue-rotate(2deg) brightness(86%) contrast(111%); } -.headline-lg, .single-location h1, .single-location .h1, .post-type-archive-location .intro h1, .post-type-archive-location .intro .h1, .testimonials-section h1, .testimonials-section .h1, .testimonials-section h2, .testimonials-section .h2, .testimonials-section h3, .testimonials-section .h3, .plain-text h1, .plain-text .h1, .plain-text h2, .plain-text .h2, .plain-text h3, .plain-text .h3 { +.headline-sm { + font-weight: 600; + font-size: 40px; + line-height: 40px; + letter-spacing: -1px; +} +@media (max-width: 767.98px) { + .headline-sm { + font-size: 30px; + line-height: 30px; + } +} + +.headline-md, .callout-page h3, .callout-page .h3, .callout-category h3, .callout-category .h3, section.intro-header h1, section.intro-header .h1 { + font-weight: 600; + font-size: 54px; + line-height: 54px; + letter-spacing: -1px; +} +@media (max-width: 767.98px) { + .headline-md, .callout-page h3, .callout-page .h3, .callout-category h3, .callout-category .h3, section.intro-header h1, section.intro-header .h1 { + font-size: 40px; + line-height: 40px; + } +} + +.headline-lg, .single-location h1, .single-location .h1, .post-type-archive-location .intro h1, .post-type-archive-location .intro .h1, .category-slice-top h1, .category-slice-top .h1, .callout-text h2, .callout-text .h2, section.vertical-callouts h2, section.vertical-callouts .h2, .testimonials-section h1, .testimonials-section .h1, .testimonials-section h2, .testimonials-section .h2, .testimonials-section h3, .testimonials-section .h3, .plain-text h1, .plain-text .h1, .plain-text h2, .plain-text .h2, .plain-text h3, .plain-text .h3 { font-weight: 600; font-size: 60px; line-height: 60px; letter-spacing: -3%; } @media (max-width: 767.98px) { - .headline-lg, .single-location h1, .single-location .h1, .post-type-archive-location .intro h1, .post-type-archive-location .intro .h1, .testimonials-section h1, .testimonials-section .h1, .testimonials-section h2, .testimonials-section .h2, .testimonials-section h3, .testimonials-section .h3, .plain-text h1, .plain-text .h1, .plain-text h2, .plain-text .h2, .plain-text h3, .plain-text .h3 { + .headline-lg, .single-location h1, .single-location .h1, .post-type-archive-location .intro h1, .post-type-archive-location .intro .h1, .category-slice-top h1, .category-slice-top .h1, .callout-text h2, .callout-text .h2, section.vertical-callouts h2, section.vertical-callouts .h2, .testimonials-section h1, .testimonials-section .h1, .testimonials-section h2, .testimonials-section .h2, .testimonials-section h3, .testimonials-section .h3, .plain-text h1, .plain-text .h1, .plain-text h2, .plain-text .h2, .plain-text h3, .plain-text .h3 { font-size: 45px; line-height: 45px; } @@ -12253,21 +12279,21 @@ img { } .cta-button a, .single-location .form-wrapper p:has(input[type=submit]) a, .cta-button input, .single-location .form-wrapper p:has(input[type=submit]) input { text-transform: uppercase; - background-color: #ae1716; + background-color: #c80000; color: #fff !important; text-decoration: none; display: inline-block; min-height: 47px; line-height: 47px; - border: 1px solid #ae1716; + border: 1px solid #c80000; border-radius: 25px; padding: 0 60px; transition: all 0.3s ease; font-size: 20px; } .cta-button a:hover, .single-location .form-wrapper p:has(input[type=submit]) a:hover, .cta-button input:hover, .single-location .form-wrapper p:has(input[type=submit]) input:hover { - background-color: #f5f5f5; - color: #ae1716 !important; + background-color: #f2f2f2; + color: #c80000 !important; } .cta-button.small a, .single-location .form-wrapper p.small:has(input[type=submit]) a { padding: 0 25px; @@ -12286,7 +12312,7 @@ input, label, textarea { } .top-bar { - background-color: #f5f5f5; + background-color: #f2f2f2; padding: 25px 0 25px; } .top-bar input[type=text] { @@ -12458,7 +12484,7 @@ input, label, textarea { } footer.site-footer { - background-color: #f5f5f5; + background-color: #f2f2f2; padding: 2rem 0; } footer.site-footer h2, footer.site-footer .h2 { @@ -12521,7 +12547,7 @@ footer.site-footer .logo-col img { } footer.sub-footer { - background-color: #f5f5f5; + background-color: #f2f2f2; border-top: 1px solid #cbcbcb; padding: 1.5rem 0; } @@ -12679,6 +12705,74 @@ footer.sub-footer { font-weight: bold; } +section.block-links { + padding: 4rem 0; +} + +section.vertical-callouts { + background-color: #f2f2f2; + margin-bottom: 4rem; + padding: 4rem 0; +} +section.vertical-callouts h2, section.vertical-callouts .h2 { + text-align: center; + text-transform: uppercase; + margin-bottom: 4rem; +} + +.callout-text { + background-color: #f2f2f2; + text-align: center; + padding: 3rem 0; +} +.callout-text h2, .callout-text .h2 { + text-transform: uppercase; +} +.callout-text h2 span, .callout-text .h2 span { + color: #c80000; +} +.callout-text h2 span.line-2, .callout-text .h2 span.line-2 { + display: block; +} +.callout-text p { + font-size: 29px; + margin-top: 1rem; + margin-bottom: 0; +} + +section.accordian-content { + padding: 4rem 0; +} +section.accordian-content .accordian-item { + margin: 3rem 0; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); + padding: 1rem; +} +section.accordian-content .accordian-item svg { + transition: transform 0.3s ease; +} +section.accordian-content .accordian-item.expanded svg { + transform: rotate(180deg); +} +section.accordian-content .accordian-item .content { + display: none; +} +section.accordian-content a { + color: #c80000; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; +} + +section.intro-header { + background-color: #f2f2f2; + padding: 4rem 0; +} +section.intro-header h1, section.intro-header .h1 { + text-transform: uppercase; + margin: 0; +} + .top-image { position: relative; background-size: cover; @@ -12726,6 +12820,41 @@ section.intro-slide p { font-size: 34px; } +.callout-page, .callout-category { + background-color: #fff; + border-radius: 15px; + padding: 1rem; + box-shadow: 0 0 30px rgba(0, 0, 0, 0.1); + margin-bottom: 2rem; +} +.callout-page .image-wrapper .image-side, .callout-category .image-wrapper .image-side { + aspect-ratio: 1; + display: block; + width: 500px; + background-position: center; + background-size: cover; +} +.callout-page .meta-top, .callout-category .meta-top { + text-transform: uppercase; + color: #c80000; + font-size: 16px; + letter-spacing: 1px; + margin: 0; +} +.callout-page h3, .callout-page .h3, .callout-category h3, .callout-category .h3 { + text-transform: uppercase; + margin-bottom: 1.5rem; +} +.callout-page .excerpt-wrapper, .callout-category .excerpt-wrapper { + max-width: 600px; + font-size: 1.25rem; + line-height: 2rem; + margin-bottom: 2rem; +} +.callout-page .excerpt-wrapper p, .callout-category .excerpt-wrapper p { + margin: 0; +} + section.woocommerce-wrapper { margin-top: 4rem; } @@ -12734,14 +12863,14 @@ section.woocommerce-wrapper ul.products { flex-wrap: wrap; } -div.product-tile { +div.product-tile, div.page-tile { border-radius: 15px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); padding: 1rem; position: relative; height: 100%; } -div.product-tile a.add_to_cart_button { +div.product-tile a.add_to_cart_button, div.page-tile a.add_to_cart_button { position: absolute; top: 1rem; right: 1rem; @@ -12752,20 +12881,21 @@ div.product-tile a.add_to_cart_button { justify-content: center; align-items: center; margin: 0 !important; + opacity: 0; transition: all 0.3s ease; border-radius: 50%; } -div.product-tile a.add_to_cart_button img { +div.product-tile a.add_to_cart_button img, div.page-tile a.add_to_cart_button img { margin: 0 !important; width: 20px !important; } -div.product-tile a.add_to_cart_button::after { +div.product-tile a.add_to_cart_button::after, div.page-tile a.add_to_cart_button::after { position: absolute; left: 80%; margin: 0 !important; top: -20%; } -div.product-tile a.added_to_cart { +div.product-tile a.added_to_cart, div.page-tile a.added_to_cart { padding-top: 0; position: absolute; display: block; @@ -12774,7 +12904,7 @@ div.product-tile a.added_to_cart { text-transform: uppercase; font-weight: bold; } -div.product-tile a.added_to_cart::after { +div.product-tile a.added_to_cart::after, div.page-tile a.added_to_cart::after { content: ""; width: 13px; height: 14px; @@ -12785,26 +12915,26 @@ div.product-tile a.added_to_cart::after { top: 3px; background-size: contain; } -div.product-tile a.added_to_cart:hover::after { +div.product-tile a.added_to_cart:hover::after, div.page-tile a.added_to_cart:hover::after { left: 105%; } -div.product-tile:hover .add_to_cart_button { +div.product-tile:hover .add_to_cart_button, div.page-tile:hover .add_to_cart_button { opacity: 1; } -div.product-tile h2, div.product-tile .h2 { +div.product-tile h2, div.product-tile .h2, div.page-tile h2, div.page-tile .h2 { font-weight: bold; font-size: 20px; line-height: 26px; text-align: center; } -div.product-tile h2 a, div.product-tile .h2 a { +div.product-tile h2 a, div.product-tile .h2 a, div.page-tile h2 a, div.page-tile .h2 a { color: #000; text-decoration: none; } -div.product-tile h2 a:hover, div.product-tile .h2 a:hover { +div.product-tile h2 a:hover, div.product-tile .h2 a:hover, div.page-tile h2 a:hover, div.page-tile .h2 a:hover { color: #c80000; } -div.product-tile p.price { +div.product-tile p.price, div.page-tile p.price { color: #c80000 !important; font-size: 25px !important; line-height: 26px; @@ -12812,20 +12942,96 @@ div.product-tile p.price { margin: 2rem 0 0 !important; font-weight: bold !important; } -div.product-tile p.msrp { +div.product-tile p.msrp, div.page-tile p.msrp { color: #acacac !important; font-size: 15px !important; line-height: 21px; text-align: center; margin: 0; } -div.product-tile p.savings { +div.product-tile p.savings, div.page-tile p.savings { color: #c80000 !important; font-size: 16px !important; line-height: 16px; text-align: center; margin: 0; } +div.product-tile a.learn-more, div.page-tile a.learn-more { + text-transform: uppercase; + color: #c80000; + font-weight: bold; + text-decoration: none; + padding-bottom: 1rem; +} + +.page-tile h2, .page-tile .h2 { + text-align: left !important; + font-size: 32px !important; + line-height: 37px !important; + text-transform: uppercase; + margin: 1rem 0; +} + +.category-slice-top { + background-color: #f2f2f2; + padding: 4rem 0; + text-align: center; +} +.category-slice-top h1, .category-slice-top .h1 { + text-transform: uppercase; +} +.category-slice-top p { + font-size: 29px; + line-height: 30px; +} + +.category-slice { + padding: 4rem 0 0; +} +.category-slice img { + max-height: 300px; + width: auto; +} +.category-slice h2, .category-slice .h2 { + font-weight: bold; + margin-bottom: 2rem; +} + +.single-product .single-product-top { + background-color: #f2f2f2; + padding: 4rem 0 !important; + margin-top: 0 !important; +} +.single-product .wc-tabs { + list-style-type: none; + display: flex; + border-bottom: 1px solid #000; + padding: 0 0 1rem; + margin: 0 0 2rem; + gap: 2rem; +} +.single-product .wc-tabs li { + font-weight: 600; + text-transform: uppercase; + font-size: 1.5rem; +} +.single-product .wc-tabs li a { + color: #505050; + text-decoration: none; +} +.single-product .wc-tabs li.active { + position: relative; +} +.single-product .wc-tabs li.active:after { + content: ""; + position: absolute; + top: calc(100% + 1rem); + transform: translateY(-1px); + display: block; + width: 100%; + height: 3px; + background-color: #c80000; +} .post-type-archive-location .intro { text-align: center; @@ -12892,3 +13098,7 @@ div.product-tile p.savings { color: #505050; text-decoration: none; } + +.search-results .tile-wrapper { + margin-bottom: 1.5rem; +} diff --git a/dist/app.js b/dist/app.js index 5ceba91..be83da5 100644 --- a/dist/app.js +++ b/dist/app.js @@ -13837,11 +13837,25 @@ jquery__WEBPACK_IMPORTED_MODULE_0___default()("body").on("click", ".toggle-sub-n jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).parent("li").toggleClass("children-showing"); }); // mobile nav toggle -document.getElementById("mobile-nav-toggle").addEventListener("click", function (e) { +jquery__WEBPACK_IMPORTED_MODULE_0___default()("#mobile-nav-toggle").on("click", function (e) { e.preventDefault(); document.getElementsByTagName("body")[0].classList.toggle("mobile-nav-open"); }); +// accordian expander +// $(".accordian-item .content").fadeOut(0); +jquery__WEBPACK_IMPORTED_MODULE_0___default()(".accordian-item a").on("click", function (e) { + e.preventDefault(); + var wrapper = jquery__WEBPACK_IMPORTED_MODULE_0___default()(e.target).closest(".accordian-item"); + window.activeThingy = wrapper; + if (wrapper.hasClass("expanded")) { + wrapper.find(".content").fadeOut(); + } else { + wrapper.find(".content").fadeIn(); + } + wrapper.toggleClass("expanded"); +}); + /***/ }), /***/ "./src/scss/app.scss": diff --git a/dist/mix-manifest.json b/dist/mix-manifest.json index e3ccc73..ea27c30 100644 --- a/dist/mix-manifest.json +++ b/dist/mix-manifest.json @@ -1,4 +1,4 @@ { - "/app.js": "/app.js?id=dba67887fc4ea12d32fe1c2757aaa5c1", - "/app.css": "/app.css?id=4a8b4a07b6234e03881bacb9bf94454f" + "/app.js": "/app.js?id=8af0c9c0d989b79afe124f8138dc1a63", + "/app.css": "/app.css?id=d043bd4af528893790cc648d33110d1f" } diff --git a/header.php b/header.php index c3f1a48..ba77ef9 100644 --- a/header.php +++ b/header.php @@ -6,9 +6,7 @@ // https://rad-theme-engine.ofco.cloud/docs/guides/helpers/ echo site()->render("header", [ - "logo" => site()->getAssetURL("main-logo.jpg"), "accountHref" => get_permalink(73), - "person-icon" => site()->getAssetContents("person-circle.svg"), - "phone-icon" => site()->getAssetContents("telephone.svg"), "menu" => site()->renderMenu("main-nav"), + "searchTerm" => $_GET["s"] ?? "", ]); diff --git a/helpers/McCansHelpers.php b/helpers/McCansHelpers.php index b1b72de..4649498 100644 --- a/helpers/McCansHelpers.php +++ b/helpers/McCansHelpers.php @@ -18,6 +18,13 @@ class McCansHelpers }; } + public static function usd() + { + return function ($template, $context, $args, $source) { + return "$" . number_format((float) $context->get($args), 2); + }; + } + public static function locationTile() { return function ($template, $context, $args, $source) { @@ -36,17 +43,156 @@ class McCansHelpers "woocommerce.cartUrl", "woocommerce.attribute.msrp", ]); - if ((float) $data["msrp"] && (float) $data["price"]) { - if ($data["price"] != 0) { - $difference = $data["msrp"] - $data["price"]; - if ($difference > 0) { - $savingsPercent = round(($difference / $data["msrp"])*100); - } + $data["savings"] = self::calcDifference($data["price"], $data["msrp"]); - $data["savings"] = $savingsPercent; - } - } return site()->render("product-tile", $data); }; } + + public static function renderBlock() + { + return function ($template, $context, $args, $source) { + // if a page or product is chosen... + if ($context->get($args)["page_product"]) { + $post = $context->get($args)["page_product"]; + + if ($post->post_type === "page") { + return site()->render("page-tile", site()->getPost($post, [ + "title", + "url", + "thumbnail", + ])); + } + + $data = site()->getPost($post, [ + "url", + "id", + "title", + "thumbnail", + "woocommerce.price", + "woocommerce.attribute.msrp", + "woocommerce.cartUrl", + "woocommerce.sku", + ]); + $data["savings"] = self::calcDifference($data["price"], $data["msrp"]); + + return site()->render("product-tile", $data); + } + + // if we got here, then hopefully the product_category is set + if (!$context->get($args)["product_category"]) { + return "No valid option chosen..."; + } + + $termID = $context->get($args)["product_category"]; + $term = get_term($termID); + return site()->render("page-tile", site()->getQueriedObject($term, ['title', 'thumbnail', 'url'])); + }; + } + + public static function renderCallout() + { + return function ($template, $context, $args, $source) { + // if a page or product is chosen... + if ($context->get($args)["page_product"]) { + $post = $context->get($args)["page_product"]; + + if ($post->post_type === "page") { + return site()->render("page-callout", site()->getPost($post, [ + "title", + "url", + "thumbnail", + "excerpt", + ])); + } + + $data = site()->getPost($post, [ + "url", + "id", + "title", + "thumbnail", + "woocommerce.price", + "woocommerce.attribute.msrp", + "woocommerce.cartUrl", + "woocommerce.sku", + ]); + $data["savings"] = self::calcDifference($data["price"], $data["msrp"]); + + return site()->render("product-tile", $data); + } + + // if we got here, then hopefully the product_category is set + if (!$context->get($args)["category"]) { + return "No valid option chosen..."; + } + + $termID = $context->get($args)["category"]; + $term = get_term($termID); + return site()->render("category-callout", site()->getQueriedObject($term, [ + 'title', + 'thumbnail', + 'url', + 'description', + ])); + }; + } + + public static function calcDifference($price, $msrp): string + { + if (!$price) { + return ""; + } + if (!$msrp) { + return ""; + } + + $difference = $msrp - $price; + if ($difference === 0) { + return ""; + } + return round(($difference / $msrp) * 100); + } + + public static function searchResultBox(string $type) + { + return function ($template, $context, $args, $source) use ($type) { + $post = $context->get($args); + + if ($type === "product") { + if ($post["post_type"] !== "product") { + return ""; + } + + $data = site()->getPost($post["id"], [ + "url", + "id", + "title", + "thumbnail", + "woocommerce.price", + "woocommerce.attribute.msrp", + "woocommerce.cartUrl", + "woocommerce.sku", + ]); + $data["savings"] = self::calcDifference($data["price"], $data["msrp"]); + + return site()->render("product-tile", $data); + } + + if ($type === "page") { + // var_dump($post); + if ($post["post_type"] !== "page") { + return ""; + } + + return site()->render("page-tile", site()->getPost($post["id"], [ + "url", + "id", + "title", + "thumbnail", + ])); + } + + return site()->render("search-box", $context->get($args)); + }; + } } diff --git a/search.php b/search.php new file mode 100644 index 0000000..483cc9c --- /dev/null +++ b/search.php @@ -0,0 +1,15 @@ +getDefaultPosts(["id", "post_type", "title"]); +$hasResults = count($results) > 0; + +echo site()->render("search-results", [ + "searchTerm" => $_GET["s"] ?? "", + "hasResults" => $hasResults, + "pages" => array_filter($results, fn ($r) => $r["post_type"] === "page"), + "products" => array_filter($results, fn ($r) => $r["post_type"] === "product"), +]); + +get_footer(); diff --git a/single-product.php b/single-product.php deleted file mode 100644 index 573cf14..0000000 --- a/single-product.php +++ /dev/null @@ -1,13 +0,0 @@ - { $(e.target).parent("li").toggleClass("children-showing"); }); // mobile nav toggle -document.getElementById("mobile-nav-toggle").addEventListener("click", (e) => { +$("#mobile-nav-toggle").on("click", (e) => { e.preventDefault(); document.getElementsByTagName("body")[0].classList.toggle("mobile-nav-open"); }); + + +// accordian expander +// $(".accordian-item .content").fadeOut(0); +$(".accordian-item a").on("click", (e) => { + e.preventDefault(); + const wrapper = $(e.target).closest(".accordian-item"); + window.activeThingy = wrapper; + + if (wrapper.hasClass("expanded")) { + wrapper.find(".content").fadeOut(); + } else { + wrapper.find(".content").fadeIn(); + } + + wrapper.toggleClass("expanded"); +}); diff --git a/src/scss/app.scss b/src/scss/app.scss index 7c5d2c0..805d269 100644 --- a/src/scss/app.scss +++ b/src/scss/app.scss @@ -13,10 +13,20 @@ @import "flex-plain-text"; @import "flex-logo-slider"; @import "flex-testimonials"; +@import "flex-block-links"; +@import "flex-veritcal-callouts"; +@import "flex-callout-text"; +@import "flex-accordian-content"; +@import "flex-intro-header"; + @import "top-image"; @import "intro-slide"; +@import "callouts"; @import "shop"; +@import "shop-catgeory"; +@import "product"; @import "locations"; @import "location"; +@import "search"; diff --git a/src/scss/callouts.scss b/src/scss/callouts.scss new file mode 100644 index 0000000..f17acfd --- /dev/null +++ b/src/scss/callouts.scss @@ -0,0 +1,42 @@ +.callout-page, .callout-category { + background-color: $c-white; + border-radius: 15px; + padding: 1rem; + box-shadow: 0 0 30px rgba($c-black, 0.1); + margin-bottom: 2rem; + + .image-wrapper { + .image-side { + aspect-ratio: 1; + display: block; + width: 500px; + background-position: center; + background-size: cover; + } + } + + .meta-top { + text-transform: uppercase; + color: $c-brightRed; + font-size: 16px; + letter-spacing: 1px; + margin: 0; + } + + h3 { + @extend .headline-md; + text-transform: uppercase; + margin-bottom: 1.5rem; + } + + .excerpt-wrapper { + max-width: 600px; + font-size: 1.25rem; + line-height: 2rem; + margin-bottom: 2rem; + + p { + margin: 0; + } + } +} diff --git a/src/scss/flex-accordian-content.scss b/src/scss/flex-accordian-content.scss new file mode 100644 index 0000000..7cb4762 --- /dev/null +++ b/src/scss/flex-accordian-content.scss @@ -0,0 +1,31 @@ +section.accordian-content { + padding: 4rem 0; + + .accordian-item { + margin: 3rem 0; + box-shadow: 0 0 20px rgba($c-black, 0.1); + padding: 1rem; + + svg { + transition: transform $transition-time ease; + } + + &.expanded { + svg { + transform: rotate(180deg); + } + } + + .content { + display: none; + } + } + + a { + @extend .montserrat; + color: $c-brightRed; + text-decoration: none; + font-weight: bold; + text-transform: uppercase; + } +} diff --git a/src/scss/flex-block-links.scss b/src/scss/flex-block-links.scss new file mode 100644 index 0000000..e781800 --- /dev/null +++ b/src/scss/flex-block-links.scss @@ -0,0 +1,3 @@ +section.block-links { + padding: 4rem 0; +} diff --git a/src/scss/flex-callout-text.scss b/src/scss/flex-callout-text.scss new file mode 100644 index 0000000..bb92aa0 --- /dev/null +++ b/src/scss/flex-callout-text.scss @@ -0,0 +1,24 @@ +.callout-text { + background-color: $c-offWhite; + text-align: center; + padding: 3rem 0; + + h2 { + @extend .headline-lg; + text-transform: uppercase; + + span { + color: $c-brightRed; + + &.line-2 { + display: block; + } + } + } + + p { + font-size: 29px; + margin-top: 1rem; + margin-bottom: 0; + } +} diff --git a/src/scss/flex-intro-header.scss b/src/scss/flex-intro-header.scss new file mode 100644 index 0000000..19da1ee --- /dev/null +++ b/src/scss/flex-intro-header.scss @@ -0,0 +1,11 @@ +section.intro-header { + background-color: $c-offWhite; + padding: 4rem 0; + + h1 { + @extend .montserrat; + @extend .headline-md; + text-transform: uppercase; + margin: 0; + } +} diff --git a/src/scss/flex-veritcal-callouts.scss b/src/scss/flex-veritcal-callouts.scss new file mode 100644 index 0000000..20c6464 --- /dev/null +++ b/src/scss/flex-veritcal-callouts.scss @@ -0,0 +1,12 @@ +section.vertical-callouts { + background-color: $c-offWhite; + margin-bottom: 4rem; + padding: 4rem 0; + + h2 { + @extend .headline-lg; + text-align: center; + text-transform: uppercase; + margin-bottom: 4rem; + } +} diff --git a/src/scss/global.scss b/src/scss/global.scss index 137cfb4..9515b6b 100644 --- a/src/scss/global.scss +++ b/src/scss/global.scss @@ -10,6 +10,32 @@ img { filter: invert(10%) sepia(79%) saturate(7388%) hue-rotate(2deg) brightness(86%) contrast(111%); } +.headline-sm { + @extend .montserrat; + font-weight: 600; + font-size: 40px; + line-height: 40px; + letter-spacing: -1px; + + @include media-breakpoint-down(md) { + font-size: 30px; + line-height: 30px; + } +} + +.headline-md { + @extend .montserrat; + font-weight: 600; + font-size: 54px; + line-height: 54px; + letter-spacing: -1px; + + @include media-breakpoint-down(md) { + font-size: 40px; + line-height: 40px; + } +} + .headline-lg { @extend .montserrat; font-weight: 600; @@ -42,13 +68,13 @@ img { a, input { @extend .montserrat; text-transform: uppercase; - background-color: $c-red; + background-color: $c-brightRed; color: $c-white !important; text-decoration: none; display: inline-block; min-height: 47px; line-height: 47px; - border: 1px solid $c-red; + border: 1px solid $c-brightRed; border-radius: 25px; padding: 0 60px; transition: all $transition-time ease; @@ -56,7 +82,7 @@ img { &:hover { background-color: $c-offWhite; - color: $c-red !important; + color: $c-brightRed !important; } } diff --git a/src/scss/product.scss b/src/scss/product.scss new file mode 100644 index 0000000..0a52a63 --- /dev/null +++ b/src/scss/product.scss @@ -0,0 +1,43 @@ +.single-product { + .single-product-top { + background-color: $c-offWhite; + padding: 4rem 0 !important; + margin-top: 0 !important; + } + + .wc-tabs { + list-style-type: none; + display: flex; + border-bottom: 1px solid $c-black; + padding: 0 0 1rem; + margin: 0 0 2rem; + gap: 2rem; + + li { + @extend .montserrat; + font-weight: 600; + text-transform: uppercase; + font-size: 1.5rem; + + a { + color: $c-textAlt; + text-decoration: none; + } + + &.active { + position: relative; + + &:after { + content: ""; + position: absolute; + top: calc(100% + 1rem); + transform: translateY(-1px); + display: block; + width: 100%; + height: 3px; + background-color: $c-brightRed; + } + } + } + } +} diff --git a/src/scss/search.scss b/src/scss/search.scss new file mode 100644 index 0000000..b5d246d --- /dev/null +++ b/src/scss/search.scss @@ -0,0 +1,5 @@ +.search-results { + .tile-wrapper { + margin-bottom: 1.5rem; + } +} diff --git a/src/scss/shop-catgeory.scss b/src/scss/shop-catgeory.scss new file mode 100644 index 0000000..c4665d1 --- /dev/null +++ b/src/scss/shop-catgeory.scss @@ -0,0 +1,30 @@ +.category-slice-top { + background-color: $c-offWhite; + padding: 4rem 0; + text-align: center; + + h1 { + @extend .headline-lg; + text-transform: uppercase; + } + + p { + font-size: 29px; + line-height: 30px; + } +} + +.category-slice { + padding: 4rem 0 0; + + img { + max-height: 300px; + width: auto; + } + + h2 { + @extend .montserrat; + font-weight: bold; + margin-bottom: 2rem; + } +} diff --git a/src/scss/shop.scss b/src/scss/shop.scss index 5d93385..966bb32 100644 --- a/src/scss/shop.scss +++ b/src/scss/shop.scss @@ -8,7 +8,7 @@ section.woocommerce-wrapper { } -div.product-tile { +div.product-tile, div.page-tile { border-radius: 15px; box-shadow: 0 0 20px rgba($c-black, 0.1); padding: 1rem; @@ -26,7 +26,7 @@ div.product-tile { justify-content: center; align-items: center; margin: 0 !important; - // opacity: 0; + opacity: 0; transition: all $transition-time ease; border-radius: 50%; @@ -119,4 +119,24 @@ div.product-tile { text-align: center; margin: 0; } + + a.learn-more { + @extend .montserrat; + text-transform: uppercase; + color: $c-brightRed; + font-weight: bold; + text-decoration: none; + padding-bottom: 1rem; + } +} + +.page-tile { + h2 { + @extend .montserrat; + text-align: left !important; + font-size: 32px !important; + line-height: 37px !important; + text-transform: uppercase; + margin: 1rem 0; + } } diff --git a/src/scss/variables.scss b/src/scss/variables.scss index 14ccc2e..e4c0e01 100644 --- a/src/scss/variables.scss +++ b/src/scss/variables.scss @@ -1,6 +1,6 @@ $c-black: #000; $c-white: #fff; -$c-offWhite: #f5f5f5; +$c-offWhite: #f2f2f2; $c-lightGrey: #d9d9d9; $c-grey: #cbcbcb; $c-midGrey: #acacac; diff --git a/tpl/category-callout.tpl b/tpl/category-callout.tpl new file mode 100644 index 0000000..ac4603e --- /dev/null +++ b/tpl/category-callout.tpl @@ -0,0 +1,20 @@ +
+
+
+
 
+
+ +
+
+
diff --git a/tpl/flex_accordian_text.tpl b/tpl/flex_accordian_text.tpl new file mode 100644 index 0000000..5d41a45 --- /dev/null +++ b/tpl/flex_accordian_text.tpl @@ -0,0 +1,24 @@ +
+
+
+
+ {{#each text_blocks}} +
+
+
+ {{ headline }} +
+ {{{ content }}} +
+
+ + +
+
+ {{/each}} +
+
+
+
diff --git a/tpl/flex_block_links.tpl b/tpl/flex_block_links.tpl new file mode 100644 index 0000000..5c91046 --- /dev/null +++ b/tpl/flex_block_links.tpl @@ -0,0 +1,11 @@ + diff --git a/tpl/flex_callout_text.tpl b/tpl/flex_callout_text.tpl new file mode 100644 index 0000000..b35b924 --- /dev/null +++ b/tpl/flex_callout_text.tpl @@ -0,0 +1,16 @@ +
+
+
+
+

{{{ headline_1 }}} + {{#if headline_2}} + {{ headline_2 }} + {{/if}} +

+ {{#if descriptive_text}} +

{{descriptive_text}}

+ {{/if}} +
+
+
+
diff --git a/tpl/flex_vertical_callouts.tpl b/tpl/flex_vertical_callouts.tpl new file mode 100644 index 0000000..27718fb --- /dev/null +++ b/tpl/flex_vertical_callouts.tpl @@ -0,0 +1,12 @@ +
+
+
+
+

{{ headline }}

+ {{#each blocks}} + {{#renderCallout this}} + {{/each}} +
+
+
+
diff --git a/tpl/header.tpl b/tpl/header.tpl index 7a85bce..677c1a7 100644 --- a/tpl/header.tpl +++ b/tpl/header.tpl @@ -20,10 +20,12 @@
diff --git a/tpl/page-callout.tpl b/tpl/page-callout.tpl new file mode 100644 index 0000000..5dfb5b2 --- /dev/null +++ b/tpl/page-callout.tpl @@ -0,0 +1,20 @@ +
+
+
+
 
+
+ +
+

Available Now

+

{{{ title }}}

+ +
+ {{{ excerpt }}} +
+ +

+ Shop {{{ title }}} +

+
+
+
diff --git a/tpl/page-tile.tpl b/tpl/page-tile.tpl new file mode 100644 index 0000000..9ef33cb --- /dev/null +++ b/tpl/page-tile.tpl @@ -0,0 +1,9 @@ + diff --git a/tpl/product-tile.tpl b/tpl/product-tile.tpl index 429d9cd..d8e7294 100644 --- a/tpl/product-tile.tpl +++ b/tpl/product-tile.tpl @@ -14,9 +14,9 @@ {{ title }}

- {{ title }} + {{{ title }}}

-

${{ price }}

+

{{#usd price }}

{{#if msrp}}

MSRP: ${{ msrp }}

{{/if}} diff --git a/tpl/search-results.tpl b/tpl/search-results.tpl new file mode 100644 index 0000000..9f448a6 --- /dev/null +++ b/tpl/search-results.tpl @@ -0,0 +1,56 @@ +
+
+
+
+
+

Search results for {{ searchTerm }} ({{#queryCount}})

+ {{#paginationLinks}} +
+
+
+
+
+ +
+
+
+
+ {{#if hasResults}} +

Products:

+ +
+ {{#each products}} +
+ {{#productBox this}} +
+ {{/each}} +
+ +

Pages

+ +
+ {{#each pages}} +
+ {{#pageBox this}} +
+ {{else}} +
+

No pages

+
+ {{/each}} +
+ +
+
+
+
+ {{else}} +

 

+

Sorry, there were no results found for "{{ searchTerm }}". Please try a different search.

+

 

+

 

+ {{/if}} +
+
+
+
diff --git a/tpl/shop-category-slice.tpl b/tpl/shop-category-slice.tpl new file mode 100644 index 0000000..d2448fa --- /dev/null +++ b/tpl/shop-category-slice.tpl @@ -0,0 +1,30 @@ +
+
+
+
+

{{{ title }}}

+

{{ description }}

+
+
+
+
+ +
+
+
+
+ {{ title }} +
+
+

{{ intro_headline }}

+ {{{ intro_content }}} + +

+ Shop Now +

+
+
+
+
+ + diff --git a/tpl/shop-category-top.tpl b/tpl/shop-category-top.tpl new file mode 100644 index 0000000..511125f --- /dev/null +++ b/tpl/shop-category-top.tpl @@ -0,0 +1,10 @@ +
+
+
+
+

{{{ title }}}

+

{{ description }}

+
+
+
+
diff --git a/tpl/woocommerce-before-content.tpl b/tpl/woocommerce-before-content.tpl index 3020d66..cc73a8e 100644 --- a/tpl/woocommerce-before-content.tpl +++ b/tpl/woocommerce-before-content.tpl @@ -1,4 +1,4 @@ -
+
diff --git a/vendor/bin/getIcon b/vendor/bin/rad similarity index 96% rename from vendor/bin/getIcon rename to vendor/bin/rad index 2c883c9..179bab3 100755 --- a/vendor/bin/getIcon +++ b/vendor/bin/rad @@ -4,7 +4,7 @@ /** * Proxy PHP file generated by Composer * - * This file includes the referenced bin path (../open-function-computers-llc/rad-theme-engine/bin/getIcon) + * This file includes the referenced bin path (../open-function-computers-llc/rad-theme-engine/bin/rad) * using a stream wrapper to prevent the shebang from being output on PHP<8 * * @generated @@ -112,8 +112,8 @@ if (PHP_VERSION_ID < 80000) { (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) ) { - return include("phpvfscomposer://" . __DIR__ . '/..'.'/open-function-computers-llc/rad-theme-engine/bin/getIcon'); + return include("phpvfscomposer://" . __DIR__ . '/..'.'/open-function-computers-llc/rad-theme-engine/bin/rad'); } } -return include __DIR__ . '/..'.'/open-function-computers-llc/rad-theme-engine/bin/getIcon'; +return include __DIR__ . '/..'.'/open-function-computers-llc/rad-theme-engine/bin/rad'; diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 81e868b..1a0af61 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -54,30 +54,30 @@ }, { "name": "open-function-computers-llc/rad-theme-engine", - "version": "v1.0.34", - "version_normalized": "1.0.34.0", + "version": "v1.0.38", + "version_normalized": "1.0.38.0", "source": { "type": "git", "url": "https://github.com/open-function-computers-llc/rad-theme-engine.git", - "reference": "c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e" + "reference": "90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/open-function-computers-llc/rad-theme-engine/zipball/c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e", - "reference": "c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e", + "url": "https://api.github.com/repos/open-function-computers-llc/rad-theme-engine/zipball/90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4", + "reference": "90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4", "shasum": "" }, "require": { "jjgrainger/posttypes": "^2.1", - "php": ">=7.4", + "php": ">=8.1", "salesforce/handlebars-php": "^2.3" }, "require-dev": { "phpunit/phpunit": "^9.5" }, - "time": "2025-05-20T21:03:45+00:00", + "time": "2025-06-13T18:23:21+00:00", "bin": [ - "bin/getIcon" + "bin/rad" ], "type": "library", "installation-source": "dist", @@ -98,7 +98,7 @@ ], "support": { "issues": "https://github.com/open-function-computers-llc/rad-theme-engine/issues", - "source": "https://github.com/open-function-computers-llc/rad-theme-engine/tree/v1.0.34" + "source": "https://github.com/open-function-computers-llc/rad-theme-engine/tree/v1.0.38" }, "install-path": "../open-function-computers-llc/rad-theme-engine" }, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 99a04c7..52dca02 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'open-function-computers-llc/wp-theme', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'c074a5ef18d6702ae4abe09fa1289fc93726117d', + 'reference' => 'edcad561a551ed7689bc2ae7fb39e1cde81aba2e', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -20,9 +20,9 @@ 'dev_requirement' => false, ), 'open-function-computers-llc/rad-theme-engine' => array( - 'pretty_version' => 'v1.0.34', - 'version' => '1.0.34.0', - 'reference' => 'c0b814bdd0ee1f093a051ed2e78efdf8c1f4f94e', + 'pretty_version' => 'v1.0.38', + 'version' => '1.0.38.0', + 'reference' => '90a351370bbd5a92a2c68c226a2c0cf3f97ce8f4', 'type' => 'library', 'install_path' => __DIR__ . '/../open-function-computers-llc/rad-theme-engine', 'aliases' => array(), @@ -31,7 +31,7 @@ 'open-function-computers-llc/wp-theme' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'c074a5ef18d6702ae4abe09fa1289fc93726117d', + 'reference' => 'edcad561a551ed7689bc2ae7fb39e1cde81aba2e', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 580fa96..4c3a5d6 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 70400)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/open-function-computers-llc/rad-theme-engine/bin/getIcon b/vendor/open-function-computers-llc/rad-theme-engine/bin/getIcon deleted file mode 100755 index ef427d9..0000000 --- a/vendor/open-function-computers-llc/rad-theme-engine/bin/getIcon +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env php -\n"); - exit(1); -} - -$icon = trim(strtolower($argv[1])); - -try { - IconGetter::get($icon); -} catch (Exception $e) { - fwrite(STDERR, "Error: ".$e->getMessage().PHP_EOL); - exit(1); -} diff --git a/vendor/open-function-computers-llc/rad-theme-engine/bin/rad b/vendor/open-function-computers-llc/rad-theme-engine/bin/rad new file mode 100755 index 0000000..a552b48 --- /dev/null +++ b/vendor/open-function-computers-llc/rad-theme-engine/bin/rad @@ -0,0 +1,49 @@ +#!/usr/bin/env php + [options]\n"); + exit(1); +} + +$command = strtolower(trim($argv[1])); +$arguments = array_slice($argv, 2); + +$availableCommands = [ + "get-icon" => \ofc\Commands\GetIconCommand::class, + + // TODO: additional commands go below + // "swap-library" => \ofc\Commands\LibrarySwap::class, +]; + +if (!isset($availableCommands[$command])) { + fwrite(STDERR, "Error: Unknown command '$command'\n"); + exit(1); +} + +// If the user requested help +if (in_array('--help', $arguments)) { + echo $availableCommands[$command]::getHelp().PHP_EOL.PHP_EOL; + exit(0); +} + +$availableCommands[$command]::run($arguments); diff --git a/vendor/open-function-computers-llc/rad-theme-engine/composer.json b/vendor/open-function-computers-llc/rad-theme-engine/composer.json index 2aed46e..d309c32 100644 --- a/vendor/open-function-computers-llc/rad-theme-engine/composer.json +++ b/vendor/open-function-computers-llc/rad-theme-engine/composer.json @@ -2,7 +2,7 @@ "name": "open-function-computers-llc/rad-theme-engine", "description": "A suite of classes to make WordPress theme development cleaner", "require": { - "php": ">=7.4", + "php": ">=8.1", "jjgrainger/posttypes": "^2.1", "salesforce/handlebars-php": "^2.3" }, @@ -25,6 +25,6 @@ "post-create-project-cmd": "ofc\\RadThemeEngine::setup" }, "bin": [ - "bin/getIcon" + "bin/rad" ] } diff --git a/vendor/open-function-computers-llc/rad-theme-engine/src/Commands/GetIconCommand.php b/vendor/open-function-computers-llc/rad-theme-engine/src/Commands/GetIconCommand.php new file mode 100644 index 0000000..1443a8c --- /dev/null +++ b/vendor/open-function-computers-llc/rad-theme-engine/src/Commands/GetIconCommand.php @@ -0,0 +1,35 @@ +\n"); + var_dump($args); + exit(1); + } + + $icon = trim(strtolower($args[0])); + + IconGetter::get($icon); + } + + public static function getHelp(): string + { + return << + +Description: + Download the SVG icon from https://icons.getbootstrap.com and place it in your theme assets folder. + TODO: link to the docs page. + +Example: + rad get-icon phone +HELP; + } +} diff --git a/vendor/open-function-computers-llc/rad-theme-engine/src/RadThemeEngine.php b/vendor/open-function-computers-llc/rad-theme-engine/src/RadThemeEngine.php index 996b294..77688ad 100644 --- a/vendor/open-function-computers-llc/rad-theme-engine/src/RadThemeEngine.php +++ b/vendor/open-function-computers-llc/rad-theme-engine/src/RadThemeEngine.php @@ -85,6 +85,39 @@ class RadThemeEngine }; } + public static function pagination() + { + return function ($template, $context, $args, $source) { + return site()->renderTemplate(<< +
    + {{#if older }} +
  • Next
  • + {{/if}} + {{#if newer }} +
  • Previous
  • + {{/if}} +
+ + HTML, site()->getPaginationLinks()); + }; + } + + public static function count() + { + return function ($template, $context, $args, $source) { + return count($context->get($args)); + }; + } + + public static function queryCount() + { + global $wp_query; + return function ($template, $context, $args, $source) use ($wp_query) { + return $wp_query->found_posts; + }; + } + public static function assetURL() { return function ($template, $context, $args, $source) { diff --git a/vendor/open-function-computers-llc/rad-theme-engine/src/Site.php b/vendor/open-function-computers-llc/rad-theme-engine/src/Site.php index 4a6ef8b..553d33b 100644 --- a/vendor/open-function-computers-llc/rad-theme-engine/src/Site.php +++ b/vendor/open-function-computers-llc/rad-theme-engine/src/Site.php @@ -2,6 +2,7 @@ namespace ofc; +use Exception; use PostTypes\PostType; use Handlebars\Handlebars; use Handlebars\Loader\FilesystemLoader; @@ -77,7 +78,8 @@ class Site $this->registerCPTs(); // register custom hook callbacks - $this->processHooks(); + $this->processActions(); + $this->processFilters(); // TODO // add custom shortcodes $this->registerShortcodes(); @@ -432,6 +434,10 @@ class Site define('DISALLOW_FILE_EDIT', true); continue; } + if ($key === "revisions") { + add_filter('wp_revisions_to_keep', fn ($num, $post) => 0, 10, 2); + continue; + } if ($key === "gutenberg") { add_filter('use_block_editor_for_post', '__return_false', 10); add_action('wp_enqueue_scripts', function () { @@ -481,6 +487,25 @@ class Site add_action('init', fn () => add_filter('woocommerce_show_page_title', '__return_false')); continue; } + if ($key === "archive_description") { + add_action('init', fn () => remove_action('woocommerce_archive_description', 'woocommerce_taxonomy_archive_description', 10)); + continue; + } + if ($key === "reviews") { + add_action('init', function () { + remove_post_type_support('product', 'comments'); + }); + + add_filter('woocommerce_product_reviews_enabled', '__return_false'); + add_filter('comments_array', function ($comments, $post_id) { + if (get_post_type($post_id) === 'product') { + return []; + } + return $comments; + }, 10, 2); + + continue; + } continue; } @@ -541,6 +566,11 @@ class Site add_theme_support('menus'); continue; } + if ($key === "excerpts" || $key === "excerpt") { + add_action('init', fn () => add_post_type_support('page', ['excerpt'])); + add_action('init', fn () => add_post_type_support('post', ['excerpt'])); + continue; + } if ($key === "styleselect") { add_filter('mce_buttons_2', function ($buttons) { return array_merge(['styleselect'], $buttons); @@ -556,6 +586,9 @@ class Site } if ($key === "woocommerce") { 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'); continue; } @@ -655,6 +688,10 @@ class Site "assetURL" => \ofc\RadThemeEngine::assetURL(), "assetUrl" => \ofc\RadThemeEngine::assetURL(), "assetContents" => \ofc\RadThemeEngine::assetContents(), + "count" => \ofc\RadThemeEngine::count(), + "length" => \ofc\RadThemeEngine::count(), + "paginationLinks" => \ofc\RadThemeEngine::pagination(), + "queryCount" => \ofc\RadThemeEngine::queryCount(), ]; foreach ($helpers as $name => $callback) { $this->hb->addHelper($name, $callback); @@ -700,7 +737,20 @@ class Site } return ""; } - return $this->hb->render($fileName, $data); + + try { + return $this->hb->render($fileName, $data); + } catch (Exception $e) { + $template = <<{{{ message }}}
+ HTML; + + $message = isset($this->config["debug"]) && $this->config["debug"] === true ? + "There was an error. Please see the message below:
" . $e->getMessage() ."": + "There was an error rendering this page. Please reach out to the site owner or try again later."; + + return $this->renderTemplate($template, ["message" => $message]); + } } /** @@ -1012,6 +1062,19 @@ class Site return $output; } + public function getQueriedObject($term = null, $fields = []) + { + if (is_null($term)) { + $term = get_queried_object(); + } + + if ($fields === []) { + return $term; + } + + return $this->getFieldsForTerm($fields, $term); + } + public function getTerm($slug, $fields = []) { $args = [ @@ -1027,32 +1090,51 @@ class Site $output = []; foreach ($results as $term) { - $append = []; - foreach ($fields as $key) { - $oldKey = $key; - if ($key == "id") { - $key = "term_id"; - } - if ($key == "title") { - $key = "name"; - } - - if ($oldKey != $key) { - $append[$oldKey] = $term->$key; - continue; - } - - if ($key === "url" || $key === "permalink") { - $append[$key] = get_term_link($term); - continue; - } - $append[$key] = $term->$key; - } + $append = $this->getFieldsForTerm($fields, $term); $output[] = $append; } return $output; } + private function getFieldsForTerm(array $fields, $term) + { + $output = []; + foreach ($fields as $key) { + if ($key === "id" || $key === "ID" || $key === "term_id") { + $output[$key] = $term->term_id; + continue; + } + + if ($key === "title" || $key === "name") { + $output[$key] = $term->name; + continue; + } + + if ($key === "url" || $key === "permalink") { + $output[$key] = get_term_link($term); + continue; + } + + if ($key === "thumbnail") { + $thumbnailID = get_term_meta($term->term_id, 'thumbnail_id', true); + if (!$thumbnailID) { + $output[$key] = ""; + continue; + } + $output[$key] = wp_get_attachment_url($thumbnailID); + continue; + } + + if (substr($key, 0, 4) === "acf.") { + $key = str_replace("acf.", "", $key); + $output[$key] = get_field($key, $term->taxonomy . "_" . $term->term_id); + continue; + } + $output[$key] = $term->$key; + } + return $output; + } + private function processArgs(array $args) : array { // wordpress default @@ -1413,19 +1495,51 @@ class Site } } - private function processHooks() + private function processActions() { - if (!isset($this->config["hooks"]) || !is_array($this->config["hooks"])) { + if (!isset($this->config["actions"]) || !is_array($this->config["actions"])) { return; } - $defaultPriorities = [ - 'woocommerce_before_main_content' => 5, - 'woocommerce_after_main_content' => 50, - ]; - foreach ($this->config["hooks"] as $hookName => $callback) { - $priority = $defaultPriorities[$hookName] ?? 99; - add_action($hookName, $callback, $priority); + foreach ($this->config["actions"] as $hookName => $callback) { + if (is_array($callback) && array_is_list($callback)) { + $priority = $callback[1]; + $callback = $callback[0]; + add_action($hookName, $callback, $priority); + continue; + } + if (is_array($callback) && isset($callback["hook"]) && isset($callback["callback"])) { + add_action($callback["hook"], $callback["callback"], $callback["priority"] ?? 99); + continue; + } + + add_action($hookName, $callback, 99); } } + + /** + * parseArgs + * Used in conjuction with the handlebars helpers to grab all the different args + * + * @param string $args + * @return array + */ + public function parseArgs(string $args): array + { + $parsed = []; + + // Match key="value", key='value', or key=value + preg_match_all('/(\w+)=(".*?"|\'.*?\'|\S+)/', $args, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + $key = $match[1]; + $value = $match[2]; + + // Strip quotes if present + $value = trim($value, "\"'"); + $parsed[$key] = $value; + } + + return $parsed; + } }