Appearance
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
- Field Organization
- Section Fields
- Block and Part Fields
- Global Fields
- Field Access
- Field Reuse
- Flexible Content
- Best Practices
Overview
LamaPress automatically builds ACF field groups from component definitions:
- Component Fields - Defined in each component's
acf.phpfile - Automatic Registration - Fields are automatically registered on every request
- Template Integration - Fields are accessible via helper functions
- 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_02Why: 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$titlevariables - Only return the
$groupFieldsarray - 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 categorySections 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,Related Documentation
- Component System - Component structure
- PHP Functions Reference - Field helper functions
- Component Guidelines - ACF field guidelines
Next Steps:
- Review Component System to see how fields integrate with components
- Check existing components for real-world field examples
- See Component Guidelines for ACF best practices