fiedsch / contao-jsonwidget
widget for Contao Open Source CMS backend forms
Installs: 19 857
Dependents: 2
Suggesters: 0
Security: 0
Stars: 6
Watchers: 1
Forks: 1
Open Issues: 0
Type:contao-bundle
Requires
- php: ^8.1
- ext-json: *
- contao/core-bundle: ^4.9 || ^5.1
- symfony/yaml: ^4.2 || ^5.0 || ^6.0
Requires (Dev)
- phpunit/phpunit: ^9.5
README
The jsonWidget
can be used in DCA files to create a text field that contains a JSON string.
While saving it will be checked if that the string is valid JSON.
The widget displays the JSON string with JSON_PRETTY_PRINT
so that checking/finding errors
is easier for the user.
The yamlWidget
is mostly the same, except that it uses the YAML format.
Example: extending Members
DCA
$GLOBALS['TL_DCA']['tl_member']['fields']['json_data'] = [ 'inputType' => 'jsonWidget', 'label' => &$GLOBALS['TL_LANG']['tl_member']['json_data'], 'eval' => ['tl_class' => 'long', 'decodeEntities' => true], 'sql' => "blob NULL", ]; // Add json_data to $GLOBALS['TL_DCA']['tl_member']['palettes']['default'] // where ever you like
Other valid options in eval
are the same as for textarea
s (as WidgetJSON
extends TextArea
),
except that setting rte
will be ignored because the editors provided do not make sense here.
How to use the JSON data?
Extend tl_member
as in the above example. Then create an ExtendedMemberModel
that
extends Contao's MemberModel
. In the magic methodd __set()
and _get
you can intercept
the "fields" stored in json_data
. The Fiedsch\JsonWidgetBundle\JsonGetterSetterTrait
takes
care of that:
// models/ExtendedMemberModel.php namespace Contao; use Fiedsch\JsonWidgetBundle\Traits\JsonGetterSetterTrait; class ExtendedMemberModel extends MemberModel { // let __set() and __get() take care of the JSON or YAML data (both at the same time will not work!) use JsonGetterSetterTrait; // or (see above!) use YamlGetterSetterTrait; /** * The column name we selected for the `jsonWidget` in the example above * @var string */ protected static $strJsonColumn = 'my_json_data_column'; /** * Same thing for the `yamlWidget` * @var string */ protected static $strYamlColumn = 'my_yaml_data_column'; }
// config/config.php $GLOBALS['TL_MODELS']['tl_member'] = 'Contao\ExtendedMemberModel';
Using the Model
$member = \ExtendedMemberModel::findById(42); // access fields columns created by contao's default DCA printf("read member %s %s\n", $member->firstname, $member->lastname); // access a field stored in our JSON data column printf("transparently accessing a field from the JSON data ... '%s'\n", $member->whatever); // set values and store in database $member->a_key_for_a_scalar_value = "fourtytwo"; $member->key_for_an_array = ['an','array','containing','some','strings']; $member->save(); // Note that saving will lose comments in your YAML-data // as Symfony\Component\Yaml\Yaml will not save them
YAML-Syntax Highlighting with ACE
Set
'eval' => [ /* ... , */ 'rte'=>'ace|yaml'],
in your field's DCA definitions.
Quick and dirty way: add desired CSS-Rules like e.g.
.ace_comment { color: red !important; }
to your be_ace.html5
(which you create it if you do not yet have a custom version).
OR: use a custom backend style and add the CSS rules there.
Set JSON (or JAML) Data
If you want to set all the JSON (or YAML) data at once you cannot use
# In this example we assume $strJsonColumn = 'json_data'; $data = [ 'foo' => 1, 'bar' => 'baz ]; $model->json_data = $data; # will throw an exception
To do this you have to use
$data = [ 'foo' => 1, 'bar' => 'baz ]; $model->setJsonColumnData(array $data); # or # $model->setYamlColumnData(array $data);
Note that this way previously set JSON (or YAML) data is overwritten.
Also note that the behaviour of setJsonColumnData([])
(when setting an empty data array) changed in version 0.5.0
. Previously it created []
where it
now creates {}
in the respective database column.
In version 0.7.0
we slightly changed this again to achieve the original goal: The storage of empty arrays as object ({}
) is only enforced on the top level
of the data. In lower levels, empty arrays will be stored as arrays ([]
) not as "empty" objects ({}
): compare
{ "foo": [] }
(versions >= 0.7.0) to { "foo": {} }
(versions >=0.5.0 and <0.7.0).