Creating a New Field Type


Photon CMS ships with a number of pre-set field types, but knowing that all use-cases can never be covered, we made sure that the platform is to extend with new field types.

Table of Contents
  1. The Artisan Method
  2. Changes in the API
  3. Changes In the Control Panel
  4. Video Guide

The Artisan Method

Currently, the process is manual, but we will automate the process to make the new field creation accessible via an Artisan command.

Changes in the API

Step 1. 

Add a new entry in field_types table with following fields:

type - field type system name
title - field type user friendly name
laravel_type - laravel's field type which will be used when generating migations
is_system - flag that indicates if attributes of this field type can be modified via API

Step 2. 

Create a new class in /app/PhotonCms/Dependencies/DynamicModuleFieldTypes using the following Template:


<?php
namespace Photon\PhotonCms\Dependencies\DynamicModuleFieldTypes;
use Photon\PhotonCms\Core\Entities\FieldType\FieldType;
use Photon\PhotonCms\Core\Entities\DynamicModuleField\Contracts\TransformsInput;
use Photon\PhotonCms\Core\Entities\DynamicModuleField\Contracts\TransformsOutput;
use Photon\PhotonCms\Core\Entities\DynamicModuleField\Contracts\HasValidation;
class Test extends FieldType implements TransformsInput, TransformsOutput, HasValidation
{
    public function __construct()
    {
        // is this field type attribute
        $this->isAttribute = true;
        // is this field type relation
        $this->isRelation = false;
        // if field type is relation does it requires a pivot table
        $this->requiresPivot = false;
        // if field type is relation what is it's relation type (OneToOne, OneToMany, ManyToOne or ManyToMany)
        $this->relationType = '';
    }
    /**
     * Setter method for all fields of this field type
     *
     * @param mixed     $object         Object that is being modified
     * @param string    $attributeName  Name of the attribute from object
     * @param mixed     $value          Value that is being stored in attribute
     */
    public function input($object, $attributeName, $value)
    {
        $object->$attributeName = $value;
    }
    /**
     * Getter method for all fields of this field type
     *
     * @param mixed     $object         Object that is being modified
     * @param string    $attributeName  Name of the attribute from object
     */
    public function output($object, $attributeName)
    {
        return $object->$attributeName;
    }
    /**
     * Validation rules that will always be used for fields of this field type. Those rules will be applied after dynamic validation rules defined within generator
     */
    public function getValidationString()
    {
        return 'string';
    }
}

Step 3.

Add new field type to array within /config/field-types.php with same values that you entered in field_types table in step 1

NOTE: Currently it is not possible to add new relation field type. We will cover this use-case during the Artisan command addition, soon.

Changes In the Control Panel

Step 1.

Make sure you've pulled-in your dependencies running either yarn or npm install from your project web root folder.

Step 2.

Edit the /resources/assets/photonCms/dependencies/js/services/fieldTypes.js file to include a new object property in the format fieldTypeId: fieldTypeName

Here's an example:


/**
 * Field id to field object map
 *
 * @type  {Object}
 */
export const mapFromId = {
    25: test,
};


While editing the /resources/assets/photonCms/dependencies/js/services/fieldTypes.js, also add a new field type object right above the mapFromId definition.

Example:


export const test = {
    id: 25,
    name: 'Test',
    vueComponent: 'InputText',
    valueType: 'string',
    isSystem: false
};

Step 3.

Edit the /resources/assets/photonCms/dependencies/js/config/fieldTypeComponents.js file to add a new fiel type component. You can use any of the components listed in /resources/assets/photonCms/core/js/config/fieldTypeComponents.js as a starting point. For example, if you want to make a version of a Input Text Field, use the following example:


export const TestField = Vue.component(
        'InputTextField',
        require('_/components/FieldTypes/InputTag/InputTag.vue')
    );

Step 4.

Finally, run the npm run production command so that the changes are compiled, and you should see your new field type available in the Generator.

Video Guide

Sign-up to stay informed about news and updates.