Skip to content

ACF Integration

LamaPress has deep integration with Advanced Custom Fields (ACF) Pro, automatically building the CMS from component field definitions. This guide explains how ACF works in LamaPress and how to create and use fields effectively.

Table of Contents

Overview

LamaPress automatically builds ACF field groups from component definitions:

  1. Component Fields - Defined in each component's acf.php file
  2. Automatic Registration - Fields are automatically registered on every request
  3. Template Integration - Fields are accessible via helper functions
  4. Flexible Content - Sections can be combined in flexible layouts

Field Organization

Component-Specific Fields

Fields are organized by component type:

  • Sections - components/sections/{name}/acf.php
  • Blocks - components/blocks/{name}/acf.php
  • Parts - components/parts/{name}/acf.php

Global Fields

Global fields are stored in config/fields/:

  • Options page fields
  • Post type fields
  • Reusable field groups

Section Fields

Sections require a complete ACF field group definition:

Basic Structure

php
<?php
$key = 'section_hero_basic';
$name = 'hero_basic';
$title = 'Hero Basic';

$groupFields = [
    [
        'key' => $name . '_01',
        'label' => 'Title',
        'name' => 'title',
        'type' => 'text',
        'required' => true,
    ],
    [
        'key' => $name . '_02',
        'label' => 'Content',
        'name' => 'content',
        'type' => 'wysiwyg',
    ],
];

Required Variables

  • $key - Unique identifier for the field group (must be unique across all sections)
  • $name - Section name (should match directory name)
  • $title - Display title in WordPress admin
  • $groupFields - Array of field definitions

Optional Variables

  • $category - Category for organizing sections in flexible content

Field Key Naming

Always prefix field keys with the section name:

php
'key' => $name . '_01',  // hero_basic_01
'key' => $name . '_02',  // hero_basic_02

Why: Prevents key conflicts and makes debugging easier

Block and Part Fields

Blocks and parts have a simpler structure - they only return the field array:

Basic Structure

php
<?php
$groupFields = [
    [
        'key' => 'title',
        'label' => 'Title',
        'name' => 'title',
        'type' => 'text',
    ],
];

Important:

  • Do NOT define $key, $name, or $title variables
  • Only return the $groupFields array
  • These fields are reusable and composable

When to Create Block/Part Fields

Create acf.php for blocks/parts when:

  • Fields are reusable across multiple contexts
  • Fields form a logical group
  • Fields will be composed into larger structures

Don't create acf.php if:

  • Fields are only used in one specific context
  • No fields are needed (data passed via props)

Global Fields

Global fields are defined in config/fields/ and can be attached to:

  • Options pages
  • Post types
  • Taxonomies

Options Page Fields

php
<?php
$key = 'company_info';
return [
    'key' => $key,
    'title' => 'Company Info',
    'type' => [
        'options' => 'Company'  // Options page name
    ],
    'fields' => [
        [
            'key' => $key . '_01',
            'label' => 'Company Name',
            'name' => 'company_name',
            'type' => 'text',
        ],
    ]
];

Post Type Fields

php
<?php
$key = 'employee_fields';
return [
    'key' => $key,
    'title' => 'Employee Information',
    'type' => [
        'post_type' => 'employee'
    ],
    'fields' => [
        // Field definitions
    ]
];

Accessing Options Fields

php
// Get option field
$companyName = get_field('company_name', 'option');

// Or using helper
$companyName = llField('company_name');

Field Access

Using llField()

The llField() helper function provides flexible field access:

php
// Section fields (with key prefix)
$title = llField('title', $key);  // Gets 'section_hero_basic_title'

// Options fields
$companyName = llField('company_name');  // Gets from options

// From section array
$title = llField('title', false, $section);

Using llFields()

Get multiple fields at once:

php
// Get multiple fields
$data = llFields('title', 'content', 'image', $key);

// With field name mapping
$data = llFields(
    ['title' => 'heading'],
    ['content' => 'body'],
    $key
);
// Returns: ['heading' => '...', 'body' => '...']

Direct ACF Functions

You can also use ACF functions directly:

php
// Get field with key prefix
$title = get_field($key . '_title');

// Get field from options
$companyName = get_field('company_name', 'option');

// Get field from post
$customField = get_field('custom_field', $postId);

Field Reuse

Reusing Block/Part Fields

Use llGetFields() to reuse fields from other components:

