PHPackages                             digitalnodecom/larafields - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. digitalnodecom/larafields

ActivePackage[Utility &amp; Helpers](/categories/utility)

digitalnodecom/larafields
=========================

A Laravel-powered form maker for your WordPress site.

2.0.5(9mo ago)2160↓75%[1 PRs](https://github.com/digitalnodecom/larafields/pulls)MITPHPPHP ^8.2CI passing

Since Feb 17Pushed 9mo ago1 watchersCompare

[ Source](https://github.com/digitalnodecom/larafields)[ Packagist](https://packagist.org/packages/digitalnodecom/larafields)[ RSS](/packages/digitalnodecom-larafields/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (2)Versions (58)Used By (0)

Larafields
==========

[](#larafields)

A flexible form maker package that allows you to define custom form groups for WordPress posts and taxonomies built with Acorn (Laravel) &amp; Livewire.

Installation
------------

[](#installation)

You can install this package with Composer:

```
composer require digitalnodecom/larafields
```

After installation, you need to:

1. Clear the Acorn cache:

```
wp acorn clear
```

This step is necessary for the package to be recognized by Acorn.

2. Publish the package assets and configuration:

```
wp acorn vendor:publish --tag="larafields"
```

3. Run the database migrations:

```
wp acorn migrate
```

4. Build the JavaScript and CSS assets:

```
npm install
npm run build
```

This step compiles the JavaScript and CSS files needed for the package to function properly.

4. Add the following hooks to your current theme's `functions.php` file.

```
use Livewire\Mechanisms\HandleRequests\HandleRequests;

add_filter('admin_enqueue_scripts', function () {
    echo Blade::render('@livewireStyles');
});

add_filter('admin_footer', function () {
    echo Blade::render('@livewireScripts');
});

add_action('init', function() {
    if (function_exists('app') && class_exists(Route::class)) {
        Route::post('/livewire/update', [HandleRequests::class, 'handleUpdate'])->name('livewire.update')->middleware('web');

        app('router')->getRoutes()->refreshNameLookups();
        app('router')->getRoutes()->refreshActionLookups();
    }
}, 20);

```

5. Clear the cached views

```
wp acorn clear:views
```

Configuration
-------------

[](#configuration)

Form groups are defined in the `config/larafields.php` file. Each form group can be configured to display on specific post types or taxonomies.

### Basic Structure

[](#basic-structure)

```
return [
    'forms' => [
        [
            'label'    => 'Your Field Group Name',
            'name'     => 'unique_field_group_name',
            'settings' => [
                'showInRestApi' => true,
                'storage'       => [
                    'type'     => 'json',
                    'location' => 'shared_table'
                ],
                'conditions'    => [
                    // Define where to display the form
                ]
            ],
            'fields'   => [
                // Your field definitions
            ]
        ]
    ]
];
```

### Core Concepts

[](#core-concepts)

The package uses several key terms throughout its configuration and API:

#### Object Types and Names

[](#object-types-and-names)

- **object\_type**: Defines the WordPress entity type where fields can be attached. Can be one of:

    - `post_type`: For WordPress posts and custom post types
    - `taxonomy`: For categories, tags, and custom taxonomies
    - `user`: For WordPress user profiles
    - `settings`: For option pages, term option pages, and user option pages
- **object\_name**: The specific identifier within an object type. Examples:

    - For `post_type`: Could be "post", "page", "product", or any custom post type name
    - For `taxonomy`: Could be "category", "post\_tag", "product\_cat", or any custom taxonomy name
    - For `user`: Always `null`
    - For `settings`: The slug of the options page, term options page, or user options page
- **object\_id**: The unique identifier for a specific instance:

    - For posts: The post ID
    - For taxonomies: The term ID
    - For users: The user ID
    - For settings pages: The page slug

These concepts are used throughout the package's API and configuration to precisely target where fields should be displayed and how data should be stored and retrieved.

### Display Conditions

[](#display-conditions)

You can display form groups on any Post Type, any Term, and/or create a custom Options page:

#### Post Type Display

[](#post-type-display)

This will display the form group on the specified post type's edit screen in the WordPress Admin dashboard.

```
'conditions' => [
    [ 'postType' => 'product' ]
]
```

#### Taxonomy Display

[](#taxonomy-display)

This will display the form group on the specified taxonomy's term edit screen in the WordPress Admin dashboard.

```
'conditions' => [
    [ 'taxonomy' => 'product_brand' ]
]
```

#### Options Page Display

[](#options-page-display)

This will create a new page in the WordPress Admin dashboard with the specified title and menu entry. The form group will be rendered on this custom options page.

```
'conditions' => [
    [
        'page' => [
            'page_title' => 'Testing',
            'menu_title' => 'Testing',
            'slug' => 'testing',
            // 'parent' => 'parent_slug'  // Optional: Specify a parent slug to create this as a submenu page
        ]
    ]
]
```

#### Term Option Page Display

[](#term-option-page-display)

This will add an action link (alongside Edit, Quick Edit, Delete, View) on the taxonomy overview page. When clicked, it opens a custom page where the form group will be rendered, with the data being related to both the selected term and taxonomy.

```
'conditions' => [
    'term_page' => [
        'taxonomy' => 'wcpv_product_vendors',
        'action_name' => 'Change Mappings',
        'page_title' => 'Brand Testing',
        'menu_title' => 'Brand Testing',
        'slug' => 'brand_testing'
    ]
]
```

#### User Profile Display

[](#user-profile-display)

This will display the form group on the user's "Edit Profile" page in the WordPress Admin dashboard.

```
'conditions' => [
    'user'
]
```

#### User Page Display

[](#user-page-display)

This will add an action link (alongside Edit, Delete, and other user actions) on the Users overview page. When clicked, it opens a custom page where the form group will be rendered for the selected user.

```
'conditions' => [
    'user_page' => [
        'action_name' => 'Adjust Mappings',
        'page_title' => 'Vendor User Mappings',
        'menu_title' => 'Vendor User Mappings',
        'slug' => 'vendor_mappings_user'
    ]
]
```

Available Field Types
---------------------

[](#available-field-types)

### Text Field

[](#text-field)

Simple text input with optional character limit.

```
[
    'type'           => 'text',
    'label'          => 'Input Label',
    'name'           => 'field_name',
    'defaultValue'   => 'Default text',
    'required'       => true,
    'characterLimit' => 50
]
```

### Date Field

[](#date-field)

Date picker input field.

```
[
    'type'           => 'date',
    'label'          => 'Date Created',
    'name'           => 'date_created',
    'defaultValue'   => '',
    'required'       => true,
    'characterLimit' => 50
]
```

### DateTime Field

[](#datetime-field)

Date and time picker input field.

```
[
    'type'           => 'datetime',
    'label'          => 'Event Date and Time',
    'name'           => 'event_datetime',
    'defaultValue'   => '',
    'required'       => true,
    'characterLimit' => 50
]
```

### Week Field

[](#week-field)

Week picker input field.

```
[
    'type'           => 'week',
    'label'          => 'Week Selection',
    'name'           => 'selected_week',
    'defaultValue'   => '',
    'required'       => true,
    'characterLimit' => 50
]
```

### Month Field

[](#month-field)

Month picker input field.

```
[
    'type'           => 'month',
    'label'          => 'Month Selection',
    'name'           => 'selected_month',
    'defaultValue'   => '',
    'required'       => true,
    'characterLimit' => 50
]
```

### File Field

[](#file-field)

File upload field with image preview support. Files are stored in the default disk under the 'larafields' directory.

```
[
    'type'           => 'file',
    'label'          => 'Image',
    'name'           => 'image',
    'defaultValue'   => '',
    'required'       => true,
]
```

### Textarea Field

[](#textarea-field)

Multiline text input with optional character limit.

```
[
    'type'           => 'textarea',
    'label'          => 'Textarea Label',
    'name'           => 'textarea_field',
    'defaultValue'   => 'Default multiline text',
    'required'       => false,
    'characterLimit' => 200
]
```

### Number Field

[](#number-field)

Numeric input with optional min/max values.

```
[
    'type'         => 'number',
    'label'        => 'Number Input',
    'name'         => 'number_field',
    'defaultValue' => 10,
    'required'     => true,
    'minValue'     => 1,
    'maxValue'     => 100
]
```

### Multiselect Field

[](#multiselect-field)

Dropdown field that allows selecting multiple options.

```
[
    'type'         => 'multiselect',
    'label'        => 'Multiple Choice',
    'name'         => 'multiselect_field',
    'defaultValue' => '',
    'required'     => true,
    'options'      => [
        [
            'value' => 'option1',
            'label' => 'Option 1'
        ],
        [
            'value' => 'option2',
            'label' => 'Option 2'
        ]
    ],
    'custom_values' => false // Set to true to allow users to enter custom values not in the options list
]
```

When `custom_values` is set to `true`, users can enter and select values that are not predefined in the options list. This is useful when you want to allow for flexible input while still providing common options.

### Repeater Field

[](#repeater-field)

Group of fields that can be repeated multiple times.

```
[
    'type'          => 'repeater',
    'label'         => 'Repeatable Group',
    'name'          => 'repeater_field',
    'showSearch'    => true,  // Optional: Enable search for nested repeaters (default: false)
    'subfields'     => [
        [
            'type'           => 'text',
            'label'          => 'Sub Field 1',
            'name'           => 'sub_field_1',
            'defaultValue'   => '',
            'required'       => true
        ],
        [
            'type'           => 'text',
            'label'          => 'Sub Field 2',
            'name'           => 'sub_field_2',
            'defaultValue'   => '',
            'required'       => true
        ]
    ]
]
```

#### Repeater Field Options

[](#repeater-field-options)

- **showSearch** (boolean, default: false): By default, only top-level repeaters display search functionality to save screen space. Set this to `true` to enable search for nested repeaters.

Example with nested repeaters:

```
[
    'type' => 'repeater',
    'label' => 'Contact Persons',
    'name' => 'contact_persons',
    'subfields' => [
        [
            'type' => 'text',
            'label' => 'Name',
            'name' => 'name',
            'required' => true
        ],
        [
            'type' => 'repeater',
            'label' => 'Phone Numbers',
            'name' => 'phone_numbers',
            'showSearch' => true,  // Enable search for this nested repeater
            'subfields' => [
                [
                    'type' => 'text',
                    'label' => 'Phone',
                    'name' => 'phone',
                    'required' => true
                ]
            ]
        ]
    ]
]
```

Repeater Field Validation
-------------------------

[](#repeater-field-validation)

The package includes a validation system that allows you to enforce data integrity rules on your form fields, including unique validation within repeater fields.

### Unique Within Repeater Validation

[](#unique-within-repeater-validation)

You can ensure that values within a repeater field are unique by adding validation rules to your field schema. This is particularly useful for fields like categories, IDs, or names that should not be duplicated within the same repeater.

```
[
    'type' => 'repeater',
    'label' => 'Category Mappings',
    'name' => 'vendor_mappings',
    'subfields' => [
        [
            'type' => 'text',
            'label' => 'Vendor Category',
            'name' => 'vendor_category',
            'defaultValue' => '',
            'required' => true,
            'characterLimit' => 50,
            'validation' => [
                'unique_within_repeater' => true,
                'unique_message' => 'This vendor category already exists. Please choose a different name.',
            ],
        ],
        [
            'type' => 'select',
            'label' => 'Product Gender',
            'name' => 'product_gender',
            'defaultValue' => [],
            'required' => true,
            'options' => [
                [
                    'value' => 'men',
                    'label' => 'Men',
                ],
                [
                    'value' => 'women',
                    'label' => 'Women',
                ],
                [
                    'value' => 'unisex',
                    'label' => 'Unisex',
                ],
            ],
        ],
        // ... other subfields
    ],
]
```

### Validation Features

[](#validation-features)

- **Case-insensitive comparison**: "Test" and "test" are considered duplicates
- **Whitespace trimming**: Leading and trailing spaces are ignored during comparison
- **Empty value handling**: Empty values are ignored (required validation handles empty fields separately)
- **Error display**: Validation errors appear below each field in red text
- **Form submission prevention**: Forms with validation errors cannot be submitted until fixed

### Validation Rules

[](#validation-rules)

The validation system supports the following rules:

- `unique_within_repeater`: Ensures the value is unique within the current repeater field
- `unique_message`: Custom error message to display when uniqueness validation fails
- `required`: Field must have a value (existing functionality)
- `characterLimit`: Maximum number of characters allowed (existing functionality)
-

Adding Field Groups Programmatically
------------------------------------

[](#adding-field-groups-programmatically)

You can programmatically add new field groups using the `FormMaker::add_group()` method. This can be added to an action hook in your theme or plugin:

```
add_action('init', function() {
    FormMaker::add_group([
        'label'    => 'CODE Field Group Term',
        'name'     => 'code_field_group_term',
        'settings' => [
            // settings
        ],
        'fields'   => [
            // fields
        ]
    ]);
});
```

The structure follows the same format as defined in the configuration file, allowing you to specify labels, settings, and fields for your new group.

### Retrieving Field Data Programmatically

[](#retrieving-field-data-programmatically)

You can fetch field data from the database using the `FormMaker::get_field()` method. This method accepts three optional parameters:

```
FormMaker::get_field(?string $fieldKey = null, ?string $objectName = null, ?string $objectId = null)
```

At least one of these parameters must be provided:

- `$fieldKey`: The specific field key to retrieve
- `$objectName`: The name of the object type (e.g., 'product', 'category')
- `$objectId`: The ID of the object

The method will throw an Exception if none of these parameters are provided.

Example usage:

```
// Get all fields for a specific object
$fields = FormMaker::get_field(objectName: 'product', objectId: '123');

// Get a specific field
$field = FormMaker::get_field(fieldKey: 'product_gender');

// Get fields by object name
$fields = FormMaker::get_field(objectName: 'product');
```

Extending Fields
----------------

[](#extending-fields)

You can modify or manipulate the existing fields using the `larafields_load_fields` WordPress filter. This filter provides access to the fields collection before it's processed:

```
use Illuminate\Support\Collection;

add_filter('larafields_load_fields', function(Collection $fields){
    // Manipulate the $fields collection.
});
```

Dashboard Menu Pages
--------------------

[](#dashboard-menu-pages)

You can add custom dashboard menu pages using the `larafields_load_pages` filter. This allows you to create additional admin pages for your application.

### Adding Dashboard Menu Pages

[](#adding-dashboard-menu-pages)

Use the `larafields_load_pages` filter to add new pages to the WordPress admin dashboard:

```
add_filter('larafields_load_pages', function ($pages) {
    return [
        [
            'type' => 'page',
            'page_title' => 'Example Page',
            'menu_title' => 'Example Page',
            'slug' => 'page-example',
            // 'hide_from_submenu' => true // This prevents the parent page from appearing in the submenu
        ],
    ];
});
```

JavaScript Bundling
-------------------

[](#javascript-bundling)

This package uses webpack to bundle JavaScript dependencies. The main JavaScript dependency is tom-select, which is used for the multiselect field type.

### Development

[](#development)

To work on the JavaScript files:

1. Make changes to the JavaScript files in the `resources/js` directory
2. Run `npm run dev` to watch for changes and automatically rebuild the JavaScript files

### Production

[](#production)

To build the JavaScript files for production:

1. Run `npm run build` to build both CSS and JavaScript files
2. The bundled JavaScript file will be available at `resources/js/public/larafields.js`
3. The tom-select CSS file will be available at `resources/js/public/css/tom-select.css`

API Documentation
-----------------

[](#api-documentation)

The package provides REST API endpoints for querying and updating forms and their data.

### Query Endpoint

[](#query-endpoint)

```
GET /larafields/forms

```

### Authentication

[](#authentication)

The API uses Basic Authentication with WordPress Application Passwords:

- Username: Your WordPress username
- Password: Generated Application Password key

### Request Body Parameters

[](#request-body-parameters)

The endpoint accepts the following parameters in the request body:

ParameterRequiredDescriptionobject\_idNo\*The ID of the object (post, term, etc.)object\_nameNo\*The name of the object typefield\_keyNo\*The key of the specific field to retrieve\*At least one of these parameters must be provided.

### Field Validation

[](#field-validation)

The API implements the following validation rules:

- `object_id`: Required if neither `object_name` nor `field_key` is provided
- `object_name`: Required if neither `object_id` nor `field_key` is provided
- `field_key`: Required if neither `object_id` nor `object_name` is provided

This means you must provide at least one of these three parameters in your request.

### Query Examples

[](#query-examples)

#### Query by Object ID

[](#query-by-object-id)

```
// Request body
{
  "object_id": "123"
}
```

This will return all form data associated with the object ID 123.

#### Query by Object Name

[](#query-by-object-name)

```
// Request body
{
  "object_name": "product"
}
```

This will return all form data associated with the object type "product".

#### Query by Field Key

[](#query-by-field-key)

```
// Request body
{
  "field_key": "product_gender"
}
```

This will return the specific field data for the field key "product\_gender".

#### Combined Query

[](#combined-query)

```
// Request body
{
  "object_id": "123",
  "object_name": "product"
}
```

This will return form data that matches both the object ID 123 and object type "product".

### Update Endpoint

[](#update-endpoint)

```
POST /larafields/forms

```

#### Authentication

[](#authentication-1)

The API uses Basic Authentication with WordPress Application Passwords (same as the Query Endpoint).

#### Request Body

[](#request-body)

The request body should be a JSON object with the following properties:

PropertyRequiredDescriptionfield\_keyYesThe key of the field to updatefield\_valueYesThe new value for the fieldobject\_idYesThe ID of the object (post, term, etc.)object\_nameYesThe name of the object type#### Example Request

[](#example-request)

```
{
  "field_key": "location",
  "field_value": "Europe",
  "object_id": "1000",
  "object_name": "product"
}
```

#### Response

[](#response)

A successful update will return a JSON response with status 'ok':

```
{
  "status": "ok"
}
```

Complete Examples
-----------------

[](#complete-examples)

### Post Type Form Group

[](#post-type-form-group)

```
[
    'label'    => 'Product Details',
    'name'     => 'product_details',
    'settings' => [
        'showInRestApi' => true,
        'storage'       => [
            'type'     => 'json',
            'location' => 'shared_table'
        ],
        'conditions'    => [
            [ 'postType' => 'product' ]
        ]
    ],
    'fields'   => [
        [
            'type'         => 'multiselect',
            'label'        => 'Product Gender',
            'name'         => 'product_gender',
            'defaultValue' => '',
            'required'     => true,
            'options'      => [
                [
                    'value' => 'men',
                    'label' => 'Men'
                ],
                [
                    'value' => 'women',
                    'label' => 'Women'
                ],
                [
                    'value' => 'unisex',
                    'label' => 'Unisex'
                ]
            ]
        ],
        [
            'type'           => 'textarea',
            'label'          => 'Product Description',
            'name'           => 'product_description',
            'defaultValue'   => '',
            'required'       => false,
            'characterLimit' => 200
        ]
    ]
]
```

### Taxonomy Form Group

[](#taxonomy-form-group)

```
[
    'label'    => 'Brand Information',
    'name'     => 'brand_information',
    'settings' => [
        'showInRestApi' => true,
        'storage'       => [
            'type'     => 'json',
            'location' => 'shared_table'
        ],
        'conditions'    => [
            [ 'taxonomy' => 'product_brand' ]
        ]
    ],
    'fields'   => [
        [
            'type'          => 'repeater',
            'label'         => 'Brand Contacts',
            'name'          => 'brand_contacts',
            'subfields'     => [
                [
                    'type'           => 'text',
                    'label'          => 'Contact Name',
                    'name'           => 'contact_name',
                    'defaultValue'   => '',
                    'required'       => true
                ],
                [
                    'type'           => 'text',
                    'label'          => 'Contact Email',
                    'name'           => 'contact_email',
                    'defaultValue'   => '',
                    'required'       => true
                ]
            ]
        ],
        [
            'type'           => 'text',
            'label'          => 'Brand Website',
            'name'           => 'brand_website',
            'defaultValue'   => '',
            'required'       => true,
            'characterLimit' => 100
        ]
    ]
]
```

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance57

Moderate activity, may be stable

Popularity13

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 86.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

49

Last Release

285d ago

Major Versions

1.2.13 → v2.0.02025-07-24

PHP version history (2 changes)1.0.0PHP ^8.0

1.1.20PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/e920ffec7749ac8929e37e82c4e6d03bbfc90eac652a385906fa2000af9bd7f3?d=identicon)[trajche](/maintainers/trajche)

---

Top Contributors

[![KIKOmanasijev](https://avatars.githubusercontent.com/u/34198639?v=4)](https://github.com/KIKOmanasijev "KIKOmanasijev (198 commits)")[![trajche](https://avatars.githubusercontent.com/u/2382019?v=4)](https://github.com/trajche "trajche (28 commits)")[![SimonAnastasov](https://avatars.githubusercontent.com/u/86790702?v=4)](https://github.com/SimonAnastasov "SimonAnastasov (2 commits)")

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/digitalnodecom-larafields/health.svg)

```
[![Health](https://phpackages.com/badges/digitalnodecom-larafields/health.svg)](https://phpackages.com/packages/digitalnodecom-larafields)
```

###  Alternatives

[supermundano/sage-the-events-calendar

1724.5k](/packages/supermundano-sage-the-events-calendar)[mwdelaney/sage-fonts-preload

Automatically preload fonts from the Sage mix manifest

188.3k](/packages/mwdelaney-sage-fonts-preload)[tombroucke/sage-bootstrap-components

Bootstrap 4 components for Sage

113.1k1](/packages/tombroucke-sage-bootstrap-components)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
