arshpharala/advanced-custom-fields
Composer 安装命令:
composer require arshpharala/advanced-custom-fields
包简介
A powerful, beautiful, and easy-to-use custom fields system for Laravel with Admin UI, drag-and-drop sorting, and migrate:fresh-safe export/import.
README 文档
README
Empower your Laravel application with a sophisticated, user-friendly, and developer-centric custom fields system. Inspired by WordPress ACF but rebuilt from the ground up for the modern Laravel ecosystem, this package provides a schema-less, highly performant way to manage content that doesn't belong in your core database tables.
Table of Contents
- Why ACF++ for Laravel?
- Features
- Requirements
- Installation
- Quick Start
- Admin Panel
- Configuration
- Permissions & Security
- Model Integration
- Rendering Fields
- Reading Values
- Querying & Filtering
- Locations & Rules
- Field Types
- Presentation & Theming
- Conditional Logic
- Export/Import & migrate:fresh Safety
- Health & Recovery
- Caching & Performance
- Troubleshooting FAQ
- Roadmap
- License
Why ACF++ for Laravel?
Laravel often forces a choice: either bloat your models with dozens of nullable columns or use a rigid EAV system. Advanced Custom Fields solves this by providing:
- Schema-less values: Values live in a single polymorphic table, keeping your main tables clean.
- Powerful UI: A plug-and-play admin interface for non-technical users.
- Developer Experience: Fluent API, Blade directives, and exportable definitions that version-control perfectly.
Features
💎 Admin UX
- Beautiful Dashboard: Glassmorphism-inspired UI with Bootstrap 5 and Alpine.js.
- Drag & Drop: Reorder fields effortlessly using integrated SortableJS.
- Search & Filter: Find field groups instantly in large-scale setups.
- Contextual Management: Manage fields directly where they are used.
🛠️ Developer DX
- Fluent Trait: Simple
use HasAdvancedCustomFieldson any Eloquent model. - Blade Components:
<x-acf::form />handles all input rendering and validation. - Global Helpers: Access data anywhere with
acf($model, 'key'). - Eager Loading: Prevents N+1 issues when fetching custom data.
🛡️ Safety & Stability
- Export/Import Engine: Definitions move from DB to JSON, making
migrate:freshpainless for teams. - Soft Deletes: Field groups and fields are never destroyed accidentally.
- Mismatch Detection: Real-time warnings if your database is out of sync with your JSON definitions.
⚡ Performance
- Optimized SQL: Polymorphic queries are indexed and eager-load friendly.
- Tag-based Caching: Instant retrieval of field definitions.
Requirements
- PHP 8.1 or higher
- Laravel 10.x, 11.x, or 12.x
- Bootstrap 5 or Tailwind CSS (for Admin UI)
Installation
1. Install via Composer
composer require arshpharala/advanced-custom-fields
2. Run the Install Command
This command will publish the config, migrations, and assets, and run the initial migrations.
php artisan acf:install
3. Manual Publishing (Optional)
If you need to manually publish specific tags:
# Publish Config php artisan vendor:publish --tag="acf-config" # Publish Assets php artisan vendor:publish --tag="acf-assets" # Publish Views (for deep customization) php artisan vendor:publish --tag="acf-views"
Quick Start (5-Minute Setup)
- Create a Group: Go to
/admin/advanced-custom-fieldsand create "Product Details". - Add a Field: Add a "Technical Specifications" textarea with key
specs. - Set Location: Set the rule to
Post Type == Product. - Attach Trait: Add the trait to your model.
use Arshpharala\AdvancedCustomFields\Traits\HasAdvancedCustomFields; class Product extends Model { use HasAdvancedCustomFields; }
- Render Form: Add the component to your edit view.
<x-acf::form :model="$product" />
- Read Value: Use the helper in your frontend.
<div class="specs">{{ acf($product, 'specs') }}</div>
Admin Panel
The Admin Panel is accessible via /admin/advanced-custom-fields by default.
Available Screens:
- Field Groups: List, search, and manage groups.
- Group Editor: Add fields, configure location rules, and sort via drag & drop.
- Import/Export: Handle JSON synchronization.
- Health Check: Detect orphan values and system issues.
Tip
You can change the route prefix and apply custom middleware (e.g., auth, admin.only) in the config/advanced-custom-fields.php file.
Configuration
return [ /* |-------------------------------------------------------------------------- | Admin Route Configuration |-------------------------------------------------------------------------- */ 'route_prefix' => 'admin/advanced-custom-fields', 'middleware' => ['web', 'auth'], /* |-------------------------------------------------------------------------- | Theme & UI Presets |-------------------------------------------------------------------------- | 'bootstrap5' (default) or 'tailwind' */ 'theme' => 'bootstrap5', /* |-------------------------------------------------------------------------- | Export Configuration |-------------------------------------------------------------------------- */ 'export_path' => storage_path('app/acf/definitions.json'), 'auto_export' => false, // Automatically export on save (dev only) ];
Permissions & Security
Defining Access
Use a Laravel Gate to control who can access the ACF Admin UI.
// app/Providers/AuthServiceProvider.php Gate::define('view-acf-admin', function ($user) { return $user->is_admin; });
Then specify the middleware in config/advanced-custom-fields.php:
'middleware' => ['web', 'auth', 'can:view-acf-admin'],
HTML Snippet Safety
If using fields that allow HTML, ensure you sanitize output unless explicitly trusted.
{!! clean(acf($post, 'html_content')) !!}
Model Integration
Add the HasAdvancedCustomFields trait to any Eloquent model.
API Reference
acf(string $key, $default = null): Get a processed value.setAcf(string $key, $value): Set a value (persists on save or via updateOrCreate).syncAcf(array $values): Batch update values.acfAll(): Get all custom values for the model.acfMeta(string $key): Get the rawValuemodel (includes locale/metadata).
Rendering Fields (Admin)
Blade Component
The most common way to render fields on a model edit page.
{{-- Renders all groups assigned to the "normal" position for this model --}} <x-acf::form :model="$product" position="normal" /> {{-- Renders for a create screen (no model instance yet) --}} <x-acf::form :model-type="App\Models\Product::class" context="admin.create" />
Manual Rendering
@foreach($product->acfGroups() as $group) <h3>{{ $group->name }}</h3> @foreach($group->fields as $field) {!! acf_field($field, $product) !!} @endforeach @endforeach
Reading Values (Frontend Blade)
1. Loop Through All Assigned Fields
Ideal for "Details" or "Specifications" tabs where you want to show everything assigned to the model.
<div class="product-specs"> <h4>Specifications</h4> <dl class="row"> @foreach($product->acfAll() as $key => $value) @if($value) <dt class="col-sm-4">{{ ucfirst(str_replace('_', ' ', $key)) }}</dt> <dd class="col-sm-8">{{ is_array($value) ? implode(', ', $value) : $value }}</dd> @endif @endforeach </dl> </div>
2. Access Specific Fields Individually
Use the @acf directive or the acf() helper for fine-grained control.
{{-- Using the Directive (Best for simple strings/colors) --}} <div class="banner" style="background-color: @acf($product, 'theme_color', '#ffffff')"> <h1>@acf($product, 'headline')</h1> </div> {{-- Using the Helper (Best for toggles and logic) --}} @if(acf($product, 'show_sidebar')) <aside>...</aside> @endif @foreach(acf($product, 'features', []) as $feature) <li>{{ $feature }}</li> @endforeach
4. Repeater Fields
Repeater fields allow you to create rows of content with sub-fields.
@if(have_rows('hero_slides', $product)) <div class="carousel"> @while(have_rows('hero_slides', $product)) @php the_row('hero_slides', $product); @endphp <div class="slide"> <img src="{{ get_sub_field('image') }}"> <h3>{{ get_sub_field('caption') }}</h3> <p>{{ get_sub_field('description') }}</p> </div> @endwhile </div> @endif
Note
the_row() advances the pointer and returns the row data. get_sub_field() retrieves values from the current row.
3. Accessing Field Metadata (Labels/Instructions)
If you need the Label instead of the Raw Key:
@php $field = $product->acfMeta('warranty_info'); @php @if($field) <div class="field-info"> <label class="fw-bold">{{ $field->name }}</label> <span class="text-muted d-block small">{{ $field->instructions }}</span> <div class="content">{{ acf($product, 'warranty_info') }}</div> </div> @endif
Querying & Filtering
ACF for Laravel provides powerful query scopes to filter models based on custom field values.
Basic Filtering
// Find all products with a 'rating' > 4 $topProducts = Product::whereAcf('rating', '>', 4)->get(); // Find products with 'color' in a list $blueItems = Product::whereAcfIn('color', ['blue', 'navy', 'sky'])->get();
Sorting & Ordering
// Order products by a custom 'priority' field $ordered = Product::orderByAcf('priority', 'desc')->get();
Advanced Eloquent Integration
// Combine with standard Eloquent queries and relationships $products = Product::where('status', 'active') ->with('category') ->whereAcf('sale_price', '<', 100) ->orderBy('created_at', 'desc') ->paginate(15);
Locations & Rules
Field Groups are displayed based on Location Rules.
Rule Structure (JSON Metadata)
{
"param": "post_type",
"operator": "==",
"value": "App\\Models\\Product"
}
Standard Contexts:
admin.edit: Default edit screen.admin.create: Only show during creation.frontend.form: Public facing forms.
Field Types
| Type | Data Type | UI Component |
|---|---|---|
text |
String | Standard Input |
textarea |
Text | Textarea |
number |
Integer/Float | Number Input |
toggle |
Boolean | Switch/Checkbox |
select |
String/Array | Dropdown/Multi-select |
date |
Date | HTML5 Date Picker |
email |
String | Email Input |
url |
String | URL Input |
color |
String | Color Picker |
repeater |
Array | Repeating rows of sub-fields |
Presentation & Theming
Control the wrapper, label, and input styling via the Presentation JSON.
Admin Template Integration
Tailwind (Default)
The package utilizes Tailwind-friendly classes for its internal UI. You can override these in config.
AdminLTE 3 / Bootstrap 3 & 4
Specify the bootstrap5 or bootstrap4 theme preset in config to adjust wrapper classes like form-group vs mb-3.
Conditional Logic
Show or hide fields based on the values of other fields in the same group.
Logic Example
[
{
"field": "has_discount",
"operator": "==",
"value": "1"
}
]
In the example above, the current field will only appear if the has_discount toggle is checked.
Export/Import & migrate:fresh Safety
The Problem
If you store your ACF definitions (Field Groups/Fields) only in the database, running php artisan migrate:fresh will wipe them out.
The Solution: JSON Synchronization
Use the provided commands to keep a version-controlled copy of your configuration.
- Export: After creating fields in UI, run:
php artisan acf:export
- Commit: Check
storage/app/acf/definitions.jsoninto Git. - Import: On staging/production or after a fresh local migration, run:
php artisan acf:import
Recommended Team Workflow
- Add
php artisan acf:importto yourcomposer.jsonpost-install/update scripts or your deployment pipeline.
Health & Recovery
Orphan Values
If you delete a Field definition, the stored Values in acf_values remain as "orphans". Use the Health Check screen to:
- Detect orphaned data.
- Bulk delete values for obsolete fields.
Safe Deletion
By default, the package uses Soft Deletes. When you delete a group, it's moved to the trash. You can restore it from the database or via the Admin UI.
Caching & Performance
What is Cached?
- Field definitions (keyed by Model + Key).
- Location rule evaluations for a model instance.
Management
# Clear all ACF cache
php artisan cache:forget acf.definitions
Troubleshooting FAQ
Q: My fields are not showing on the model edit page.
- Check the Location Rules. Ensure the
model_typematches exactly (including namespace). - Ensure the
positionin<x-acf::form />matches the group's position.
Q: Why do I see a "Definitions Mismatch" banner?
- Your database has changes that haven't been exported to JSON, or someone updated the JSON file and you haven't run
acf:import.
Roadmap
- Flexible Content blocks (Layout based).
- Advanced Relationship fields (Select from other Models).
- REST API & GraphQL integration.
- Inertia.js / Vue.js rendering components.
License
The MIT License (MIT). Please see License File for more information.
arshpharala/advanced-custom-fields 适用场景与选型建议
arshpharala/advanced-custom-fields 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 13 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 30 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「admin-panel」 「polymorphic」 「acf」 「custom-fields」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 arshpharala/advanced-custom-fields 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 arshpharala/advanced-custom-fields 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 arshpharala/advanced-custom-fields 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Laravel Ownership simplify management of Eloquent model's owner.
Implement a polymorphic morphMany relationship for managing attachments within Filament
A Laravel package providing a full-featured, framework-agnostic commenting system for any Eloquent model.
Metamel Addresses is a polymorphic Laravel package, for address book management. You can add addresses to any eloquent model with ease.
A simple, flexible Laravel package for adding polymorphic reactions to any model. React with any text: like, love, care, or anything you want.
Rinvex Categories is a polymorphic Laravel package, for category management. You can categorize any eloquent model with ease, and utilize the power of Nested Sets, and the awesomeness of Sluggable, and Translatable models out of the box.
统计信息
- 总下载量: 13
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 38
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-30