In Contao palettes are defined as array of strings like this:
'palettes' => array(
'__selector__' => array('type'),
'default' => '{title_legend},type,title;{published_legend:hide},published',
'type_one' => '{title_legend},type,title;{experts_legend:hide},expert_option;{published_legend:hide},published',
),
'subpalettes' => array(
'published' => 'start,stop'
),
Which is very limited in every case. Strings make it difficult to manipulate palettes. And there is only two level of conditional fields, the palette selection and subpalettes. Because string based palettes are very limited, the MetaPalettes extension tries to extend palettes by defining them as arrays of arrays like this:
'palettes' => array(
'__selector__' => array('type')
),
'metapalettes' => array(
'default' => array(
'title' => array('type', 'title'),
'published' => array(':hide', published')
),
'type_one' => array(
'title' => array('type', 'title'),
'experts' => array(':hide', 'expert_option'),
'published' => array(':hide', published')
)
),
'metasubpalettes' => array(
'published' => array('start', 'stop')
),
MetaPalettes make the definition and manipulation of palettes easier, but it is still hardly limited in fact it only generate string based palettes from the arrays. Everything else is done by Contao’s DC_Table.
To break the known limitations, the DC General contains an object oriented palette system.
Container
\-1:1- PaletteCollection
\-( contains a set of palettes )
\-1:n- Palette
\-( contains a set of legends )
\-( can have a condition that define the active palette )
\-1:n- Legend
\-( contains a set of properties aka fields )
\-1:n- Property
\-( a property aka field in a legend )
\-( can have conditions that define if the property is visible and editable )
There is no place for subpalettes or something similar. Instead of use a direct hierarchical bounding between fields, each field can have a condition (or more through a chain) that define if the field is visible and/or editable.
Same for palettes, which will not selected by their name (the name is supported, but is marked as deprecated will be dropped in the future). Palettes even can have a condition (or more through a chain) that define if the palette is active or not.
Properties has two conditions. One for its visibility and one for the editable state. If no condition is set, the property is supposed to be visible and editable.
Palette conditions are a bit more complex, even if they have only one condition. To determinate the active palette, a matching count is calculated from the condition. The DefaultPaletteCondition produce a matching count of 0 (the lowest value by definition, negative values are not supported). Every other condition produce a matching count of 1 or greater. A PaletteConditionChain summarize all counts from its conditions. A false matching count means “no matching”. The palette with the highest matching count is supposed as active palette.
The palettes are object oriented, that means you can directly create your palettes via PHP code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | // main objects
use DcGeneral\DataDefinition\Palette\PaletteCollection;
use DcGeneral\DataDefinition\Palette\Palette;
use DcGeneral\DataDefinition\Palette\Legend;
use DcGeneral\DataDefinition\Palette\Property;
// conditions for palettes
use DcGeneral\DataDefinition\Palette\Condition\Palette\DefaultPaletteCondition;
use DcGeneral\DataDefinition\Palette\Condition\Palette\PropertyValueCondition as PalettePropertyValueCondition;
// conditions for properties
use DcGeneral\DataDefinition\Palette\Condition\Property\PropertyValueCondition;
// default palette
{
// create type property
$typeProperty = new Property();
$typeProperty->setName('type');
// create title property
$titleProperty = new Property();
$titleProperty->setName('title');
// create published property
$publishedProperty = new Property();
$publishedProperty->setName('published');
// create start property
$startProperty = new Property();
$startProperty->setName('start');
$startProperty->setCondition(new PropertyValueCondition('published', true));
// create stop property
$stopProperty = new Property();
$stopProperty->setName('stop');
$stopProperty->setCondition(new PropertyValueCondition('published', true));
// create title legend
$titleLegend = new Legend();
$titleLegend->setName('title');
$titleLegend->addProperty($typeProperty);
$titleLegend->addProperty($titleProperty);
// create published legend
$publishedLegend = new Legend();
$publishedLegend->setName('published');
$publishedLegend->addProperty($publishedProperty);
$publishedLegend->addProperty($startProperty);
$publishedLegend->addProperty($stopProperty);
// create default palette
$defaultPalette = new Palette();
$defaultPalette->setName('default');
$defaultPalette->addLegend($titleLegend);
$defaultPalette->addLegend($publishedLegend);
$defaultPalette->setCondition(new DefaultPaletteCondition());
}
// type_one palette
{
// create type property
$typeProperty = new Property();
$typeProperty->setName('type');
// create title property
$titleProperty = new Property();
$titleProperty->setName('title');
// create expert option property
$expertOptionProperty = new Property();
$expertOptionProperty->setName('expert_option');
// create published property
$publishedProperty = new Property();
$publishedProperty->setName('published');
// create start property
$startProperty = new Property();
$startProperty->setName('start');
$startProperty->setCondition(new PropertyValueCondition('published', true));
// create stop property
$stopProperty = new Property();
$stopProperty->setName('stop');
$stopProperty->setCondition(new PropertyValueCondition('published', true));
// create title legend
$titleLegend = new Legend();
$titleLegend->setName('title');
$titleLegend->addProperty($typeProperty);
$titleLegend->addProperty($titleProperty);
// create experts legend
$expertsLegend = new Legend();
$expertsLegend->setName('experts');
$expertsLegend->addProperty($expertOptionProperty);
// create published legend
$publishedLegend = new Legend();
$publishedLegend->setName('published');
$publishedLegend->addProperty($publishedProperty);
$publishedLegend->addProperty($startProperty);
$publishedLegend->addProperty($stopProperty);
// create default palette
$defaultPalette = new Palette();
$defaultPalette->setName('default');
$defaultPalette->addLegend($titleLegend);
$defaultPalette->addLegend($expertsLegend);
$defaultPalette->addLegend($publishedLegend);
$defaultPalette->setCondition(new PalettePropertyValueCondition('type', 'type_one'));
}
// create the palette collection and add all palettes
$collection = new PaletteCollection();
$collection->addPalette($defaultPalette);
$collection->addPalette($typeOnePalette);
|
This create the same palette as the example in the first chapter History and basics.
The PHP example show how to create palettes by directly accessing the API. Using the API may result in a lot of code. If you need to use PHP, it is easier to use the Palette builder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | use DcGeneral\DataDefinition\Palette\PaletteBuilder;
$collection = null;
PaletteBuilder::create()
->createPalette('default')
->createLegend('title')
->createProperty('type', 'title')
->finishProperty()
->finishLegend()
->finishLegend()
->createLegend('published')
->createProperty('published')
->finishProperty()
->createProperty('start', 'stop')
->createPropertyValueCondition('published', true)
->finishCondition()
->finishProperty()
->finishLegend()
->finishPalette()
->createPalette('type_one')
->createPropertyValueCondition('type', 'type_one')
->createLegend('title')
->createProperty('type', 'title')
->finishProperty()
->finishLegend()
->createLegend('experts')
->createProperty('expert_option')
->finishProperty()
->finishLegend()
->createLegend('published')
->createProperty('published')
->finishProperty()
->createProperty('start', 'stop')
->createPropertyValueCondition('published', true)
->finishCondition()
->finishProperty()
->finishLegend()
->finishPalette()
->finishPaletteCollection($collection);
|
Using the build simplify the palette creation a lot. And can be more simplified by simply omitt the finishPalette(), finishLegend(), finishProperty() and finishCondition() calls. The finish* methods are only required in two situations. First if you need to “close” the current element to make sure the next call will be affect the previous element (this is required for create*Condition which can affect palettes or properties. And second if you want to “fetch” the build element, in the example this is done by finishPaletteCollection($collection). All finish*() methods “return” the created element by reference back into the parameter.
Hint: The createProperty method is a little special, because it accept multiple property names. If you pass multiple property names, they will be considered as a set of properties. All following calls will affect the complete set, not only the last property. This is useful if you need to add the same condition to multiple fields, like the start and stop properties in the example above.
Parsers are used to create palettes from other data formats than PHP.
TODO there are currently no parsers exists, this chapter will be completed if there are any parsers