4

I have been struggling to create my own custom field, so I would like to ask how to create it.

First of all, I don't know where the files should be in. I have some custom fields in Craft 2. It might be able to be migrated, but it is not.

I have these files under src folder in a plugin.

fields/{fieldtypeName}FieldType.php
templates/_fieldtypes/{fieldtypeHandle}/input.html
templates/_fieldtypes/{fieldtypeHandle}/settings.html

Then I added a registration as the documentation, but Craft says it is not found. https://docs.craftcms.com/v3/extend/field-types.html

2
  • Could you be a little bit more precise? There are more than enough examples of custom field types in several plugins that shows you how to create one. And there are many example of Craft fields that you can look at. Not sure where you struggle. What is not found? The class? The Template? Do you try to use your old field or create a new one? Commented Apr 9, 2019 at 14:44
  • I have looked for sample code on the Internet, but I found nothing. However, I didn't see other plugins. I have no idea what the codes like, and where the code should be in. And I would like to create a new one. I tried to migrate the old one because I thought it helps me somewhat.
    – Kota.M
    Commented Apr 9, 2019 at 14:51

1 Answer 1

5

In order to include a custom field type you first need to register your own module or plugin you can create the basic structure for both from pluginfactory.io and register them as you like. There is also a default module that comes with every Craft 3 installation. You only need to bootstrap it in your app.php

Then in your module you need the following code

public function init()
{
    Event::on(Fields::class, Fields::EVENT_REGISTER_FIELD_TYPES, function(RegisterComponentTypesEvent $event) {
        $event->types[] = MyField::class;
    });
}

And your class could look like the Incognito Field for example. Basically every field has several methods implemented in the FieldInterface such as getInputHtml to render the HTML or normalizeValue to create a field value based on user or DB input and serializeValue to prepare the value for your DB. The interface has everything you need.

A good example to get started is to extend the PlainText field and customize it's functions. You can overwrite the inputHtml function and render a custom template

public function getInputHtml($value, ElementInterface $element = null): string
{
    // Get our id and namespace
    $id = Craft::$app->getView()->formatInputId($this->handle);
    $namespacedId = Craft::$app->getView()->namespaceInputId($id);

    // Render the input template
    return Craft::$app->getView()->renderTemplate(
        'module-id/fields/hidden/_input',
        [
            'name' => $this->handle,
            'value' => $value,
            'field' => $this,
            'id' => $id,
            'namespacedId' => $namespacedId,
        ]
    );
}
4
  • Thank you for answering my question again. I made a new PHP file next to plugin PHP file, but unfortunately the registration function causes error due to an error; "Cannot declare class craft\fields\AssetsWithDL, because the name is already in use". I am looking for the cause now. By the way, I would like to have an assets field with download link, so I try to extend Assets field.
    – Kota.M
    Commented Apr 9, 2019 at 15:27
  • If it's only that you can download a plugin or register a custom js file with about 15 lines that adds the functionality to the default assets field Commented Apr 9, 2019 at 15:39
  • Is it this one? craftcms.stackexchange.com/questions/24089/…
    – Kota.M
    Commented Apr 9, 2019 at 17:31
  • I added it in main.js, but it does not work. Could I ask where the js function should be in?
    – Kota.M
    Commented Apr 9, 2019 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.