Jump to content

Inputfield setup made more concise?


petsagouris
 Share

Recommended Posts

I have been digging in the Processwire source to find out how everything works for making some contributions.

I noticed that module configuration is similarly to this (Taken from the ModulesManager module by Soma):

static public function getModuleConfigInputfields(array $data) {
  $data = array_merge(self::$defaults, $data);

  $fields = new InputfieldWrapper();
  $modules = wire("modules");
    
  $field = $modules->get("InputfieldText");
  $field->attr('name', 'apikey');
  $field->attr('size', 10);
  $field->attr('value', $data['apikey']);
  $field->label = "modules.processwire.com APIkey";
  $fields->append($field);

  $field = $modules->get("InputfieldText");
  $field->attr('name', 'remoteurl');
  $field->attr('size', 0);
  $field->attr('value', $data['remoteurl']);
  $field->label = "URL to webservice";
  $fields->append($field);

  $field = $modules->get("InputfieldInteger");
  $field->attr('name', 'limit');
  $field->attr('value', $data['limit']);
  $field->label = "Limit";
  $fields->append($field);

  $field = $modules->get("InputfieldInteger");
  $field->attr('name', 'max_redirects');
  $field->attr('value', $data['max_redirects']);
  $field->label = "Max Redirects for file_get_contents stream context (in case)";
  $fields->append($field);

  return $fields;
}

Would it be cleaner if Processwire allowed for a way to pass an array to setup the fields and maybe even pass an array of arrays of fields to generate an InputfieldWrapper (for instance)?

something like:

static public function getModuleConfigInputfields(array $data) {
  $data = array_merge(self::$defaults, $data);

  $fields = new InputfieldWrapper();
  $modules = wire("modules");
   
  $fields->append(array(
    'module' => 'InputfieldText',
    'attributes' => array( 'name' => 'apikey', 'size' => 10, 'value' => $data['apikey'] ),
    'label' => _('modules.processwire.com APIkey'),
    ));

  $fields->append(array(
    'module' => 'InputfieldText',
    'attributes' => array( 'name' => 'remoteurl', 'size' => 0, 'value' => $data['remoteurl'] ),
    'label' => _('URL to webservice'),
    ));

  $fields->append(array(
    'module' => 'InputfieldInteger',
    'attributes' => array( 'name' => 'limit', 'value' => $data['limit'] ),
    'label' => _('Limit'),
    ));

  $fields->append(array(
    'module' => 'InputfieldInteger',
    'attributes' => array( 'name' => 'max_redirects', 'value' => $data['max_redirects'] ),
    'label' => _('Max Redirects for file_get_contents stream context (in case)'),
    ));
   
  return $fields;
}

Or even:

static public function getModuleConfigInputfields(array $data) {
  
  $data = array_merge(self::$defaults, $data);

  return new InputfieldWrapper(
    array(
      array(
        'module' => 'InputfieldText',
        'attributes' => array( 'name' => 'apikey', 'size' => 10, 'value' => $data['apikey'] ),
        'label' => _('modules.processwire.com APIkey'),
        ),
      array(
        'module' => 'InputfieldText',
        'attributes' => array( 'name' => 'remoteurl', 'size' => 0, 'value' => $data['remoteurl'] ),
        'label' => _('URL to webservice'),
      ),
      array(
        'module' => 'InputfieldInteger',
        'attributes' => array( 'name' => 'limit', 'value' => $data['limit'] ),
        'label' => _('Limit'),
        ),
      array(
        'module' => 'InputfieldInteger',
        'attributes' => array( 'name' => 'max_redirects', 'value' => $data['max_redirects'] ),
        'label' => _('Max Redirects for file_get_contents stream context (in case)'),
        )
      ));
}

Such a attitude towards form and input declaration can open the door to having forms stored in a structured static data format and just have them fed into to the appropriate container object.

If the 'array(' parts are too much on the eyes remember that PHP 5.4 has short array syntax using [ and ].

Link to comment
Share on other sites

Hi pestagouris

I don't see the benefit? :)

Problems:

1. What about $field->collapsed, $field->notes? You'd need new keys

2. What if you want to call a method on the Inputfield after creating it and before adding it to the Wrapper? You can't because you don't create the objects anymore.

Link to comment
Share on other sites

$field->collapsed|notes are going to be treated the same as the $field->label in the above example. All the magic attributes are known before hand by the Inputfield so there is no problem to actually pass an array and let the Inputfield object do the work of assigning the configuration to the object.

From the first post it isn't clear that the intent is not to remove existing behavior. The object creation is not going away in fact it is going to be used at the Inputfield level (at a deeper level in the inheritance tree) by using the data inputted from the field configuration array.

The way I have understood the current situation is that making a field is basically "configuring" a field. Since there is nothing dynamic about inputing configuration, that is exactly what I am proposing to make easier.

Link to comment
Share on other sites

I think Ryan has pretty much build this kind of behaviour with form builder form export/import. Here is children (= fields) part of one form:

{
    "children": {
        "your_name": {
            "type": "Text",
            "label": "Your name",
            "required": 1,
            "columnWidth": 50,
            "maxlength": 2048
        },
        "your_email": {
            "type": "Email",
            "label": "Your email",
            "required": 1,
            "columnWidth": 50,
            "maxlength": 512
        },
        "tours": {
            "type": "Page",
            "label": "Tours you are interested in",
            "columnWidth": 50,
            "template_id": 59,
            "labelFieldName": "title",
            "inputfield": "InputfieldCheckboxes"
        },
        "accommodation": {
            "type": "Page",
            "label": "Accommodation options you are interested in",
            "columnWidth": 50,
            "parent_id": 1046,
            "labelFieldName": "title",
            "inputfield": "InputfieldCheckboxes"
        },
        "size": {
            "type": "Text",
            "label": "Size of your group",
            "required": 1,
            "columnWidth": 100,
            "maxlength": 2048
        },
        "information": {
            "type": "Textarea",
            "label": "Other information and questions you might have for us?",
            "columnWidth": 100,
            "rows": 5
        },
        "minimum_budget_available": {
            "type": "Text",
            "label": "Minimum budget available",
            "columnWidth": 50,
            "maxlength": 2048
        },
        "maximum_budget_available": {
            "type": "Text",
            "label": "Maximum budget available",
            "columnWidth": 50,
            "maxlength": 2048
        }
    }
}
  • Like 1
Link to comment
Share on other sites

Apeisa is correct in that inputfields can be represented as arrays, and it's fairly simple to convert them to or from arrays. In the case of FormBuilder, the forms are converted to an array and then to JSON for storage. So far the only place I've found this useful is in FormBuilder, though I'm sure there's more potential.

As for manually composing inputfields or forms via arrays, I don't really like doing that because there is no interface… just a faceless array. Reminds me a little too much of configuring forms in Drupal. :) But I'm fine with supporting the option if people like it. 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...