Template Fields

Behold! The revolutionary template field system — the very heart of FrankenCMS. Define editable fields directly in your Blade templates using typed directives, and watch your content come alive.

How It Works

Instead of defining content fields in a separate configuration file, FrankenCMS allows you to declare fields inline within your templates. When a page is loaded, the system:

  1. Parses the template file to discover all field directives
  2. Collects field values from the database (or uses defaults)
  3. Pre-populates a $frankenFields collection
  4. Renders the template with field values available throughout
Zero Duplicate Rendering: Fields are parsed once and reused, ensuring efficient rendering even with many fields. The creature is smart, yes!

Basic Usage

Define a simple text field in your template:

resources/views/theme/page-home.blade.php
<h1>
    @frankenText('hero.title', [
        'label' => 'Hero Title',
        'default' => 'Welcome to our site',
        'maxLength' => 100
    ])
</h1>

The field will:

  • Display in the admin panel with the label "Hero Title"
  • Show "Welcome to our site" as the default value
  • Limit input to 100 characters
  • Store the value associated with the current page

Accessing Field Values

FrankenCMS provides multiple ways to access field values throughout your template:

1. Direct Array Access

blade
{{ $frankenFields['heroTitle'] }}

2. Collection Method

blade
{{ $frankenFields->get('heroTitle') }}


{{ $frankenFields->get('heroTitle', 'Default Title') }}

3. Helper Function

blade
{{ frankenField('hero.title') }}
{{ frankenField('heroTitle') }}


{{ frankenField('hero.title', 'Default Title') }}
The helper function frankenField() automatically converts dot notation to camelCase, so hero.title becomes heroTitle. Igor finds this very convenient!

Field Naming Conventions

Field names support dot notation for organization:

Declaration Collection Key
'title' $frankenFields['title']
'hero.title' $frankenFields['heroTitle']
'hero.cta.text' $frankenFields['heroCtaText']
'section_1.heading' $frankenFields['section1Heading']

Common Field Types

Text Field

Single-line text input — perfect for titles and short text:

blade
@frankenText('page.title', [
    'label' => 'Page Title',
    'default' => 'Untitled Page',
    'maxLength' => 120,
    'placeholder' => 'Enter a title...',
    'required' => true,
])

Textarea

Multi-line text input for descriptions and longer text:

blade
@frankenTextarea('page.description', [
    'label' => 'Description',
    'default' => '',
    'rows' => 4,
    'maxLength' => 500,
])

Rich Editor

WYSIWYG editor for formatted content — the creature's voice:

blade
<div class="content">
    @frankenRichEditor('page.content', [
        'label' => 'Page Content',
        'default' => '<p>Start writing...</p>',
    ])
</div>

Image

Image upload with media library integration:

blade
@frankenImage('hero.background', [
    'label' => 'Hero Background Image',
    'collection' => 'hero-images',
])

Toggle

Boolean on/off switch — flip the switch!

blade
@frankenToggle('settings.showNewsletter', [
    'label' => 'Show Newsletter Signup',
    'default' => true,
])

@if(frankenField('settings.showNewsletter'))
    <div class="newsletter-form">...</div>
@endif

Select

Dropdown selection for predefined options:

blade
@frankenSelect('hero.style', [
    'label' => 'Hero Style',
    'options' => [
        'minimal' => 'Minimal',
        'bold' => 'Bold',
        'centered' => 'Centered',
    ],
    'default' => 'minimal',
])

Using Field Values in Meta Tags

Field values are available at the start of template rendering, making them perfect for meta tags:

blade
@section('meta')
<title>{{ frankenField('seo.title', frankenField('page.title')) }}</title>
<meta name="description" content="{{ frankenField('seo.description') }}">
<meta property="og:title" content="{{ frankenField('seo.title') }}">
<meta property="og:image" content="{{ frankenField('seo.ogImage') }}">
@endsection

Caching Behavior

FrankenCMS uses smart caching for template fields:

Development Mode

Set CMS_CACHE_PARSED_FIELDS=false in your .env for instant template updates during development.

Production Mode

Set CMS_CACHE_PARSED_FIELDS=true (default) for optimal performance. The cache automatically invalidates when template files are modified.

Octane/FrankenPHP Compatible: The caching system uses file modification time tracking, making it safe for persistent worker environments. Even the most demanding laboratories can handle it!

Template File Naming

FrankenCMS uses template naming conventions to match pages:

Template File Usage
page.blade.php Default page template
page-home.blade.php Page with slug "home"
page-about.blade.php Page with slug "about"
post.blade.php Default post template
post-featured.blade.php Custom "featured" post type template

Complete Example

Here's a complete page template showcasing multiple field types in action:

resources/views/theme/page-home.blade.php
@extends('theme.layouts.app')

@section('content')
<section class="hero">
    @frankenImage('hero.bgImage', [
        'label' => 'Hero Background',
    ])

    <h1>
        @frankenText('hero.heading', [
            'label' => 'Hero Title',
            'default' => 'Welcome',
        ])
    </h1>

    <p>
        @frankenTextarea('hero.subtitle', [
            'label' => 'Hero Subtitle',
            'default' => 'Your tagline here',
        ])
    </p>

    @frankenToggle('hero.showCta', [
        'label' => 'Show CTA Button',
        'default' => true,
    ])

    @if(frankenField('hero.showCta'))
    <a href="{{ frankenField('hero.ctaUrl', '#') }}" class="btn">
        @frankenText('hero.ctaText', [
            'label' => 'CTA Button Text',
            'default' => 'Learn More',
        ])
    </a>
    @endif
</section>

<section class="content">
    @frankenRichEditor('page.content', [
        'label' => 'Main Content',
    ])
</section>
@endsection

Next Steps

Your templates are ready to come alive! Continue exploring: