Skip to content

Fir Theme Framework

Fir is our sophisticated WordPress theme framework built on top of Roots Sage, leveraging modern PHP and JavaScript technologies. Named after the Douglas Fir tree, it features a component-based architecture where individual components are called "Pinecones" - creating a cohesive, nature-themed development ecosystem.

The framework's modular Pinecone system is designed for maximum portability and reusability. Pinecones are self-contained components that can typically be dropped into other Fir-based projects with little to no adjustment, enabling rapid development and consistent functionality across multiple sites.

Architecture Overview

Core Technologies

  • Laravel Blade for templating
  • Roots Acorn for Laravel-like features in WordPress
  • Tailwind CSS v4 with CSS-first configuration
  • Vue.js 3 for interactive components
  • GSAP for advanced animations
  • Vite for lightning-fast build tooling (upgraded from Bud.js)
  • ACF Composer for Advanced Custom Fields management

Foundation

Fir extends Roots Sage with a sophisticated component system that bridges traditional WordPress development with cutting-edge frontend technologies, providing a scalable and maintainable architecture for complex WordPress sites.

Pinecone Component System

The heart of Fir's architecture is the Pinecone system - self-contained, reusable components with a standardized structure designed for cross-project portability. Each Pinecone encapsulates all its dependencies, styles, and functionality, making them highly modular building blocks that can be easily shared between different Fir-based websites.

Component Structure

Each Pinecone follows a consistent, portable structure that enables easy transfer between projects:

fir/Pinecones/[ComponentName]/
├── App.vue                    # Vue.js component (if needed)
├── view.blade.php            # Blade template
├── script.js                 # JavaScript logic (Web Components)
├── admin.css                 # Admin styling
├── tailwind.js               # Component-specific Tailwind config
├── Blocks/[ComponentName].php # ACF Block definition
├── Components/               # Sub-components (if complex)
└── README.md                 # Documentation

Portability Features:

  • Self-contained assets - All styles, scripts, and dependencies included
  • Standardized structure - Consistent patterns across all components
  • Framework integration - Automatic discovery and registration
  • Minimal configuration - Works out-of-the-box in any Fir project
  • Version compatibility - Components work across Fir framework versions

Available Pinecones

Layout Components:

  • Layout - Main page structure and containers
  • Wrap - Content wrapper with spacing controls
  • Columns - Flexible column layouts
  • Spacer - Vertical spacing control

Content Components:

  • Hero - Hero sections with background options
  • Heading - Typography with size and style controls
  • Paragraph - Text content with formatting
  • Markdown - Markdown content processing
  • Image - Advanced image display with transformations

Interactive Components:

  • Accordion - Expandable content sections
  • Form - Contact and submission forms
  • Button - Call-to-action buttons with styling
  • Drawer - Slide-out navigation panels
  • Sticky - Sticky positioned elements

Data Display:

  • Cards - Content card layouts
  • Table - Data table presentation
  • Testimonials - Client testimonial displays
  • Bio - Team member profiles
  • Callout - Highlighted content blocks

Visual Elements:

  • Collage - Image collage layouts
  • Panel/Panels - Content panel systems
  • Infobox - Information highlight boxes

Innovative Features

Web Components Integration

Each Pinecone uses modern Web Components (Custom Elements) for JavaScript functionality:

javascript
class Accordion extends HTMLElement {
    constructor(...args) {
        const self = super(...args)
        self.init()
        return self
    }
    
    init() {
        this.props = this.getInitialProps()
        this.resolveElements()
    }
    
    getInitialProps() {
        // Parse JSON data from template
        return JSON.parse(
            this.querySelector('script[type="application/json"]').innerText
        )
    }
}

customElements.define('fir-accordion', Accordion)

Vue.js Hybrid Approach

Complex components seamlessly integrate Vue.js for reactive interfaces:

javascript
// Form component with Vue integration
initVue() {
    let vueWrapper = this.querySelector('[data-vue]')
    if(vueWrapper) {
        const app = createApp(App)
        app.config.globalProperties.$formdata = this.props   
        app.mount(`#${this.ID}`)
    }
}

Auto-Discovery System

Components are automatically discovered, registered, and built without manual configuration:

php
// Automatic discovery and registration
$dirs = glob(get_theme_file_path('/fir/Pinecones/*'), GLOB_ONLYDIR);
foreach ($dirs as $d) {
    $name = basename($d);
    $class = "Fir\\Pinecones\\" . $name . '\\';
    app('AcfComposer')->registerPath($d, $class);
}

Development Features

Global Fields System

Sophisticated reusable field configurations for common use cases:

php
class GlobalFields {
    public static function getFields($field, $name = false, $label = false) {
        return self::$field($name, $label);
    }
    
    private static function animation($name, $label) {
        // Complex animation field configuration with:
        // - Fade controls
        // - Transform options  
        // - Filter effects
        // - Masking reveals
        // - Timing and easing
    }
}

