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.
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.
base-theme | Package: Base_Theme | Version constant: THEME_VERSION
Starting a New Client Project
When spinning up a new client site from this base:
- Rename the function prefix from
theme_→{project}_(e.g.acme_) - Update the text domain from
base-theme→{project} - Replace all design tokens in
sources/sass/abstract/_variables.scss - Swap in the client's Google Fonts in
inc/enqueue.php - Update
BrowserSyncproxy ingulpfile.jsline 54
Stack
Technologies and libraries bundled into every project.
Build & Setup
Commands to install dependencies and compile assets.
| Command | Action |
|---|---|
npm install | First-time setup — installs all dependencies |
gulp | Compile everything + watch + BrowserSync |
gulp compileSass | Compile CSS only (no watch) |
gulp compileJs | Compile JS only (no watch) |
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.scss→assets/css/theme.css(with sourcemaps in dev) - Concatenates & minifies
sources/js/**/*.js→assets/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.
Adding a New Page Template
Three files required every time:
- Create
page-templates/my-template.php - Create
sources/sass/theme/_my-template.scss - Add
@use "theme/my-template";tosources/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.
_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
| Variable | Value | Pixels | CSS Var |
|---|---|---|---|
$space-1 | 0.25rem | 4px | --space-1 |
$space-2 | 0.5rem | 8px | --space-2 |
$space-3 | 0.75rem | 12px | --space-3 |
$space-4 | 1rem | 16px | --space-4 |
$space-5 | 1.5rem | 24px | --space-5 |
$space-6 | 2rem | 32px | --space-6 |
$space-7 | 3rem | 48px | --space-7 |
$space-8 | 4rem | 64px | --space-8 |
Colors
Defined in $colors map in _variables.scss. Generates .text-*, .bg-*, and .border-* utility classes automatically.
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.
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.
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.
| Mixin | Output | Usage |
|---|---|---|
flex-center | display:flex; align+justify: center | @include flex-center; |
flex-between | display:flex; align: center; justify: space-between | @include flex-between; |
flex-col | display:flex; flex-direction: column | @include flex-col; |
flex-col-center | column flex, centered | @include flex-col-center; |
absolute-fill | position:absolute; inset:0 | @include absolute-fill; |
absolute-center | absolute; top/left 50%; translate -50% | @include absolute-center; |
cover-image | width/height 100%; object-fit: cover | @include cover-image; |
line-clamp(n) | Clamp to n lines with ellipsis | @include line-clamp(3); |
truncate | Single-line ellipsis overflow | @include truncate; |
transition(props…) | 0.3s ease transition on each prop | @include transition(opacity, transform); |
visually-hidden | SR-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.
| Function | Input → Output | Use 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 File | Sass File | Template Name |
|---|---|---|
page-templates/home.php | theme/_home-template.scss | Home Template |
page-templates/about.php | theme/_about-template.scss | About Template |
page-templates/contact.php | theme/_contact-template.scss | Contact Template |
page-templates/experts.php | theme/_experts-template.scss | Experts Template |
page-templates/news.php | theme/_news-template.scss | News Template |
Template Checklist
- Add the
Template Name:docblock at the top of the PHP file defined('ABSPATH') || exit;on line 1- Call
get_header()andget_footer() - Create the paired Sass file and
@useit intheme.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.
| Rule | Example |
|---|---|
| Function prefix | theme_enqueue_styles() → rename to {project}_ |
| Customizer key prefix | get_theme_mod('theme_logo_width') |
| Security first line | defined('ABSPATH') || exit; |
| Theme support hook | theme_setup() on after_setup_theme |
| Escape HTML output | esc_html() |
| Escape URLs | esc_url() |
| Escape attributes | esc_attr() |
| Escape rich content | wp_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.
theme-general-settings. ACF Pro must be installed and activated.
Options Page Fields
| Field Key | Purpose | Used In |
|---|---|---|
footer_intro | Footer introductory text | footer-template.php |
address | Company physical address | footer-template.php |
contact_number | Main phone number | footer, contact page |
email | Main email address | footer, contact page |
whatsapp | WhatsApp number | Various CTAs |
social_links | Repeater: social platform + URL | footer-template.php |
theme_logo_header | Image object — header logo | header-template.php |
theme_logo_footer | Image object — footer logo | footer-template.php |
footer_bg_image | Footer background image | footer-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.
| Key | Purpose |
|---|---|
theme_sticky_header | Enable sticky header behaviour |
theme_login_bg_image | Login page background image |
theme_login_logo | Custom logo on the login page |
theme_login_logo_width | Login logo width (px) |
theme_login_logo_height | Login logo height (px) |
theme_logo_width | Site header logo width |
theme_logo_height | Site header logo height |
theme_display_wp_version | Show WordPress version in dashboard |
theme_enable_svg_upload | Allow 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.
| Plugin | Why Required |
|---|---|
| ACF Pro | All content fields, the theme options page, and repeater fields |
| Classic Editor | Block 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.
1. Clone & Rename
- Clone or copy this theme folder and rename it to
{project}-theme - Find + replace all instances of
theme_with{project}_across all PHP files - Find + replace text domain
base-themewith{project} - Update
style.cssheader: Theme Name, Description, Author, Version
2. Design Tokens
- Open
sources/sass/abstract/_variables.scss - Update all
$color-*variables with client brand colors - Set
$primary-fontand$secondary-fontto the project fonts - Add Google Fonts
<link>tags toinc/enqueue.php
3. Build Setup
- Run
npm installto install Gulp dependencies - Edit
gulpfile.jsline 54: setproxyto your Local WP URL - Run
gulpto start development
4. WordPress Setup
- Activate the theme in WordPress admin
- Install and activate ACF Pro and Classic Editor
- Create the ACF options page fields (import JSON if available)
- Create nav menus and assign them to
primaryandfooterlocations - Create pages and assign page templates
5. Page Templates
For each new page template needed on the project:
- Duplicate an existing template in
page-templates/ - Update the
Template Name:docblock - Create
sources/sass/theme/_{name}-template.scss - Add
@use "theme/{name}-template";tosources/sass/theme.scss