Enfection Labs · Internal Documentation

Base Theme
Developer Guide

Everything you need to build new WordPress projects from this starter theme — architecture, tokens, PHP patterns, and deployment steps all in one place.

SCSS Framework Reference → WordPress + Bootstrap 5 Gulp 5 + Sass

Overview

Project identity and naming conventions for the base theme.

This WordPress starter theme is maintained by Enfection Labs. It is used as the foundation for all new client WordPress projects. The theme is generic by design — no client-specific code should exist in this repository.

Text domain: base-theme  |  Package: Base_Theme  |  Version constant: THEME_VERSION

Starting a New Client Project

When spinning up a new client site from this base:

  1. Rename the function prefix from theme_{project}_ (e.g. acme_)
  2. Update the text domain from base-theme{project}
  3. Replace all design tokens in sources/sass/abstract/_variables.scss
  4. Swap in the client's Google Fonts in inc/enqueue.php
  5. Update BrowserSync proxy in gulpfile.js line 54

Stack

Technologies and libraries bundled into every project.

CSS Framework
Bootstrap 5
Grid + utilities base
Build Tool
Gulp 5
+ npm scripts
Styles
Sass (SCSS)
→ assets/css/theme.css
JavaScript
Concat + Terser
→ assets/js/theme.js
Animations
GSAP + AOS
ScrollTrigger included
Lightbox
GLightbox
CDN — no JS bundle
Icons
Remix Icon
CDN — 2800+ icons
CMS Extras
ACF Pro
Required — fields + options

Build & Setup

Commands to install dependencies and compile assets.

CommandAction
npm installFirst-time setup — installs all dependencies
gulpCompile everything + watch + BrowserSync
gulp compileSassCompile CSS only (no watch)
gulp compileJsCompile JS only (no watch)
BrowserSync proxy: Edit gulpfile.js line 54 to match your local development URL before running gulp. For example: proxy: 'myproject.local'

What Gulp does

  • Compiles sources/sass/theme.scssassets/css/theme.css (with sourcemaps in dev)
  • Concatenates & minifies sources/js/**/*.jsassets/js/theme.js
  • Reloads browser on file change via BrowserSync

Sass Architecture

sources/sass/theme.scss is the single Sass entry point. Load order matters.

theme.scss ├── _vendors.scss # Bootstrap, AOS via @import ├── abstract/ │ ├── _index.scss # @forward entry for the abstract layer │ ├── _variables.scss # ← DESIGN TOKENS — edit here only │ ├── _functions.scss # strip-unit(), rem(), get-vw() │ ├── _mixins.scss # respond-to(), flex helpers, transitions… │ ├── _global.scss # Font face, :root CSS vars, reset, base elements │ ├── _colors.scss # .text-*, .bg-*, .border-* utility classes │ └── _common.scss # Full utility framework (spacing, flex, display…) └── theme/ ├── _header.scss ├── _footer.scss ├── _home-template.scss ├── _about-template.scss ├── _contact-template.scss ├── _experts-template.scss ├── _news-template.scss └── template-parts/ ├── _title-with-intro.scss └── _practice-areas.scss

Adding a New Page Template

Three files required every time:

  1. Create page-templates/my-template.php
  2. Create sources/sass/theme/_my-template.scss
  3. Add @use "theme/my-template"; to sources/sass/theme.scss
<?php
/**
 * Template Name: My Template
 * @package Base_Theme
 */
defined( 'ABSPATH' ) || exit;
get_header();
// template output here
get_footer();

Adding a Single Post Type Template

Create single/single-{post_type}.php — WordPress's single.php routes to it automatically via the template hierarchy.

Design Tokens

All tokens live in sources/sass/abstract/_variables.scss — the single source of truth.

Never edit the maps directly. Change only the named Sass variables at the top of _variables.scss. All derived maps, CSS custom properties, and utility classes update automatically.

How It Works

The variables file defines named Sass variables. Sass maps are then derived from those variables and used to generate:

  • CSS custom properties in _global.scss — e.g. --color-primary, --space-4, --bp-md
  • Color utility classes in _colors.scss — e.g. .bg-primary, .text-secondary
  • Font utility classes in _common.scss — e.g. .primary-font, .secondary-font

Spacing Scale

