About this talk
In this talk, Alexey Karepov discusses a simplified approach to creating forms in Drupal using schema definitions instead of traditional PHP methods. He demonstrates how to generate forms automatically with minimal code by leveraging YAML schemas, which saves significant space and reduces complexity. The speaker provides detailed examples comparing the old method, which involves extensive PHP coding and multiple files, to the streamlined YAML approach, highlighting the benefits of using constraints for validation and configuration overrides. Additionally, he introduces new features for custom forms and plugin-based fields, emphasizing how these innovations can enhance the configuration management experience in Drupal. The session concludes with a call to action for the audience to adopt this new methodology and help improve it by providing feedback and contributing to the project.
Full transcript
Okay, hello everyone. My name is Alexey Karepov. I came from Armenia here to the USA with the appeal stop creating Drupal forms. Just describe a schema and the form will appear automatically. Let me explain. So, creating forms in Drupal is quick and simple. They say it, right? Okay, let's create a simple form. Something simple like this, my API settings with endpoint URL and the access token. To
do this, we should create we should use PHP, right? We should create a class that extends a config form base class and describe there the form ID, editable config names. Then we should write the function build form where we put the long array with description of our fields. And also we should create a function validate form where we will validating our data and the submit form where
we actually updating the config and do all the storage stuff. And using this classical approach, you end up with something like this, the PHP file with around 100 of code lines. And all this just for two fields. 100 lines, Carl. It's too much, right? Ah, and also we should create a routing. Seven lines of YAML. And our form is almost ready. It looks like this. Let's click
on the save configuration. And oh, unexpected error. Try again later. Let's clean our desk. What should we do? Let's enable debug output and we see that we forgot the schema. So, if you want to save the configuration, we should create a schema file. Let's create it. So, here is an example of 10 line config put the name of our schema and the mapping of fields. Endpoint URL
is string and access token as string. Actually, pretty simple file. Also, you create the previously the seven line route file. And our 100 lines of PHP code. And now our form works perfectly. That's great, right? But we created 10 lines of YAML for the schema file, created routing file, and the settings form PHP with 100 lines with 100 lines and almost 3 and 1/2 kilobytes. 170 lines,
Carl. 3,500 bytes. It's too much, right? Agree with me? Okay, let's save this space by deleting something redundant there. Can we? Let's choose file that we can delete. Maybe this one, the schema file, but it looks kind of useful, right? We describe the mapping, we describe the labels. Okay, let's keep it. And maybe the routing file. It's also needed because we need the URL and reference to
the form. Without it, the page will not work. just delete the biggest one. I think that's a good choice. And replace it with a module schema in in the replacement of this PHP, we should extend the routing file where we changing the deleted my API settings form class to the schema config from route form class. And in the options, just put the name of our schema. And
actually, that's it. We deleted 100 of PHP code lines and added just four YAML lines. Pretty good, right? Let's compare. Here is a form by 100 of code lines and here is a form by four YAML lines. Who can find the difference? Ah, descriptions are gone. Forgot about them. Let's show it into the schema right right there because we have no PHP where to put it. In
the my module schema YAML file, we just add the description lines with description that we want. And Now, both forms are the same. Okay, not by six not by four YAML lines, but by six YAML lines, but still it's a bit less than 100 of code lines, right? we forgot the validation. And now I think it's good time for PHP. But not that time. Still YAML time.
Ah, to add the validation, we don't need to write any PHP code. We just open our schema file and put constraints there. So, the for the endpoint URL, we put a regular expression with a pattern and error message if pattern doesn't match. And the same for access token. We put constraints with a minimum maximum length of the value and regular expression to check if it fits the
requirements. And having this on the submission, the form will automatically generate all the error messages. By the way, these constraints apply on every configuration, not only when you submit the form, but when you try to update the config values programmatically or using any other ways to to update the configs. They will check and refuse changes that does not allow And here in constraints, you can use not
only building constraints like regular expressions or length, you can write your own constraints and use them across all the forms on your website. And again, with no PHP, we just describe the ID of the constraints plugin and the status. And let's compare. So, before we had a form with three files, two YAML files and PHP file. And now just two files, the routing file and the schema
file. And actually, that's all that we need. the bundle size was 4 and 1/2 kilobytes and now less than a kilobyte. So, we have 80% of the space that can be used for better things than just describing And you will have more space on your floppy drive for better things. Yeah, and here also you will get a bonus, configuration overrides. Usually, if you have some configuration values,
you want to override them on production, for example, to hide your API keys or override some values to not allow them to be changed in in the interface. For this, usually we use the settings.php. And immediately when you add this values to the your settings.php or override the values using any other Drupal way, the form will get this and automatically add the status message describing that these
values are overridden and if you change this, they will actually not be changed. And also, the module automatically adds a description with the overridden value. So, you can see here that the instead of myapi.com, the overridden value is my superapi.com. And if here the field is a password, the config value is overridden, but the actual password is not shown for security reasons. And all this we achieved
with no code. Actually, only YAML. And you might ask why YAML is not a Ah, because YAML is just a static declarative structure. It's not a code that can produce bugs. You just describe what you want, not how to achieve this. And the rest will be generated automatically by the module. So, you have much less mistake, much less code that you have to review, to manage, and
update, and so on. And using this approach with config forms, you can actually ah, make not only API credential pages, but site general settings. For example, you know the basic site settings where you set the site name, site slogan, and so on. And using this, you can create number of fields that you want. Ah, header and footer like copyright, legal information, etc. You can also just describe
the schema and one YAML to make the with this form. Editable contact information like company name, address, phone, social media links, custom module settings, site labels and text. For example, if you have some text that repeated on every page, you just put it into the form and just use it everywhere. Ah, let's try to use this approach to recreate the basic site settings form from the Drupal
core with no code. Ah, so Drupal settings provide a page like this with basic site settings and a bunch of fields. To do the same, we need just to create the routing file because the schema file is already existing in the Drupal core. So, we create the routing file where we point to the schema config from route form file and in editable config names, put the name
of the schema system.site. And actually, that's it. We have almost uh form page generated automatically with PHP lines. Just 10 YAML lines and it works. Sounds awesome, right? Uh but probably you want more simplifications, not only this. And I have them. Some of you, I think, already created custom entities with custom fields, created some base fields, text fields, integer, and so on. But usually you don't see
them uh in the edit form because it just Drupal does it. You should create everything by hands. Uh let me show how it looks. Uh so, here's an example of a config entity with three fields, ID, my string, and my number. And uh we create the schema because without schema we will get the error uh that schema is missing. Where we describing the ID as string, my
string as string, my number as integer. And uh Drupal automatically generates schema like uh the form like this with the cool save button, but something's missing there, right? Let me fix this. Let's replace uh the building entity form uh class so that in this case kind of useless to the schema form entity form class. Just change this into fields of the uh config entity declaration. And uh
all the fields automatically appear appeared on the page. So, which form is better? The first one or the second one? I think the second one is a bit more useful than the first one, right? And all this uh actually by changing uh the declaration of the config entity. Again, with no PHP changes, just pointing to the schema form entity form um makes all the magic. And uh
using the same approach, you can describe any fields you want. And if you want to group fields, to make nested fields, it also works out of the box. You just describe the mapping and uh the module will render the field set with all the fields inside it. And all uh fields are plugin based, so you're not limited to use only building uh fields, but uh can write
your own plugins. So, every field is rendered by plugin uh schema form field type. And I already implemented the uh plugins for checkbox, language code, mapping, number, text area, text field. Uh also trying to finalize the entity uh plugin. It works, but requires some testing and test coverage. So, you can join this issue and test it. Actually, it works, but I want to get some feedback from
you about this. And plan is the sequence uh plugin. Sequence is when you uh have repeated fields. You can create, uh delete, or reorder things. So, it's a bit complicated, but still possible. Just had no time to finalize this. Yeah. And for all other element types that you want, uh you can create your own plugins and uh create them in your modules or in your websites as
a a plugin, they uh do not require changes in the um base schema form module. So, soon uh I think uh it will be a lot of uh different plugins that implements the same uh fields as we have in the uh custom fields. For example, when you create a node, you have a variety of fields, and the same can be done uh here for the configuration fields.
Or maybe you implement them faster than me because I'm not limiting you to implement this. And if you create something cool, just uh create a merge request and I will be happy to add it to the module. Uh the next feature is custom forms. Uh so, not all forms are configuration and probably you want to make some form that uh have a custom uh processing of the
submitted data. Uh and creating a simple custom form is uh also pretty easy. Uh let's create a feedback form with four fields. Uh for example, the field the first name, the last name, email, and message text. Something like this. Uh what approach will we choose? Write or write 20 lines of YAML? I think the second one now is better. Um actually, we should create uh the schema
file with uh fields like this. So, we describe just the fields, the field type, and the label. And the not blank constraint to make the field uh required. Uh yeah, two YAML files. So, we should create the routing uh to make this form available And still a bit of PHP because uh data submission can be displayed described it in YAML. It's uh usually custom logic, uh but
here you still have uh more simple approach than uh with the standard forms because um uh you create the form that extends the schema form base that already provides validation out of the box. So, if you have constraints or uh other uh validation rules, they will be applied before your PHP code start to process the submitted values. And the second function is process submitted values where you
put your all your logic that you want. For example, here we just adding a message. And here you can uh write the email or do anything you want. Uh So, it's a bit of PHP. And yes, it's already validated, so you should not spend uh your PHP uh lines on revalidating the things that already validated. Uh but soft-generated forms are kind of boring, so probably you want
to make them more beautiful. Uh for this, you can use the third-party settings section uh to customize the Uh let's add to this boring form some beauty like this. Uh so, we change the order of the fields, adding the message text, putting the message text on the first place, add add a description, first name and last name put them to one line. Uh to do this, uh
we just open the uh schema file, YAML file, and put all uh all our customization there in the third-party settings block. So, third-party settings, then schema form, form element, and there you can put any data uh as you want uh as usual with uh the PHP array, but here in the YAML format. Also, you can attach libraries, uh manipulate with weights, and uh do all other things.
And having this, uh our boring form will be uh automatically converted to the designed one. And again, with no PHP. Uh but probably some of you uh will say that uh the schema data schema is not a good place to store the markup and this kind of things because it's actually uh should describe only the data data format. And I agree with this. let's remove uh all
this from the data schema uh to make it lightweight. But not all of this. Uh I think uh one thing we should keep there, it's description because uh in the schema file we should describe what want we store there. And uh just label is not enough. For example, the endpoint URL gives no idea about uh what kind of URL should be there. And the same with access
token. So, these things uh I think it's better to keep in the description. But uh Drupal core doesn't like this. Uh it will produce a uh error. Uh so, I added this issue uh in the issue tracker and find a couple of guys that uh likes this idea. So, we created a separate uh feature request to add description property to the Drupal config object uh to make
it possible to add descriptions to any uh schema field in addition to label. I think this will be useful addition to the current to to current schema uh YAML files. Okay, if we add a description, maybe let's then allow other garbage to keep there, too. And my answer is no. This is really not a good idea. And this is a good time to introduce uh another feature,
the schema form designs. It's a separate YAML storage for your form designs. Uh to add a custom design uh for your schema, you uh you can open the administration configuration content after in schema form design page and click on the add schema form design button. Uh there a form like this will appear uh with the ID you put the identifier of your design uh to make it
possible to reference to it uh in the routes. Label is just display name in the admin panel where you can write The schema key is a reference to the schema that you want to design. If uh it's the same as the design ID, you can just uh skip this and keep the empty one And here is all the magic uh happens, design overrides. Uh so, we just
remove all uh all third-party settings with all markup from the YAML file and put them again as YAML but already in the design entity. Here is the editor where where we can edit and modify this. And right in this page you can make a live preview. So just click update preview and without saving you see the result. And you can play with design and immediately check how
it looks without saving without breaking And when it is ready, click on the save it will be added. And automatically when the model will render the form with specific schema, it will check for the schema form design and if it exists, it will apply it automatically. And if you want, you can apply it manually like this in the routing YAML here is not designed form generated automatically.
If you add the to the options the design uh section with the ID that you created, the form will be designed. And using this approach, you can even manage several designs of the same schema. So for example, the same send us your feedback form can be designed differently. You can change the fields, hide the fields, uh add different descriptions, titles, and any other modifications. But the data
structure will be the same because it's based on the same data schema. So all your submission processing will be the same but the design of the uh form will be different. That is kind of useful. Oh, and I am talking you already 10 minutes without talking about AI. Let's fix this. Adding AI to forms. Yeah, let's add that AI to our forms. So we have a boring
form without AI. And to add AI, we should create the schema form And there we just override the label for the endpoint that's access token and the title. And now we have an amazing form with AI. We have three mentions of AI there. Yes, reuse the same AI approach to design the core basic site settings form because we already did this previously but it looked not very
good with a lot of difference and missing descriptions. Uh so here you can see on the right the Drupal score form and in the middle the basic site settings form generated automatically without any design. Uh let's add the design as I showed and put there all modifications that you want. We hide the UUID field because it is not needed here. Add descriptions, manipulate with nothing complex actually,
adding titles. And in the routing file, we attach the design to this config name. we created a form almost like the Drupal score form. So in the middle you can see that the fields are missing the descriptions and on the left and on the right, they are almost the same and you can easily replace the basic site settings form without touching and modifying the core And it's
again still only YAML with no PHP. And here is how it looks in the Drupal core. The site information form is a file with more than 200 PHP lines with a lot of code and that should be maintained and updated and so on. So let's remove that boilerplate from core and generate all the base forms automatically using just YAML. It should simplify the things not only for
basic site settings but for all other forms. Let's make the Drupal core lightweight again. but most of you are programmers and you like to suffer with PHP with not YAML. Uh then you still have to still can do this. You can get the generated schema form as a base class and just extend it with your very custom in PHP as usual. So creating a you can create
a class my feedback form extending the schema form base. And in the build form, you call the parent build form that will generate the form automatically and then you put all customizations that you want. So here you are not limited to any API, just do anything that you want. And the same for the validation and submit functions. So you just receive the data, reuse the parent function
to the data from the YAML from the schema and then modify or revalidate it and do anything you want. So you are not limited to any API. Schema form is just providing you the boilerplate that you do not need to write. Yeah, that's all look great, I suppose, you don't want to install one more module just for this. It's too much for simple feature. Let's explore maybe
a Drupal core still provides something like this. Actually, I explored it several times and found only issues. this issue is about allowing forms to be defined at in three segments, schema, UI, and data. And actually it's from uh 17. Pretty old one and still no progress there. So the idea came a long time ago two people. The next one is extend config schema for each of the
default experience. It's kind of the same and the same from the same year but And add the weight automatically generate basic site forms. This is pretty fresh issue. It describes the same idea but got stuck with the implementation. And this is a kind of trigger that triggers me to create this module actually. So let's join and finally add this to So just test the schema form module
and if it works, we can try to move it to core to have it If you want more examples, you can check the schema form test file. There I tried to cover all the cases and all the features that module provides. And actually it's used it for testing all commits on regressions. So you can be sure that everything works there correctly and use the modern approach without
any outdated features. Also, I published documentation on a separate page. You can use this QR code and there I tried to describe the whole idea and the main features that the module provides, examples, and so on. And let me repeat the the appeal. Stop creating Drupal forms and start declaring Drupal forms using simple YAML instead of that PHP. but maybe who already opened the module page figured
out that this is the alpha version. And mostly this is because of this. Only my site is using this module. Uh and because of this, I afraid to release the stable version. I want to somehow from you. So please test this module on your sites to ensure that the API is suitable for everyone. Fill the issues, share your ideas, and I will try to implement this before
releasing the stable version because after releasing the stable version, introducing breaking changes is not but probably you are not ready to install alpha modules from some Alexey to your damn stable website because it can explode. Let's explore the alternatives. And actually there several alternatives. I found two direct alternatives to this module, automatic configuration form and schema based config forms. They resolve the same problem actually with the
same Let's compare them. Uh so by reported installs, they a bit better than me. the automatic configuration form is five four times better than me. But still not a lot. all these modules provide building forms directly from the schemas without that the number of supported field types differs. The schema based config forms have more than 12 field types and I still try to at least 10. widgets
can be provided by plugins in the schema form file and schema form And automatic configuration form let's hardcode the things. Uh form handler for config entities is implemented only in the schema form. All other modules require manual suffering as PHP. and creating forms pages by YAML without PHP is also possible only with schema form. All other modules force you to create classes, PHP, and produce bugs in
your PHP code. Uh custom field settings in the YAML declaration is possible in the schema form and schema base config form where you can copy your schemas with all the design stuff and markup that is not good. And customizing system forms without modifying schema without putting everything into the schema is available only in the schema form. So, actually we have the winner there, Except the first line
of this table. Uh, and if you already use one of these four or two users of these alternatives, you can migrate to schema Uh, you just need to rewrite your schemas from scratch to the new format. Actually, I'm just kidding. You just remove this modules and install schema form and it uses same format. So, you don't need to change anything. Just replace the modules and they will
work as usual without any changing code Also, there are a bunch of modules with content entities. One of them was presented today's morning in another room. It's config pages. And there are similar modules, site settings and labels, ESC site settings and content entity builder. They are very powerful, very one thing that differs them from this Because they store everything as a content entities, but not configuration. Uh,
but we are here to store the configuration. And configuration is the configuration and the content is content. Let's not mix the things and use the right things to to store the configuration settings. And if you need to make them editable by end users or different different pair environment, we can use config split, config ignore and all other thousand ways that Drupal provide. So, it's actually not a
problem and using this module you use the right storage, the config storage that can be exported, imported you can keep all the changes in the config in the Git history. So, since no alternatives and you should brace yourself and still add the schema form module to your website. Be brave. Uh, and together with this you can help with Yeah, the first one is just install the module,
start using it and report bugs, how it broke your stable website. And I will try to do the best to resolve your issues. And the second one is make some floods in the issues to move them forward and to make this feature available out of the box in the Drupal core not as a country module from some Alexey. So, the first one is add the way to
automatically generate basic config forms. It's exactly what I implemented, but just to move it in core into core. The second one is adding description because everyone will receive a lot of good things from this, not only my Allow forms to be defined in three segments, schema, UI and data is the same almost idea, but let's try to move it forward by two ways. Enhancing config schema for
richer default experience is about adding custom values to the schema because now it's limited to the type of the value and the label and that's it. So, you can't extend it. But in some cases you want to do this. And last one is about adding third-party settings property to the Drupal schema to allow not only schema form, but any other module to put third-party settings to reuse.
Using the same approach not for schema design, but for everything else. And actually, that's all that I wanted to show you. Let me repeat the appeal. Stop creating Drupal forms. Start declaring Drupal Uh, if you want to get the presentation, you can use this QR code. It's available right now for free. And if you have questions, it's now good time to ask them. And if no questions,
you can use this QR code to leave the feedback. Yeah, and if you have some questions, I will be happy to answer. Yeah? I might have covered this earlier, but so like if you wanted to have your regular submit button and another button that like does something a little bit different, you could still override your and edit the submit form method kind of thing? Yeah, yeah. So,
the question is how to customize the submit buttons. Yeah, you can use the schema form class as a base. It provides you the automatically generated array and then you just add button, remove buttons, put any other handlers and so on. So, you're not limited. It erases boilerplate for you that you you already described the things in the schema and describing the same in PHP and managing the
same things in two places is always is not a good idea. So, you just get the base and then do everything you want that you want. Yeah, more questions? Mm, since no questions, that means that I did well and I Thank you for your attention and start to use my module.