GSAP Animation System

Integrated GSAP animations with intersection observers:

javascript
function setupDrawStroke() {
    const drawStrokeElements = document.querySelectorAll('[data-animation~="drawStroke"]');
    
    const handleDrawStroke = (entries, observer) => {
        entries.forEach(entry => {
            let path = entry.target.querySelector('path');
            if(entry.isIntersecting) {
                gsap.to(path, {duration:3, drawSVG: "0% 100%"});
            }
        });
    }
}

Modern Build Pipeline (Vite-Powered)

  • Lightning-fast HMR - Instant hot module replacement for development
  • Automatic asset discovery - Dynamic discovery and bundling of Pinecone components
  • Individual component bundling - Each Pinecone gets its own optimized entry point
  • Code splitting - Automatic chunk splitting for better caching and performance
  • Tailwind CSS v4 - CSS-first configuration with automatic theme.json generation
  • Enhanced WordPress integration - Laravel Vite plugin with WordPress-specific optimizations

Tailwind CSS v4 Integration

Modern CSS-first approach with enhanced WordPress integration:

CSS-First Configuration:

css
@import "tailwindcss";
@source "../views/";
@source "../../fir/Pinecones/**/*.php";
@source "../../fir/Lib/Utils/Tailwind.php";
@source "../../public/build/assets/safelist.json";

Automatic WordPress Integration:

  • Theme.json generation - Automatically extracts CSS variables and generates WordPress theme.json
  • Block editor sync - Keeps WordPress editor styles in sync with design tokens
  • Dynamic safelist - Generates safelist.json for Tailwind purging automatically

Advanced Features:

  • Container queries native support
  • CSS cascade layers for better specificity control
  • Modern CSS features leveraging latest browser capabilities
  • Component-specific configurations per Pinecone
  • Design token integration with WordPress theme system

Build System Evolution

The Fir framework has evolved through multiple build systems. Choose the appropriate build system based on your project's version and avoid upgrading older projects unnecessarily.

Version Compatibility

Do not upgrade older Fir projects from Bud.js or Laravel Mix to Vite. Each build system is tied to specific framework versions and dependencies. Upgrading can break existing functionality and introduce compatibility issues.

Current: Vite (Latest Versions)

When to Use: New projects, latest Fir framework versions

Primary Configuration (vite.config.js):

javascript
export default defineConfig({
  base: '/app/themes/fir/public/build/',
  plugins: [
    tailwindcss(),
    vue(),
    laravel({
      input: [
        'resources/css/app.css',
        'resources/js/app.js',
        ...firPineconeAssets(), // Auto-discovered Pinecone assets
      ],
      refresh: true,
    }),
    wordpressPlugin(),           // WordPress dependency handling
    wordpressThemeJson(),        // Automatic theme.json generation
    firSafelistPlugin(),         // Dynamic Tailwind safelist
  ],
})

Development Commands:

bash
# Development with HMR
npm run dev

# Production build with optimization
npm run build

Previous: Bud.js (Mid-Generation Versions)

When to Use: Existing projects using Bud.js - do not upgrade to Vite

Configuration (bud.config.js):

javascript
export default async (bud) => {
  bud
    .entry('app', ['@scripts/app', '@styles/app'])
    .entry('editor', ['@scripts/editor', '@styles/editor'])
    .assets(['images'])
    .external(['jquery'])
    .vue()
    .tailwindcss()
    .copyDir('fir/assets')
    .watch(['resources/views', 'app', 'fir']);

  // Auto-discover Pinecone assets
  const pinecones = await bud.glob('fir/Pinecones/**/script.js');
  pinecones.forEach(pinecone => {
    const name = pinecone.split('/')[2];
    bud.entry(name.toLowerCase(), [`fir/Pinecones/${name}/script.js`]);
  });
}

Development Commands:

bash
# Development with file watching
yarn dev

# Production build
yarn build

# Build diagnostics
yarn dr

# Clean build artifacts
yarn clean

Legacy: Laravel Mix (Early Versions)

When to Use: Older Fir projects using Mix - do not upgrade

Configuration (webpack.mix.js):

javascript
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
   .vue({ version: 3 })
   .postCss('resources/css/app.css', 'public/css', [
     require('tailwindcss'),
     require('autoprefixer'),
   ])
   .options({
     processCssUrls: false
   });

// Auto-discover Pinecone components
const glob = require('glob');
const pinecones = glob.sync('fir/Pinecones/**/script.js');
pinecones.forEach(pinecone => {
  const name = pinecone.split('/')[2].toLowerCase();
  mix.js(pinecone, `public/js/pinecones/${name}.js`);
});

if (mix.inProduction()) {
  mix.version();
}

Development Commands:

bash
# Development with file watching
npm run watch

# Production build
npm run production

# Development build
npm run dev

Build System Comparison

