Freeframe

Documentation

Wander

v1.0.0Updated Oct 12, 2026A sun-warmed, editorial site for a small-group tour company, with a trip finder, filters and a booking enquiry.

Overview#

Wander is a site for a small-group tour company, built as a WordPress block theme. The fictional brand is Saltwind Journeys, a travel company on Bristol's harbourside that runs trips of twelve travellers or fewer in Morocco, Peru, Norway, the Aegean, Japan and Tanzania. The theme has a home page with a trip finder, featured tours, regions, traveller postcards and a newsletter; a tours page you can filter by region, style, duration, month and budget; tour pages with a day-by-day itinerary, an illustrated route map, departure dates and a booking widget with a live-priced enquiry; a destinations page with a month-by-month seasonality chart; a journal with a topic filter and an article; an about page; a contact page with an FAQ; and a 404 page. It is version 1.0.0 (see template.json and style.css), works with WordPress 7.1 and PHP 7.4 or newer, and is the WordPress version of the HTML template of the same name. See it live at freeframe.dev/templates/wander.

The pages (headings, copy, region cards, reviews, the journal, the about and contact pages, buttons) are core WordPress blocks arranged in block patterns, so you edit them in the block editor without touching code. The tours work as in the HTML version: the twelve trips and six regions are lists in assets/js/main.js, and the script draws the tour cards, the filters' results, the tour page, the departure dates, the prices and the seasonality chart from them. There are no photos: every landscape, route map and portrait is an SVG illustration drawn by the same script. Colours and fonts are design tokens in theme.json: change them in Appearance > Editor > Styles and the whole site follows.

Quick start#

Requirements: WordPress 7.1 or newer and PHP 7.4 or newer. No plugins are needed.

  1. Download wander.zip from freeframe.dev/templates/wander (the WordPress tab).
  2. In your WordPress admin go to Appearance > Themes > Add New Theme > Upload Theme, choose the zip and click Install Now, then Activate. The theme is listed as Freeframe Wander.
  3. Go to Appearance > Wander setup and click Create the demo pages. This creates the Home, Tours, Tour, Destinations, Journal, Article (Walking the High Atlas), About and Contact pages from the theme's page patterns, sets Home as the front page (Settings > Reading) and creates the header menu. Pages that already exist with the same slug are left alone, so it is safe to click it again.
  4. In Settings > General, the demo uses "Saltwind" as the Site Title and "Journeys · Bristol" as the Tagline: the header shows both next to the logo. Set your own.
  5. Visit your site. Edit any page in Pages, and the header, footer and templates in Appearance > Editor.

You can also try the theme without installing anything: the Try it in WordPress button on freeframe.dev opens it in WordPress Playground (WordPress running in your browser) with the demo pages already set up.

To work on the theme's files locally you need Node.js 24 and pnpm; WordPress itself runs in WordPress Playground, so there is no PHP, web server or database to install:

sh
pnpm install
pnpm dev     # builds the CSS, then starts WordPress with the theme at http://127.0.0.1:9400

pnpm dev signs you in as admin (password password) and creates the demo pages. The site is rebuilt from scratch every time you start it; your edits to theme files are live, edits made in the WordPress admin are not kept.

Pages#

Each page is a page pattern (in Patterns > Wander pages) made of section patterns. Every section is also offered on its own in the block inserter under Patterns > Wander.

Page Slug Page pattern Sections (pattern files in patterns/)
Home / page-home.php home-hero (postcards and stamp), trip-finder, ticker, featured-tours (tour cards), why-travel, regions (destination cards), reviews, journal-teaser, newsletter
Tours /tours/ page-tours.php tours-header, tours-results (filters, sort, chips and tour grid), private-trip-cta
Tour /tour/?id=atlas-sahara page-tour.php tour-hero (key facts and price), tour-details (highlights, itinerary, route, included, dates, booking widget, enquiry), tour-related, tour-mobile-bar
Destinations /destinations/ page-destinations.php destinations-hero, seasonality (the year at a glance), region-morocco, region-andes, region-nordics, region-aegean, region-japan, region-africa, when-to-go-cta
Journal /journal/ page-journal.php journal-header, journal-feature, journal-stories (topic filter and story cards), journal-cta
Article /article/ page-article.php article-progress (reading progress bar), article-body (header, contents and story), article-trips
About /about/ page-about.php about-hero, about-numbers, about-story (timeline), guides, responsible (commitments and where your money goes), about-cta
Contact /contact/ page-contact.php contact-header, contact-form (form, office and emergency line), faq
404 any missing URL templates/404.html 404

