processwire / processwire-requests

ProcessWire feature requests.
40 stars 0 forks source link

Create New Fields/Template via API+JSON #79

Open ethanbeyer opened 7 years ago

ethanbeyer commented 7 years ago

Short description of the enhancement

My suggestion is to allow passing the exported JSON from ProcessTemplateExportImport & ProcessFieldExportImport to the PW API in order to construct a new Template or Field.

This would allow for dummy-proof, API-based, Templates and Fields in a version-controllable way.

Optional: Steps that explain the enhancement

  1. Copy the JSON object from /admin/setup/template/export/ or /admin/setup/field/export/
  2. Assign JSON to PHP variable: $exported_json = '{ "project": { ... } }';
  3. Create new Template(s) or Field(s) via API

Current vs. suggested behavior

Currently, the ProcessTemplateExportImport & ProcessFieldExportImport Modules provide the most direct, robust, and complete way of exporting a Template or Field in its entirety so that the Templates/Fields in question can be added to another installation.

The issue is that maintaining Templates and Fields over multiple environments of the same site is incredibly time consuming. @LostKobrakai's Migrations Module makes this process code-based so that values are version controlled and deploy-able. I love it--it is an awesome addition to the sites I work with; but creating a new Template or Field via the API is very complex (from Migrations' Docs):

$f->name = "num_max_participants";
$f->type = "FieldtypeInteger";
$f->label = "Max. Participants";
$f->description = "The maximum number of participants for this event.";
$f->collapsed = Inputfield::collapsedNever;
$f->zeroNotEmpty = 1;
$f->min = 0;
$f->inputType = "number";
$this->insertIntoTemplate("event", $f->name, "date");

That's only a few of the values you might need to adjust, and I can never find these in the Docs anyways. Writing Migration code for a Template that contains a Repeater Field is an immense undertaking.

My suggestion is to allow passing the exported JSON to the API in order to construct a new Template or Field because it leaves a much smaller margin for error. Potentially something like this:

$t = new Template();
$t->importJson($exported_json);
$t->save();

Or

$f = new Field();
$f->importJson($exported_json);
$f->save();

Why would the enhancement be useful to users?

  1. Fewer lines of code in order to achieve a better result.
  2. Version Control of the JSON that is used to construct the Template(s) or Field(s).
  3. One JSON Export could technically install potentially hundreds of Templates or Fields. Again, cutting down on complexity.
  4. When paired with the Migrations Module, perfect Templates and Fields can be updated or downgraded.
Toutouwai commented 7 years ago

It's possible to do this already with only a couple of steps beyond what you are proposing here. You just have decode the JSON and create your field properties from the array.

$json = '
{
    "text_1": {
        "id": 141,
        "type": "FieldtypeText",
        "flags": 0,
        "name": "text_1",
        "label": "Text 1",
        "textformatters": [
            "TextformatterSmartypants",
            "TextformatterEntities"
        ],
        "collapsed": 0,
        "size": 0,
        "maxlength": 2048,
        "showIf": "",
        "columnWidth": 100,
        "required": "",
        "requiredAttr": "",
        "requiredIf": "",
        "minlength": 0,
        "showCount": 0,
        "stripTags": "",
        "placeholder": "",
        "pattern": ""
    }
}
';
$data = wireDecodeJSON($json);
foreach($data as $field_data) {
    unset($field_data['id']);
    $f = new Field();
    foreach($field_data as $property => $value) {
        $f->$property = $value;
    }
    $f->save();
}

See ProcessFieldExportImport.php and ProcessTemplateExportImport.php for how the process modules handle it.

ethanbeyer commented 7 years ago

That's pretty solid. Does this mean there is no case for making this a part of core?

LostKobrakai commented 7 years ago

The json import/export is still considered beta and for some fieldtypes this is very true, so I'd really suggest using the API and not the json representation for anything automated.

ethanbeyer commented 7 years ago

@LostKobrakai I totally get where you're coming from.

If, as a beta feature, JSON Import/Export is not to be trusted, I guess the only thing to fall back on is the Documentation for Templates and Fields. But at the same time, wouldn't making improvements to Import/Export be worthwhile for those edge cases, as well?

LostKobrakai commented 7 years ago

Yeah it would be nice to have a reliable json export/import for all fieldtypes, but we can really only provide that for core fieldtypes. 3rd party fieldtypes are probably even more messy. I can really feel your pain as I got my knowledge about all those api properties by checking fieldnames in the field edit screen of the backend of various core files as well. It's certainly improvable, but I'd start with documentation, which helps people as soon as it's created. Most often the properties one does need to set to an field are mostly core (Inputfield.php / Fieldtype.php) properties inherited by all types of fields, while only the smaller subset is actually dependent on what field you need to create.

ethanbeyer commented 7 years ago

I know that right now the Docs are sourced through the actual PHP files themselves; would it be helpful for me to work on improving the docs and their general organization as a part of the ongoing development of PW?

As it stands, I will probably be writing my own set of Docs for at least this process, because it just doesn't make sense to not have easy access to every method and property the API offers.