VariableValuePixelsCSS Var
$space-10.25rem4px--space-1
$space-20.5rem8px--space-2
$space-30.75rem12px--space-3
$space-41rem16px--space-4
$space-51.5rem24px--space-5
$space-62rem32px--space-6
$space-73rem48px--space-7
$space-84rem64px--space-8

Colors

Defined in $colors map in _variables.scss. Generates .text-*, .bg-*, and .border-* utility classes automatically.

Bootstrap class conflicts: Our color utilities are prefixed body .bg-* / body .text-* to outspecify Bootstrap's same-named classes. Always use bg-primary, text-secondary, etc. — they will use brand colors, not Bootstrap's defaults.
primary
#1a1a2e
.bg-primary · .text-primary
secondary
#16213e
.bg-secondary · .text-secondary
surface
#0f3460
.bg-surface · .text-surface
white
#ffffff
.bg-white · .text-white
text
#f5f5f5
.bg-text · .text-text
text-muted
#6b7280
.text-text-muted
border
#e5e7eb
.border-border
dark-primary
#0d0d1a
.bg-dark-primary

Changing a Color

// sources/sass/abstract/_variables.scss
$color-primary:   #132D51;    // ← change this
$color-secondary: #0a1628;
$color-surface:   #1e3a5f;

Breakpoints

Defined in $breakpoints map. Use the mixin in Sass, the CSS var in inline contexts.

sm 640px
$bp-sm --bp-sm
md 768px
$bp-md --bp-md md-* classes
lg 1024px
$bp-lg --bp-lg lg-* classes
xl 1280px
$bp-xl --bp-xl xl-* classes
2xl 1536px
$bp-2xl --bp-2xl

Usage in Sass

// Mobile-first (min-width)
@include respond-to('md') {
  /* applies at ≥768px */
}

// Max-width (below a breakpoint)
@include respond-below('lg') {
  /* applies at <1024px */
}

Mixins

Defined in sources/sass/abstract/_mixins.scss. Use with @include.

MixinOutputUsage
flex-centerdisplay:flex; align+justify: center@include flex-center;
flex-betweendisplay:flex; align: center; justify: space-between@include flex-between;
flex-coldisplay:flex; flex-direction: column@include flex-col;
flex-col-centercolumn flex, centered@include flex-col-center;
absolute-fillposition:absolute; inset:0@include absolute-fill;
absolute-centerabsolute; top/left 50%; translate -50%@include absolute-center;
cover-imagewidth/height 100%; object-fit: cover@include cover-image;
line-clamp(n)Clamp to n lines with ellipsis@include line-clamp(3);
truncateSingle-line ellipsis overflow@include truncate;
transition(props…)0.3s ease transition on each prop@include transition(opacity, transform);
visually-hiddenSR-only, invisible but accessible@include visually-hidden;
focus-ring($color)2px outline + 2px offset@include focus-ring();

Utility Functions

Defined in sources/sass/abstract/_functions.scss.

FunctionInput → OutputUse case
rem($px) rem(16px)1rem Convert px to rem (base 16)
get-vw($px) get-vw(32px)1.667vw Viewport-relative size based on 1920px design width
strip-unit($val) strip-unit(4px)4 Remove CSS unit from a value
// In your SCSS
.hero-title {
  font-size: rem(48px);   // → 3rem
}

@include respond-to('xl') {
  .hero-title {
    font-size: get-vw(72px); // → 3.75vw (scales with viewport)
  }
}

Page Templates

Each page template lives in page-templates/ and is paired with a Sass file.

PHP FileSass FileTemplate Name
page-templates/home.phptheme/_home-template.scssHome Template
page-templates/about.phptheme/_about-template.scssAbout Template
page-templates/contact.phptheme/_contact-template.scssContact Template
page-templates/experts.phptheme/_experts-template.scssExperts Template
page-templates/news.phptheme/_news-template.scssNews Template

Template Checklist

  1. Add the Template Name: docblock at the top of the PHP file
  2. defined('ABSPATH') || exit; on line 1
  3. Call get_header() and get_footer()
  4. Create the paired Sass file and @use it in theme.scss

Single Post Type Templates

WordPress routes single-{post_type}.php automatically via the template hierarchy.

Create the file in the single/ directory:

// single/single-news_insight.php
<?php
defined( 'ABSPATH' ) || exit;
get_header();

