5 Horizons Starter Theme

Bare-bones WordPress starter for new 5 Horizons builds. Bootstrap CSS is loaded for the grid only (bootstrap-grid.min.css — containers, rows/cols, flex/spacing/display utilities; no component styles). The Bootstrap JS bundle (with Popper) is loaded too, so modals/collapse/dropdowns are available — their CSS isn’t, so style them yourself or switch to full bootstrap.min.css in inc/enqueue.php. Swiper is loaded for sliders (front end and editor). Pages are built from Genesis Custom Blocks.

What’s in theme/

PathPurpose
style.cssTheme header only — rename per project
functions.phpThin bootstrap; requires the files in inc/
inc/setup.phpTheme supports, editor styles, menus (Primary, Footer Links), image sizes, sidebar
inc/enqueue.phpGoogle Fonts, Bootstrap grid + JS, Swiper, css/theme.css, js/theme.js; editor assets
inc/customizer.phpTag Manager head/body scripts, Theme Colors → --color-* CSS variables
header.php / footer.phpLogo + primary nav (mobile drawer) / copyright + footer links
index.php, single.php, archive.php, search.php, 404.phpMinimal loops in a .container > .row > .col-12 grid
page.phpJust the_content() — blocks bring their own .container so backgrounds can go full width
blocks/Genesis Custom Block templates (empty — add your own)
scss/theme.scss → @import "custom"; everything lives in _custom.scss. editor-style.scss imports theme + editor tweaks
js/theme.jsMobile nav, generic Swiper init (initSwipers()), stub for block init functions
js/editor-reinit.jsRe-runs block init functions inside the block editor

Starting a new project

  1. Copy this repo (download the ZIP — don’t clone) and initialize it as a new repo.
  2. Update theme/style.css (Theme Name, Description).
  3. Set fonts in fivehd_google_fonts_url() (inc/enqueue.php) and $font-body / $font-heading in scss/_custom.scss.
  4. Set default colors in fivehd_color_defaults() (inc/customizer.php) and the matching fallbacks at the top of _custom.scss.
  5. Use Node 22 (nvm use — the repo’s .nvmrc pins it; Node >= 20.19 is required), then npm install, then npm start to build + watch SCSS (or npm run build once). Build is Gulp 5 + Dart Sass + Autoprefixer (gulpfile.mjs).
  6. In WP Admin: set the logo (Customizer → Site Identity), assign the Primary Menu and Footer Links menus.

Adding a block

Full walkthrough: docs/genesis-custom-blocks-workflow.md. Short version:

  1. Template: create theme/blocks/block-{slug}.php. Wrap the markup in <section class="{slug}"><div class="container"><div class="row">….
  2. Fields: WP Admin → Custom Blocks → Add New, slug {slug}, field names matching what the template reads (block_value() / block_field()).
  3. Styles: add a /*Block Name*/ section to the Blocks area at the bottom of scss/_custom.scss.
  4. JS (only if needed): add an idempotent init{Name}() function to js/theme.js, call it on DOMContentLoaded, expose it on window, and add its name to INIT_FUNCTIONS in js/editor-reinit.js. Never use inline <script> in block markup — it doesn’t run in the editor.

Full Documentation Here

Sliders (Swiper)

Any .swiper is initialized automatically by initSwipers() (front end and editor):

<div class="swiper-slider-wrap">
  <div class="swiper" data-swiper='{"slidesPerView": 1, "breakpoints": {"768": {"slidesPerView": 3}}}'>
    <div class="swiper-wrapper">
      <div class="swiper-slide">…</div>
    </div>
  </div>
  <div class="swiper-pagination"></div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

data-swiper (optional) is JSON merged over the defaults (1 per view, 30px gap, loop, arrows/pagination if present). For a slider that needs its own logic, add swiper--custom and write a dedicated init function. Bump the version with FIVEHD_SWIPER_VER in functions.php.

Full Documentation Here

Deploying (GitLab → WP Engine)

  1. Create staging + production SFTP users at WP Engine with path /wp-content.
  2. Rename .gitlab-ci.yml.template → .gitlab-ci.yml and fill in THEME_DIR and the two hosts.
  3. Add WPENGINE_PROD_USER/PASS and WPENGINE_STAGING_USER/PASS in GitLab → Settings → CI/CD → Variables (protected + masked).
  4. Pushes to staging deploy to staging; pushes to main deploy to production (deploy.sh archives the previous theme folder first).

Upload on save (VS Code)

.vscode/sftp.json (git-ignored) is set up for the Natizyskunk SFTP extension: fill in host, username, password and theme folder for each profile (staging is the default; switch with SFTP: Set Profile). Saving any file in theme/ uploads it, and the watcher also uploads Gulp’s output in theme/css/ whenever npm start rebuilds it. A fresh clone won’t have this file – copy it from another project or recreate it.

(Sublime users: copy theme/sftp-config.example.json to theme/sftp-config.json, also git-ignored.)