The script finds the tours, tour and contact pages by their slugs (tours, tour, contact): if you rename one, change its URL in freeframe_wander_page_urls() in inc/setup.php too. Posts use templates/single.html; the blog, archives and search results use templates/index.html, templates/archive.html and templates/search.html.

Project structure#

freeframe-wander/
  style.css                 theme header (name, version, requirements, license); no styles
  theme.json                design tokens: palette, fonts, font sizes, spacing, layout widths, button
  functions.php             loads the files in inc/
  inc/setup.php             stylesheet and script (with its strings and page URLs), editor styles,
                            the `js` class script, pattern categories
  inc/icons.php             registers assets/icons/*.svg for the Icon block
  inc/icon-labels.php       the icons' names shown in the editor
  inc/block-styles.php      button block style
  inc/site-setup.php        Appearance > Wander setup: creates the demo pages and the menu
  templates/                page.html (pages), page-with-title.html, single.html, index.html,
                            archive.html, search.html, 404.html
  parts/                    header.html and footer.html (they show the header and footer patterns)
  patterns/                 every section and page (PHP files with block markup)
  assets/css/theme.css      the compiled stylesheet (do not edit: built from src/)
  assets/css/editor.css     the same for the block editor (generated by src/editor-css.mjs)
  assets/js/main.js         tours and regions, illustrations, filters, tour page, booking, forms
  assets/icons/             SVG icons for the Icon block
  assets/img/               logo, favicon, social image
  assets/fonts/             Caprasimo, Outfit and Kalam, with their licenses
  src/theme.css             the Tailwind CSS source of assets/css/theme.css
  src/icons.css             icons drawn before or after text with CSS (generated)
  src/editor-css.mjs        writes assets/css/editor.css after each build
  languages/                freeframe-wander.pot, the template for translations
  blueprint.json            WordPress Playground setup used by `pnpm dev`
  screenshot.png            the picture shown in Appearance > Themes
  package.json              the CSS build and the local WordPress (Node.js tooling)
  readme.txt, README.md, DOCS.md, CHANGELOG.md, LICENSE.txt

Customising#

Brand and colours#

The colours are in theme.json (settings.color.palette) and in Appearance > Editor > Styles > Colors > Palette:

Colour Default Used for
Paper #fbf5ea the page background
Postcard #fffaf1 cards, form fields, stamps
Sand, Dune #f4e6cc, #ecd5ad panels, chart cells
Line #e2cfae borders and dashed rules
Ink #23180f text, outlines and the offset card shadows
Muted #66523f secondary text
Clay, Clay dark #b0431d, #8c3214 the brand: primary buttons, links, eyebrows
Sun, Sun deep #f4a62a, #b86e00 stamps, the ticker, highlights; stars and icons
Sea, Deep #0e5a5f, #0a3b3f dark bands, "best" season, the footer
Lagoon, Coral #7cc4b8, #ef7b5a decoration and charts
Foam #fff9ef text on dark backgrounds
White, Black for your own blocks

The theme's stylesheet reads these colours from the palette (bg-clay, text-muted...), so changing Clay in Styles recolours every button and link at once. A few colours are written directly into SVG: the landscape palettes (SKIES and LAYERS) and the route map pins in assets/js/main.js, the logo (assets/img/logo.svg), the 404 compass and the favicon.

Typography#

Three fonts are bundled in assets/fonts/ and declared in theme.json (settings.typography.fontFamilies), so no request goes to Google: Caprasimo (preset display) for headings, prices and stamps, Outfit (variable, 300 to 700; preset sans) for text, and Kalam (400 and 700; preset hand) for the handwritten postcard notes (the hand class). Caprasimo has a single weight, so headings use font-normal. To use other fonts, install them in Styles > Typography > Fonts (the Font Library) and select them, or replace the fontFace entries in theme.json. The utility classes read the presets (--wp--preset--font-family--display, --sans, --hand), so keep those slugs. The route map labels and the postmarks name Outfit directly (font-family="Outfit, sans-serif").

Font sizes are the presets in theme.json (xs 0.75rem to 9xl 8rem, the Tailwind scale).

Content#

Edit pages in Pages: click any text to change it, select a button to change its link. Sections are groups; open List View (the stacked lines icon at the top left) to select a section, move it, duplicate it or delete it. To add a section from another page, use the block inserter (+) > Patterns > Wander.

What the script draws or fills is in Custom HTML blocks: edit those in the block's HTML view, and keep their ids and data- attributes.

Pattern Custom HTML What it is
most sections <div class="art-frame …" data-art="dunes" data-time="dusk">, <span … data-avatar="…"> landscapes and portraits, see Images and artwork
home-hero, newsletter, about-hero, contact-form, 404 the postmarks and the compass decorative SVG
trip-finder the finder form see Trip finder
ticker the scrolling place names hidden from screen readers (decoration)
featured-tours, tour-related, article-trips the tour grid (data-featured-tours, data-related, data-tour-list="toubkal-trek,atlas-sahara,inca-trail") tour cards from the tour list
tours-results the filters and the results (count, sort, chips, grid, empty state) see Tour filters
tour-hero, tour-details, tour-mobile-bar the breadcrumb, rating, artwork, highlights, itinerary, map, included lists, dates table, booking widget, enquiry form and price bar see Tour page
seasonality, region-* the legend, the table and each region's chart (data-season="morocco") see Seasonality
journal-stories the topic buttons and the status line see Journal filter
responsible the "where your money goes" bar and its legend an illustration with a text alternative
all pages breadcrumbs, forms and their success messages see Forms
header, footer the menu button, the footer wave and the toast driven by the script

A few blocks carry a class (Block settings > Advanced > Additional CSS class(es)) that the script or stylesheet reads:

  • ffd-<name>--<value> is turned into the attribute data-<name>="<value>" when the page loads (blocks can't store data attributes): ffd-tour--name on the tour page's heading marks it to be filled with the tour's name, ffd-topic--food files a journal story under Food, ffd-region-count--morocco shows a region's number of trips ("2 trips").
  • reveal fades a block in as it scrolls into view.
  • link-card on a group makes the whole group clickable: the first link inside it stretches over the group (the region cards on the home page, the logo).
  • stamp and stamp-inner draw the perforated postage stamp; airmail the striped airmail border; eyebrow the small clay heading with a dash; display the Caprasimo headline style; hand the handwritten font.

The tour list

Tours are the TOURS list in section 1 of assets/js/main.js. Each tour looks like this:

js
{
  id: 'dolomites-huts', name: 'Dolomites Hut to Hut', region: 'alps', country: 'Italy', style: 'hiking',
  days: 8, price: 2290, single: 280, rating: 4.8, reviews: 0, group: 12, level: 'Moderate', badge: 'New',
  months: [6, 7, 8, 9], scene: 'mountains', time: 'day', featured: 0,
  summary: 'Seven days between mountain huts, with your bags sent ahead.',
  highlights: ['Tre Cime at sunrise', 'Nights in family-run huts', 'Via ferrata taster'],
  includes: ['Hut-to-hut luggage transfers'], excludes: [],
  stops: [[20, 70, 'Cortina'], [45, 45, 'Tre Cime'], [75, 30, 'Sesto']],
  itinerary: [
    { d: '1', t: 'Cortina', x: 'Meet the group and walk to the first hut.', stay: 'Rifugio Lago' },
    { d: '2–7', t: 'Hut to hut', x: 'Six days on high trails.', stay: 'Mountain huts' },
    { d: '8', t: 'Departure', x: 'Transfers to Venice airport.', stay: '' }
  ]
}
Field Notes
id Unique, lower case, used in /tour/?id=… and /contact/?tour=… (any letter case)
region, style The id of a REGIONS and a STYLES entry: the tour then appears under those filters. A new region also needs a checkbox in the filters (the Custom HTML of tours-results: copy a <label class="pill-check"> and change value and data-count-for), an option in the trip finder, and a region section on the destinations page if you want one
price, single The lowest price per person and the own-room supplement per person, in pounds
months The months (1–12) the tour departs: they drive the month filter and the departure dates
scene, time The card and hero artwork (see Images and artwork)
stops Route map points [x, y, name], x and y as percentages of the map's width and height
itinerary Accordion rows: d the day or range, t the title, x the text, stay the overnight (empty hides it)
featured 1 to 4 puts the tour on the home page in that order and first in "Recommended" sort
badge Optional label on the card

The other settings sit next to the list: REGIONS (with each region's season), STYLES, DURATIONS, INCLUDED and EXCLUDED (lines on every tour page), PRICE_MIN and PRICE_MAX (the budget slider), PEAK_SUPPLEMENT (£150), DEPOSIT (£300 per person), MAX_TRAVELLERS (8), BOOKING_CUTOFF (21 days) and DEPARTURE_DAYS. Prices are formatted as pounds with toLocaleString('en-GB') and dates with Intl.DateTimeFormat('en-GB'); change money(), fmtShort and fmtLong for another currency or locale. The tour page's blocks contain Atlas to the Sahara as default text; the script replaces it with the tour from the URL.

Edit assets/js/main.js in a child theme (copy it there and load it instead), or your tours are overwritten when you update the theme. Tour names, summaries and itineraries are data, not translatable strings.

Images and artwork#

There are no photos. Every landscape is an SVG drawn by art(scene, time, label) in assets/js/main.js. Scenes are dunes, mountains, fjord (with northern lights at night), coast, fuji and savannah; times are dawn, day, dusk and night. Place one anywhere with a Custom HTML block (add data-label to give it alt text; without it the art is decorative):

html
<div class="art-frame aspect-[4/3] rounded-[2rem]" data-art="coast" data-time="dusk" data-label="Sunset over Milos"></div>

The art is cropped to fit its frame, so any aspect ratio works. To use a photo instead, replace the Custom HTML block with an Image block (cards and region sections are 4:3, the tour hero 21:9 on desktop), or return an <img> from art(). The art-frame class adds a subtle paper grain over whatever is inside. routeMap(tour) draws the tour page map from stops, and avatar(spec) the guide and traveller portraits for elements with data-avatar="skin,hair,style,background" (style is short, long, bun, curly or bald). In the editor the frames are empty: the script draws them on the site.

The logo is assets/img/logo.svg in an Image block next to the Site Title and Site Tagline blocks in the header (the title alone in the footer); the words come from Settings > General. Icons are Icon blocks: select one and pick another from the Wander collection or WordPress's own. The social image is assets/img/og-image.png (1200 × 630, source og-image.svg); the favicon assets/img/favicon.svg is used until you set a Site Icon in Settings > General.

The header and footer are template parts (parts/header.html, parts/footer.html) showing the header and footer patterns. Edit them in Appearance > Editor > Patterns > Header / Footer. The header pattern starts with the announcement bar ("Next season's departures are open").

The header has two Navigation blocks showing the same menu: the desktop one and the one in the mobile menu. Edit the menu once in Appearance > Editor > Navigation (the setup creates "Main menu"). Its first link (Home) is hidden in the desktop header, as in the HTML version; keep Home first, or remove the .site-nav … :first-child rule in src/theme.css. A Navigation block that doesn't point at a menu shows the most recently created one; to pin a menu, select the Navigation block and choose it in the block settings, for both blocks.

The footer's Trips and Saltwind menus and the bottom links are List blocks: click a link to change it, press Enter to add one. The Instagram, booking conditions and privacy links point to #; replace them with your own pages.

Features#

Trip finder#

initFinder(). The form #trip-finder on the home page (the trip-finder pattern) has four selects (region, month, style, duration). On submit it opens the tours page with only the chosen values as URL parameters, for example /tours/?region=japan&month=4. Without JavaScript the form still submits to the tours page.

Tour filters#

initTours() on the tours page. The form #tour-filters has checkboxes named region, style and duration (several in one group combine with OR, groups combine with AND), a month select and a max budget slider. #sort orders by recommended, price, length or rating (SORTS). Every change re-renders #tour-grid, updates the live count #result-count, the removable chips in #active-filters and the small count next to each option (how many trips you'd see if you ticked it), and writes the state to the URL:

/tours/?region=morocco,japan&style=hiking&duration=medium&month=5&max=3000&sort=price-asc

Names and values are case-insensitive, lists can be comma-separated or repeated, and unknown values are ignored, so filtered views can be linked (the footer's "Hiking & trekking" link is /tours/?style=hiking). When nothing matches, #tour-empty appears with a reset button. On phones the filters are behind #filters-toggle (aria-expanded), with a badge showing how many are active. When a month is chosen, card links carry it (/tour/?id=…&month=5) so the tour page preselects a departure in that month.

Tour page#

initTourPage(). /tour/?id=lofoten-peaks shows that tour (any letter case); a missing or unknown id shows the first tour. The browser tab title, the blocks marked ffd-tour--name (and summary, days, price, rating, reviews, level, group, region, country, style, single), the hero art, highlights, included and excluded lists, route map and related tours are filled from the data. The itinerary is a list of buttons with aria-expanded; the first day starts open and "Expand all days" opens or closes every day.

Departures and prices#

departures(tour, limit) works out the next eight departures: in each month in tour.months, a departure leaves on the first Saturday on or after each day in DEPARTURE_DAYS, skipping any sooner than BOOKING_CUTOFF days from today. Months rated 3 ("best") in the region's season cost PEAK_SUPPLEMENT more and are marked "Peak". Places left are demo data from a stable hash of the tour and date, so they are the same on every visit: 0 shows "Full", 1–3 "Only N left", and a departure with four or more travellers booked shows "Guaranteed". Replace departures() with your real dates if you have them; the table and widget only need objects of the form { start, end, month, price, peak, left, guaranteed }.

Booking widget and enquiry#

The #booking-widget card has a departure select (#dep-select), a travellers stepper (1 to MAX_TRAVELLERS, never more than the places left) and a room choice. quote() returns the price per person, the own-room supplement, the total and the deposit, shown live in an aria-live list. "Choose" buttons in the dates table select a departure. The current choice is written to the summary above the enquiry form and to its hidden fields (tour, departure, travellers, room, total), so a connected form receives everything. On phones a fixed bar at the bottom shows the total. ?date=YYYY-MM-DD, ?month=5 and ?travellers=3 preselect choices.

Seasonality#

initSeasons() on the destinations page builds the #season-table table (a row per region, a cell per month, each with a screen-reader label such as "April: Best") and fills each [data-season="<region id>"] element with a 12-bar chart and the list of best months, all from REGIONS[].season. Levels are 0 (avoid), 1 (possible), 2 (good) and 3 (best). The table scrolls sideways on small screens with the region names kept in view.

Journal filter#

initJournal(). The topic buttons (data-topic-btn, with aria-pressed) show only the story cards whose topic matches; #journal-status announces the result and the URL keeps ?topic=. To add a story, duplicate a story card in List View and change its class ffd-topic--<topic> to one of guides, stories, food or practical.

Scroll reveal, ticker, progress and back to top#

Blocks with the reveal class fade in when scrolled into view. The home page ticker scrolls with CSS and pauses on hover; the hero stamp floats (float). On the article page the progress bar grows with how far you have read. Reveals, the ticker and the float stop for visitors who prefer reduced motion. The back-to-top button appears after scrolling about one screen down, returns to the top and moves focus to the main content; to remove it, delete the "Back to top" part of assets/js/main.js and the .back-to-top styles in src/theme.css, then run pnpm build.

Block styles#

In the block settings' Styles panel:

Block Styles
Button Fill (default, the clay button), Outline, Sun

The classes is-px-5, is-px-7, is-px-8, is-py-2-5, is-py-3-5 and is-py-4 on a Button block make it wider or taller (the hero buttons use them); icon-after-arrow-right adds the arrow.

FAQ answers on the contact page are Details blocks: add one by duplicating an answer in List View; its summary layout comes from classes starting with [&>summary]: and its round plus button is drawn by CSS (ff-faq).

Forms#

All forms with data-validate are checked by initForms() in assets/js/main.js: errors appear on blur and on submit, the first invalid field is focused, and each error is in the element <field id>-error, linked with aria-describedby. Rules come from attributes in the forms' Custom HTML: required (checkboxes must be ticked; message from data-msg), type="email", type="tel" (digits, spaces, +, (, ) and -, 7 to 20 characters), minlength and data-label (the words in the "Enter …" message).

Form Where Success state
Newsletter (#newsletter-form) Home (newsletter) #newsletter-success
Enquiry (#enquiry-form) Tour (tour-details, #enquire) #enquiry-success, repeating the booking summary
Contact (#contact-form) Contact (contact-form) #contact-success

The form's data-success attribute names its success box. Nothing is sent, and the success messages say so. To collect submissions, use a form plugin (replace the form's Custom HTML block with the plugin's block; add the classes field, field-label and btn-primary to its fields, labels and button), or post the form in onValid() in section 11 of assets/js/main.js (in a child theme), for example to Formspree:

js
function onValid(form) {
  fetch('https://formspree.io/f/your-id', {
    method: 'POST', body: new FormData(form), headers: { Accept: 'application/json' }
  }).then(function (res) {
    if (res.ok) showSuccess(form); else toast('Something went wrong. Please email us.');
  });
}

Then change the success text in the patterns to say the message was received. Every field has a name, so FormData carries all values; keep a name on any field you add. The contact form's trip list is filled from TOURS, and /contact/?tour=kumano-kodo preselects a trip.

SEO and sharing#

Page titles come from WordPress: the page title, a vertical bar and the site name (for example "Tours | Saltwind"); the home page shows the site name and tagline (Settings > General). The tour page sets its title from the tour ("Lofoten Peaks & Fjords — 7 days in Norway | Saltwind") once the script runs (and the meta description, if an SEO plugin prints one). The theme doesn't output meta descriptions or Open Graph tags; use an SEO plugin such as Yoast SEO, Rank Math or The SEO Framework, and give it assets/img/og-image.png (or your own 1200 × 630 image) as the default social image. WordPress already generates a sitemap at /wp-sitemap.xml. Tours are drawn by JavaScript from one page; if search visibility for each tour matters, give each tour a page of its own.

Accessibility#

Built in: a skip link to the main content (added by WordPress, styled by the theme), landmarks (header, labelled navigation, main, footer), one h1 per page, labelled sections, breadcrumbs with aria-current, visible focus rings, the menu button with aria-expanded and a label that changes with its state (Escape closes the menu), real checkboxes and radios for filters and room choices, live regions for the result count, the journal status, the booking total and the toast, an itinerary of buttons with aria-expanded, FAQ answers in <details>, a seasonality table with text for every cell, text alternatives for the route map, region charts and meaningful art (decorative art is hidden), form errors announced through aria-describedby and aria-invalid, and reduced-motion support for every animation. The demo passes axe (WCAG 2.1 A and AA).

When you edit: keep one Heading 1 per page, give images alt text (or mark them decorative), add data-label to art that carries meaning, keep link text meaningful, and label any field you add to a form (<label for="...">).

Building and deploying#

You only need this if you change the theme's files. The stylesheet assets/css/theme.css is compiled with Tailwind CSS from src/theme.css and the classes used in patterns/, parts/, templates/, inc/ and assets/js/:

sh
pnpm install
pnpm build   # compile assets/css/theme.css and assets/css/editor.css
pnpm watch   # recompile assets/css/theme.css on every change (run pnpm build before you commit)

Run pnpm build after adding a utility class to a pattern, template or the script's markup, otherwise the class has no style. Classes you type in the editor's Additional CSS class(es) field are only styled if the stylesheet already contains them.

To deploy, zip the theme folder (named freeframe-wander, without node_modules/) and upload it in Appearance > Themes, or copy the folder to wp-content/themes/ on your server.

Translations#

The theme is translation-ready with the text domain freeframe-wander. All text in patterns, templates and PHP goes through WordPress's translation functions; the script's strings (tour cards, filters, the tour page, booking messages, seasons, form errors) are translated in PHP (freeframe_wander_script_strings() in inc/setup.php). Tour names, summaries and itineraries are data in assets/js/main.js. Create a translation with Loco Translate, or with WP-CLI and Poedit:

sh
wp i18n make-pot wp-content/themes/freeframe-wander wp-content/themes/freeframe-wander/languages/freeframe-wander.pot

Save freeframe-wander-de_DE.mo (for example) in wp-content/languages/themes/ or in the theme's languages/ folder. Page content created by Wander setup is copied into your pages in the site's language at that moment; translate it in the editor like any other content.

Child themes#

Use a child theme for changes you want to keep when Wander is updated (your tours in particular). Create wp-content/themes/wander-child/style.css:

css
/*
Theme Name: Wander Child
Template: freeframe-wander
*/

