Skip to content

Configuration

Each config class is customized by creating a *.config.php file in your app directory.

How Config Files Work

Føhn reads every file matching the *.config.php pattern in the directories it discovers. Each file must return a config class instance:

php
<?php
// app/timber.config.php

use Studiometa\Foehn\Config\TimberConfig;

return new TimberConfig(
    templatesDir: ['views', 'templates'],
);

Føhn registers the returned instance in the container, under its own class and any interface it implements, so anything asking for a TimberConfig receives yours. If no config file is found, sensible defaults are used.

Installed packages are read before your own files, so a package can ship defaults that your project overrides.

Per-environment files

A file can be named for an environment, and is then read only in that one, as reported by wp_get_environment_type():

FileRead when the environment is
foehn.config.phpalways
foehn.local.config.phplocal
foehn.dev.config.phpdevelopment
foehn.staging.config.phpstaging
foehn.production.config.phpproduction

The environment's own file wins over the plain file beside it, so the plain one holds what every environment shares:

php
<?php
// app/foehn.config.php — the default everywhere

use Studiometa\Foehn\Config\FoehnConfig;
use Tempest\Discovery\DiscoveryCacheStrategy;

return new FoehnConfig(discoveryCacheStrategy: DiscoveryCacheStrategy::NONE);
php
<?php
// app/foehn.production.config.php — production caches discovery

use Studiometa\Foehn\Config\FoehnConfig;
use Tempest\Discovery\DiscoveryCacheStrategy;

return new FoehnConfig(discoveryCacheStrategy: DiscoveryCacheStrategy::FULL);

WARNING

A config file replaces the object, it does not merge into it. Kernel::boot()'s configuration array is a default that a foehn.config.php overrides wholesale — prefer the file.

Available Config Classes

FoehnConfig — Core Settings

Controls the bootstrap process: discovery caching, debug mode, and opt-in hooks.

php
<?php
// app/foehn.config.php

use Studiometa\Foehn\Config\FoehnConfig;
use Studiometa\Foehn\Hooks\Cleanup\CleanHeadTags;
use Tempest\Discovery\DiscoveryCacheStrategy;

return new FoehnConfig(
    discoveryCacheStrategy: DiscoveryCacheStrategy::FULL,
    hooks: [CleanHeadTags::class],
    debug: false,
);
PropertyTypeDefaultDescription
discoveryCacheStrategyDiscoveryCacheStrategyNONEDiscovery cache strategy
discoveryCachePath?stringnullCustom cache path
hooksclass-string[][]Opt-in hook classes
debugboolfalseEnable discovery debug logging

See FoehnConfig API for details.

TimberConfig — Templates

Controls where Timber looks for .twig template files.

php
<?php
// app/timber.config.php

use Studiometa\Foehn\Config\TimberConfig;

return new TimberConfig(
    templatesDir: ['views'],
);
PropertyTypeDefaultDescription
templatesDirstring[]['templates']Template directory names

See TimberConfig API for details.

AcfConfig — ACF Integration

Controls how ACF fields are handled in blocks.

php
<?php
// app/acf.config.php

use Studiometa\Foehn\Config\AcfConfig;

return new AcfConfig(
    transformFields: true,
);
PropertyTypeDefaultDescription
transformFieldsbooltrueAuto-convert ACF values to Timber objects

See AcfConfig API for details.

RestConfig — REST API

Controls default permissions for #[AsRestRoute] endpoints.

php
<?php
// app/rest.config.php

use Studiometa\Foehn\Config\RestConfig;

return new RestConfig(
    defaultCapability: 'edit_posts',
);
PropertyTypeDefaultDescription
defaultCapability?string'edit_posts'Default capability for routes

See RestConfig API for details.

RenderApiConfig — Server-side Rendering

Controls the REST endpoint for server-side template rendering.

php
<?php
// app/render-api.config.php

use Studiometa\Foehn\Config\RenderApiConfig;

return new RenderApiConfig(
    templates: ['partials/*', 'components/*'],
    cacheMaxAge: 3600,
);
PropertyTypeDefaultDescription
templatesstring[][]Allowed template patterns
cacheMaxAgeint0Cache-Control max-age in seconds
debugboolfalseInclude exception details in errors

See RenderApiConfig API for details.

QueryFiltersConfig — URL Query Filtering

Controls which custom taxonomies and query vars are exposed via URL parameters.

php
<?php
// app/query-filters.config.php

use Studiometa\Foehn\Config\QueryFiltersConfig;

return new QueryFiltersConfig(
    taxonomies: [
        'genre' => ['in', 'not_in'],
        'product_cat' => ['in'],
    ],
    publicVars: [
        'posts_per_page' => [12, 24, 48],
    ],
);

See Guide: Query Filters for details.

Override Priority

When multiple sources provide the same config:

  1. Environment config file (app/*.{environment}.config.php) — highest priority
  2. Config file (app/*.config.php)
  3. Package config file — defaults an installed package ships
  4. Kernel::boot() array — legacy fallback (only for FoehnConfig)
  5. Defaults — built-in defaults from the config class constructor

Environment-Specific Configuration

Use PHP logic in your config files for environment-specific settings:

php
<?php
// app/foehn.config.php

use Studiometa\Foehn\Config\FoehnConfig;
use Tempest\Discovery\DiscoveryCacheStrategy;

$isDev = defined('WP_DEBUG') && WP_DEBUG;

return new FoehnConfig(
    discoveryCacheStrategy: $isDev
        ? DiscoveryCacheStrategy::NONE
        : DiscoveryCacheStrategy::FULL,
    debug: $isDev,
);

File Structure Example

theme/
├── app/
│   ├── foehn.config.php         # Core configuration
│   ├── timber.config.php        # Template directories
│   ├── acf.config.php           # ACF settings
│   ├── rest.config.php          # REST API defaults
│   ├── render-api.config.php    # Render API allowlist
│   ├── query-filters.config.php # Query filter rules
│   ├── foehn.production.config.php # Read in production only
│   ├── Hooks/
│   ├── Models/
│   └── ...
└── functions.php

Released under the MIT License.