Posted on 2013-07-29 20:00:00+00:00
The Drupal Form API is powerful, but very extensive and complicated. In another post we discussed how to add a custom element from scratch. Watch out for the errors and mistakes highlighted in this advanced-level post.
To fully understand the API, you need to understand
how elements are built. When you define a form field, custom or not, you have
to give it a #type
.
When the form is being built, Drupal will look at the #type
and decide what
to do with it. If it's a custom element you've defined, Drupal will look at the
hook_element_info()
that defined that custom element, and grab all the
information from that array. That is, keys and values in that array will be
merged into your field. This allows you to set defaults for that element
#type
. Let's look at an example. For simplification, let's define a basic
custom element type:
1 2 3 4 5 6 7 8 |
|
Note that this element won't do much. But now, let's use it in a form:
1 2 3 4 5 6 7 8 |
|
If we want each usage of the element to, by default, have certain properties,
we can just add it to the hook_element_info()
function. So doing this:
1 2 3 4 5 6 7 8 9 |
|
Will mean that all uses of your element in forms would be as if you had declared the form like so:
1 2 3 4 5 6 7 8 9 |
|
In other words, #some_property
will "bubble" up from the element declaration
to the actual element useful.
This means you can do powerful things, like declaring default #theme
functions,
default #prefix
and #suffix
content, etc.
To summarize: the form declaration for that element will get merged to the properties
defined in hook_element_info()
. So keep this in mind when defining your custom
elements.
So you've defined your custom element, but now want to control its appearance.
Easy right? Just give it a #theme
function in hook_element_info()
. Well,
it's not that simple.
You might notice it's not rendering now or ignoring your theme function. So you
go and add that function to the theme registry, using hook_theme()
.
But now we have another problem: our theme function isn't being called with the
right arguments. That's because when defining this function in hook_theme()
,
you need to use the render element
property, rather than your typical
variables
property. As follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
And there you go: two big secrets about custom Drupal elements. With this knowledge on hand, you should be able to create all the custom elements you'll need. Without surprises.