2

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

  • 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? – Robin Schambach Apr 9 '19 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 Apr 9 '19 at 14:51
3

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,
        ]
    );
}
| improve this answer | |
  • 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 Apr 9 '19 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 – Robin Schambach Apr 9 '19 at 15:39
  • Is it this one? craftcms.stackexchange.com/questions/24089/… – Kota.M Apr 9 '19 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 Apr 9 '19 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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