FeatureViteBud.jsLaravel Mix
Speed⚡ Instant HMR🚀 Fast builds🐌 Slower webpack
Bundle Size📦 Optimal📦 Good📦 Larger
Vue.js Support✅ Native✅ Plugin✅ Plugin
Tailwind CSS✅ v4 Native✅ v3 Plugin✅ v2/v3 PostCSS
WordPress Integration✅ Specialized✅ Custom⚠️ Manual
Auto-discovery✅ Advanced✅ Good⚠️ Basic
Maintenance🔄 Active🔄 Stable⚠️ Legacy

Migration Guidelines

Do Not Upgrade Existing Projects

Keep existing projects on their current build system. Each build system has specific dependencies and configurations that are not backwards compatible.

For New Projects:

  • Use Vite for all new Fir framework projects
  • Leverage the latest Tailwind CSS v4 features
  • Take advantage of enhanced WordPress integration

For Existing Projects:

  • Bud.js projects: Continue using Bud.js commands and configuration
  • Laravel Mix projects: Maintain existing webpack.mix.js setup
  • Only upgrade if absolutely necessary and with full testing

Identifying Your Build System:

bash
# Check package.json for build dependencies
cat package.json | grep -E "(vite|bud|mix)"

# Look for configuration files
ls -la | grep -E "(vite.config|bud.config|webpack.mix)"

Developer Experience

Enhanced Component Development

  • Individual component bundling - Each Pinecone gets its own optimized entry point
  • Instant HMR - Changes to CSS, JavaScript, and Vue components reflect immediately
  • Automatic asset enqueuing - Laravel Vite plugin handles WordPress asset integration
  • Component templates with preview examples
  • Automatic block registration in WordPress
  • Custom block categories organization
  • Live preview capabilities with Vite dev server

Utility System

Rich helper classes for common operations:

  • Image transformation utilities
  • Animation helpers
  • Menu generation
  • State management
  • Content processing

Progressive Enhancement

Components work without JavaScript but enhance with interactive features when available, ensuring accessibility and performance.

Best Practices

Component Design

  • Self-contained - Each Pinecone manages its own assets and dependencies
  • Portable - Components can be copied between projects with minimal setup
  • Configurable - Extensive field options for customization
  • Accessible - Built with accessibility in mind
  • Performance-focused - Optimized loading and rendering
  • Drop-in ready - Automatic registration and integration in any Fir project

Development Workflow

  • Use the auto-discovery system for new components
  • Follow the established Pinecone structure for maximum portability
  • Leverage global fields for common configurations
  • Test components in isolation and integration
  • Document component usage and options
  • Design components for reuse across multiple projects
  • Avoid project-specific hardcoded values or dependencies

Naming Conventions

  • Follow the nature theme (Fir → Pinecones)
  • Use descriptive, action-oriented component names
  • Maintain consistency across similar components
  • Consider component grouping and organization

Key Innovations

  1. Vite-Powered Performance - Lightning-fast builds and HMR with modern ESM-first architecture
  2. Automatic WordPress Integration - Seamless theme.json generation and block editor synchronization
  3. Modular Component Portability - Pinecones are designed as drop-in components that work across projects with minimal adjustment
  4. CSS-First Design Tokens - Tailwind v4 integration with automatic WordPress theme synchronization
  5. Thematic Consistency - The tree/nature naming convention creates memorable, cohesive branding
  6. Hybrid Architecture - Seamlessly blends WordPress blocks, Web Components, and Vue.js
  7. Auto-Discovery - Eliminates manual configuration for component registration and asset bundling
  8. Global Field Reusability - Sophisticated system for sharing configurations
  9. Animation Integration - Built-in GSAP with accessible configuration
  10. Progressive Enhancement - Works everywhere, enhanced where possible

Performance Benefits with Vite

Development Speed

  • Instant server start - Cold server start in milliseconds
  • Lightning-fast HMR - Changes reflect immediately without full page reload
  • Optimized dependency pre-bundling - Dependencies are pre-bundled with esbuild
  • Enhanced error reporting - Better error messages and stack traces

Production Optimization

  • Smaller bundle sizes - Better tree shaking and dead code elimination
  • Code splitting - Automatic chunk splitting for improved caching
  • Asset optimization - Built-in minification and compression
  • Modern browser targeting - Generates optimized code for current browsers
  • Critical CSS extraction - Automatic extraction of critical styles

WordPress-Specific Enhancements

  • Asset versioning - Automatic cache busting with content-based hashing
  • Dependency tracking - WordPress dependencies tracked automatically in manifest
  • Block editor integration - Real-time synchronization with WordPress editor styles
  • Theme.json automation - Eliminates manual theme.json maintenance

Fir with Vite represents the cutting edge of WordPress theme development, combining lightning-fast build tooling with sophisticated component architecture. The migration to Vite delivers significant performance improvements for both development and production while maintaining the flexibility and ease-of-use that makes WordPress accessible to content creators and developers alike.