Promotion landing pages
A promotion landing page is a content page of type Promotions, at /promotions/your-page/. It does three jobs:
- it is the landing page for the offer
- it is meant to put a card on the
/promotionslist, though none show today (see The/promotionslist) - it puts a banner at the top of each matching product page
It does not set any prices. Each product’s sale price and promo dates are set on the product itself, and nothing keeps them in step with the page.
To set up, check or end a promotion, follow Run a promotion end to end. This page is the reference for what the promotion page’s fields do and what the page shows.
Fields
| Field | What it does |
|---|---|
| Name | Page heading, /promotions card heading, and heading of the product-page banner |
| Date Posted | Start date. Only the date counts; the time is ignored |
| Label 1 | Promotion code. Must match the code on the products exactly. On the category layout it also switches on the Related Content cards (see below) |
| Label 3 | Length in whole days, for example 30. Never leave it empty |
| Short Description 1 | Text on the /promotions card. Not shown on the page itself with the category layout |
| Main image | /promotions card image, cropped to 3:1 (2:1 on phones). Also the background of the product-page banner, and the page banner on the promotions layout, cropped to 3:1. Upload a 3:1 image, for example 1599 × 533 px, the size used for Learn article banners |
| Alt image 1 | Upload at 450 × 450 (square), the site-wide image for a content page. Shown beside Description 1, cropped to 3:2 |
| Description 1, 2, 3 | Where each shows depends on the body template (see below) |
| Related Content | What it does depends on the body template (see below) |
| Sort Order | Order of the cards on /promotions |
How the dates work
The page has no end-date field. The theme works out the end from Date Posted plus Label 3 days, and compares dates only, never times.
- The promotion is valid from the Date Posted day through Date Posted + Label 3 − 1 days.
- On day Date Posted + Label 3 the
/promotionscard turns “Expired”. - The end date printed on the card, and in the “Promotion Period” line on the
promotionslayout, is Date Posted + Label 3. That is the day after the last valid day.
Example: Date Posted 1 November, Label 3 30. The promotion is valid 1 to 30 November, the card prints “Valid 1 November - 1 December”, and it shows “Expired” from 1 December.
The old guide said the promotion expires at the same time of day as it started. That is wrong: time of day makes no difference to the page or its card. Product promo dates do have times; the workflow gives the recommended times in How promotion dates work.
The banner on product pages
A product page shows the promotion banner when all three of these are true:
- The product is on promotion (between its own promo start and end).
- The product is assigned to the promotion page.
- The product’s promotion code exactly matches the page’s Label 1.
The banner shows the page Name, “Valid until” with the product’s promo end date (not the page’s dates), and a “View Details” button to the promotion page. Its background is the page’s Main image. If the page has no Main image, a stock photo is used instead.
Product pages are cached, so banner changes can take up to about an hour to show.
What live promotion pages show today
Both Promotions pages in the 20 October 2026 content pull use the category body template: the live /promotions/rhino-rack-november/ (Date Posted 18 November 2025) and an inactive test page. No page uses the promotions body template.
On the category layout, from top to bottom:
| Part | What shows |
|---|---|
| Heading | The page Name |
| Description 1 | Shown with the Alt image 1 beside it, only when Description 1 is filled. There is no fallback if Alt image 1 is empty |
| Related Content cards | Up to 4 link cards, only when both Label 1 and Description 1 are filled. Each card shows the related page’s Alt image 1, Name and Short Description 1 |
| Adverts | The category_ad banner carousel, and on the first page of results any adverts assigned to this page with no group |
| Product list | Every product assigned to the page, with filters, sorting and paging |
| Description 2 | At the bottom |
Not shown on this layout: the Main image banner, the “Promotion Period” line, Short Description 1 and Description 3.
The promotions body template
On the promotions layout, from top to bottom:
| Part | What shows |
|---|---|
| Banner | The Main image, cropped to 3:1, when the page has one |
| Heading | The page Name |
| Promotion Period | ”Promotion Period: start - end”, when Date Posted is set. The end printed is the day after the last valid day |
| Short Description 1 | Under the heading |
| Description 1 | With the Alt image 1 beside it. If Alt image 1 is empty, a stock sketch image is used |
| Description 2 | Under Description 1 |
| Product sections | One section per Related Content entry, up to 6. Each lists up to 6 products that are assigned to this page, in that category, and currently on promotion, plus a “See More” card |
| Description 3 | At the bottom |
What this means in practice:
- With no Related Content, the page lists no products at all.
- Products drop off the page by themselves when their promo ends.
The /promotions list
/promotions itself is an ordinary content page named “Promotions”, not the Promotions type. It uses the promotions-list body template, and its intro is that page’s Description 1. It shows a card for each Promotions page, sorted by Sort Order. Each card has the Name, Short Description 1, a status line, a “Read More” link and the Main image. The status is one of:
- “Starts” and the start date, before Date Posted
- ”Valid” and the start and printed end dates, while the promotion runs
- ”Expired” in red, after it ends
Ended promotions stay listed as “Expired” until the page is deactivated.
For developers
Checked against Altapac-ReDev (development branch), Altapac-Content pages/promotions/**/meta.json (both type 16, BodyTemplate: "category") and live altapac.com on 21 October 2026.
src/templates/cms/promotions-list.template.html:content_type=promotionslist sorted bysortorder(line 112);#Y#M#Ddate maths withadd:'[@content_label3@] day'(119-122); Valid / Starts / Expired branches (127-133); card imagethumb:'main'in a 3:1 box, 2:1 on mobile (34-45, 69-71);*ifemptyfallback linking to/current-promotions/(150-154; commit805b848, AUD-63, not onmain). Nothing else in the tree uses*ifemptyon[%list type:'content'%], so check it renders after the releasesrc/templates/cms/promotions.template.html:validThroughstructured data (17); bannerthumb:'full',_cover-banner3:1 (36-41); Promotion Period (47-51); Alt image 1 default4x4-sketch.jpg(66); related-content sections withfilter_content,filter_category,filter_inpromo:'1'(109-161); Description 3 (165)src/css/blog-containers.css:_cover-banner3:1,_content-image3:2src/templates/cms/category.template.html: Description 1 block with Alt image 1 3:2 (109-118); Label 1 related cards nested inside the Description 1 check, limit 4 (120-216);category_ad(223); blank-group adverts (276, 303); unfilteredthumb_list(314); Description 2 (448-452)src/templates/products/template.htmlandproducts/bikeRacks.template.html(lines 2-38):displaycache;inpromogate;content_path type:'promotions';promo_id eq content_label1;glenworth.jpgfallback; “Valid until” frompromo_end.claude/skills/base-templating/references/caching.md:displaycache default ttl 3600 s- Banner image:
asset_url type:'content'with nothumbrenders the page’s base image<id>.jpg, the same filethumb:'full'gives. Live 2026-10-21: the no-thumb call on/locationsrenderscms/02/14002.jpg; the Learn article 15977 cover banner (thumb:'full') iscms/77/15977.jpg, 1599 × 533, and its Alt image 1 is15977-1.jpg, 450 × 450 /promotionshub: content 12352, type 2,BodyTemplate: "promotions-list"(Altapac-Content pull 2026-10-20). Image sizes: Altapac-ContentCLAUDE.md
Open owner decision: category or promotions body template for Promotions pages.