Extended Attributes

overview

Extending attributes will allow to create new attribute types (i.e. available in any content_type) based on some generic types.

Genreric types are our previous attribute_type:

  • TEXT
  • LARGETEXT
  • RICHTEXT (these could also be put as a single TEXT generic type
  • INT
  • URL
  • FILE
  • CHOICE

As these generic types are very limited (I can see only 5 as LARGETEXT and RICHTEXT could be extended TEXT attributes) we can simply store their ID's as Php Constants and avoid creating an attribute_generic_type table in DB)

proposed schema

CREATE TABLE `attribute_type` (
  `attribute_type_id` int(11) NOT NULL default '0',
  `generic_type_id` varchar(64) NOT NULL default '',  <- added field
  `name` varchar(64) NOT NULL default '',
  `alias` varchar(255) NOT NULL default '',
  `params` text,                                      <- added field
  PRIMARY KEY  (`attribute_type_id`)
)

proposed data

INSERT INTO `attribute_type` VALUES (1, 'CHOICE', 'BRAND', 'Brand', 'a:3:{s:4:"type";s:4:"list";s:8:"multiple";b:1;s:4:"list";a:2:{s:3:"foo";s:3:"bar";s:3:"baz";s:4:"quux";}}');

usage in content type mgr admin inteface

Alias        Name      Type
=====        ====      ====
[My Attrib]  myAttrib  [Brand]

creating new content

  • combobox is rendered for chosen attribute

storing a selected brand

INSERT INTO `attribute_data` VALUES (4, 2, 4, 'foo');  -- store key

adding flexibility to widgets

If we stored meta data in hash we could have multi-select comboboxes as well, eg:

$data = array(
            'type' => 'select', // could also be check, radio
            'multiple' => false, // true for multi-select
            'data-inline' => array(
                'key1' => 'val1',
                'key2' => 'val2',
                ),
        );

We could also have dynamic lists, where keys and values would be linked to some table fields

$data = array(
            'type'     => 'select',
            'multiple' => false, // true for multi-select
            'data-db'  => array(
                'listTable'  => 'countries',
                'listKey'   => 'country_id',
                'listValue' => 'country_name'
                ),
            'options' => array(
                'sortBy'    => 'name',
                'sortOrder' => 'ASC',
                'limit'     => 5,
                'filters'   => array(....TBC...)
            ),
        );

We could also have static lists, where keys and values are populated from a PHP or XML file:

$data = array(
            'type'     => 'select',
            'multiple' => false, // true for multi-select
            'data-file' => array(
                'type'        => 'PHP',
                'location'    => '/modules/default/data/data.attributelist.countries.php', // path from SGL_PATH
            ),
        );

To access attribute list data call SGL_Attribute::getData(); Any PHP file defining list data assume data will be available via a variable called $aData:

$aData  = array(key1 => value1, key2 => value2, key3 => value3); 

a list attribute type - visibility

  1. option in attribute_type (meaning the defined attribute_type is available for any content_type)
  2. option in attribute (meaning the defined attribute_type is available once for a specific content_type)
  3. options in attribute_data (meaning the defined data will only customise one instance of the attribute)

requirements

  • adding new fields to attribute_type
  • updating Content.php and ContentDAO.php so an attribute typeId now references the attribute_type.generic_type_id instead of attribute_type.attribute_type_id
  • update CmsOutput?.php and Editable.js so they are able to build/parse our extended attributes

Attribute lists

Many content types will have attribute lists associated with them (enumerations). If one attribute element of a content type is country, the attribute list will be a list of countries.

One way of storing this is adding a serialized additional field to the attribute table. The field could be called 'options' and would contain hash of the info.

Then the corresponding attribute data field would list the selected key, IOW the data field would hold the attribute list's selected index.

Example:

// data
$a = array('foo' => 'bar', 'baz' => 'quux');

// ready for storage in attribute.options
a:2:{s:3:"foo";s:3:"bar";s:3:"baz";s:4:"quux";}

// if quux was pre-selected, attribute_data.value contains
baz

Ability to assign options to attributes

Some attributes may have some options

  • choice : type (radio/checkbox), labels, values

Ability to assign parameters to attribute datas

Add param field to attribute_data table.

Some attribute_data, i.e. instances of an attribute may have some params:

  • upload (media/image) : mode (preview, link), size (from thumbnail sizes), alt text, title
  • links : text (instead of the link href)

Ability to override some options (attribute level) by some params values (attribute_data level)

In the example of an upload attribute we may decide that we'll show a preview of the media, or even force the type of the media to choose from.

Then we may want to force the media size to be small, or let the user decide when she will actually create an instance of the attribute.

Should we implement this?

Reference VS Manual list selection

Anytime an enumeration will be possible in the option/param of an attribute/attribute_data, the list of values could come from a reference to an existing list (countries, thumbnail sizes) or be manually entered.