php
<?php
// In a section's acf.php
$blockFields = llGetFields('block', 'accordion', $key);
$partFields = llGetFields('part', 'button', $key);

$groupFields = array_merge(
    [
        // Section-specific fields
    ],
    $blockFields,  // Reused from accordion block
    $partFields    // Reused from button part
);

Benefits:

  • DRY principle
  • Consistent field definitions
  • Easier maintenance

Flexible Content

Creating Flexible Sections

The flexible section allows combining multiple sections:

php
<?php
// In a template
llSection('flexible', 'flexible_content_1');

Defining Available Sections

Sections are automatically discovered from the components/sections/ directory. To limit which sections are available:

php
<?php
// In template file
llSection('flexible', 'flexible_content_1', ['hero_basic', 'rich_content']);

Section Categories

Organize sections into categories:

php
<?php
// In section's acf.php
$category = 'content';  // Optional category

Sections with the same category will be grouped in the flexible content selector.

Common Field Types

Text Fields

php
[
    'key' => $name . '_01',
    'label' => 'Title',
    'name' => 'title',
    'type' => 'text',
    'required' => true,
    'placeholder' => 'Enter title',
]

WYSIWYG Editor

php
[
    'key' => $name . '_02',
    'label' => 'Content',
    'name' => 'content',
    'type' => 'wysiwyg',
    'toolbar' => 'full',
    'media_upload' => 1,
]

Image Field

php
[
    'key' => $name . '_03',
    'label' => 'Image',
    'name' => 'image',
    'type' => 'image',
    'return_format' => 'array',  // or 'id', 'url'
    'preview_size' => 'medium',
]

Repeater Field

php
[
    'key' => $name . '_04',
    'label' => 'Items',
    'name' => 'items',
    'type' => 'repeater',
    'sub_fields' => [
        [
            'key' => $name . '_04_01',
            'label' => 'Title',
            'name' => 'title',
            'type' => 'text',
        ],
        [
            'key' => $name . '_04_02',
            'label' => 'Content',
            'name' => 'content',
            'type' => 'textarea',
        ],
    ],
    'button_label' => 'Add Item',
]

Select Field

php
[
    'key' => $name . '_05',
    'label' => 'Style',
    'name' => 'style',
    'type' => 'select',
    'choices' => [
        'default' => 'Default',
        'dark' => 'Dark',
        'light' => 'Light',
    ],
    'default_value' => 'default',
]

Group Field

php
[
    'key' => $name . '_06',
    'label' => 'Address',
    'name' => 'address',
    'type' => 'group',
    'sub_fields' => [
        [
            'key' => $name . '_06_01',
            'label' => 'Street',
            'name' => 'street',
            'type' => 'text',
        ],
        [
            'key' => $name . '_06_02',
            'label' => 'City',
            'name' => 'city',
            'type' => 'text',
        ],
    ],
]

Conditional Logic

php
[
    'key' => $name . '_07',
    'label' => 'Show Advanced',
    'name' => 'show_advanced',
    'type' => 'true_false',
],
[
    'key' => $name . '_08',
    'label' => 'Advanced Content',
    'name' => 'advanced_content',
    'type' => 'wysiwyg',
    'conditional_logic' => [
        [
            [
                'field' => $name . '_07',
                'operator' => '==',
                'value' => '1',
            ],
        ],
    ],
]

Best Practices

1. Unique Keys

Always use unique keys for all fields:

php
// ✅ Good - Prefix with section name
'key' => $name . '_01'

// ❌ Bad - Generic key
'key' => 'title'

2. Descriptive Names

Use clear, descriptive field names:

php
// ✅ Good
'name' => 'hero_title'
'name' => 'cta_button_text'

// ❌ Bad
'name' => 'title1'
'name' => 'text'

3. Field Organization

Group related fields logically:

php
$groupFields = [
    // Basic fields
    [...],
    // Media fields
    [...],
    // Advanced fields
    [...],
]

4. Required Fields

Mark truly required fields:

php
'required' => true,

Note: Only mark fields as required if they're essential for the component to function.

5. Default Values

Provide sensible defaults:

php
'default_value' => 'default',

6. Instructions

Add helpful instructions for content editors:

php
'instructions' => 'Enter a compelling title that describes the section',

7. Field Validation

Use ACF validation where appropriate:

php
'min' => 10,
'max' => 100,

Next Steps:

Released under the MIT License.