if ( have_posts() ) :
  while ( have_posts() ) :
    the_post();
    // output single post content
  endwhile;
endif;

get_footer();

PHP Conventions

Standards to follow in all PHP files in this theme.

RuleExample
Function prefixtheme_enqueue_styles() → rename to {project}_
Customizer key prefixget_theme_mod('theme_logo_width')
Security first linedefined('ABSPATH') || exit;
Theme support hooktheme_setup() on after_setup_theme
Escape HTML outputesc_html()
Escape URLsesc_url()
Escape attributesesc_attr()
Escape rich contentwp_kses_post()
AJAX URL (JS)theme_ajax.ajax_url
AJAX nonce (JS)theme_ajax.nonce
Verify AJAX nonce (PHP)check_ajax_referer('theme_nonce')

Escaping Examples

// Text content
echo esc_html( get_the_title() );

// URLs
echo esc_url( get_permalink() );

// Attributes
echo esc_attr( get_field( 'alt_text' ) );

// HTML (limited tags allowed)
echo wp_kses_post( get_the_content() );

ACF Fields

Advanced Custom Fields configuration for the global options page.

The options page is registered under the slug theme-general-settings. ACF Pro must be installed and activated.

Options Page Fields

Field KeyPurposeUsed In
footer_introFooter introductory textfooter-template.php
addressCompany physical addressfooter-template.php
contact_numberMain phone numberfooter, contact page
emailMain email addressfooter, contact page
whatsappWhatsApp numberVarious CTAs
social_linksRepeater: social platform + URLfooter-template.php
theme_logo_headerImage object — header logoheader-template.php
theme_logo_footerImage object — footer logofooter-template.php
footer_bg_imageFooter background imagefooter-template.php

Getting an Options Field

$logo = get_field( 'theme_logo_header', 'option' );
if ( $logo ) {
  echo '<img src="' . esc_url( $logo['url'] ) . '" alt="' . esc_attr( $logo['alt'] ) . '">';
}

Customizer Options

Available under Appearance → Customize in the WordPress admin.

KeyPurpose
theme_sticky_headerEnable sticky header behaviour
theme_login_bg_imageLogin page background image
theme_login_logoCustom logo on the login page
theme_login_logo_widthLogin logo width (px)
theme_login_logo_heightLogin logo height (px)
theme_logo_widthSite header logo width
theme_logo_heightSite header logo height
theme_display_wp_versionShow WordPress version in dashboard
theme_enable_svg_uploadAllow SVG file uploads to media library
$sticky = get_theme_mod( 'theme_sticky_header', false );
if ( $sticky ) {
  // add sticky class to header
}

Required Plugins

These plugins must be installed for full theme functionality.

PluginWhy Required
ACF ProAll content fields, the theme options page, and repeater fields
Classic EditorBlock editor is disabled via use_block_editor_for_post filter — Classic Editor must be active

New Project Kickstart

Step-by-step checklist for spinning up a new client project from this base theme.

Complete these steps in order. Each depends on the previous.

1. Clone & Rename

  1. Clone or copy this theme folder and rename it to {project}-theme
  2. Find + replace all instances of theme_ with {project}_ across all PHP files
  3. Find + replace text domain base-theme with {project}
  4. Update style.css header: Theme Name, Description, Author, Version

2. Design Tokens

  1. Open sources/sass/abstract/_variables.scss
  2. Update all $color-* variables with client brand colors
  3. Set $primary-font and $secondary-font to the project fonts
  4. Add Google Fonts <link> tags to inc/enqueue.php

3. Build Setup

  1. Run npm install to install Gulp dependencies
  2. Edit gulpfile.js line 54: set proxy to your Local WP URL
  3. Run gulp to start development

4. WordPress Setup

  1. Activate the theme in WordPress admin
  2. Install and activate ACF Pro and Classic Editor
  3. Create the ACF options page fields (import JSON if available)
  4. Create nav menus and assign them to primary and footer locations
  5. Create pages and assign page templates

5. Page Templates

For each new page template needed on the project:

  1. Duplicate an existing template in page-templates/
  2. Update the Template Name: docblock
  3. Create sources/sass/theme/_{name}-template.scss
  4. Add @use "theme/{name}-template"; to sources/sass/theme.scss