3

When you use a form macro to generate an input in the CP, you'll end up with something like this...

<input type="text" id="fields-myField" name="fields[myField]">

Oddly, it looks like "myField" is generally passed around the code as a single name value.

What code in Craft core is responsible for automatically appending the fields- to the id attribute, and wrapping fields[] around the name attribute?

I've scoured the Craft core code and just can't find it. That magic doesn't seem to be happening in a Twig macro or JavaScript.

6

I believe its the namespace twig template function - and fields typically use the default namespace as fields. This is defined under templates/_includes/fields.html

Looking at that file (below), you'll notice that if you don't provide a namespace variable to the include, it'll use fields.

{% if element is not defined %}{% set element = null %}{% endif %}
{% if namespace is not defined %}{% set namespace = 'fields' %}{% endif %}

{% namespace namespace %}
    {% for field in fields %}
        {% include "_includes/field" with {
            field:    field.getField(),
            required: field.required,
            element:  element,
            static:   (static is defined ? static : null)
        } only %}
    {% endfor %}
{% endnamespace %}

In another scenario, you might have the following in your regular templates:

{% namespace 'myNamespace' %}
  <input id="test" name="test">
  <input id="another-test" name="another-test">
{% endnamespace %}

Which would produce the equivalent, rendered HTML of:

<input id="myNamespace-test" name="myNamespace[test]">
<input id="myNamespace-another-test" name="myNamespace[another-test]">

Its particularly useful in plugins or other complicated field handling where you don't have to worry about settings up name attributes (heaven forbid you have to change all your field name attributes with lots of fields!). This way, you can easily provide a wrap of context to your fields, while keeping the form elements pretty lean.

Another important factor is the ID generation, which also flows onto labels for field - useful for accessibility.


In PHP, this is done with the TemplatesService::namespaceInputs method...

craft()->templates->namespaceInputs($element, $namespace);

You can read a detailed breakdown of how this method works in the class reference docs...

  • Amazing, thanks @crawf! You definitely got me pointed in the right direction. Once I knew where to look, I dug a little deeper and found out where this is happening in the PHP, and added that PHP info to your already-excellent answer. :) – Lindsey D Feb 27 '17 at 6:44
  • Ah gotcha, yeah thats a handy function on the PHP-side too. – crawf Feb 27 '17 at 6:54

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.