Templates, parts, patterns and theme.json in the child theme override the parent's files of the same name. To use your own copy of assets/js/main.js, dequeue the parent's script (freeframe-wander) and enqueue yours with the same dependencies in the child's functions.php. The parent's stylesheet only contains the classes the parent uses: if your child theme uses new utility classes, compile a stylesheet for the child (copy package.json and src/theme.css, point the @source lines at the child's folders) and enqueue it.

Troubleshooting#

  • The pages look unstyled or new classes do nothing. The stylesheet only contains classes it found when it was built. Run pnpm build after editing patterns, then reload.
  • "This block contains unexpected or invalid content". A pattern or page was edited by hand with markup that doesn't match the block. Click Attempt recovery, or re-insert the section from Patterns > Wander.
  • Tour cards link to a page that doesn't exist. The script links to /tour/, /tours/ and /contact/. If you renamed those pages, update freeframe_wander_page_urls() in inc/setup.php.
  • A new tour doesn't appear under a filter, or shows no departures. Its region and style must match an id in REGIONS and STYLES, and its months must be numbers from 1 to 12; departures are only generated for the next 15 months and never sooner than BOOKING_CUTOFF days away.
  • Prices look higher than "from". Departures in a region's best months add PEAK_SUPPLEMENT; set it to 0 to turn peak pricing off.
  • Home is missing from the desktop menu, or another link is. The desktop header hides the menu's first link. See Navigation, header and footer.
  • Wander setup says the pages exist, but they are empty. It never overwrites existing pages. Delete (and empty the trash of) the pages with those slugs, or open each page and insert its page pattern from Patterns > Wander pages.
  • The forms don't send anything. They are demo forms; see Forms.

License#

MIT, which is compatible with the GPL that WordPress requires (see LICENSE.txt in the theme folder). Free for personal and commercial use. The illustrations, logo and social image are included under the same license. Caprasimo, Outfit and Kalam are licensed under the SIL Open Font License 1.1 (OFL.txt in each folder of assets/fonts/).

Search documentation

Search the guides and every template's documentation