Skip to content

Advanced Topics

This guide covers advanced features and integrations in LamaPress, including Bunny.net, custom integrations, and advanced patterns.

Table of Contents

Bunny.net Integration

Overview

LamaPress includes integration with Bunny.net for video hosting and CDN services.

Configuration

Set up Bunny.net constants in wp-config.php:

php
define('LL_BUNNY_API_KEY', 'your-api-key');
define('LL_BUNNY_LIBRARY_ID', 'your-library-id');
define('LL_BUNNY_PULL_ZONE', 'your-pull-zone');

Video Library

Access Bunny.net video library:

php
<?php
// Get video library helper
$bunnyHelper = new BunnyHelpers();

// Upload video
$video = $bunnyHelper->uploadVideo($file, $title);

// Get video URL
$videoUrl = $bunnyHelper->getVideoUrl($videoId);
?>

Video Components

Use Bunny.net videos in components:

php
<?php
$video = llField('bunny_video', $key);
if ($video) {
    llBlock('video/bunny', ['fields' => ['video' => $video]]);
}
?>

ACF Field Integration

Bunny.net provides ACF field integration:

php
<?php
// In component acf.php
$groupFields = [
    [
        'key' => $name . '_01',
        'label' => 'Bunny Video',
        'name' => 'bunny_video',
        'type' => 'bunny_video',  // Custom field type
    ],
];
?>

Custom Integrations

Adding Custom Integrations

Create integration files in functions/:

php
<?php
// functions/custom-integration.php

function llCustomIntegration() {
    // Integration logic
}
add_action('init', 'llCustomIntegration');

Include in functions/bootstrap.php:

php
include_once $templateDirectory.'/functions/custom-integration.php';

Third-Party APIs

Example: Integrating with external API:

php
<?php
function llFetchExternalData($endpoint) {
    $response = wp_remote_get($endpoint, [
        'timeout' => 30,
        'headers' => [
            'Authorization' => 'Bearer ' . get_option('api_token'),
        ],
    ]);
    
    if (is_wp_error($response)) {
        return false;
    }
    
    return json_decode(wp_remote_retrieve_body($response), true);
}
?>

Advanced ACF Patterns

Dynamic Field Options

Populate field options dynamically:

php
<?php
function acf_populate_dynamic_options($field) {
    $choices = [];
    
    // Get options from database, API, etc.
    $items = get_posts(['post_type' => 'custom_type']);
    
    foreach ($items as $item) {
        $choices[$item->ID] = $item->post_title;
    }
    
    $field['choices'] = $choices;
    return $field;
}
add_filter('acf/load_field/name=dynamic_select', 'acf_populate_dynamic_options');

Conditional Field Groups

Show/hide field groups based on conditions:

php
<?php
function acf_conditional_field_group($field_group) {
    // Only show on specific post types
    if (!in_array(get_post_type(), ['page', 'post'])) {
        return false;
    }
    
    return $field_group;
}
add_filter('acf/get_field_groups', 'acf_conditional_field_group');

Field Validation

Add custom field validation:

php
<?php
function acf_validate_custom_field($valid, $value, $field, $input) {
    if (!$valid) {
        return $valid;
    }
    
    // Custom validation logic
    if ($field['name'] === 'email' && !is_email($value)) {
        $valid = 'Please enter a valid email address';
    }
    
    return $valid;
}
add_filter('acf/validate_value/name=email', 'acf_validate_custom_field', 10, 4);

Custom Post Types

Creating Post Types

Define post types in config/post-types.php:

php
<?php
return [
    [
        'name' => 'employee',
        'label' => 'Employees',
        'public' => true,
        'has_archive' => true,
        'supports' => ['title', 'editor', 'thumbnail'],
        'menu_icon' => 'dashicons-groups',
    ],
];
?>

Post Type Fields

Create fields in config/fields/:

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

Querying Post Types

Query custom post types:

php
<?php
$employees = get_posts([
    'post_type' => 'employee',
    'posts_per_page' => -1,
    'meta_query' => [
        [
            'key' => 'department',
            'value' => 'engineering',
        ],
    ],
]);
?>

Advanced JavaScript Patterns

Custom Event System

Create custom events:

javascript
import { app } from '@src/js/core/app'

export default class CustomComponent {
  triggerCustomEvent = (data) => {
    app.instances.get('eventManager').trigger('customEvent', {
      component: this,
      data: data
    })
  }
  
  listenToEvent = () => {
    app.instances.get('eventManager').on('customEvent', (eventData) => {
      // Handle event
    })
  }
}

Async Component Loading

Load components asynchronously:

javascript
export default class AsyncComponent {
  constructor(element) {
    this.element = element
    this.loaded = false
    this.init()
  }
  
  init = async () => {
    await this.loadData()
    this.render()
  }
  
  loadData = async () => {
    const response = await fetch('/api/data')
    this.data = await response.json()
    this.loaded = true
  }
  
  render = () => {
    if (this.loaded) {
      // Render component
    }
  }
}

Intersection Observer

Use Intersection Observer for performance:

javascript
export default class ObserverComponent {
  constructor(element) {
    this.element = element
    this.observer = null
    this.init()
  }
  
  init = () => {
    this.createObserver()
  }
  
  createObserver = () => {
    this.observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.handleIntersect()
        }
      })
    }, {
      threshold: 0.5
    })
    
    this.observer.observe(this.element)
  }
  
  handleIntersect = () => {
    // Component is visible
  }
  
  destroy = () => {
    if (this.observer) {
      this.observer.disconnect()
    }
  }
}

WordPress Hooks

Action Hooks

Use WordPress action hooks:

php
<?php
// In functions/custom.php

// Add custom action
function llCustomAction() {
    // Custom logic
}
add_action('wp_head', 'llCustomAction');

// Modify existing action
function llModifyAction() {
    // Modification logic
}
add_action('wp_footer', 'llModifyAction', 20); // Priority 20
?>

Filter Hooks

Use WordPress filter hooks:

php
<?php
// Filter post content
function llFilterContent($content) {
    // Modify content
    return $content;
}
add_filter('the_content', 'llFilterContent');

// Filter ACF field value
function llFilterAcfField($value, $post_id, $field) {
    // Modify field value
    return $value;
}
add_filter('acf/load_value/name=my_field', 'llFilterAcfField', 10, 3);
?>

Custom Hooks

Create custom hooks:

php
<?php
// Trigger custom action
do_action('ll_custom_action', $data);

// Apply custom filter
$filtered = apply_filters('ll_custom_filter', $data);
?>

Best Practices

1. Error Handling

Always handle errors gracefully:

php
<?php
try {
    $result = riskyOperation();
} catch (Exception $e) {
    error_log($e->getMessage());
    $result = false;
}
?>

2. Caching

Cache expensive operations:

php
<?php
$cacheKey = 'expensive_operation_' . $id;
$result = wp_cache_get($cacheKey);

if (false === $result) {
    $result = expensiveOperation();
    wp_cache_set($cacheKey, $result, '', 3600);
}
?>

3. Security

Always sanitize and validate:

php
<?php
// Sanitize input
$input = sanitize_text_field($_POST['input']);

// Validate
if (empty($input)) {
    return false;
}

// Escape output
echo esc_html($output);
?>

4. Performance

Optimize for performance:

  • Use efficient queries
  • Cache expensive operations
  • Minimize database calls
  • Use object caching

Next Steps:

Released under the MIT License.